Skip to content

Commit

Permalink
runfix: Fix grace period computation for verified devices (#16930)
Browse files Browse the repository at this point in the history
  • Loading branch information
atomrc authored Feb 27, 2024
1 parent dfe144d commit f814b6e
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 9 deletions.
8 changes: 4 additions & 4 deletions src/script/E2EIdentity/E2EIdentityEnrollment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,11 @@ import {formatDelayTime, TIME_IN_MILLIS} from 'Util/TimeUtil';
import {removeUrlParameters} from 'Util/UrlUtil';

import {hasActiveCertificate, getActiveWireIdentity, isFreshMLSSelfClient} from './E2EIdentityVerification';
import {EnrollmentStore} from './Enrollment.store';
import {getEnrollmentTimer} from './EnrollmentTimer';
import {getModalOptions, ModalType} from './Modals';
import {OIDCService} from './OIDCService';
import {OIDCServiceStore} from './OIDCService/OIDCServiceStorage';
import {getEnrollmentTimer} from './SnoozableTimer/delay';
import {SnoozableTimerStore} from './SnoozableTimer/SnoozableTimerStorage';

const {TaskScheduler} = util;
interface E2EIHandlerParams {
Expand Down Expand Up @@ -142,8 +142,8 @@ export class E2EIHandler extends TypedEventEmitter<Events> {
*/
public async startTimers() {
// We store the first time the user was prompted with the enrollment modal
const e2eActivatedAt = SnoozableTimerStore.get.e2eiActivatedAt() || Date.now();
SnoozableTimerStore.store.e2eiActivatedAt(e2eActivatedAt);
const e2eActivatedAt = EnrollmentStore.get.e2eiActivatedAt() || Date.now();
EnrollmentStore.store.e2eiActivatedAt(e2eActivatedAt);

const timerKey = 'enrollmentTimer';
const identity = await getActiveWireIdentity();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

const e2eActivatedAtKey = 'e2eActivatedAt';

export const SnoozableTimerStore = {
export const EnrollmentStore = {
store: {
e2eiActivatedAt: (time: number) => localStorage.setItem(e2eActivatedAtKey, String(time)),
},
Expand Down
65 changes: 65 additions & 0 deletions src/script/E2EIdentity/EnrollmentTimer/EnrollmentTimer.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
* Wire
* Copyright (C) 2023 Wire Swiss GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see http://www.gnu.org/licenses/.
*
*/

import {getEnrollmentTimer, messageRetentionTime} from './EnrollmentTimer';

import {MLSStatuses} from '../E2EIdentityVerification';

describe('e2ei delays', () => {
const gracePeriod = 3600;
beforeEach(() => {
jest.useFakeTimers();
jest.setSystemTime(0);
});

it('should return an immediate delay if the identity is expired', () => {
const delay = getEnrollmentTimer({status: MLSStatuses.EXPIRED} as any, Date.now(), gracePeriod);

expect(delay).toEqual({firingDate: Date.now(), isSnoozable: false});
});

it('should return a snoozable timer if device is new and still in the grace period', () => {
const {firingDate, isSnoozable} = getEnrollmentTimer(undefined, Date.now(), gracePeriod);

expect(isSnoozable).toBeTruthy();
expect(firingDate).toBeLessThanOrEqual(gracePeriod);
});

it('should return a snoozable timer if device is certified and still in the grace period', () => {
const {firingDate, isSnoozable} = getEnrollmentTimer(
{certificate: ' ', notAfter: Date.now() + messageRetentionTime + gracePeriod + 1000} as any,
Date.now(),
gracePeriod,
);

expect(isSnoozable).toBeTruthy();
expect(firingDate).toBeLessThanOrEqual(gracePeriod);
});

it('should return a non snoozable timer if device is certified about to expired', () => {
const {firingDate, isSnoozable} = getEnrollmentTimer(
{certificate: ' ', notAfter: Date.now() + gracePeriod + 1000} as any,
Date.now(),
gracePeriod,
);

expect(isSnoozable).toBeFalsy();
expect(firingDate).toBeLessThanOrEqual(gracePeriod);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export const FOUR_HOURS = TimeInMillis.HOUR * 4;
export const ONE_DAY = TimeInMillis.DAY;

// message retention time on backend (hardcoded to 28 days)
const messageRetentionTime = 28 * TimeInMillis.DAY;
export const messageRetentionTime = 28 * TimeInMillis.DAY;

/**
* Will return a suitable snooze time based on the grace period
Expand All @@ -40,7 +40,7 @@ function getNextTick(expiryDate: number, gracePeriodDuration: number, isFirstEnr
const leftoverTimer = expiryDate - Date.now();

// First a first enrollment we only consider the grace period. For enrolled devices we also consider the backend message retention time
const extraDelay = isFirstEnrollment ? 0 : randomInt(TimeInMillis.DAY) - messageRetentionTime;
const extraDelay = isFirstEnrollment ? 0 : randomInt(TimeInMillis.DAY) + messageRetentionTime;

const gracePeriod = Math.max(0, Math.min(gracePeriodDuration, leftoverTimer - extraDelay));
if (gracePeriod <= 0) {
Expand All @@ -61,7 +61,7 @@ function getNextTick(expiryDate: number, gracePeriodDuration: number, isFirstEnr

export function getEnrollmentTimer(
identity: WireIdentity | undefined,
deviceCreatedAt: number,
e2eiActivatedAt: number,
teamGracePeriodDuration: number,
) {
if (identity?.status === MLSStatuses.EXPIRED) {
Expand All @@ -70,7 +70,7 @@ export function getEnrollmentTimer(

const isFirstEnrollment = !identity?.certificate;
const expiryDate = isFirstEnrollment
? deviceCreatedAt + teamGracePeriodDuration
? e2eiActivatedAt + teamGracePeriodDuration
: Number(identity.notAfter) * TimeInMillis.SECOND;

const nextTick = getNextTick(expiryDate, teamGracePeriodDuration, isFirstEnrollment);
Expand Down
20 changes: 20 additions & 0 deletions src/script/E2EIdentity/EnrollmentTimer/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/*
* Wire
* Copyright (C) 2024 Wire Swiss GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see http://www.gnu.org/licenses/.
*
*/

export * from './EnrollmentTimer';

0 comments on commit f814b6e

Please sign in to comment.