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) { } private router: Router, private logService: LogService) { }
async submit() { async submit() {
const request = await this.userVerificationService.buildRequest(this.masterPassword);
try { 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; await this.formPromise;
this.toasterService.popAsync('success', this.i18nService.t('organizationDeleted'), this.toasterService.popAsync('success', this.i18nService.t('organizationDeleted'),
this.i18nService.t('organizationDeletedDesc')); 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, const sendService = new SendService(cryptoService, userService, apiService, fileUploadService, storageService,
i18nService, cryptoFunctionService); i18nService, cryptoFunctionService);
const keyConnectorService = new KeyConnectorService(storageService, userService, cryptoService, apiService, const keyConnectorService = new KeyConnectorService(storageService, userService, cryptoService, apiService,
environmentService, tokenService, consoleLogService); tokenService, consoleLogService);
const vaultTimeoutService = new VaultTimeoutService(cipherService, folderService, collectionService, const vaultTimeoutService = new VaultTimeoutService(cipherService, folderService, collectionService,
cryptoService, platformUtilsService, storageService, messagingService, searchService, userService, tokenService, cryptoService, platformUtilsService, storageService, messagingService, searchService, userService, tokenService,
policyService, keyConnectorService, null, async () => messagingService.send('logout', { expired: false })); 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); environmentService, async () => messagingService.send('logout', { expired: true }), consoleLogService);
const auditService = new AuditService(cryptoFunctionService, apiService); const auditService = new AuditService(cryptoFunctionService, apiService);
const eventLoggingService = new EventLoggingService(storageService, apiService, userService, cipherService, consoleLogService); const eventLoggingService = new EventLoggingService(storageService, apiService, userService, cipherService, consoleLogService);
const userVerificationService = new UserVerificationService(cryptoService, i18nService, apiService);
containerService.attachToWindow(window); containerService.attachToWindow(window);
@ -234,8 +235,8 @@ export function initFactory(): Function {
{ provide: PolicyServiceAbstraction, useValue: policyService }, { provide: PolicyServiceAbstraction, useValue: policyService },
{ provide: SendServiceAbstraction, useValue: sendService }, { provide: SendServiceAbstraction, useValue: sendService },
{ provide: KeyConnectorServiceAbstraction, useValue: keyConnectorService }, { provide: KeyConnectorServiceAbstraction, useValue: keyConnectorService },
{ provide: UserVerificationServiceAbstraction, useValue: userVerificationService },
{ provide: PasswordRepromptServiceAbstraction, useClass: PasswordRepromptService }, { provide: PasswordRepromptServiceAbstraction, useClass: PasswordRepromptService },
{ provide: UserVerificationServiceAbstraction, useClass: UserVerificationService },
{ provide: LogService, useValue: consoleLogService }, { provide: LogService, useValue: consoleLogService },
{ {
provide: APP_INITIALIZER, provide: APP_INITIALIZER,

View File

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

View File

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

View File

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

View File

@ -28,10 +28,9 @@ export class PurgeVaultComponent {
private router: Router, private logService: LogService) { } private router: Router, private logService: LogService) { }
async submit() { async submit() {
const request = await this.userVerificationService.buildRequest(this.masterPassword);
try { 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; await this.formPromise;
this.toasterService.popAsync('success', null, this.i18nService.t('vaultPurged')); this.toasterService.popAsync('success', null, this.i18nService.t('vaultPurged'));
if (this.organizationId != null) { 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 { 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({ @Component({
selector: 'app-two-factor-verify', selector: 'app-two-factor-verify',
templateUrl: 'two-factor-verify.component.html', templateUrl: 'two-factor-verify.component.html',
@ -24,51 +36,53 @@ export class TwoFactorVerifyComponent {
@Output() onAuthed = new EventEmitter<any>(); @Output() onAuthed = new EventEmitter<any>();
secret: Verification; secret: Verification;
formPromise: Promise<any>; formPromise: Promise<TwoFactorResponse>;
constructor(private apiService: ApiService, private logService: LogService, constructor(private apiService: ApiService, private logService: LogService,
private userVerificationService: UserVerificationService) { } private userVerificationService: UserVerificationService) { }
async submit() { async submit() {
const request = await this.userVerificationService.buildRequest(this.secret); let hashedSecret: string;
try { try {
switch (this.type) { this.formPromise = this.userVerificationService.buildRequest(this.secret)
case -1: .then(request => {
this.formPromise = this.apiService.getTwoFactorRecover(request); hashedSecret = this.secret.type === VerificationType.MasterPassword
break; ? request.masterPasswordHash
case TwoFactorProviderType.Duo: : request.otp;
case TwoFactorProviderType.OrganizationDuo: return this.apiCall(request);
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;
}
const response = await this.formPromise; const response = await this.formPromise;
this.onAuthed.emit({ this.onAuthed.emit({
response: response, response: response,
secret: this.secret.type === VerificationType.MasterPassword secret: hashedSecret,
? request.masterPasswordHash
: request.otp,
verificationType: this.secret.type, verificationType: this.secret.type,
}); });
} catch (e) { } catch (e) {
this.logService.error(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);
}
}
} }