1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-18 01:03:35 +00:00

[EC-598] feat: wait for session close before closing window

This commit is contained in:
Andreas Coroiu
2023-04-11 16:02:45 +02:00
parent 2992142681
commit a06b9ad020
5 changed files with 196 additions and 176 deletions

View File

@@ -86,6 +86,9 @@ export type BrowserFido2Message = { sessionId: string } & (
type: "AbortResponse"; type: "AbortResponse";
fallbackRequested: boolean; fallbackRequested: boolean;
} }
| {
type: "CloseRequest";
}
); );
export class BrowserFido2UserInterfaceService implements Fido2UserInterfaceServiceAbstraction { export class BrowserFido2UserInterfaceService implements Fido2UserInterfaceServiceAbstraction {
@@ -237,6 +240,13 @@ export class BrowserFido2UserInterfaceSession implements Fido2UserInterfaceSessi
await this.receive("AbortResponse"); await this.receive("AbortResponse");
} }
async close() {
await this.send({ type: "CloseRequest", sessionId: this.sessionId });
this.closed = true;
this.destroy$.next();
this.destroy$.complete();
}
private async send(msg: BrowserFido2Message): Promise<void> { private async send(msg: BrowserFido2Message): Promise<void> {
if (!this.connected$.value) { if (!this.connected$.value) {
await this.connect(); await this.connect();
@@ -276,10 +286,4 @@ export class BrowserFido2UserInterfaceSession implements Fido2UserInterfaceSessi
); );
await firstValueFrom(this.connected$.pipe(filter((connected) => connected === true))); await firstValueFrom(this.connected$.pipe(filter((connected) => connected === true)));
} }
private close() {
this.closed = true;
this.destroy$.next();
this.destroy$.complete();
}
} }

View File

@@ -1,5 +1,6 @@
<ng-container *ngIf="data$ | async as data"> <ng-container *ngIf="data$ | async as data">
<div class="auth-wrapper"> <div class="auth-wrapper">
<i class="bwi bwi-spinner bwi-lg bwi-spin" [hidden]="!loading" aria-hidden="true"></i>
<ng-container *ngIf="data.type == 'ConfirmCredentialRequest'"> <ng-container *ngIf="data.type == 'ConfirmCredentialRequest'">
A site is asking for authentication using the following credential: A site is asking for authentication using the following credential:
<div class="box list"> <div class="box list">

View File

@@ -33,6 +33,7 @@ export class Fido2Component implements OnInit, OnDestroy {
protected data$ = new BehaviorSubject<BrowserFido2Message>(null); protected data$ = new BehaviorSubject<BrowserFido2Message>(null);
protected sessionId?: string; protected sessionId?: string;
protected ciphers?: CipherView[] = []; protected ciphers?: CipherView[] = [];
protected loading = false;
constructor(private activatedRoute: ActivatedRoute, private cipherService: CipherService) {} constructor(private activatedRoute: ActivatedRoute, private cipherService: CipherService) {}
@@ -92,6 +93,8 @@ export class Fido2Component implements OnInit, OnDestroy {
return cipher.decrypt(); return cipher.decrypt();
}) })
); );
} else if (data?.type === "CloseRequest") {
window.close();
} }
}), }),
takeUntil(this.destroy$) takeUntil(this.destroy$)
@@ -122,7 +125,7 @@ export class Fido2Component implements OnInit, OnDestroy {
}); });
} }
window.close(); this.loading = true;
} }
confirm() { confirm() {
@@ -130,7 +133,7 @@ export class Fido2Component implements OnInit, OnDestroy {
sessionId: this.sessionId, sessionId: this.sessionId,
type: "ConfirmCredentialResponse", type: "ConfirmCredentialResponse",
}); });
window.close(); this.loading = true;
} }
confirmNew() { confirmNew() {
@@ -138,7 +141,7 @@ export class Fido2Component implements OnInit, OnDestroy {
sessionId: this.sessionId, sessionId: this.sessionId,
type: "ConfirmNewCredentialResponse", type: "ConfirmNewCredentialResponse",
}); });
window.close(); this.loading = true;
} }
abort(fallback: boolean) { abort(fallback: boolean) {

View File

@@ -41,4 +41,5 @@ export abstract class Fido2UserInterfaceSession {
existingCipherIds: string[], existingCipherIds: string[],
abortController?: AbortController abortController?: AbortController
) => Promise<void>; ) => Promise<void>;
close: () => void;
} }

View File

@@ -43,11 +43,15 @@ export class Fido2AuthenticatorService implements Fido2AuthenticatorServiceAbstr
): Promise<Fido2AuthenticatorMakeCredentialResult> { ): Promise<Fido2AuthenticatorMakeCredentialResult> {
const userInterfaceSession = await this.userInterface.newSession(abortController); const userInterfaceSession = await this.userInterface.newSession(abortController);
try {
if (params.credTypesAndPubKeyAlgs.every((p) => p.alg !== Fido2AlgorithmIdentifier.ES256)) { if (params.credTypesAndPubKeyAlgs.every((p) => p.alg !== Fido2AlgorithmIdentifier.ES256)) {
throw new Fido2AutenticatorError(Fido2AutenticatorErrorCode.NotSupported); throw new Fido2AutenticatorError(Fido2AutenticatorErrorCode.NotSupported);
} }
if (params.requireResidentKey != undefined && typeof params.requireResidentKey !== "boolean") { if (
params.requireResidentKey != undefined &&
typeof params.requireResidentKey !== "boolean"
) {
throw new Fido2AutenticatorError(Fido2AutenticatorErrorCode.Unknown); throw new Fido2AutenticatorError(Fido2AutenticatorErrorCode.Unknown);
} }
@@ -151,6 +155,9 @@ export class Fido2AuthenticatorService implements Fido2AuthenticatorServiceAbstr
authData, authData,
publicKeyAlgorithm: -7, publicKeyAlgorithm: -7,
}; };
} finally {
userInterfaceSession.close();
}
} }
async getAssertion( async getAssertion(
@@ -159,6 +166,7 @@ export class Fido2AuthenticatorService implements Fido2AuthenticatorServiceAbstr
): Promise<Fido2AuthenticatorGetAssertionResult> { ): Promise<Fido2AuthenticatorGetAssertionResult> {
const userInterfaceSession = await this.userInterface.newSession(abortController); const userInterfaceSession = await this.userInterface.newSession(abortController);
try {
if ( if (
params.requireUserVerification != undefined && params.requireUserVerification != undefined &&
typeof params.requireUserVerification !== "boolean" typeof params.requireUserVerification !== "boolean"
@@ -239,6 +247,9 @@ export class Fido2AuthenticatorService implements Fido2AuthenticatorServiceAbstr
} catch { } catch {
throw new Fido2AutenticatorError(Fido2AutenticatorErrorCode.Unknown); throw new Fido2AutenticatorError(Fido2AutenticatorErrorCode.Unknown);
} }
} finally {
userInterfaceSession.close();
}
} }
/** Finds existing crendetials and returns the `cipherId` for each one */ /** Finds existing crendetials and returns the `cipherId` for each one */