Update jslib and use new UserVerificationService pattern (#1302)

* Use try/catch pattern for userVerification

* Update deps
This commit is contained in:
Thomas Rittson 2021-11-17 09:37:36 +10:00 committed by GitHub
parent 8889722388
commit f740d8b057
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 58 additions and 48 deletions

2
jslib

@ -1 +1 @@
Subproject commit e02e663ce1aed94d42db00dcdb2e42bdd625f0dc
Subproject commit 720967475b37d635c18a1eb74bb3702445647b4d

View File

@ -25,10 +25,9 @@ export class DeleteOrganizationComponent {
private router: Router, private logService: LogService) { }
async submit() {
const request = await this.userVerificationService.buildRequest(this.masterPassword);
try {
this.formPromise = this.apiService.deleteOrganization(this.organizationId, request);
this.formPromise = this.userVerificationService.buildRequest(this.masterPassword)
.then(request => this.apiService.deleteOrganization(this.organizationId, request));
await this.formPromise;
this.toasterService.popAsync('success', this.i18nService.t('organizationDeleted'),
this.i18nService.t('organizationDeletedDesc'));

View File

@ -129,7 +129,7 @@ const policyService = new PolicyService(userService, storageService, apiService)
const sendService = new SendService(cryptoService, userService, apiService, fileUploadService, storageService,
i18nService, cryptoFunctionService);
const keyConnectorService = new KeyConnectorService(storageService, userService, cryptoService, apiService,
environmentService, tokenService, consoleLogService);
tokenService, consoleLogService);
const vaultTimeoutService = new VaultTimeoutService(cipherService, folderService, collectionService,
cryptoService, platformUtilsService, storageService, messagingService, searchService, userService, tokenService,
policyService, keyConnectorService, null, async () => messagingService.send('logout', { expired: false }));
@ -150,6 +150,7 @@ const notificationsService = new NotificationsService(userService, syncService,
environmentService, async () => messagingService.send('logout', { expired: true }), consoleLogService);
const auditService = new AuditService(cryptoFunctionService, apiService);
const eventLoggingService = new EventLoggingService(storageService, apiService, userService, cipherService, consoleLogService);
const userVerificationService = new UserVerificationService(cryptoService, i18nService, apiService);
containerService.attachToWindow(window);
@ -234,8 +235,8 @@ export function initFactory(): Function {
{ provide: PolicyServiceAbstraction, useValue: policyService },
{ provide: SendServiceAbstraction, useValue: sendService },
{ provide: KeyConnectorServiceAbstraction, useValue: keyConnectorService },
{ provide: UserVerificationServiceAbstraction, useValue: userVerificationService },
{ provide: PasswordRepromptServiceAbstraction, useClass: PasswordRepromptService },
{ provide: UserVerificationServiceAbstraction, useClass: UserVerificationService },
{ provide: LogService, useValue: consoleLogService },
{
provide: APP_INITIALIZER,

View File

@ -32,10 +32,9 @@ export class ApiKeyComponent {
constructor(private userVerificationService: UserVerificationService, private logService: LogService) { }
async submit() {
const request = await this.userVerificationService.buildRequest(this.masterPassword);
try {
this.formPromise = this.postKey(this.entityId, request);
this.formPromise = this.userVerificationService.buildRequest(this.masterPassword)
.then(request => this.postKey(this.entityId, request));
const response = await this.formPromise;
this.clientSecret = response.apiKey;
this.clientId = `${this.keyType}.${this.entityId}`;

View File

@ -23,10 +23,9 @@ export class DeauthorizeSessionsComponent {
private messagingService: MessagingService, private logService: LogService) { }
async submit() {
const request = await this.userVerificationService.buildRequest(this.masterPassword);
try {
this.formPromise = this.apiService.postSecurityStamp(request);
this.formPromise = this.userVerificationService.buildRequest(this.masterPassword)
.then(request => this.apiService.postSecurityStamp(request));
await this.formPromise;
this.toasterService.popAsync('success', this.i18nService.t('sessionsDeauthorized'),
this.i18nService.t('logBackIn'));

View File

@ -23,10 +23,9 @@ export class DeleteAccountComponent {
private messagingService: MessagingService, private logService: LogService) { }
async submit() {
const request = await this.userVerificationService.buildRequest(this.masterPassword);
try {
this.formPromise = this.apiService.deleteAccount(request);
this.formPromise = this.userVerificationService.buildRequest(this.masterPassword)
.then(request => this.apiService.deleteAccount(request));
await this.formPromise;
this.toasterService.popAsync('success', this.i18nService.t('accountDeleted'),
this.i18nService.t('accountDeletedDesc'));

View File

@ -28,10 +28,9 @@ export class PurgeVaultComponent {
private router: Router, private logService: LogService) { }
async submit() {
const request = await this.userVerificationService.buildRequest(this.masterPassword);
try {
this.formPromise = this.apiService.postPurgeCiphers(request, this.organizationId);
this.formPromise = this.userVerificationService.buildRequest(this.masterPassword)
.then(request => this.apiService.postPurgeCiphers(request, this.organizationId));
await this.formPromise;
this.toasterService.popAsync('success', null, this.i18nService.t('vaultPurged'));
if (this.organizationId != null) {

View File

@ -14,6 +14,18 @@ import { UserVerificationService } from 'jslib-common/abstractions/userVerificat
import { Verification } from 'jslib-common/types/verification';
import { TwoFactorAuthenticatorResponse } from 'jslib-common/models/response/twoFactorAuthenticatorResponse';
import { TwoFactorDuoResponse } from 'jslib-common/models/response/twoFactorDuoResponse';
import { TwoFactorEmailResponse } from 'jslib-common/models/response/twoFactorEmailResponse';
import { TwoFactorRecoverResponse } from 'jslib-common/models/response/twoFactorRescoverResponse';
import { TwoFactorWebAuthnResponse } from 'jslib-common/models/response/twoFactorWebAuthnResponse';
import { TwoFactorYubiKeyResponse } from 'jslib-common/models/response/twoFactorYubiKeyResponse';
import { SecretVerificationRequest } from 'jslib-common/models/request/secretVerificationRequest';
type TwoFactorResponse = TwoFactorRecoverResponse | TwoFactorDuoResponse | TwoFactorEmailResponse |
TwoFactorWebAuthnResponse | TwoFactorAuthenticatorResponse | TwoFactorYubiKeyResponse;
@Component({
selector: 'app-two-factor-verify',
templateUrl: 'two-factor-verify.component.html',
@ -24,51 +36,53 @@ export class TwoFactorVerifyComponent {
@Output() onAuthed = new EventEmitter<any>();
secret: Verification;
formPromise: Promise<any>;
formPromise: Promise<TwoFactorResponse>;
constructor(private apiService: ApiService, private logService: LogService,
private userVerificationService: UserVerificationService) { }
async submit() {
const request = await this.userVerificationService.buildRequest(this.secret);
let hashedSecret: string;
try {
switch (this.type) {
case -1:
this.formPromise = this.apiService.getTwoFactorRecover(request);
break;
case TwoFactorProviderType.Duo:
case TwoFactorProviderType.OrganizationDuo:
if (this.organizationId != null) {
this.formPromise = this.apiService.getTwoFactorOrganizationDuo(this.organizationId, request);
} else {
this.formPromise = this.apiService.getTwoFactorDuo(request);
}
break;
case TwoFactorProviderType.Email:
this.formPromise = this.apiService.getTwoFactorEmail(request);
break;
case TwoFactorProviderType.WebAuthn:
this.formPromise = this.apiService.getTwoFactorWebAuthn(request);
break;
case TwoFactorProviderType.Authenticator:
this.formPromise = this.apiService.getTwoFactorAuthenticator(request);
break;
case TwoFactorProviderType.Yubikey:
this.formPromise = this.apiService.getTwoFactorYubiKey(request);
break;
}
this.formPromise = this.userVerificationService.buildRequest(this.secret)
.then(request => {
hashedSecret = this.secret.type === VerificationType.MasterPassword
? request.masterPasswordHash
: request.otp;
return this.apiCall(request);
});
const response = await this.formPromise;
this.onAuthed.emit({
response: response,
secret: this.secret.type === VerificationType.MasterPassword
? request.masterPasswordHash
: request.otp,
secret: hashedSecret,
verificationType: this.secret.type,
});
} catch (e) {
this.logService.error(e);
}
}
private apiCall(request: SecretVerificationRequest): Promise<TwoFactorResponse> {
switch (this.type) {
case -1:
return this.apiService.getTwoFactorRecover(request);
case TwoFactorProviderType.Duo:
case TwoFactorProviderType.OrganizationDuo:
if (this.organizationId != null) {
return this.apiService.getTwoFactorOrganizationDuo(this.organizationId, request);
} else {
return this.apiService.getTwoFactorDuo(request);
}
case TwoFactorProviderType.Email:
return this.apiService.getTwoFactorEmail(request);
case TwoFactorProviderType.WebAuthn:
return this.apiService.getTwoFactorWebAuthn(request);
case TwoFactorProviderType.Authenticator:
return this.apiService.getTwoFactorAuthenticator(request);
case TwoFactorProviderType.Yubikey:
return this.apiService.getTwoFactorYubiKey(request);
}
}
}