mirror of
https://github.com/bitwarden/browser.git
synced 2024-12-22 16:29:09 +01:00
[SG-698] Passwordless Login with 2FA enabled does not redirect to 2FA page (#3820)
* added 2fa enabled * added passwordless authentication to 2fa * passwordless strategy to authservice * changes to 2FA to allow email sending for passwordless * updated imports
This commit is contained in:
parent
ff3420d373
commit
cc0199d351
@ -237,6 +237,8 @@ export class TwoFactorComponent extends CaptchaProtectedComponent implements OnI
|
||||
request.email = this.authService.email;
|
||||
request.masterPasswordHash = this.authService.masterPasswordHash;
|
||||
request.deviceIdentifier = await this.appIdService.getAppId();
|
||||
request.authRequestAccessCode = this.authService.accessCode;
|
||||
request.authRequestId = this.authService.authRequestId;
|
||||
this.emailPromise = this.apiService.postTwoFactorEmail(request);
|
||||
await this.emailPromise;
|
||||
if (doToast) {
|
||||
@ -274,7 +276,8 @@ export class TwoFactorComponent extends CaptchaProtectedComponent implements OnI
|
||||
return (
|
||||
this.authService.authingWithPassword() ||
|
||||
this.authService.authingWithSso() ||
|
||||
this.authService.authingWithApiKey()
|
||||
this.authService.authingWithApiKey() ||
|
||||
this.authService.authingWithPasswordless()
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -15,6 +15,9 @@ import { AuthRequestPushNotification } from "../models/response/notification.res
|
||||
export abstract class AuthService {
|
||||
masterPasswordHash: string;
|
||||
email: string;
|
||||
accessCode: string;
|
||||
authRequestId: string;
|
||||
|
||||
logIn: (
|
||||
credentials:
|
||||
| ApiLogInCredentials
|
||||
@ -31,6 +34,7 @@ export abstract class AuthService {
|
||||
authingWithApiKey: () => boolean;
|
||||
authingWithSso: () => boolean;
|
||||
authingWithPassword: () => boolean;
|
||||
authingWithPasswordless: () => boolean;
|
||||
getAuthStatus: (userId?: string) => Promise<AuthenticationStatus>;
|
||||
authResponsePushNotifiction: (notification: AuthRequestPushNotification) => Promise<any>;
|
||||
|
||||
|
@ -10,7 +10,6 @@ import { TokenService } from "../../abstractions/token.service";
|
||||
import { TwoFactorService } from "../../abstractions/twoFactor.service";
|
||||
import { AuthResult } from "../../models/domain/auth-result";
|
||||
import { PasswordlessLogInCredentials } from "../../models/domain/log-in-credentials";
|
||||
import { SymmetricCryptoKey } from "../../models/domain/symmetric-crypto-key";
|
||||
import { PasswordTokenRequest } from "../../models/request/identity-token/password-token.request";
|
||||
import { TokenTwoFactorRequest } from "../../models/request/identity-token/token-two-factor.request";
|
||||
|
||||
@ -21,14 +20,16 @@ export class PasswordlessLogInStrategy extends LogInStrategy {
|
||||
return this.tokenRequest.email;
|
||||
}
|
||||
|
||||
get masterPasswordHash() {
|
||||
return this.tokenRequest.masterPasswordHash;
|
||||
get accessCode() {
|
||||
return this.passwordlessCredentials.accessCode;
|
||||
}
|
||||
|
||||
get authRequestId() {
|
||||
return this.passwordlessCredentials.authRequestId;
|
||||
}
|
||||
|
||||
tokenRequest: PasswordTokenRequest;
|
||||
|
||||
private localHashedPassword: string;
|
||||
private key: SymmetricCryptoKey;
|
||||
private passwordlessCredentials: PasswordlessLogInCredentials;
|
||||
|
||||
constructor(
|
||||
cryptoService: CryptoService,
|
||||
@ -56,8 +57,8 @@ export class PasswordlessLogInStrategy extends LogInStrategy {
|
||||
}
|
||||
|
||||
async onSuccessfulLogin() {
|
||||
await this.cryptoService.setKey(this.key);
|
||||
await this.cryptoService.setKeyHash(this.localHashedPassword);
|
||||
await this.cryptoService.setKey(this.passwordlessCredentials.decKey);
|
||||
await this.cryptoService.setKeyHash(this.passwordlessCredentials.localPasswordHash);
|
||||
}
|
||||
|
||||
async logInTwoFactor(
|
||||
@ -69,8 +70,7 @@ export class PasswordlessLogInStrategy extends LogInStrategy {
|
||||
}
|
||||
|
||||
async logIn(credentials: PasswordlessLogInCredentials) {
|
||||
this.localHashedPassword = credentials.localPasswordHash;
|
||||
this.key = credentials.decKey;
|
||||
this.passwordlessCredentials = credentials;
|
||||
|
||||
this.tokenRequest = new PasswordTokenRequest(
|
||||
credentials.email,
|
||||
|
@ -1,4 +1,5 @@
|
||||
export class SecretVerificationRequest {
|
||||
masterPasswordHash: string;
|
||||
otp: string;
|
||||
authRequestAccessCode: string;
|
||||
}
|
||||
|
@ -3,4 +3,5 @@ import { SecretVerificationRequest } from "./secret-verification.request";
|
||||
export class TwoFactorEmailRequest extends SecretVerificationRequest {
|
||||
email: string;
|
||||
deviceIdentifier: string;
|
||||
authRequestId: string;
|
||||
}
|
||||
|
@ -38,7 +38,14 @@ const sessionTimeoutLength = 2 * 60 * 1000; // 2 minutes
|
||||
|
||||
export class AuthService implements AuthServiceAbstraction {
|
||||
get email(): string {
|
||||
return this.logInStrategy instanceof PasswordLogInStrategy ? this.logInStrategy.email : null;
|
||||
if (
|
||||
this.logInStrategy instanceof PasswordLogInStrategy ||
|
||||
this.logInStrategy instanceof PasswordlessLogInStrategy
|
||||
) {
|
||||
return this.logInStrategy.email;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
get masterPasswordHash(): string {
|
||||
@ -47,6 +54,18 @@ export class AuthService implements AuthServiceAbstraction {
|
||||
: null;
|
||||
}
|
||||
|
||||
get accessCode(): string {
|
||||
return this.logInStrategy instanceof PasswordlessLogInStrategy
|
||||
? this.logInStrategy.accessCode
|
||||
: null;
|
||||
}
|
||||
|
||||
get authRequestId(): string {
|
||||
return this.logInStrategy instanceof PasswordlessLogInStrategy
|
||||
? this.logInStrategy.authRequestId
|
||||
: null;
|
||||
}
|
||||
|
||||
private logInStrategy:
|
||||
| ApiLogInStrategy
|
||||
| PasswordLogInStrategy
|
||||
@ -196,6 +215,10 @@ export class AuthService implements AuthServiceAbstraction {
|
||||
return this.logInStrategy instanceof PasswordLogInStrategy;
|
||||
}
|
||||
|
||||
authingWithPasswordless(): boolean {
|
||||
return this.logInStrategy instanceof PasswordlessLogInStrategy;
|
||||
}
|
||||
|
||||
async getAuthStatus(userId?: string): Promise<AuthenticationStatus> {
|
||||
const isAuthenticated = await this.stateService.getIsAuthenticated({ userId: userId });
|
||||
if (!isAuthenticated) {
|
||||
|
Loading…
Reference in New Issue
Block a user