mirror of
https://github.com/bitwarden/jslib
synced 2025-12-17 16:53:20 +00:00
Lift tokenRequest and api call to request methods
Also reduce amount of persistent state (WIP)
This commit is contained in:
@@ -3,14 +3,6 @@ import { SymmetricCryptoKey } from "../models/domain/symmetricCryptoKey";
|
|||||||
import { TwoFactorData } from '../models/request/identityToken/tokenRequest';
|
import { TwoFactorData } from '../models/request/identityToken/tokenRequest';
|
||||||
|
|
||||||
export abstract class AuthService {
|
export abstract class AuthService {
|
||||||
email: string;
|
|
||||||
masterPasswordHash: string;
|
|
||||||
code: string;
|
|
||||||
codeVerifier: string;
|
|
||||||
ssoRedirectUrl: string;
|
|
||||||
clientId: string;
|
|
||||||
clientSecret: string;
|
|
||||||
|
|
||||||
logIn: (email: string, masterPassword: string, twoFactor?: TwoFactorData, captchaToken?: string) => Promise<AuthResult>;
|
logIn: (email: string, masterPassword: string, twoFactor?: TwoFactorData, captchaToken?: string) => Promise<AuthResult>;
|
||||||
logInSso: (
|
logInSso: (
|
||||||
code: string,
|
code: string,
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ import { DeviceRequest } from "../deviceRequest";
|
|||||||
|
|
||||||
export class ApiTokenRequest extends TokenRequest {
|
export class ApiTokenRequest extends TokenRequest {
|
||||||
constructor(
|
constructor(
|
||||||
private clientId: string,
|
public clientId: string,
|
||||||
private clientSecret: string,
|
public clientSecret: string,
|
||||||
protected twoFactor: TwoFactorData,
|
protected twoFactor: TwoFactorData,
|
||||||
captchaResponse: string,
|
captchaResponse: string,
|
||||||
device?: DeviceRequest
|
device?: DeviceRequest
|
||||||
|
|||||||
@@ -6,16 +6,13 @@ import { Utils } from "../../../misc/utils";
|
|||||||
|
|
||||||
export class PasswordTokenRequest extends TokenRequest {
|
export class PasswordTokenRequest extends TokenRequest {
|
||||||
constructor(
|
constructor(
|
||||||
private email: string,
|
public email: string,
|
||||||
private masterPasswordHash: string,
|
public masterPasswordHash: string,
|
||||||
protected twoFactor: TwoFactorData,
|
protected twoFactor: TwoFactorData,
|
||||||
captchaResponse: string,
|
captchaResponse: string,
|
||||||
device?: DeviceRequest
|
device?: DeviceRequest
|
||||||
) {
|
) {
|
||||||
super(twoFactor, captchaResponse, device);
|
super(twoFactor, captchaResponse, device);
|
||||||
|
|
||||||
this.email = email;
|
|
||||||
this.masterPasswordHash = masterPasswordHash;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
toIdentityToken(clientId: string) {
|
toIdentityToken(clientId: string) {
|
||||||
|
|||||||
@@ -4,18 +4,14 @@ import { DeviceRequest } from "../deviceRequest";
|
|||||||
|
|
||||||
export class SsoTokenRequest extends TokenRequest {
|
export class SsoTokenRequest extends TokenRequest {
|
||||||
constructor(
|
constructor(
|
||||||
private code: string,
|
public code: string,
|
||||||
private codeVerifier: string,
|
public codeVerifier: string,
|
||||||
private redirectUri: string,
|
public redirectUri: string,
|
||||||
protected twoFactor: TwoFactorData,
|
protected twoFactor: TwoFactorData,
|
||||||
captchaResponse: string,
|
captchaResponse: string,
|
||||||
device?: DeviceRequest
|
device?: DeviceRequest
|
||||||
) {
|
) {
|
||||||
super(twoFactor, captchaResponse, device);
|
super(twoFactor, captchaResponse, device);
|
||||||
|
|
||||||
this.code = code;
|
|
||||||
this.codeVerifier = codeVerifier;
|
|
||||||
this.redirectUri = redirectUri;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
toIdentityToken(clientId: string) {
|
toIdentityToken(clientId: string) {
|
||||||
|
|||||||
@@ -50,4 +50,8 @@ export abstract class TokenRequest implements CaptchaProtectedRequest {
|
|||||||
alterIdentityTokenHeaders(headers: Headers) {
|
alterIdentityTokenHeaders(headers: Headers) {
|
||||||
// Implemented in subclass if required
|
// Implemented in subclass if required
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setTwoFactor(twoFactor: TwoFactorData) {
|
||||||
|
this.twoFactor = twoFactor;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,17 +35,12 @@ import { TokenService } from "../abstractions/token.service";
|
|||||||
|
|
||||||
import { TwoFactorService } from "../abstractions/twoFactor.service";
|
import { TwoFactorService } from "../abstractions/twoFactor.service";
|
||||||
import { Utils } from "../misc/utils";
|
import { Utils } from "../misc/utils";
|
||||||
|
import { IdentityCaptchaResponse } from "../models/response/identityCaptchaResponse";
|
||||||
|
|
||||||
export class AuthService implements AuthServiceAbstraction {
|
export class AuthService implements AuthServiceAbstraction {
|
||||||
email: string;
|
private localMasterPasswordHash: string;
|
||||||
masterPasswordHash: string;
|
|
||||||
localMasterPasswordHash: string;
|
private savedTokenRequest: ApiTokenRequest | PasswordTokenRequest | SsoTokenRequest;
|
||||||
code: string;
|
|
||||||
codeVerifier: string;
|
|
||||||
ssoRedirectUrl: string;
|
|
||||||
clientId: string;
|
|
||||||
clientSecret: string;
|
|
||||||
captchaToken: string;
|
|
||||||
|
|
||||||
private key: SymmetricCryptoKey;
|
private key: SymmetricCryptoKey;
|
||||||
|
|
||||||
@@ -65,7 +60,12 @@ export class AuthService implements AuthServiceAbstraction {
|
|||||||
private setCryptoKeys = true
|
private setCryptoKeys = true
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
async logIn(email: string, masterPassword: string, twoFactor?: TwoFactorData, captchaToken?: string): Promise<AuthResult> {
|
async logIn(
|
||||||
|
email: string,
|
||||||
|
masterPassword: string,
|
||||||
|
twoFactor?: TwoFactorData,
|
||||||
|
captchaToken?: string
|
||||||
|
): Promise<AuthResult> {
|
||||||
this.twoFactorService.clearSelectedProvider();
|
this.twoFactorService.clearSelectedProvider();
|
||||||
const key = await this.makePreloginKey(masterPassword, email);
|
const key = await this.makePreloginKey(masterPassword, email);
|
||||||
const hashedPassword = await this.cryptoService.hashPassword(masterPassword, key);
|
const hashedPassword = await this.cryptoService.hashPassword(masterPassword, key);
|
||||||
@@ -74,20 +74,32 @@ export class AuthService implements AuthServiceAbstraction {
|
|||||||
key,
|
key,
|
||||||
HashPurpose.LocalAuthorization
|
HashPurpose.LocalAuthorization
|
||||||
);
|
);
|
||||||
return await this.logInHelper(
|
|
||||||
|
const tokenRequest = new PasswordTokenRequest(
|
||||||
email,
|
email,
|
||||||
hashedPassword,
|
hashedPassword,
|
||||||
|
await this.createTwoFactorData(twoFactor, email),
|
||||||
|
captchaToken,
|
||||||
|
await this.createDeviceRequest()
|
||||||
|
);
|
||||||
|
const response = await this.apiService.postIdentityToken(tokenRequest);
|
||||||
|
|
||||||
|
const result = await this.processTokenResponse(
|
||||||
|
response,
|
||||||
|
email,
|
||||||
localHashedPassword,
|
localHashedPassword,
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
null,
|
|
||||||
null,
|
|
||||||
key,
|
key,
|
||||||
twoFactor,
|
|
||||||
captchaToken,
|
|
||||||
null
|
null
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (result.twoFactor) {
|
||||||
|
this.saveState(tokenRequest, key, localHashedPassword, result.twoFactorProviders);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
async logInSso(
|
async logInSso(
|
||||||
@@ -95,59 +107,84 @@ export class AuthService implements AuthServiceAbstraction {
|
|||||||
codeVerifier: string,
|
codeVerifier: string,
|
||||||
redirectUrl: string,
|
redirectUrl: string,
|
||||||
orgId: string,
|
orgId: string,
|
||||||
twoFactor?: TwoFactorData,
|
twoFactor?: TwoFactorData
|
||||||
): Promise<AuthResult> {
|
): Promise<AuthResult> {
|
||||||
this.twoFactorService.clearSelectedProvider();
|
this.twoFactorService.clearSelectedProvider();
|
||||||
return await this.logInHelper(
|
|
||||||
null,
|
const tokenRequest = new SsoTokenRequest(
|
||||||
null,
|
|
||||||
null,
|
|
||||||
code,
|
code,
|
||||||
codeVerifier,
|
codeVerifier,
|
||||||
redirectUrl,
|
redirectUrl,
|
||||||
|
await this.createTwoFactorData(twoFactor, null),
|
||||||
|
null,
|
||||||
|
await this.createDeviceRequest()
|
||||||
|
);
|
||||||
|
const response = await this.apiService.postIdentityToken(tokenRequest);
|
||||||
|
|
||||||
|
const result = await this.processTokenResponse(
|
||||||
|
response,
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
|
code,
|
||||||
|
null,
|
||||||
null,
|
null,
|
||||||
twoFactor,
|
|
||||||
null,
|
null,
|
||||||
orgId
|
orgId
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (result.twoFactor) {
|
||||||
|
this.saveState(tokenRequest, null, null, result.twoFactorProviders);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
async logInApiKey(clientId: string, clientSecret: string, twoFactor?: TwoFactorData): Promise<AuthResult> {
|
async logInApiKey(
|
||||||
|
clientId: string,
|
||||||
|
clientSecret: string,
|
||||||
|
twoFactor?: TwoFactorData
|
||||||
|
): Promise<AuthResult> {
|
||||||
this.twoFactorService.clearSelectedProvider();
|
this.twoFactorService.clearSelectedProvider();
|
||||||
return await this.logInHelper(
|
|
||||||
null,
|
const tokenRequest = new ApiTokenRequest(
|
||||||
null,
|
clientId,
|
||||||
|
clientSecret,
|
||||||
|
await this.createTwoFactorData(twoFactor, null),
|
||||||
null,
|
null,
|
||||||
|
await this.createDeviceRequest()
|
||||||
|
);
|
||||||
|
const response = await this.apiService.postIdentityToken(tokenRequest);
|
||||||
|
|
||||||
|
const result = await this.processTokenResponse(
|
||||||
|
response,
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
clientId,
|
clientId,
|
||||||
clientSecret,
|
clientSecret,
|
||||||
null,
|
null,
|
||||||
twoFactor,
|
|
||||||
null,
|
|
||||||
null
|
null
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (result.twoFactor) {
|
||||||
|
this.saveState(tokenRequest, null, null, result.twoFactorProviders);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
async logInTwoFactor(
|
async logInTwoFactor(twoFactor: TwoFactorData): Promise<AuthResult> {
|
||||||
twoFactor: TwoFactorData,
|
this.savedTokenRequest.setTwoFactor(twoFactor);
|
||||||
): Promise<AuthResult> {
|
const response = await this.apiService.postIdentityToken(this.savedTokenRequest);
|
||||||
return await this.logInHelper(
|
|
||||||
this.email,
|
return await this.processTokenResponse(
|
||||||
this.masterPasswordHash,
|
response,
|
||||||
|
(this.savedTokenRequest as PasswordTokenRequest).email,
|
||||||
this.localMasterPasswordHash,
|
this.localMasterPasswordHash,
|
||||||
this.code,
|
(this.savedTokenRequest as SsoTokenRequest).code,
|
||||||
this.codeVerifier,
|
(this.savedTokenRequest as ApiTokenRequest).clientId,
|
||||||
this.ssoRedirectUrl,
|
(this.savedTokenRequest as ApiTokenRequest).clientSecret,
|
||||||
this.clientId,
|
this.key
|
||||||
this.clientSecret,
|
|
||||||
this.key,
|
|
||||||
twoFactor,
|
|
||||||
this.captchaToken,
|
|
||||||
null
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -156,16 +193,20 @@ export class AuthService implements AuthServiceAbstraction {
|
|||||||
this.messagingService.send("loggedOut");
|
this.messagingService.send("loggedOut");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO
|
||||||
authingWithApiKey(): boolean {
|
authingWithApiKey(): boolean {
|
||||||
return this.clientId != null && this.clientSecret != null;
|
return null;
|
||||||
|
// return this.clientId != null && this.clientSecret != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
authingWithSso(): boolean {
|
authingWithSso(): boolean {
|
||||||
return this.code != null && this.codeVerifier != null && this.ssoRedirectUrl != null;
|
return null;
|
||||||
|
// return this.code != null && this.codeVerifier != null && this.ssoRedirectUrl != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
authingWithPassword(): boolean {
|
authingWithPassword(): boolean {
|
||||||
return this.email != null && this.masterPasswordHash != null;
|
return null;
|
||||||
|
// return this.email != null && this.masterPasswordHash != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
async makePreloginKey(masterPassword: string, email: string): Promise<SymmetricCryptoKey> {
|
async makePreloginKey(masterPassword: string, email: string): Promise<SymmetricCryptoKey> {
|
||||||
@@ -186,34 +227,16 @@ export class AuthService implements AuthServiceAbstraction {
|
|||||||
return this.cryptoService.makeKey(masterPassword, email, kdf, kdfIterations);
|
return this.cryptoService.makeKey(masterPassword, email, kdf, kdfIterations);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async logInHelper(
|
private async processTokenResponse(
|
||||||
|
response: IdentityTokenResponse | IdentityTwoFactorResponse | IdentityCaptchaResponse,
|
||||||
email: string,
|
email: string,
|
||||||
hashedPassword: string,
|
|
||||||
localHashedPassword: string,
|
localHashedPassword: string,
|
||||||
code: string,
|
code: string,
|
||||||
codeVerifier: string,
|
|
||||||
redirectUrl: string,
|
|
||||||
clientId: string,
|
clientId: string,
|
||||||
clientSecret: string,
|
clientSecret: string,
|
||||||
key: SymmetricCryptoKey,
|
key: SymmetricCryptoKey,
|
||||||
twoFactor: TwoFactorData,
|
|
||||||
captchaToken?: string,
|
|
||||||
orgId?: string
|
orgId?: string
|
||||||
): Promise<AuthResult> {
|
): Promise<AuthResult> {
|
||||||
const request = await this.createTokenRequest(
|
|
||||||
email,
|
|
||||||
hashedPassword,
|
|
||||||
code,
|
|
||||||
codeVerifier,
|
|
||||||
redirectUrl,
|
|
||||||
clientId,
|
|
||||||
clientSecret,
|
|
||||||
twoFactor,
|
|
||||||
captchaToken
|
|
||||||
);
|
|
||||||
|
|
||||||
const response = await this.apiService.postIdentityToken(request);
|
|
||||||
|
|
||||||
this.clearState();
|
this.clearState();
|
||||||
const result = new AuthResult();
|
const result = new AuthResult();
|
||||||
|
|
||||||
@@ -224,19 +247,6 @@ export class AuthService implements AuthServiceAbstraction {
|
|||||||
|
|
||||||
result.twoFactor = !!(response as any).twoFactorProviders2;
|
result.twoFactor = !!(response as any).twoFactorProviders2;
|
||||||
if (result.twoFactor) {
|
if (result.twoFactor) {
|
||||||
this.saveState(
|
|
||||||
email,
|
|
||||||
hashedPassword,
|
|
||||||
localHashedPassword,
|
|
||||||
code,
|
|
||||||
codeVerifier,
|
|
||||||
redirectUrl,
|
|
||||||
clientId,
|
|
||||||
clientSecret,
|
|
||||||
key,
|
|
||||||
(response as IdentityTwoFactorResponse).twoFactorProviders2
|
|
||||||
);
|
|
||||||
|
|
||||||
result.twoFactorProviders = (response as IdentityTwoFactorResponse).twoFactorProviders2;
|
result.twoFactorProviders = (response as IdentityTwoFactorResponse).twoFactorProviders2;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -292,19 +302,7 @@ export class AuthService implements AuthServiceAbstraction {
|
|||||||
return new DeviceRequest(appId, this.platformUtilsService);
|
return new DeviceRequest(appId, this.platformUtilsService);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async createTokenRequest(
|
private async createTwoFactorData(twoFactor: TwoFactorData, email: string) {
|
||||||
email: string,
|
|
||||||
hashedPassword: string,
|
|
||||||
code: string,
|
|
||||||
codeVerifier: string,
|
|
||||||
redirectUrl: string,
|
|
||||||
clientId: string,
|
|
||||||
clientSecret: string,
|
|
||||||
twoFactor: TwoFactorData,
|
|
||||||
captchaToken: string
|
|
||||||
) {
|
|
||||||
const deviceRequest = await this.createDeviceRequest();
|
|
||||||
|
|
||||||
if (twoFactor == null) {
|
if (twoFactor == null) {
|
||||||
const storedTwoFactorToken = await this.tokenService.getTwoFactorToken(email);
|
const storedTwoFactorToken = await this.tokenService.getTwoFactorToken(email);
|
||||||
if (storedTwoFactorToken != null) {
|
if (storedTwoFactorToken != null) {
|
||||||
@@ -312,38 +310,16 @@ export class AuthService implements AuthServiceAbstraction {
|
|||||||
token: storedTwoFactorToken,
|
token: storedTwoFactorToken,
|
||||||
provider: TwoFactorProviderType.Remember,
|
provider: TwoFactorProviderType.Remember,
|
||||||
remember: false,
|
remember: false,
|
||||||
}
|
};
|
||||||
} else {
|
} else {
|
||||||
twoFactor = {
|
twoFactor = {
|
||||||
token: null,
|
token: null,
|
||||||
provider: null,
|
provider: null,
|
||||||
remember: false,
|
remember: false,
|
||||||
};
|
};
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (email != null && hashedPassword != null) {
|
|
||||||
return new PasswordTokenRequest(
|
|
||||||
email,
|
|
||||||
hashedPassword,
|
|
||||||
twoFactor,
|
|
||||||
captchaToken,
|
|
||||||
deviceRequest
|
|
||||||
);
|
|
||||||
} else if (code != null && codeVerifier != null && redirectUrl != null) {
|
|
||||||
return new SsoTokenRequest(
|
|
||||||
code,
|
|
||||||
codeVerifier,
|
|
||||||
redirectUrl,
|
|
||||||
twoFactor,
|
|
||||||
captchaToken,
|
|
||||||
deviceRequest
|
|
||||||
);
|
|
||||||
} else if (clientId != null && clientSecret != null) {
|
|
||||||
return new ApiTokenRequest(clientId, clientSecret, twoFactor, captchaToken, deviceRequest);
|
|
||||||
} else {
|
|
||||||
throw new Error("No credentials provided.");
|
|
||||||
}
|
}
|
||||||
|
return twoFactor;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async saveAccountInformation(
|
private async saveAccountInformation(
|
||||||
@@ -425,39 +401,21 @@ export class AuthService implements AuthServiceAbstraction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private saveState(
|
private saveState(
|
||||||
email: string,
|
tokenRequest: ApiTokenRequest | PasswordTokenRequest | SsoTokenRequest,
|
||||||
hashedPassword: string,
|
|
||||||
localHashedPassword: string,
|
|
||||||
code: string,
|
|
||||||
codeVerifier: string,
|
|
||||||
redirectUrl: string,
|
|
||||||
clientId: string,
|
|
||||||
clientSecret: string,
|
|
||||||
key: SymmetricCryptoKey,
|
key: SymmetricCryptoKey,
|
||||||
|
localMasterPasswordHash: string,
|
||||||
twoFactorProviders: Map<TwoFactorProviderType, { [key: string]: string }>
|
twoFactorProviders: Map<TwoFactorProviderType, { [key: string]: string }>
|
||||||
) {
|
) {
|
||||||
this.email = email;
|
this.savedTokenRequest = tokenRequest;
|
||||||
this.masterPasswordHash = hashedPassword;
|
this.localMasterPasswordHash = localMasterPasswordHash;
|
||||||
this.localMasterPasswordHash = localHashedPassword;
|
|
||||||
this.code = code;
|
|
||||||
this.codeVerifier = codeVerifier;
|
|
||||||
this.ssoRedirectUrl = redirectUrl;
|
|
||||||
this.clientId = clientId;
|
|
||||||
this.clientSecret = clientSecret;
|
|
||||||
this.key = this.setCryptoKeys ? key : null;
|
this.key = this.setCryptoKeys ? key : null;
|
||||||
this.twoFactorService.setProviders(twoFactorProviders);
|
this.twoFactorService.setProviders(twoFactorProviders);
|
||||||
}
|
}
|
||||||
|
|
||||||
private clearState(): void {
|
private clearState(): void {
|
||||||
|
this.savedTokenRequest = null;
|
||||||
this.key = null;
|
this.key = null;
|
||||||
this.email = null;
|
|
||||||
this.masterPasswordHash = null;
|
|
||||||
this.localMasterPasswordHash = null;
|
this.localMasterPasswordHash = null;
|
||||||
this.code = null;
|
|
||||||
this.codeVerifier = null;
|
|
||||||
this.ssoRedirectUrl = null;
|
|
||||||
this.clientId = null;
|
|
||||||
this.clientSecret = null;
|
|
||||||
this.twoFactorService.clearProviders();
|
this.twoFactorService.clearProviders();
|
||||||
this.twoFactorService.clearSelectedProvider();
|
this.twoFactorService.clearSelectedProvider();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,6 +26,8 @@ import { IdentityTokenResponse } from "jslib-common/models/response/identityToke
|
|||||||
import { TwoFactorService } from "jslib-common/abstractions/twoFactor.service";
|
import { TwoFactorService } from "jslib-common/abstractions/twoFactor.service";
|
||||||
import { HashPurpose } from "jslib-common/enums/hashPurpose";
|
import { HashPurpose } from "jslib-common/enums/hashPurpose";
|
||||||
import { TwoFactorProviderType } from "jslib-common/enums/twoFactorProviderType";
|
import { TwoFactorProviderType } from "jslib-common/enums/twoFactorProviderType";
|
||||||
|
import { PasswordTokenRequest } from "jslib-common/models/request/identityToken/passwordTokenRequest";
|
||||||
|
import { DeviceRequest } from "jslib-common/models/request/deviceRequest";
|
||||||
|
|
||||||
describe("Cipher Service", () => {
|
describe("Cipher Service", () => {
|
||||||
let cryptoService: SubstituteOf<CryptoService>;
|
let cryptoService: SubstituteOf<CryptoService>;
|
||||||
@@ -327,9 +329,9 @@ describe("Cipher Service", () => {
|
|||||||
|
|
||||||
it("logIn: sends stored 2FA token to server", async () => {
|
it("logIn: sends stored 2FA token to server", async () => {
|
||||||
commonSetup();
|
commonSetup();
|
||||||
logInSetup();
|
logInSetup();
|
||||||
|
|
||||||
tokenService.getTwoFactorToken(email).resolves(twoFactorToken);
|
tokenService.getTwoFactorToken(email).resolves(twoFactorToken);
|
||||||
|
|
||||||
await authService.logIn(email, masterPassword);
|
await authService.logIn(email, masterPassword);
|
||||||
|
|
||||||
@@ -351,9 +353,13 @@ describe("Cipher Service", () => {
|
|||||||
|
|
||||||
it("logIn: sends 2FA token entered by user to server", async () => {
|
it("logIn: sends 2FA token entered by user to server", async () => {
|
||||||
commonSetup();
|
commonSetup();
|
||||||
logInSetup();
|
logInSetup();
|
||||||
|
|
||||||
await authService.logIn(email, masterPassword, { provider: twoFactorProviderType, token: twoFactorToken, remember: twoFactorRemember });
|
await authService.logIn(email, masterPassword, {
|
||||||
|
provider: twoFactorProviderType,
|
||||||
|
token: twoFactorToken,
|
||||||
|
remember: twoFactorRemember,
|
||||||
|
});
|
||||||
|
|
||||||
apiService.received(1).postIdentityToken(
|
apiService.received(1).postIdentityToken(
|
||||||
Arg.is((actual) => {
|
Arg.is((actual) => {
|
||||||
@@ -371,15 +377,22 @@ describe("Cipher Service", () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
it("logInTwoFactor: sends 2FA token to server when using Master Password", async () => {
|
it("logInTwoFactor: sends 2FA token to server when using Master Password", async () => {
|
||||||
commonSetup();
|
commonSetup();
|
||||||
|
|
||||||
authService.email = email;
|
const tokenRequest = new PasswordTokenRequest(email, hashedPassword, null, null, {
|
||||||
authService.masterPasswordHash = hashedPassword;
|
identifier: deviceId,
|
||||||
authService.localMasterPasswordHash = localHashedPassword;
|
} as DeviceRequest);
|
||||||
|
|
||||||
await authService.logInTwoFactor({ provider: twoFactorProviderType, token: twoFactorToken, remember: twoFactorRemember });
|
(authService as any).localMasterPasswordHash = localHashedPassword;
|
||||||
|
(authService as any).email = email;
|
||||||
|
(authService as any).savedTokenRequest = tokenRequest;
|
||||||
|
|
||||||
|
await authService.logInTwoFactor({
|
||||||
|
provider: twoFactorProviderType,
|
||||||
|
token: twoFactorToken,
|
||||||
|
remember: twoFactorRemember,
|
||||||
|
});
|
||||||
|
|
||||||
apiService.received(1).postIdentityToken(
|
apiService.received(1).postIdentityToken(
|
||||||
Arg.is((actual) => {
|
Arg.is((actual) => {
|
||||||
|
|||||||
Reference in New Issue
Block a user