mirror of
https://github.com/bitwarden/browser.git
synced 2024-11-16 10:45:20 +01:00
[EC-598] feat: differntiate between resident auth and 2fa
This commit is contained in:
parent
132c3fe04d
commit
f7a74c8cf2
@ -1,7 +1,18 @@
|
||||
<ng-container *ngIf="data">
|
||||
<div class="auth-wrapper">
|
||||
<ng-container *ngIf="data.type == 'ConfirmCredentialRequest'">
|
||||
A site is asking for authentication using the following credential:
|
||||
<div class="box list">
|
||||
<div class="box-content">
|
||||
<app-cipher-row [cipher]="ciphers[0]"></app-cipher-row>
|
||||
</div>
|
||||
</div>
|
||||
<button type="button" class="btn btn-outline-secondary" (click)="confirm()">
|
||||
Authenticate
|
||||
</button>
|
||||
</ng-container>
|
||||
<ng-container *ngIf="data.type == 'PickCredentialRequest'">
|
||||
A site is asking for authentication, please choose one of the following credentials to use
|
||||
A site is asking for authentication, please choose one of the following credentials to use:
|
||||
<div class="box list">
|
||||
<div class="box-content">
|
||||
<app-cipher-row
|
||||
@ -11,10 +22,6 @@
|
||||
></app-cipher-row>
|
||||
</div>
|
||||
</div>
|
||||
<!-- <button type="button" class="btn btn-outline-secondary" (click)="accept()">
|
||||
<ng-container *ngIf="data.type == 'VerifyUserRequest'">Authenticate</ng-container>
|
||||
<ng-container *ngIf="data.type == 'ConfirmNewCredentialRequest'">Create</ng-container>
|
||||
</button> -->
|
||||
</ng-container>
|
||||
<ng-container *ngIf="data.type == 'ConfirmNewCredentialRequest'">
|
||||
A site wants to create the following passkey in your vault
|
||||
@ -23,9 +30,7 @@
|
||||
<app-cipher-row [cipher]="ciphers[0]"></app-cipher-row>
|
||||
</div>
|
||||
</div>
|
||||
<button type="button" class="btn btn-outline-secondary" (click)="confirm()">
|
||||
<ng-container *ngIf="data.type == 'ConfirmNewCredentialRequest'">Create</ng-container>
|
||||
</button>
|
||||
<button type="button" class="btn btn-outline-secondary" (click)="confirmNew()">Create</button>
|
||||
</ng-container>
|
||||
<button type="button" class="btn btn-outline-secondary" (click)="cancel(true)">
|
||||
Use browser built-in
|
||||
|
@ -37,6 +37,9 @@ export class Fido2Component implements OnInit, OnDestroy {
|
||||
cipher.type = CipherType.Fido2Key;
|
||||
cipher.fido2Key = new Fido2KeyView();
|
||||
this.ciphers = [cipher];
|
||||
} else if (this.data?.type === "ConfirmCredentialRequest") {
|
||||
const cipher = await this.cipherService.get(this.data.cipherId);
|
||||
this.ciphers = [await cipher.decrypt()];
|
||||
} else if (this.data?.type === "PickCredentialRequest") {
|
||||
this.ciphers = await Promise.all(
|
||||
this.data.cipherIds.map(async (cipherId) => {
|
||||
@ -62,6 +65,14 @@ export class Fido2Component implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
confirm() {
|
||||
BrowserFido2UserInterfaceService.sendMessage({
|
||||
requestId: this.data.requestId,
|
||||
type: "ConfirmCredentialResponse",
|
||||
});
|
||||
window.close();
|
||||
}
|
||||
|
||||
confirmNew() {
|
||||
BrowserFido2UserInterfaceService.sendMessage({
|
||||
requestId: this.data.requestId,
|
||||
type: "ConfirmNewCredentialResponse",
|
||||
|
@ -21,6 +21,13 @@ export type BrowserFido2Message = { requestId: string } & (
|
||||
type: "PickCredentialResponse";
|
||||
cipherId?: string;
|
||||
}
|
||||
| {
|
||||
type: "ConfirmCredentialRequest";
|
||||
cipherId: string;
|
||||
}
|
||||
| {
|
||||
type: "ConfirmCredentialResponse";
|
||||
}
|
||||
| {
|
||||
type: "ConfirmNewCredentialRequest";
|
||||
name: string;
|
||||
@ -50,6 +57,35 @@ export class BrowserFido2UserInterfaceService implements Fido2UserInterfaceServi
|
||||
BrowserApi.messageListener(BrowserFido2MessageName, this.processMessage.bind(this));
|
||||
}
|
||||
|
||||
async confirmCredential(cipherId: string): Promise<boolean> {
|
||||
const requestId = Utils.newGuid();
|
||||
const data: BrowserFido2Message = { type: "ConfirmCredentialRequest", cipherId, requestId };
|
||||
const queryParams = new URLSearchParams({ data: JSON.stringify(data) }).toString();
|
||||
this.popupUtilsService.popOut(
|
||||
null,
|
||||
`popup/index.html?uilocation=popout#/fido2?${queryParams}`,
|
||||
{ center: true }
|
||||
);
|
||||
|
||||
const response = await lastValueFrom(
|
||||
this.messages$.pipe(
|
||||
filter((msg) => msg.requestId === requestId),
|
||||
first(),
|
||||
takeUntil(this.destroy$)
|
||||
)
|
||||
);
|
||||
|
||||
if (response.type === "ConfirmCredentialResponse") {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (response.type === "RequestCancelled") {
|
||||
throw new RequestAbortedError(response.fallbackRequested);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
async pickCredential(cipherIds: string[]): Promise<string> {
|
||||
const requestId = Utils.newGuid();
|
||||
const data: BrowserFido2Message = { type: "PickCredentialRequest", cipherIds, requestId };
|
||||
|
@ -3,6 +3,7 @@ export interface NewCredentialParams {
|
||||
}
|
||||
|
||||
export abstract class Fido2UserInterfaceService {
|
||||
confirmCredential: (cipherId: string) => Promise<boolean>;
|
||||
pickCredential: (cipherIds: string[]) => Promise<string>;
|
||||
confirmNewCredential: (params: NewCredentialParams) => Promise<boolean>;
|
||||
}
|
||||
|
@ -129,7 +129,7 @@ export class Fido2Service implements Fido2ServiceAbstraction {
|
||||
throw new OriginMismatchError();
|
||||
}
|
||||
|
||||
await this.fido2UserInterfaceService.pickCredential([credential.credentialId.encoded]);
|
||||
await this.fido2UserInterfaceService.confirmCredential(credential.credentialId.encoded);
|
||||
} else {
|
||||
// We're looking for a resident key
|
||||
const credentials = await this.getCredentialsByRp(params.rpId);
|
||||
|
@ -2,6 +2,10 @@ import { Fido2UserInterfaceService as Fido2UserInterfaceServiceAbstraction } fro
|
||||
import { RequestAbortedError } from "../../abstractions/fido2/fido2.service.abstraction";
|
||||
|
||||
export class Fido2UserInterfaceService implements Fido2UserInterfaceServiceAbstraction {
|
||||
async confirmCredential(cipherId: string): Promise<boolean> {
|
||||
return false;
|
||||
}
|
||||
|
||||
pickCredential(cipherIds: string[]): Promise<string> {
|
||||
throw new RequestAbortedError();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user