1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-17 00:33:44 +00:00

[SG-168] Passwordless login web MVP (#3424)

* passwordless login page redesign

* passwordless login page redesign

* restyled login form to use tailwind

* restyled login form to use tailwind

* moved texts on login device template to locales

* made reactive form changes for clients

* added request model

* made more changes

* added implmentation to auth request api

* fixed refrencing issue

* renamed model property

* Added resend notification functionality

* Added new file

* login with device first draft

* login with device first draft

* login with device first draft

* login with device first draft

* connection to anonymous hub

* connection to anonymous hub

* refactored confirm login response

* removed comment

* cleaned up login

* changed uptyped form builder

* changed uptyped form builder

* [SG-168] Update login strategy with passwordless login credentials.

* [SG-168] Removed logs. Changed inputs for passwordless logic strategy. Removed tokenRequestPasswordless it is using the same as password.

* code cleanup

* code cleanup

* removed login with device from self hosted

* fixed PR comments

* added module for login

* fixed post request bug

* added feature flag

* added feature flag

* added feature flag

Co-authored-by: André Bispo <abispo@bitwarden.com>
This commit is contained in:
Gbubemi Smith
2022-09-26 23:26:10 +01:00
committed by GitHub
parent debaef2941
commit 22a878792e
38 changed files with 907 additions and 240 deletions

View File

@@ -1,3 +1,5 @@
import { Observable, Subject } from "rxjs";
import { ApiService } from "../abstractions/api.service";
import { AppIdService } from "../abstractions/appId.service";
import { AuthService as AuthServiceAbstraction } from "../abstractions/auth.service";
@@ -17,17 +19,20 @@ import { KdfType } from "../enums/kdfType";
import { KeySuffixOptions } from "../enums/keySuffixOptions";
import { ApiLogInStrategy } from "../misc/logInStrategies/apiLogin.strategy";
import { PasswordLogInStrategy } from "../misc/logInStrategies/passwordLogin.strategy";
import { PasswordlessLogInStrategy } from "../misc/logInStrategies/passwordlessLogin.strategy";
import { SsoLogInStrategy } from "../misc/logInStrategies/ssoLogin.strategy";
import { AuthResult } from "../models/domain/authResult";
import {
ApiLogInCredentials,
PasswordLogInCredentials,
SsoLogInCredentials,
PasswordlessLogInCredentials,
} from "../models/domain/logInCredentials";
import { SymmetricCryptoKey } from "../models/domain/symmetricCryptoKey";
import { TokenRequestTwoFactor } from "../models/request/identityToken/tokenRequestTwoFactor";
import { PreloginRequest } from "../models/request/preloginRequest";
import { ErrorResponse } from "../models/response/errorResponse";
import { AuthRequestPushNotification } from "../models/response/notificationResponse";
const sessionTimeoutLength = 2 * 60 * 1000; // 2 minutes
@@ -42,9 +47,15 @@ export class AuthService implements AuthServiceAbstraction {
: null;
}
private logInStrategy: ApiLogInStrategy | PasswordLogInStrategy | SsoLogInStrategy;
private logInStrategy:
| ApiLogInStrategy
| PasswordLogInStrategy
| SsoLogInStrategy
| PasswordlessLogInStrategy;
private sessionTimeout: any;
private pushNotificationSubject = new Subject<string>();
constructor(
protected cryptoService: CryptoService,
protected apiService: ApiService,
@@ -61,52 +72,78 @@ export class AuthService implements AuthServiceAbstraction {
) {}
async logIn(
credentials: ApiLogInCredentials | PasswordLogInCredentials | SsoLogInCredentials
credentials:
| ApiLogInCredentials
| PasswordLogInCredentials
| SsoLogInCredentials
| PasswordlessLogInCredentials
): Promise<AuthResult> {
this.clearState();
let strategy: ApiLogInStrategy | PasswordLogInStrategy | SsoLogInStrategy;
let strategy:
| ApiLogInStrategy
| PasswordLogInStrategy
| SsoLogInStrategy
| PasswordlessLogInStrategy;
if (credentials.type === AuthenticationType.Password) {
strategy = new PasswordLogInStrategy(
this.cryptoService,
this.apiService,
this.tokenService,
this.appIdService,
this.platformUtilsService,
this.messagingService,
this.logService,
this.stateService,
this.twoFactorService,
this
);
} else if (credentials.type === AuthenticationType.Sso) {
strategy = new SsoLogInStrategy(
this.cryptoService,
this.apiService,
this.tokenService,
this.appIdService,
this.platformUtilsService,
this.messagingService,
this.logService,
this.stateService,
this.twoFactorService,
this.keyConnectorService
);
} else if (credentials.type === AuthenticationType.Api) {
strategy = new ApiLogInStrategy(
this.cryptoService,
this.apiService,
this.tokenService,
this.appIdService,
this.platformUtilsService,
this.messagingService,
this.logService,
this.stateService,
this.twoFactorService,
this.environmentService,
this.keyConnectorService
);
switch (credentials.type) {
case AuthenticationType.Password:
strategy = new PasswordLogInStrategy(
this.cryptoService,
this.apiService,
this.tokenService,
this.appIdService,
this.platformUtilsService,
this.messagingService,
this.logService,
this.stateService,
this.twoFactorService,
this
);
break;
case AuthenticationType.Sso:
strategy = new SsoLogInStrategy(
this.cryptoService,
this.apiService,
this.tokenService,
this.appIdService,
this.platformUtilsService,
this.messagingService,
this.logService,
this.stateService,
this.twoFactorService,
this.keyConnectorService
);
break;
case AuthenticationType.Api:
strategy = new ApiLogInStrategy(
this.cryptoService,
this.apiService,
this.tokenService,
this.appIdService,
this.platformUtilsService,
this.messagingService,
this.logService,
this.stateService,
this.twoFactorService,
this.environmentService,
this.keyConnectorService
);
break;
case AuthenticationType.Passwordless:
strategy = new PasswordlessLogInStrategy(
this.cryptoService,
this.apiService,
this.tokenService,
this.appIdService,
this.platformUtilsService,
this.messagingService,
this.logService,
this.stateService,
this.twoFactorService,
this
);
break;
}
const result = await strategy.logIn(credentials as any);
@@ -202,7 +239,21 @@ export class AuthService implements AuthServiceAbstraction {
return this.cryptoService.makeKey(masterPassword, email, kdf, kdfIterations);
}
private saveState(strategy: ApiLogInStrategy | PasswordLogInStrategy | SsoLogInStrategy) {
async authResponsePushNotifiction(notification: AuthRequestPushNotification): Promise<any> {
this.pushNotificationSubject.next(notification.id);
}
getPushNotifcationObs$(): Observable<any> {
return this.pushNotificationSubject.asObservable();
}
private saveState(
strategy:
| ApiLogInStrategy
| PasswordLogInStrategy
| SsoLogInStrategy
| PasswordlessLogInStrategy
) {
this.logInStrategy = strategy;
this.startSessionTimeout();
}