1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-18 09:13:33 +00:00

Initial work

This commit is contained in:
gbubemismith
2023-07-25 15:45:11 -04:00
parent 31276a92f8
commit e6e088fd02
12 changed files with 126 additions and 16 deletions

View File

@@ -1,5 +1,5 @@
import { Directive, NgZone, OnDestroy, OnInit } from "@angular/core";
import { Router } from "@angular/router";
import { ActivatedRoute, Router } from "@angular/router";
import { firstValueFrom, Subject } from "rxjs";
import { concatMap, take, takeUntil } from "rxjs/operators";
@@ -41,6 +41,8 @@ export class LockComponent implements OnInit, OnDestroy {
biometricLock: boolean;
biometricText: string;
hideInput: boolean;
redirectPath: string;
sessionId: string;
protected successRoute = "vault";
protected forcePasswordResetRoute = "update-temp-password";
@@ -70,10 +72,21 @@ export class LockComponent implements OnInit, OnDestroy {
protected policyApiService: PolicyApiServiceAbstraction,
protected policyService: InternalPolicyService,
protected passwordStrengthService: PasswordStrengthServiceAbstraction,
protected dialogService: DialogServiceAbstraction
protected dialogService: DialogServiceAbstraction,
protected route: ActivatedRoute
) {}
async ngOnInit() {
this.route?.queryParams.subscribe((params) => {
this.redirectPath = params?.redirectPath;
this.sessionId = params?.sessionId;
});
//use redirectPath to redirect to a specific page after successful login
if (this.redirectPath) {
this.successRoute = this.redirectPath;
}
this.stateService.activeAccount$
.pipe(
concatMap(async () => {
@@ -291,7 +304,11 @@ export class LockComponent implements OnInit, OnDestroy {
if (this.onSuccessfulSubmit != null) {
await this.onSuccessfulSubmit();
} else if (this.router != null) {
this.router.navigate([this.successRoute]);
this.router.navigate([this.successRoute], {
queryParams: {
sessionId: this.sessionId,
},
});
}
}

View File

@@ -39,6 +39,8 @@ export class LoginComponent extends CaptchaProtectedComponent implements OnInit
showLoginWithDevice: boolean;
validatedEmail = false;
paramEmailSet = false;
redirectPath: string;
sessionId: string;
formGroup = this.formBuilder.group({
email: ["", [Validators.required, Validators.email]],
@@ -83,11 +85,17 @@ export class LoginComponent extends CaptchaProtectedComponent implements OnInit
this.route?.queryParams.subscribe((params) => {
if (params != null) {
const queryParamsEmail = params["email"];
this.redirectPath = params?.["redirectPath"];
this.sessionId = params?.["sessionId"];
if (queryParamsEmail != null && queryParamsEmail.indexOf("@") > -1) {
this.formGroup.get("email").setValue(queryParamsEmail);
this.loginService.setEmail(queryParamsEmail);
this.paramEmailSet = true;
}
//use redirectPath to redirect to a specific page after successful login
if (this.redirectPath) {
this.successRoute = this.redirectPath;
}
}
});
let email = this.loginService.getEmail();
@@ -142,7 +150,12 @@ export class LoginComponent extends CaptchaProtectedComponent implements OnInit
if (this.onSuccessfulLoginTwoFactorNavigate != null) {
this.onSuccessfulLoginTwoFactorNavigate();
} else {
this.router.navigate([this.twoFactorRoute]);
this.router.navigate([this.twoFactorRoute], {
queryParams: {
redirectPath: this.redirectPath,
sessionId: this.sessionId,
},
});
}
} else if (response.forcePasswordReset != ForceResetPasswordReason.None) {
if (this.onSuccessfulLoginForceResetNavigate != null) {

View File

@@ -39,6 +39,8 @@ export class TwoFactorComponent extends CaptchaProtectedComponent implements OnI
formPromise: Promise<any>;
emailPromise: Promise<any>;
identifier: string = null;
redirectPath: string;
sessionId: string;
onSuccessfulLogin: () => Promise<any>;
onSuccessfulLoginNavigate: () => Promise<any>;
@@ -74,6 +76,15 @@ export class TwoFactorComponent extends CaptchaProtectedComponent implements OnI
if (qParams.identifier != null) {
this.identifier = qParams.identifier;
}
if (qParams.redirectPath != null) {
this.redirectPath = qParams.redirectPath;
this.successRoute = this.redirectPath;
}
if (qParams.sessionId != null) {
this.sessionId = qParams?.sessionId;
}
});
if (this.needsLock) {
@@ -220,6 +231,7 @@ export class TwoFactorComponent extends CaptchaProtectedComponent implements OnI
this.router.navigate([this.successRoute], {
queryParams: {
identifier: this.identifier,
sessionId: this.sessionId,
},
});
}

View File

@@ -37,5 +37,6 @@ export abstract class Fido2UserInterfaceSession {
abortController?: AbortController
) => Promise<void>;
informCredentialNotFound: (abortController?: AbortController) => Promise<void>;
login: (userVerification: boolean) => Promise<{ userVerified: boolean }>;
close: () => void;
}

View File

@@ -3,6 +3,7 @@ import { CBOR } from "cbor-redux";
import { LogService } from "../../../platform/abstractions/log.service";
import { Utils } from "../../../platform/misc/utils";
import { CipherService } from "../../abstractions/cipher.service";
import { AuthService } from "../../../auth/abstractions/auth.service";
import {
Fido2AlgorithmIdentifier,
Fido2AutenticatorError,
@@ -21,6 +22,7 @@ import { Fido2KeyView } from "../../models/view/fido2-key.view";
import { joseToDer } from "./ecdsa-utils";
import { Fido2Utils } from "./fido2-utils";
import { AuthenticationStatus } from "../../../auth/enums/authentication-status";
// AAGUID: 6e8248d5-b479-40db-a3d8-11116f7e8349
export const AAGUID = new Uint8Array([
@@ -37,6 +39,7 @@ export class Fido2AuthenticatorService implements Fido2AuthenticatorServiceAbstr
constructor(
private cipherService: CipherService,
private userInterface: Fido2UserInterfaceService,
private authService: AuthService,
private logService?: LogService
) {}
async makeCredential(
@@ -220,6 +223,12 @@ export class Fido2AuthenticatorService implements Fido2AuthenticatorServiceAbstr
);
try {
const authStatus = await this.authService.getAuthStatus();
if (authStatus === AuthenticationStatus.LoggedOut) {
const response = await userInterfaceSession.login(params.requireUserVerification);
}
if (
params.requireUserVerification != undefined &&
typeof params.requireUserVerification !== "boolean"