1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-16 08:13:42 +00:00

feat(auth): [PM-13659] implement 2FA timeout handling across clients

Add timeout state management for two-factor authentication flows in web, desktop,
and browser extension clients. Includes:

- New timeout screen component with 5-minute session limit
- Updated UI elements and styling
- Comprehensive test coverage

Refs: PM-13659
This commit is contained in:
Alec Rippberger
2024-12-03 13:55:40 -06:00
committed by GitHub
parent 2e53a645c9
commit c073e91f17
13 changed files with 165 additions and 4 deletions

View File

@@ -71,4 +71,8 @@ export abstract class LoginStrategyServiceAbstraction {
* Creates a master key from the provided master password and email.
*/
makePreloginKey: (masterPassword: string, email: string) => Promise<MasterKey>;
/**
* Emits true if the two factor session has expired.
*/
twoFactorTimeout$: Observable<boolean>;
}

View File

@@ -6,6 +6,7 @@ import {
Observable,
shareReplay,
Subscription,
BehaviorSubject,
} from "rxjs";
import { ApiService } from "@bitwarden/common/abstractions/api.service";
@@ -68,7 +69,7 @@ import {
CACHE_KEY,
} from "./login-strategy.state";
const sessionTimeoutLength = 2 * 60 * 1000; // 2 minutes
const sessionTimeoutLength = 5 * 60 * 1000; // 5 minutes
export class LoginStrategyService implements LoginStrategyServiceAbstraction {
private sessionTimeoutSubscription: Subscription;
@@ -76,6 +77,9 @@ export class LoginStrategyService implements LoginStrategyServiceAbstraction {
private loginStrategyCacheState: GlobalState<CacheData | null>;
private loginStrategyCacheExpirationState: GlobalState<Date | null>;
private authRequestPushNotificationState: GlobalState<string>;
private twoFactorTimeoutSubject = new BehaviorSubject<boolean>(false);
twoFactorTimeout$: Observable<boolean> = this.twoFactorTimeoutSubject.asObservable();
private loginStrategy$: Observable<
| UserApiLoginStrategy
@@ -123,7 +127,14 @@ export class LoginStrategyService implements LoginStrategyServiceAbstraction {
);
this.taskSchedulerService.registerTaskHandler(
ScheduledTaskNames.loginStrategySessionTimeout,
() => this.clearCache(),
async () => {
this.twoFactorTimeoutSubject.next(true);
try {
await this.clearCache();
} catch (e) {
this.logService.error("Failed to clear cache during session timeout", e);
}
},
);
this.currentAuthType$ = this.currentAuthnTypeState.state$;
@@ -189,6 +200,7 @@ export class LoginStrategyService implements LoginStrategyServiceAbstraction {
| WebAuthnLoginCredentials,
): Promise<AuthResult> {
await this.clearCache();
this.twoFactorTimeoutSubject.next(false);
await this.currentAuthnTypeState.update((_) => credentials.type);
@@ -273,6 +285,7 @@ export class LoginStrategyService implements LoginStrategyServiceAbstraction {
private async clearCache(): Promise<void> {
await this.currentAuthnTypeState.update((_) => null);
await this.loginStrategyCacheState.update((_) => null);
this.twoFactorTimeoutSubject.next(false);
await this.clearSessionTimeout();
}