From 44eabc512e3b9cddf36c8fefaccca9ace0e35260 Mon Sep 17 00:00:00 2001 From: Thomas Belin Date: Thu, 18 Jan 2024 09:50:59 +0100 Subject: [PATCH 1/2] refactor: Cleanup the enrollment snooze feature --- .../E2EIdentity/E2EIdentityEnrollment.ts | 56 +++------- .../SnoozableTimer.test.ts} | 64 +++++------ .../SnoozableTimer.ts} | 105 ++++++++++-------- .../SnoozableTimerStorage.ts} | 8 +- .../{DelayTimer => SnoozableTimer}/delay.ts | 6 +- src/script/hooks/useAppSoftLock.ts | 2 +- 6 files changed, 115 insertions(+), 126 deletions(-) rename src/script/E2EIdentity/{DelayTimer/DelayTimer.test.ts => SnoozableTimer/SnoozableTimer.test.ts} (79%) rename src/script/E2EIdentity/{DelayTimer/DelayTimer.ts => SnoozableTimer/SnoozableTimer.ts} (67%) rename src/script/E2EIdentity/{DelayTimer/DelayTimerStorage.ts => SnoozableTimer/SnoozableTimerStorage.ts} (90%) rename src/script/E2EIdentity/{DelayTimer => SnoozableTimer}/delay.ts (91%) diff --git a/src/script/E2EIdentity/E2EIdentityEnrollment.ts b/src/script/E2EIdentity/E2EIdentityEnrollment.ts index 1b8e75afaa5..f7588be0bee 100644 --- a/src/script/E2EIdentity/E2EIdentityEnrollment.ts +++ b/src/script/E2EIdentity/E2EIdentityEnrollment.ts @@ -34,8 +34,6 @@ import {formatDelayTime, TIME_IN_MILLIS} from 'Util/TimeUtil'; import {removeUrlParameters} from 'Util/UrlUtil'; import {supportsMLS} from 'Util/util'; -import {getDelayTime, shouldEnableSoftLock} from './DelayTimer/delay'; -import {DelayTimerService} from './DelayTimer/DelayTimer'; import { hasActiveCertificate, isE2EIEnabled, @@ -46,6 +44,8 @@ import { import {getModalOptions, ModalType} from './Modals'; import {OIDCService} from './OIDCService'; import {OIDCServiceStore} from './OIDCService/OIDCServiceStorage'; +import {getSnoozeTime, shouldEnableSoftLock} from './SnoozableTimer/delay'; +import {SnoozableTimer} from './SnoozableTimer/SnoozableTimer'; import {Config} from '../Config'; @@ -68,7 +68,7 @@ type Events = { }; export type EnrollmentConfig = { - timer: DelayTimerService; + timer: SnoozableTimer; discoveryUrl: string; gracePeriodInMs: number; }; @@ -80,7 +80,7 @@ export class E2EIHandler extends TypedEventEmitter { private readonly core = container.resolve(Core); private readonly userState = container.resolve(UserState); private config?: EnrollmentConfig; - private currentStep: E2EIHandlerStep | null = E2EIHandlerStep.UNINITIALIZED; + private currentStep: E2EIHandlerStep = E2EIHandlerStep.UNINITIALIZED; private oidcService?: OIDCService; private get coreE2EIService() { @@ -126,12 +126,13 @@ export class E2EIHandler extends TypedEventEmitter { this.config = { discoveryUrl, gracePeriodInMs, - timer: new DelayTimerService({ + timer: new SnoozableTimer({ gracePeriodInMS: gracePeriodInMs, - gracePeriodExpiredCallback: () => null, - delayPeriodExpiredCallback: () => null, + onGracePeriodExpired: () => this.startEnrollment(ModalType.ENROLL), + onSnoozeExpired: () => this.startEnrollment(ModalType.ENROLL), }), }; + this.currentStep = E2EIHandlerStep.INITIALIZED; } return this; } @@ -142,7 +143,7 @@ export class E2EIHandler extends TypedEventEmitter { // If the client already has a certificate, we don't need to start the enrollment return; } - return this.showE2EINotificationMessage(ModalType.ENROLL); + return this.startEnrollment(ModalType.ENROLL); } public async attemptRenewal(): Promise { @@ -203,7 +204,7 @@ export class E2EIHandler extends TypedEventEmitter { // If the silent authentication fails, clear the oidc service progress/data and renew manually await this.cleanUp(true); - this.showE2EINotificationMessage(ModalType.CERTIFICATE_RENEWAL); + this.startEnrollment(ModalType.CERTIFICATE_RENEWAL); } } @@ -377,7 +378,7 @@ export class E2EIHandler extends TypedEventEmitter { resolve(); }, secondaryActionFn: async () => { - await this.showE2EINotificationMessage(ModalType.ENROLL); + await this.startEnrollment(ModalType.ENROLL); resolve(); }, }); @@ -394,22 +395,6 @@ export class E2EIHandler extends TypedEventEmitter { return true; } - private initializeEnrollmentTimer(): void { - // Only initialize the timer when the it is uninitialized - if (this.currentStep === E2EIHandlerStep.UNINITIALIZED) { - this.config?.timer.updateParams({ - gracePeriodInMS: this.config.gracePeriodInMs, - gracePeriodExpiredCallback: () => { - this.showE2EINotificationMessage(ModalType.ENROLL); - }, - delayPeriodExpiredCallback: () => { - this.showE2EINotificationMessage(ModalType.ENROLL); - }, - }); - this.currentStep = E2EIHandlerStep.INITIALIZED; - } - } - private async showEnrollmentModal(modalType: ModalType.ENROLL | ModalType.CERTIFICATE_RENEWAL): Promise { // Show the modal with the provided modal type const disableSnooze = await shouldEnableSoftLock(this.config!); @@ -422,8 +407,8 @@ export class E2EIHandler extends TypedEventEmitter { }, secondaryActionFn: () => { this.currentStep = E2EIHandlerStep.SNOOZE; - this.config?.timer.delayPrompt(); - this.showSnoozeModal(); + this.config?.timer.snooze(); + this.showSnoozeConfirmationModal(); resolve(); }, type: modalType, @@ -433,22 +418,19 @@ export class E2EIHandler extends TypedEventEmitter { }); } - private showSnoozeModal() { + private showSnoozeConfirmationModal() { // Show the modal with the provided modal type const {modalOptions, modalType: determinedModalType} = getModalOptions({ type: ModalType.SNOOZE_REMINDER, hideClose: true, extraParams: { - delayTime: formatDelayTime(getDelayTime(this.config!.gracePeriodInMs)), + delayTime: formatDelayTime(getSnoozeTime(this.config!.gracePeriodInMs)), }, }); PrimaryModal.show(determinedModalType, modalOptions); } - public async showE2EINotificationMessage( - modalType: ModalType.CERTIFICATE_RENEWAL | ModalType.ENROLL, - disableSnooze: boolean = false, - ): Promise { + private async startEnrollment(enrollmentType: ModalType.CERTIFICATE_RENEWAL | ModalType.ENROLL): Promise { // If the user has already started enrolment, don't show the notification. Instead, show the loading modal // This will occur after the redirect from the oauth provider if (this.coreE2EIService.isEnrollmentInProgress()) { @@ -460,11 +442,9 @@ export class E2EIHandler extends TypedEventEmitter { return; } - this.initializeEnrollmentTimer(); - // If the timer is not active, show the notification modal - if (this.config && !this.config.timer.isDelayTimerActive()) { - return this.showEnrollmentModal(modalType); + if (this.config && !this.config.timer.isSnoozableTimerActive()) { + return this.showEnrollmentModal(enrollmentType); } } } diff --git a/src/script/E2EIdentity/DelayTimer/DelayTimer.test.ts b/src/script/E2EIdentity/SnoozableTimer/SnoozableTimer.test.ts similarity index 79% rename from src/script/E2EIdentity/DelayTimer/DelayTimer.test.ts rename to src/script/E2EIdentity/SnoozableTimer/SnoozableTimer.test.ts index 2a7a3b7087f..d12e0d637d2 100644 --- a/src/script/E2EIdentity/DelayTimer/DelayTimer.test.ts +++ b/src/script/E2EIdentity/SnoozableTimer/SnoozableTimer.test.ts @@ -18,19 +18,19 @@ */ import {FIFTEEN_MINUTES, FOUR_HOURS, ONE_HOUR, ONE_MINUTE} from './delay'; -import {DelayTimerService} from './DelayTimer'; +import {SnoozableTimer} from './SnoozableTimer'; describe('createGracePeriodTimer', () => { - let timer: DelayTimerService | undefined; + let timer: SnoozableTimer | undefined; beforeEach(() => { jest.clearAllMocks(); jest.useFakeTimers(); global.localStorage.clear(); - timer = new DelayTimerService({ + timer = new SnoozableTimer({ gracePeriodInMS: 0, - gracePeriodExpiredCallback: jest.fn(), - delayPeriodExpiredCallback: jest.fn(), + onGracePeriodExpired: jest.fn(), + onSnoozeExpired: jest.fn(), }); }); @@ -42,8 +42,8 @@ describe('createGracePeriodTimer', () => { const gracePeriodExpiredCallback = jest.fn(); timer?.updateParams({ gracePeriodInMS: 1000, - gracePeriodExpiredCallback, - delayPeriodExpiredCallback: jest.fn(), + onGracePeriodExpired: gracePeriodExpiredCallback, + onSnoozeExpired: jest.fn(), }); jest.advanceTimersByTime(1000); @@ -55,11 +55,11 @@ describe('createGracePeriodTimer', () => { timer?.updateParams({ gracePeriodInMS: ONE_HOUR, - gracePeriodExpiredCallback, - delayPeriodExpiredCallback: jest.fn(), + onGracePeriodExpired: gracePeriodExpiredCallback, + onSnoozeExpired: jest.fn(), }); - timer?.delayPrompt(); + timer?.snooze(); jest.advanceTimersByTime(FIFTEEN_MINUTES); expect(gracePeriodExpiredCallback).not.toHaveBeenCalled(); @@ -72,10 +72,10 @@ describe('createGracePeriodTimer', () => { const gracePeriodExpiredCallback = jest.fn(); timer?.updateParams({ gracePeriodInMS: 0, - gracePeriodExpiredCallback, - delayPeriodExpiredCallback: jest.fn(), + onGracePeriodExpired: gracePeriodExpiredCallback, + onSnoozeExpired: jest.fn(), }); - timer?.delayPrompt(); + timer?.snooze(); jest.advanceTimersByTime(500); expect(gracePeriodExpiredCallback).toHaveBeenCalled(); @@ -85,12 +85,12 @@ describe('createGracePeriodTimer', () => { const gracePeriodExpiredCallback = jest.fn(); timer?.updateParams({ gracePeriodInMS: 7200000, - gracePeriodExpiredCallback, - delayPeriodExpiredCallback: jest.fn(), + onGracePeriodExpired: gracePeriodExpiredCallback, + onSnoozeExpired: jest.fn(), }); - timer?.delayPrompt(); + timer?.snooze(); jest.advanceTimersByTime(3600000); - timer?.delayPrompt(); + timer?.snooze(); jest.advanceTimersByTime(3600000); expect(gracePeriodExpiredCallback).toHaveBeenCalled(); @@ -100,11 +100,11 @@ describe('createGracePeriodTimer', () => { const delayPeriodExpiredCallback = jest.fn(); timer?.updateParams({ gracePeriodInMS: ONE_HOUR, - gracePeriodExpiredCallback: jest.fn(), - delayPeriodExpiredCallback, + onGracePeriodExpired: jest.fn(), + onSnoozeExpired: delayPeriodExpiredCallback, }); - timer?.delayPrompt(); + timer?.snooze(); // getDelayTime(ONE_HOUR) will return FIFTEEN_MINUTES according to the function provided. jest.advanceTimersByTime(FIFTEEN_MINUTES); @@ -116,18 +116,18 @@ describe('createGracePeriodTimer', () => { const gracePeriodExpiredCallback = jest.fn(); timer?.updateParams({ gracePeriodInMS: ONE_HOUR, - delayPeriodExpiredCallback, - gracePeriodExpiredCallback, + onSnoozeExpired: delayPeriodExpiredCallback, + onGracePeriodExpired: gracePeriodExpiredCallback, }); - timer?.delayPrompt(); + timer?.snooze(); // Here, instead of advancing time by "ONE_HOUR + FIFTEEN_MINUTES", we advance by "ONE_HOUR", which is the end of the grace period. jest.advanceTimersByTime(ONE_HOUR + FIFTEEN_MINUTES); expect(delayPeriodExpiredCallback).toHaveBeenCalled(); // The delayPeriodExpiredCallback should be called after ONE_HOUR. expect(gracePeriodExpiredCallback).toHaveBeenCalled(); // The gracePeriodExpiredCallback should be called when the grace period ends, which is after ONE_HOUR. - timer?.delayPrompt(); // We try to delay after the grace period has ended. + timer?.snooze(); // We try to delay after the grace period has ended. jest.advanceTimersByTime(FIFTEEN_MINUTES); expect(delayPeriodExpiredCallback).toHaveBeenCalledTimes(1); // The delayPeriodExpiredCallback should not be called again since we're now past the grace period. }); @@ -136,17 +136,17 @@ describe('createGracePeriodTimer', () => { const delayPeriodExpiredCallback = jest.fn(); timer?.updateParams({ gracePeriodInMS: FOUR_HOURS, - gracePeriodExpiredCallback: jest.fn(), - delayPeriodExpiredCallback, + onGracePeriodExpired: jest.fn(), + onSnoozeExpired: delayPeriodExpiredCallback, }); - timer?.delayPrompt(); + timer?.snooze(); jest.advanceTimersByTime(ONE_HOUR); // gracePeriod > delay, so delay = ONE_HOUR - timer?.delayPrompt(); + timer?.snooze(); jest.advanceTimersByTime(ONE_HOUR); - timer?.delayPrompt(); + timer?.snooze(); jest.advanceTimersByTime(ONE_HOUR); expect(delayPeriodExpiredCallback).toHaveBeenCalledTimes(3); @@ -157,11 +157,11 @@ describe('createGracePeriodTimer', () => { const gracePeriodExpiredCallback = jest.fn(); timer?.updateParams({ gracePeriodInMS: ONE_MINUTE, - gracePeriodExpiredCallback, - delayPeriodExpiredCallback, + onGracePeriodExpired: gracePeriodExpiredCallback, + onSnoozeExpired: delayPeriodExpiredCallback, }); - timer?.delayPrompt(); + timer?.snooze(); jest.advanceTimersByTime(ONE_MINUTE); expect(delayPeriodExpiredCallback).not.toHaveBeenCalled(); diff --git a/src/script/E2EIdentity/DelayTimer/DelayTimer.ts b/src/script/E2EIdentity/SnoozableTimer/SnoozableTimer.ts similarity index 67% rename from src/script/E2EIdentity/DelayTimer/DelayTimer.ts rename to src/script/E2EIdentity/SnoozableTimer/SnoozableTimer.ts index 3bba5a2b7f6..4147eb543cb 100644 --- a/src/script/E2EIdentity/DelayTimer/DelayTimer.ts +++ b/src/script/E2EIdentity/SnoozableTimer/SnoozableTimer.ts @@ -21,46 +21,53 @@ import logdown from 'logdown'; import {util} from '@wireapp/core'; -import {getDelayTime} from './delay'; -import {DelayTimerStore} from './DelayTimerStorage'; +import {getSnoozeTime} from './delay'; +import {SnoozableTimerStore} from './SnoozableTimerStorage'; const {TaskScheduler} = util; interface CreateGracePeriodTimerParams { gracePeriodInMS: number; - gracePeriodExpiredCallback: () => void; - delayPeriodExpiredCallback: () => void; + /** + * called when the grace period is over. The grace period is the time during which the user can keep snoozing the enrollment. + * Once the grace period is over, the user will be forced to enroll. + */ + onGracePeriodExpired: () => void; + /** + * as long as the grace period is not over, the user can snooze the enrollment. This callback is called when the user snoozes the enrollment. + */ + onSnoozeExpired: () => void; } -export class DelayTimerService { +export class SnoozableTimer { private gracePeriodInMS: number; - private gracePeriodExpiredCallback: () => void; - private delayPeriodExpiredCallback: () => void; + private onGracePeriodExpired: () => void; + private onSnoozeExpired: () => void; private readonly logger = logdown('@wireapp/core/DelayTimer'); private delayPeriodTimerKey: string = 'E2EIdentity_DelayTimer'; private gracePeriodTimerKey: string = 'E2EIdentity_GracePeriodTimer'; - constructor({gracePeriodInMS, gracePeriodExpiredCallback, delayPeriodExpiredCallback}: CreateGracePeriodTimerParams) { + constructor({ + gracePeriodInMS, + onGracePeriodExpired: onGracePeriodExpired, + onSnoozeExpired, + }: CreateGracePeriodTimerParams) { this.gracePeriodInMS = gracePeriodInMS; - this.gracePeriodExpiredCallback = gracePeriodExpiredCallback; - this.delayPeriodExpiredCallback = delayPeriodExpiredCallback; + this.onGracePeriodExpired = onGracePeriodExpired; + this.onSnoozeExpired = onSnoozeExpired; this.initialize(); } /** * @param CreateGracePeriodTimerParams The params to create the grace period timer */ - public updateParams({ - gracePeriodInMS, - gracePeriodExpiredCallback, - delayPeriodExpiredCallback, - }: CreateGracePeriodTimerParams) { - DelayTimerStore.clear.all(); + public updateParams({gracePeriodInMS, onGracePeriodExpired, onSnoozeExpired}: CreateGracePeriodTimerParams) { + SnoozableTimerStore.clear.all(); this.clearGracePeriodTimer(); - this.clearDelayPeriodTimer(); + this.clearSnoozePeriodTimer(); this.gracePeriodInMS = gracePeriodInMS; - this.gracePeriodExpiredCallback = gracePeriodExpiredCallback; - this.delayPeriodExpiredCallback = delayPeriodExpiredCallback; + this.onGracePeriodExpired = onGracePeriodExpired; + this.onSnoozeExpired = onSnoozeExpired; this.initialize(); } @@ -73,7 +80,7 @@ export class DelayTimerService { } // Check if grace period has changed - if (DelayTimerStore.get.gracePeriod() !== this.gracePeriodInMS) { + if (SnoozableTimerStore.get.gracePeriod() !== this.gracePeriodInMS) { // Check if grace period is less than the time elapsed since the last prompt if (this.gracePeriodInMS < this.getElapsedGracePeriod()) { return this.exit( @@ -84,44 +91,44 @@ export class DelayTimerService { } // Load saved data from local storage - if (DelayTimerStore.get.firingDate()) { + if (SnoozableTimerStore.get.firingDate()) { const currentTime = Date.now(); - if (DelayTimerStore.get.firingDate() <= currentTime) { + if (SnoozableTimerStore.get.firingDate() <= currentTime) { return this.exit('Grace period is already over. No more delays are allowed.'); } } else { const firingDate = Date.now() + this.gracePeriodInMS; - DelayTimerStore.store.firingDate(firingDate); - DelayTimerStore.store.gracePeriod(this.gracePeriodInMS); + SnoozableTimerStore.store.firingDate(firingDate); + SnoozableTimerStore.store.gracePeriod(this.gracePeriodInMS); } // Start / restart the grace period timer - this.startGracePeriod(DelayTimerStore.get.firingDate()); + this.startGracePeriod(SnoozableTimerStore.get.firingDate()); // this will start the delay period timer if it was active before - this.continueDelayPeriodTimer(); + this.continueSnoozePeriodTimer(); } /** - * Prompt the user to delay the enrollment + * Will start a snooze period if the conditions are met */ - public delayPrompt() { - if (this.isDelayTimerActive()) { + public snooze() { + if (this.isSnoozableTimerActive()) { return; } if (!this.isSnoozeTimeAvailable()) { return this.exit('No more delays are allowed.'); } - const delayTimeInMS = getDelayTime(this.gracePeriodInMS); + const delayTimeInMS = getSnoozeTime(this.gracePeriodInMS); if (delayTimeInMS <= 0) { return this.exit('Delay period is 0. No more delays are allowed.'); } - if (DelayTimerStore.get.firingDate() <= Date.now()) { + if (SnoozableTimerStore.get.firingDate() <= Date.now()) { return this.exit('Grace period is already over. No more delays are allowed.'); } - this.startDelayPeriod(Date.now() + delayTimeInMS); + this.startSnoozePeriod(Date.now() + delayTimeInMS); } /** @@ -129,7 +136,7 @@ export class DelayTimerService { */ private updateGracePeriod() { // Store the new grace period - DelayTimerStore.store.gracePeriod(this.gracePeriodInMS); + SnoozableTimerStore.store.gracePeriod(this.gracePeriodInMS); const elapsedGracePeriod = this.getElapsedGracePeriod(); // Check if grace period is already over @@ -143,7 +150,7 @@ export class DelayTimerService { // Calculate the new end time const firingDate = startTime + this.gracePeriodInMS; // Store the new end time - DelayTimerStore.store.firingDate(firingDate); + SnoozableTimerStore.store.firingDate(firingDate); this.startGracePeriod(firingDate); } @@ -155,10 +162,10 @@ export class DelayTimerService { */ private exit(exitMessage: string) { this.logger.info(exitMessage); - this.clearDelayPeriodTimer(); + this.clearSnoozePeriodTimer(); this.clearGracePeriodTimer(); - DelayTimerStore.clear.all(); - return this.gracePeriodExpiredCallback(); + SnoozableTimerStore.clear.all(); + return this.onGracePeriodExpired(); } /** @@ -191,12 +198,12 @@ export class DelayTimerService { * Start the delay period timer and store the delay time * @param delayTimeInMS The delay time in ms */ - private startDelayPeriod(firingDate?: number) { - this.clearDelayPeriodTimer(); + private startSnoozePeriod(firingDate?: number) { + this.clearSnoozePeriodTimer(); const task = () => { - this.logger.info('Delay time is over.'); - return this.delayPeriodExpiredCallback(); + this.logger.info('Snooze time is over.'); + return this.onSnoozeExpired(); }; if (TaskScheduler.hasActiveTask(this.delayPeriodTimerKey)) { @@ -224,12 +231,12 @@ export class DelayTimerService { /** * Clear the current delay period timer */ - private clearDelayPeriodTimer() { + private clearSnoozePeriodTimer() { TaskScheduler.cancelTask(this.delayPeriodTimerKey); } - private continueDelayPeriodTimer() { - this.startDelayPeriod(); + private continueSnoozePeriodTimer() { + this.startSnoozePeriod(); } /** @@ -237,18 +244,18 @@ export class DelayTimerService { * @returns The time elapsed since the last prompt in ms */ private getElapsedGracePeriod() { - return DelayTimerStore.get.firingDate() - ? Date.now() - (DelayTimerStore.get.firingDate() - this.gracePeriodInMS) + return SnoozableTimerStore.get.firingDate() + ? Date.now() - (SnoozableTimerStore.get.firingDate() - this.gracePeriodInMS) : 0; } - public isDelayTimerActive() { + public isSnoozableTimerActive() { return TaskScheduler.hasActiveTask(this.delayPeriodTimerKey); } public isSnoozeTimeAvailable() { - const remainingTime = DelayTimerStore.get.firingDate() - Date.now(); - const delayTime = getDelayTime(remainingTime); + const remainingTime = SnoozableTimerStore.get.firingDate() - Date.now(); + const delayTime = getSnoozeTime(remainingTime); return remainingTime - delayTime > 0; } } diff --git a/src/script/E2EIdentity/DelayTimer/DelayTimerStorage.ts b/src/script/E2EIdentity/SnoozableTimer/SnoozableTimerStorage.ts similarity index 90% rename from src/script/E2EIdentity/DelayTimer/DelayTimerStorage.ts rename to src/script/E2EIdentity/SnoozableTimer/SnoozableTimerStorage.ts index 7c122af9975..d30f1da11b8 100644 --- a/src/script/E2EIdentity/DelayTimer/DelayTimerStorage.ts +++ b/src/script/E2EIdentity/SnoozableTimer/SnoozableTimerStorage.ts @@ -20,7 +20,7 @@ const FiringDateKey = 'E2EIdentity_DelayTimer_FiringDate'; const GracePeriodKey = 'E2EIdentity_DelayTimer_GracePeriod'; -const DelayTimerStore = { +export const SnoozableTimerStore = { store: { firingDate: (firingDate: number) => localStorage.setItem(FiringDateKey, String(firingDate)), gracePeriod: (gracePeriod: number) => localStorage.setItem(GracePeriodKey, String(gracePeriod)), @@ -33,10 +33,8 @@ const DelayTimerStore = { firingDate: () => localStorage.removeItem(FiringDateKey), gracePeriod: () => localStorage.removeItem(GracePeriodKey), all: () => { - DelayTimerStore.clear.firingDate(); - DelayTimerStore.clear.gracePeriod(); + SnoozableTimerStore.clear.firingDate(); + SnoozableTimerStore.clear.gracePeriod(); }, }, }; - -export {DelayTimerStore}; diff --git a/src/script/E2EIdentity/DelayTimer/delay.ts b/src/script/E2EIdentity/SnoozableTimer/delay.ts similarity index 91% rename from src/script/E2EIdentity/DelayTimer/delay.ts rename to src/script/E2EIdentity/SnoozableTimer/delay.ts index 951de7add5a..b6ecafaed8f 100644 --- a/src/script/E2EIdentity/DelayTimer/delay.ts +++ b/src/script/E2EIdentity/SnoozableTimer/delay.ts @@ -38,7 +38,11 @@ export const ONE_HOUR = TIME_IN_MILLIS.HOUR; export const FOUR_HOURS = TIME_IN_MILLIS.HOUR * 4; export const ONE_DAY = TIME_IN_MILLIS.DAY; -export function getDelayTime(gracePeriodInMs: number): number { +/** + * Will return a suitable snooze time based on the grace period + * @param gracePeriodInMs - the full grace period length in milliseconds + */ +export function getSnoozeTime(gracePeriodInMs: number): number { if (gracePeriodInMs > 0) { if (gracePeriodInMs <= FIFTEEN_MINUTES) { return Math.min(FIVE_MINUTES, gracePeriodInMs); diff --git a/src/script/hooks/useAppSoftLock.ts b/src/script/hooks/useAppSoftLock.ts index 797f74b8733..89e9bfcd95a 100644 --- a/src/script/hooks/useAppSoftLock.ts +++ b/src/script/hooks/useAppSoftLock.ts @@ -21,7 +21,7 @@ import {useCallback, useEffect, useState} from 'react'; import {CallingRepository} from '../calling/CallingRepository'; import {E2EIHandler, EnrollmentConfig, isE2EIEnabled, WireIdentity} from '../E2EIdentity'; -import {shouldEnableSoftLock} from '../E2EIdentity/DelayTimer/delay'; +import {shouldEnableSoftLock} from '../E2EIdentity/SnoozableTimer/delay'; import {NotificationRepository} from '../notification/NotificationRepository'; export function useAppSoftLock(callingRepository: CallingRepository, notificationRepository: NotificationRepository) { From f33fe5a46f82020ebdc4f6e283be299dac47eb2c Mon Sep 17 00:00:00 2001 From: Thomas Belin Date: Thu, 18 Jan 2024 10:30:58 +0100 Subject: [PATCH 2/2] fix tests --- .../E2EIdentity/E2EIdentityEnrollment.test.ts | 42 +++++++++---------- .../E2EIdentity/E2EIdentityEnrollment.ts | 2 +- 2 files changed, 21 insertions(+), 23 deletions(-) diff --git a/src/script/E2EIdentity/E2EIdentityEnrollment.test.ts b/src/script/E2EIdentity/E2EIdentityEnrollment.test.ts index a35a62df59d..a3ef57eabb9 100644 --- a/src/script/E2EIdentity/E2EIdentityEnrollment.test.ts +++ b/src/script/E2EIdentity/E2EIdentityEnrollment.test.ts @@ -99,8 +99,6 @@ describe('E2EIHandler', () => { Config.getConfig = jest.fn().mockReturnValue({FEATURE: {ENABLE_E2EI: true}}); jest.spyOn(PrimaryModal, 'show'); - (getModalOptions as jest.Mock).mockClear(); - (getCertificateDetails as jest.Mock).mockClear(); jest .spyOn(container.resolve(UserState), 'self') @@ -110,19 +108,19 @@ describe('E2EIHandler', () => { }); it('should create instance with valid params', async () => { - const instance = await E2EIHandler.getInstance().initialize(params); + const instance = E2EIHandler.getInstance().initialize(params); expect(instance).toBeInstanceOf(E2EIHandler); }); it('should always return the same instance', async () => { - const instance1 = await E2EIHandler.getInstance().initialize(params); - const instance2 = await E2EIHandler.getInstance().initialize(params); + const instance1 = E2EIHandler.getInstance().initialize(params); + const instance2 = E2EIHandler.getInstance().initialize(params); expect(instance1).toBe(instance2); }); it('should set currentStep to INITIALIZE after initialize is called', async () => { const instance = E2EIHandler.getInstance(); - await instance.initialize(params); + instance.initialize(params); void instance.attemptEnrollment(); await wait(1); expect(instance['currentStep']).toBe(E2EIHandlerStep.INITIALIZED); @@ -135,7 +133,7 @@ describe('E2EIHandler', () => { jest.spyOn(container.resolve(Core), 'enrollE2EI').mockResolvedValueOnce(true); - const instance = await E2EIHandler.getInstance().initialize(params); + const instance = E2EIHandler.getInstance().initialize(params); void instance['enroll'](); await wait(1); expect(instance['currentStep']).toBe(E2EIHandlerStep.SUCCESS); @@ -146,14 +144,14 @@ describe('E2EIHandler', () => { jest.spyOn(container.resolve(Core), 'enrollE2EI').mockImplementationOnce(jest.fn(() => Promise.reject())); jest.spyOn(container.resolve(UserState), 'self').mockImplementationOnce(() => user); - const instance = await E2EIHandler.getInstance().initialize(params); + const instance = 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 = await E2EIHandler.getInstance().initialize(params); + const instance = E2EIHandler.getInstance().initialize(params); void instance.attemptEnrollment(); await wait(1); expect(getModalOptions).toHaveBeenCalledWith( @@ -170,7 +168,7 @@ describe('E2EIHandler', () => { }); it('should display loading message when enroled', async () => { - const handler = await E2EIHandler.getInstance().initialize(params); + const handler = E2EIHandler.getInstance().initialize(params); void handler['enroll'](); await wait(1); expect(getModalOptions).toHaveBeenCalledWith( @@ -183,7 +181,7 @@ describe('E2EIHandler', () => { it('should display success message when enrollment is done', async () => { jest.spyOn(container.resolve(Core), 'enrollE2EI').mockResolvedValueOnce(true); - const handler = await E2EIHandler.getInstance().initialize(params); + const handler = E2EIHandler.getInstance().initialize(params); handler['showLoadingMessage'] = jest.fn(); void handler['enroll'](); await wait(1); @@ -197,7 +195,7 @@ describe('E2EIHandler', () => { it('should display error message when enrollment fails', async () => { jest.spyOn(container.resolve(Core), 'enrollE2EI').mockRejectedValueOnce(false); - const handler = await E2EIHandler.getInstance().initialize(params); + const handler = E2EIHandler.getInstance().initialize(params); handler['showLoadingMessage'] = jest.fn(); void handler['enroll'](); await wait(1); @@ -220,7 +218,7 @@ describe('E2EIHandler', () => { const renewCertificateSpy = jest.spyOn(handler as any, 'renewCertificate'); // Initialize E2EI - await handler.initialize(params); + handler.initialize(params); void handler.attemptRenewal(); await wait(1); @@ -240,7 +238,7 @@ describe('E2EIHandler', () => { const enrollSpy = jest.spyOn(handler, 'enroll'); // Initialize E2EI - await handler.initialize(params); + handler.initialize(params); void handler.attemptRenewal(); await wait(1); @@ -272,7 +270,7 @@ describe('E2EIHandler', () => { const renewCertificateSpy = jest.spyOn(handler as any, 'renewCertificate'); // Initialize E2EI - await handler.initialize(params); + handler.initialize(params); void handler.attemptRenewal(); await wait(1); @@ -280,22 +278,22 @@ describe('E2EIHandler', () => { expect(renewCertificateSpy).not.toHaveBeenCalled(); }); - it('call showE2EINotificationMessage when no active certificate is found', async () => { + it('call startEnrollment when no active certificate is found', async () => { const handler = E2EIHandler.getInstance(); // Set active certificate to be false (hasActiveCertificate as jest.Mock).mockResolvedValue(false); const renewCertificateSpy = jest.spyOn(handler as any, 'renewCertificate'); - const showE2EINotificationMessageSpy = jest.spyOn(handler as any, 'showE2EINotificationMessage'); + const startEnrollmentSpy = jest.spyOn(handler as any, 'startEnrollment'); // Initialize E2EI - await handler.initialize(params); + handler.initialize(params); void handler.attemptEnrollment(); await wait(1); expect(renewCertificateSpy).not.toHaveBeenCalled(); - expect(showE2EINotificationMessageSpy).toHaveBeenCalled(); + expect(startEnrollmentSpy).toHaveBeenCalled(); }); it('for invalid certificate user can not get another certificate until deleting a client', async () => { @@ -305,7 +303,7 @@ describe('E2EIHandler', () => { (hasActiveCertificate as jest.Mock).mockResolvedValue(true); const renewCertificateSpy = jest.spyOn(handler as any, 'renewCertificate'); - const showE2EINotificationMessageSpy = jest.spyOn(handler as any, 'showE2EINotificationMessage'); + const startEnrollmentSpy = jest.spyOn(handler as any, 'startEnrollment'); const timeRemainingMS = 5 * TimeInMillis.DAY; // 5 days remaining @@ -318,11 +316,11 @@ describe('E2EIHandler', () => { jest.spyOn(handler as any, 'shouldRefresh').mockReturnValue(false); // Initialize E2EI - await handler.initialize(params); + handler.initialize(params); void handler.attemptRenewal(); await wait(1); expect(renewCertificateSpy).not.toHaveBeenCalled(); - expect(showE2EINotificationMessageSpy).not.toHaveBeenCalled(); + expect(startEnrollmentSpy).not.toHaveBeenCalled(); }); }); diff --git a/src/script/E2EIdentity/E2EIdentityEnrollment.ts b/src/script/E2EIdentity/E2EIdentityEnrollment.ts index f7588be0bee..bfde6496840 100644 --- a/src/script/E2EIdentity/E2EIdentityEnrollment.ts +++ b/src/script/E2EIdentity/E2EIdentityEnrollment.ts @@ -389,7 +389,7 @@ export class E2EIHandler extends TypedEventEmitter { private shouldShowNotification(): boolean { // If the user has already snoozed the notification, don't show it again until the snooze period has expired - if (this.currentStep !== E2EIHandlerStep.UNINITIALIZED && this.currentStep !== E2EIHandlerStep.SNOOZE) { + if (this.currentStep === E2EIHandlerStep.SNOOZE) { return false; } return true;