From 5628abb8763878451359a100affa0c68048b2c3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patryk=20G=C3=B3rka?= Date: Fri, 19 Jan 2024 11:58:37 +0100 Subject: [PATCH] feat: register e2ei root cert before the first enrollment (#16557) * feat: register e2ei root cert before the first enrollment * test: add method to core mocks * test: add check if register server certs method was called after init * chore: bump core --- package.json | 2 +- src/__mocks__/@wireapp/core.ts | 1 + .../E2EIdentity/E2EIdentityEnrollment.test.ts | 31 ++++++++++--------- .../E2EIdentity/E2EIdentityEnrollment.ts | 4 ++- src/script/main/app.ts | 2 +- .../FeatureConfigChangeHandler.tsx | 2 +- .../Features/E2EIdentity.ts | 2 +- yarn.lock | 10 +++--- 8 files changed, 29 insertions(+), 25 deletions(-) diff --git a/package.json b/package.json index 6ee5cec3488..69e1f76db36 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ "@peculiar/x509": "1.9.6", "@wireapp/avs": "9.6.9", "@wireapp/commons": "5.2.4", - "@wireapp/core": "43.6.0", + "@wireapp/core": "43.7.1", "@wireapp/react-ui-kit": "9.12.6", "@wireapp/store-engine-dexie": "2.1.7", "@wireapp/webapp-events": "0.20.1", diff --git a/src/__mocks__/@wireapp/core.ts b/src/__mocks__/@wireapp/core.ts index e6f595e4354..3e4735c2d18 100644 --- a/src/__mocks__/@wireapp/core.ts +++ b/src/__mocks__/@wireapp/core.ts @@ -40,6 +40,7 @@ export class Account extends EventEmitter { getUsersIdentities: jest.fn(() => new Map()), getDeviceIdentities: jest.fn(), getConversationState: jest.fn(), + registerServerCertificates: jest.fn(), }, mls: { schedulePeriodicKeyMaterialRenewals: jest.fn(), diff --git a/src/script/E2EIdentity/E2EIdentityEnrollment.test.ts b/src/script/E2EIdentity/E2EIdentityEnrollment.test.ts index a3ef57eabb9..03896280eab 100644 --- a/src/script/E2EIdentity/E2EIdentityEnrollment.test.ts +++ b/src/script/E2EIdentity/E2EIdentityEnrollment.test.ts @@ -108,21 +108,22 @@ describe('E2EIHandler', () => { }); it('should create instance with valid params', async () => { - const instance = E2EIHandler.getInstance().initialize(params); + const instance = await E2EIHandler.getInstance().initialize(params); expect(instance).toBeInstanceOf(E2EIHandler); }); it('should always return the same instance', async () => { - const instance1 = E2EIHandler.getInstance().initialize(params); - const instance2 = E2EIHandler.getInstance().initialize(params); + const instance1 = await E2EIHandler.getInstance().initialize(params); + const instance2 = await E2EIHandler.getInstance().initialize(params); expect(instance1).toBe(instance2); }); it('should set currentStep to INITIALIZE after initialize is called', async () => { const instance = E2EIHandler.getInstance(); - instance.initialize(params); + await instance.initialize(params); void instance.attemptEnrollment(); await wait(1); + expect(container.resolve(Core).service?.e2eIdentity?.registerServerCertificates).toHaveBeenCalled(); expect(instance['currentStep']).toBe(E2EIHandlerStep.INITIALIZED); }); @@ -133,7 +134,7 @@ describe('E2EIHandler', () => { jest.spyOn(container.resolve(Core), 'enrollE2EI').mockResolvedValueOnce(true); - const instance = E2EIHandler.getInstance().initialize(params); + const instance = await E2EIHandler.getInstance().initialize(params); void instance['enroll'](); await wait(1); expect(instance['currentStep']).toBe(E2EIHandlerStep.SUCCESS); @@ -144,14 +145,14 @@ describe('E2EIHandler', () => { jest.spyOn(container.resolve(Core), 'enrollE2EI').mockImplementationOnce(jest.fn(() => Promise.reject())); jest.spyOn(container.resolve(UserState), 'self').mockImplementationOnce(() => user); - const instance = E2EIHandler.getInstance().initialize(params); + const instance = await E2EIHandler.getInstance().initialize(params); void instance['enroll'](); await wait(1); expect(instance['currentStep']).toBe(E2EIHandlerStep.ERROR); }); it('should display user info message when initialized', async () => { - const instance = E2EIHandler.getInstance().initialize(params); + const instance = await E2EIHandler.getInstance().initialize(params); void instance.attemptEnrollment(); await wait(1); expect(getModalOptions).toHaveBeenCalledWith( @@ -168,7 +169,7 @@ describe('E2EIHandler', () => { }); it('should display loading message when enroled', async () => { - const handler = E2EIHandler.getInstance().initialize(params); + const handler = await E2EIHandler.getInstance().initialize(params); void handler['enroll'](); await wait(1); expect(getModalOptions).toHaveBeenCalledWith( @@ -181,7 +182,7 @@ describe('E2EIHandler', () => { it('should display success message when enrollment is done', async () => { jest.spyOn(container.resolve(Core), 'enrollE2EI').mockResolvedValueOnce(true); - const handler = E2EIHandler.getInstance().initialize(params); + const handler = await E2EIHandler.getInstance().initialize(params); handler['showLoadingMessage'] = jest.fn(); void handler['enroll'](); await wait(1); @@ -195,7 +196,7 @@ describe('E2EIHandler', () => { it('should display error message when enrollment fails', async () => { jest.spyOn(container.resolve(Core), 'enrollE2EI').mockRejectedValueOnce(false); - const handler = E2EIHandler.getInstance().initialize(params); + const handler = await E2EIHandler.getInstance().initialize(params); handler['showLoadingMessage'] = jest.fn(); void handler['enroll'](); await wait(1); @@ -218,7 +219,7 @@ describe('E2EIHandler', () => { const renewCertificateSpy = jest.spyOn(handler as any, 'renewCertificate'); // Initialize E2EI - handler.initialize(params); + await handler.initialize(params); void handler.attemptRenewal(); await wait(1); @@ -238,7 +239,7 @@ describe('E2EIHandler', () => { const enrollSpy = jest.spyOn(handler, 'enroll'); // Initialize E2EI - handler.initialize(params); + await handler.initialize(params); void handler.attemptRenewal(); await wait(1); @@ -270,7 +271,7 @@ describe('E2EIHandler', () => { const renewCertificateSpy = jest.spyOn(handler as any, 'renewCertificate'); // Initialize E2EI - handler.initialize(params); + await handler.initialize(params); void handler.attemptRenewal(); await wait(1); @@ -288,7 +289,7 @@ describe('E2EIHandler', () => { const startEnrollmentSpy = jest.spyOn(handler as any, 'startEnrollment'); // Initialize E2EI - handler.initialize(params); + await handler.initialize(params); void handler.attemptEnrollment(); await wait(1); @@ -316,7 +317,7 @@ describe('E2EIHandler', () => { jest.spyOn(handler as any, 'shouldRefresh').mockReturnValue(false); // Initialize E2EI - handler.initialize(params); + await handler.initialize(params); void handler.attemptRenewal(); await wait(1); diff --git a/src/script/E2EIdentity/E2EIdentityEnrollment.ts b/src/script/E2EIdentity/E2EIdentityEnrollment.ts index 4db1ca6bbac..1a0c92ff774 100644 --- a/src/script/E2EIdentity/E2EIdentityEnrollment.ts +++ b/src/script/E2EIdentity/E2EIdentityEnrollment.ts @@ -120,7 +120,7 @@ export class E2EIHandler extends TypedEventEmitter { return this.currentStep !== E2EIHandlerStep.UNINITIALIZED; } - public initialize({discoveryUrl, gracePeriodInSeconds}: E2EIHandlerParams) { + public async initialize({discoveryUrl, gracePeriodInSeconds}: E2EIHandlerParams) { const gracePeriodInMs = gracePeriodInSeconds * TIME_IN_MILLIS.SECOND; this.config = { discoveryUrl, @@ -131,6 +131,8 @@ export class E2EIHandler extends TypedEventEmitter { onSnoozeExpired: () => this.startEnrollment(ModalType.ENROLL), }), }; + + await this.coreE2EIService.registerServerCertificates(discoveryUrl); this.currentStep = E2EIHandlerStep.INITIALIZED; return this; } diff --git a/src/script/main/app.ts b/src/script/main/app.ts index 660aefb5f2e..be9dfcae2ba 100644 --- a/src/script/main/app.ts +++ b/src/script/main/app.ts @@ -425,7 +425,7 @@ export class App { telemetry.timeStep(AppInitTimingsStep.INITIALIZED_CRYPTOGRAPHY); const {members: teamMembers, features: teamFeatures} = await teamRepository.initTeam(selfUser.teamId); - const e2eiHandler = configureE2EI(this.logger, teamFeatures); + const e2eiHandler = await configureE2EI(this.logger, teamFeatures); if (e2eiHandler) { /* We first try to do the initial enrollment (if the user has not yet enrolled) * We need to enroll before anything else (in particular joining MLS conversations) diff --git a/src/script/page/components/FeatureConfigChange/FeatureConfigChangeHandler/FeatureConfigChangeHandler.tsx b/src/script/page/components/FeatureConfigChange/FeatureConfigChangeHandler/FeatureConfigChangeHandler.tsx index b8088cebe1c..7ce360f9137 100644 --- a/src/script/page/components/FeatureConfigChange/FeatureConfigChangeHandler/FeatureConfigChangeHandler.tsx +++ b/src/script/page/components/FeatureConfigChange/FeatureConfigChangeHandler/FeatureConfigChangeHandler.tsx @@ -38,7 +38,7 @@ export function FeatureConfigChangeHandler({teamState}: Props): null { useEffect(() => { if (config) { // initialize feature handlers - configureE2EI(logger, config)?.attemptEnrollment(); + void configureE2EI(logger, config)?.then(client => client.attemptEnrollment()); } }, [config]); diff --git a/src/script/page/components/FeatureConfigChange/FeatureConfigChangeHandler/Features/E2EIdentity.ts b/src/script/page/components/FeatureConfigChange/FeatureConfigChangeHandler/Features/E2EIdentity.ts index aaa2fc418f5..e50ab852979 100644 --- a/src/script/page/components/FeatureConfigChange/FeatureConfigChangeHandler/Features/E2EIdentity.ts +++ b/src/script/page/components/FeatureConfigChange/FeatureConfigChangeHandler/Features/E2EIdentity.ts @@ -26,7 +26,7 @@ import {supportsMLS} from 'Util/util'; import {hasE2EIVerificationExpiration, hasMLSDefaultProtocol} from '../../../../../guards/Protocol'; -export const configureE2EI = (logger: Logger, config: FeatureList): undefined | E2EIHandler => { +export const configureE2EI = (logger: Logger, config: FeatureList): undefined | Promise => { const e2eiConfig = config[FEATURE_KEY.MLSE2EID]; const mlsConfig = config[FEATURE_KEY.MLS]; // Check if MLS or MLS E2EIdentity feature is existent diff --git a/yarn.lock b/yarn.lock index 694796a06c1..01c8ac603a6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4874,9 +4874,9 @@ __metadata: languageName: node linkType: hard -"@wireapp/core@npm:43.6.0": - version: 43.6.0 - resolution: "@wireapp/core@npm:43.6.0" +"@wireapp/core@npm:43.7.1": + version: 43.7.1 + resolution: "@wireapp/core@npm:43.7.1" dependencies: "@wireapp/api-client": ^26.10.0 "@wireapp/commons": ^5.2.4 @@ -4896,7 +4896,7 @@ __metadata: long: ^5.2.0 uuidjs: 4.2.13 zod: 3.22.4 - checksum: 3e2333344241b46253faed7f86be71e8bffc38fd5dd3cb1f02f08aeef0c170d8e12f3c49ec8b64194cff30b0f74c78ca993d391cfd4ad41b80d0490c485751a4 + checksum: e143f09d5106d98f40bcd1e66b77baac4ea6be1321c3a96e2d541340ba56f704a99b13a30a7d28861d2c5a1e1eaeccadc74f26ed7af8f56e577500cc0413b532 languageName: node linkType: hard @@ -17568,7 +17568,7 @@ __metadata: "@wireapp/avs": 9.6.9 "@wireapp/commons": 5.2.4 "@wireapp/copy-config": 2.1.14 - "@wireapp/core": 43.6.0 + "@wireapp/core": 43.7.1 "@wireapp/eslint-config": 3.0.5 "@wireapp/prettier-config": 0.6.3 "@wireapp/react-ui-kit": 9.12.6