1
0
mirror of https://github.com/bitwarden/jslib synced 2025-12-21 18:53:32 +00:00

Make LoginTwoFactor call entry methods

Also fix authingWith* methods
This commit is contained in:
Thomas Rittson
2021-12-20 10:32:58 +10:00
parent 8e633c3604
commit 2551da6592
2 changed files with 81 additions and 59 deletions

View File

@@ -38,10 +38,8 @@ import { Utils } from "../misc/utils";
import { IdentityCaptchaResponse } from "../models/response/identityCaptchaResponse"; import { IdentityCaptchaResponse } from "../models/response/identityCaptchaResponse";
export class AuthService implements AuthServiceAbstraction { export class AuthService implements AuthServiceAbstraction {
private localMasterPasswordHash: string;
private savedTokenRequest: ApiTokenRequest | PasswordTokenRequest | SsoTokenRequest; private savedTokenRequest: ApiTokenRequest | PasswordTokenRequest | SsoTokenRequest;
private localHashedPassword: string;
private key: SymmetricCryptoKey; private key: SymmetricCryptoKey;
constructor( constructor(
@@ -67,21 +65,32 @@ export class AuthService implements AuthServiceAbstraction {
captchaToken?: string captchaToken?: string
): Promise<AuthResult> { ): Promise<AuthResult> {
this.twoFactorService.clearSelectedProvider(); this.twoFactorService.clearSelectedProvider();
const key = await this.makePreloginKey(masterPassword, email);
const hashedPassword = await this.cryptoService.hashPassword(masterPassword, key);
const localHashedPassword = await this.cryptoService.hashPassword(
masterPassword,
key,
HashPurpose.LocalAuthorization
);
const tokenRequest = new PasswordTokenRequest( let tokenRequest: PasswordTokenRequest;
email, let key: SymmetricCryptoKey;
hashedPassword, let localHashedPassword: string;
await this.createTwoFactorData(twoFactor),
captchaToken, if (this.savedTokenRequest == null) {
await this.createDeviceRequest() key = await this.makePreloginKey(masterPassword, email);
); localHashedPassword = await this.cryptoService.hashPassword(
masterPassword,
key,
HashPurpose.LocalAuthorization
);
const hashedPassword = await this.cryptoService.hashPassword(masterPassword, key);
tokenRequest = new PasswordTokenRequest(
email,
hashedPassword,
await this.createTwoFactorData(twoFactor),
captchaToken,
await this.createDeviceRequest()
);
} else {
tokenRequest = this.savedTokenRequest as PasswordTokenRequest;
key = this.key;
localHashedPassword = this.localHashedPassword;
}
const response = await this.apiService.postIdentityToken(tokenRequest); const response = await this.apiService.postIdentityToken(tokenRequest);
const result = await this.processTokenResponse( const result = await this.processTokenResponse(
@@ -95,7 +104,7 @@ export class AuthService implements AuthServiceAbstraction {
); );
if (result.twoFactor) { if (result.twoFactor) {
this.saveState(tokenRequest, key, localHashedPassword, result.twoFactorProviders); this.saveState(tokenRequest, result.twoFactorProviders, localHashedPassword, key);
} }
return result; return result;
@@ -110,14 +119,20 @@ export class AuthService implements AuthServiceAbstraction {
): Promise<AuthResult> { ): Promise<AuthResult> {
this.twoFactorService.clearSelectedProvider(); this.twoFactorService.clearSelectedProvider();
const tokenRequest = new SsoTokenRequest( let tokenRequest: SsoTokenRequest
code, if (this.savedTokenRequest == null) {
codeVerifier, tokenRequest = new SsoTokenRequest(
redirectUrl, code,
await this.createTwoFactorData(twoFactor), codeVerifier,
null, redirectUrl,
await this.createDeviceRequest() await this.createTwoFactorData(twoFactor),
); null,
await this.createDeviceRequest()
);
} else {
tokenRequest = this.savedTokenRequest as SsoTokenRequest;
}
const response = await this.apiService.postIdentityToken(tokenRequest); const response = await this.apiService.postIdentityToken(tokenRequest);
const result = await this.processTokenResponse( const result = await this.processTokenResponse(
@@ -131,7 +146,7 @@ export class AuthService implements AuthServiceAbstraction {
); );
if (result.twoFactor) { if (result.twoFactor) {
this.saveState(tokenRequest, null, null, result.twoFactorProviders); this.saveState(tokenRequest, result.twoFactorProviders);
} }
return result; return result;
@@ -144,13 +159,19 @@ export class AuthService implements AuthServiceAbstraction {
): Promise<AuthResult> { ): Promise<AuthResult> {
this.twoFactorService.clearSelectedProvider(); this.twoFactorService.clearSelectedProvider();
const tokenRequest = new ApiTokenRequest( let tokenRequest: ApiTokenRequest;
clientId, if (this.savedTokenRequest == null) {
clientSecret, tokenRequest = new ApiTokenRequest(
await this.createTwoFactorData(twoFactor), clientId,
null, clientSecret,
await this.createDeviceRequest() await this.createTwoFactorData(twoFactor),
); null,
await this.createDeviceRequest()
);
} else {
tokenRequest = this.savedTokenRequest as ApiTokenRequest;
}
const response = await this.apiService.postIdentityToken(tokenRequest); const response = await this.apiService.postIdentityToken(tokenRequest);
const result = await this.processTokenResponse( const result = await this.processTokenResponse(
@@ -164,7 +185,7 @@ export class AuthService implements AuthServiceAbstraction {
); );
if (result.twoFactor) { if (result.twoFactor) {
this.saveState(tokenRequest, null, null, result.twoFactorProviders); this.saveState(tokenRequest, result.twoFactorProviders);
} }
return result; return result;
@@ -172,16 +193,20 @@ export class AuthService implements AuthServiceAbstraction {
async logInTwoFactor(twoFactor: TwoFactorData): Promise<AuthResult> { async logInTwoFactor(twoFactor: TwoFactorData): Promise<AuthResult> {
this.savedTokenRequest.setTwoFactor(twoFactor); this.savedTokenRequest.setTwoFactor(twoFactor);
const response = await this.apiService.postIdentityToken(this.savedTokenRequest);
return await this.processTokenResponse( if (this.authingWithPassword) {
response, return await this.logIn(null, null);
this.localMasterPasswordHash, }
(this.savedTokenRequest as SsoTokenRequest).code,
(this.savedTokenRequest as ApiTokenRequest).clientId, if (this.authingWithApiKey) {
(this.savedTokenRequest as ApiTokenRequest).clientSecret, return await this.logInApiKey(null, null);
this.key }
);
if (this.authingWithSso) {
return await this.logInSso(null, null, null, null);
}
throw new Error("Error: Could not find login in progress.");
} }
logOut(callback: Function) { logOut(callback: Function) {
@@ -189,20 +214,16 @@ export class AuthService implements AuthServiceAbstraction {
this.messagingService.send("loggedOut"); this.messagingService.send("loggedOut");
} }
// TODO
authingWithApiKey(): boolean { authingWithApiKey(): boolean {
return null; return this.savedTokenRequest instanceof ApiTokenRequest;
// return this.clientId != null && this.clientSecret != null;
} }
authingWithSso(): boolean { authingWithSso(): boolean {
return null; return this.savedTokenRequest instanceof SsoTokenRequest;
// return this.code != null && this.codeVerifier != null && this.ssoRedirectUrl != null;
} }
authingWithPassword(): boolean { authingWithPassword(): boolean {
return null; return this.savedTokenRequest instanceof PasswordTokenRequest;
// return this.email != null && this.masterPasswordHash != null;
} }
async makePreloginKey(masterPassword: string, email: string): Promise<SymmetricCryptoKey> { async makePreloginKey(masterPassword: string, email: string): Promise<SymmetricCryptoKey> {
@@ -397,22 +418,24 @@ export class AuthService implements AuthServiceAbstraction {
private saveState( private saveState(
tokenRequest: ApiTokenRequest | PasswordTokenRequest | SsoTokenRequest, tokenRequest: ApiTokenRequest | PasswordTokenRequest | SsoTokenRequest,
key: SymmetricCryptoKey, twoFactorProviders: Map<TwoFactorProviderType, { [key: string]: string }>,
localMasterPasswordHash: string, localhashedPassword?: string,
twoFactorProviders: Map<TwoFactorProviderType, { [key: string]: string }> key?: SymmetricCryptoKey,
) { ) {
this.savedTokenRequest = tokenRequest; this.savedTokenRequest = tokenRequest;
this.localMasterPasswordHash = localMasterPasswordHash;
this.key = this.setCryptoKeys ? key : null;
this.twoFactorService.setProviders(twoFactorProviders); this.twoFactorService.setProviders(twoFactorProviders);
this.localHashedPassword = localhashedPassword;
this.key = key;
} }
private clearState(): void { private clearState(): void {
this.savedTokenRequest = null; this.savedTokenRequest = null;
this.key = null;
this.localMasterPasswordHash = null;
this.twoFactorService.clearProviders(); this.twoFactorService.clearProviders();
this.twoFactorService.clearSelectedProvider(); this.twoFactorService.clearSelectedProvider();
this.localHashedPassword = null;
this.key = null;
} }
private isNewSsoUser(code: string, key: string) { private isNewSsoUser(code: string, key: string) {

View File

@@ -384,7 +384,6 @@ describe("Cipher Service", () => {
identifier: deviceId, identifier: deviceId,
} as DeviceRequest); } as DeviceRequest);
(authService as any).localMasterPasswordHash = localHashedPassword;
(authService as any).savedTokenRequest = tokenRequest; (authService as any).savedTokenRequest = tokenRequest;
await authService.logInTwoFactor({ await authService.logInTwoFactor({