This commit is contained in:
SmithThe4th 2024-04-25 20:31:40 -04:00 committed by GitHub
commit 9828fb18d8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 73 additions and 4 deletions

View File

@ -26,7 +26,9 @@ export const fido2AuthGuard: CanActivateFn = async (
const authStatus = await authService.getAuthStatus();
if (authStatus === AuthenticationStatus.Locked) {
routerService.setPreviousUrl(state.url);
// Appending fromLock=true to the query params to indicate that the user is being redirected from the lock screen, this is used for user verification.
const previousUrl = `${state.url}&fromLock=true`;
routerService.setPreviousUrl(previousUrl);
return router.createUrlTree(["/lock"], { queryParams: route.queryParams });
}

View File

@ -14,6 +14,7 @@ import { EnvironmentSelectorComponent } from "@bitwarden/angular/auth/components
import { JslibModule } from "@bitwarden/angular/jslib.module";
import { ColorPasswordCountPipe } from "@bitwarden/angular/pipes/color-password-count.pipe";
import { ColorPasswordPipe } from "@bitwarden/angular/pipes/color-password.pipe";
import { UserVerificationDialogComponent } from "@bitwarden/auth/angular";
import { AvatarModule, ButtonModule, ToastModule } from "@bitwarden/components";
import { ExportScopeCalloutComponent } from "@bitwarden/vault-export-ui";
@ -108,6 +109,7 @@ import "../platform/popup/locales";
AccountComponent,
ButtonModule,
ExportScopeCalloutComponent,
UserVerificationDialogComponent,
],
declarations: [
ActionButtonsComponent,

View File

@ -13,6 +13,7 @@ import {
takeUntil,
} from "rxjs";
import { UserVerificationDialogComponent } from "@bitwarden/auth/angular";
import { SearchService } from "@bitwarden/common/abstractions/search.service";
import { DomainSettingsService } from "@bitwarden/common/autofill/services/domain-settings.service";
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
@ -36,6 +37,8 @@ import {
} from "../../../fido2/browser-fido2-user-interface.service";
import { VaultPopoutType } from "../../utils/vault-popout-window";
import { SetPinComponent } from "./../../../../auth/popup/components/set-pin.component";
interface ViewData {
message: BrowserFido2Message;
fallbackSupported: boolean;
@ -59,6 +62,7 @@ export class Fido2Component implements OnInit, OnDestroy {
protected data$: Observable<ViewData>;
protected sessionId?: string;
protected senderTabId?: string;
protected fromLock?: boolean;
protected ciphers?: CipherView[] = [];
protected displayedCiphers?: CipherView[] = [];
protected loading = false;
@ -89,6 +93,7 @@ export class Fido2Component implements OnInit, OnDestroy {
sessionId: queryParamMap.get("sessionId"),
senderTabId: queryParamMap.get("senderTabId"),
senderUrl: queryParamMap.get("senderUrl"),
fromLock: queryParamMap.get("fromLock"),
})),
);
@ -101,6 +106,7 @@ export class Fido2Component implements OnInit, OnDestroy {
this.sessionId = queryParams.sessionId;
this.senderTabId = queryParams.senderTabId;
this.url = queryParams.senderUrl;
this.fromLock = queryParams.fromLock === "true";
// For a 'NewSessionCreatedRequest', abort if it doesn't belong to the current session.
if (
message.type === "NewSessionCreatedRequest" &&
@ -374,20 +380,79 @@ export class Fido2Component implements OnInit, OnDestroy {
}
}
/**
* Handles user verification for a user based on the cipher and user verification requested.
* @param userVerificationRequested Indicates if user verification is required or not.
* @param cipher Contains details about the cipher including master password reprompt.
* @returns
*/
private async handleUserVerification(
userVerificationRequested: boolean,
cipher: CipherView,
): Promise<boolean> {
const masterPasswordRepromptRequired = cipher && cipher.reprompt !== 0;
if (masterPasswordRepromptRequired) {
return await this.passwordRepromptService.showPasswordPrompt();
// If the request is from the lock screen, treat unlocking the vault as user verification,
// unless a master password reprompt is required.
if (this.fromLock) {
return masterPasswordRepromptRequired
? await this.showMasterPasswordReprompt()
: userVerificationRequested;
}
if (masterPasswordRepromptRequired) {
return await this.showMasterPasswordReprompt();
}
if (userVerificationRequested) {
return await this.showUserVerificationDialog();
}
// We are bypassing user verification pending implementation of PIN and biometric support.
return userVerificationRequested;
}
private async showMasterPasswordReprompt(): Promise<boolean> {
return await this.passwordRepromptService.showPasswordPrompt();
}
private async showUserVerificationDialog(): Promise<boolean> {
const result = await UserVerificationDialogComponent.open(this.dialogService, {
clientSideOnlyVerification: true,
});
if (result.userAction === "cancel") {
return;
}
// Handle unsuccessful verification attempts.
if (!result.verificationSuccess) {
// Check if no client-side verification methods are available.
if (result.noAvailableClientVerificationMethods) {
return await this.promptUserToSetPin();
}
return;
}
return result.verificationSuccess;
}
private async promptUserToSetPin() {
const dialogRef = SetPinComponent.open(this.dialogService);
if (!dialogRef) {
return;
}
const userHasPinSet = await firstValueFrom(dialogRef.closed);
if (!userHasPinSet) {
return;
}
// If the user has set a PIN, re-invoke the user verification dialog to complete the verification process.
return await this.showUserVerificationDialog();
}
private send(msg: BrowserFido2Message) {
BrowserFido2UserInterfaceSession.sendMessage({
sessionId: this.sessionId,