1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-18 17:23:37 +00:00

Add support for requesting and using otp for verifying some requests (#527)

Co-authored-by: Thomas Rittson <trittson@bitwarden.com>
This commit is contained in:
Oscar Hinton
2021-11-09 17:01:22 +01:00
committed by GitHub
parent 99ff3feb53
commit 8f177e2d3a
54 changed files with 746 additions and 223 deletions

View File

@@ -4,6 +4,7 @@ import {
OnInit,
Output,
} from '@angular/core';
import { FormBuilder } from '@angular/forms';
import { CryptoService } from 'jslib-common/abstractions/crypto.service';
import { EventService } from 'jslib-common/abstractions/event.service';
@@ -12,6 +13,7 @@ import { I18nService } from 'jslib-common/abstractions/i18n.service';
import { LogService } from 'jslib-common/abstractions/log.service';
import { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';
import { PolicyService } from 'jslib-common/abstractions/policy.service';
import { UserVerificationService } from 'jslib-common/abstractions/userVerification.service';
import { EventType } from 'jslib-common/enums/eventType';
import { PolicyType } from 'jslib-common/enums/policyType';
@@ -21,15 +23,24 @@ export class ExportComponent implements OnInit {
@Output() onSaved = new EventEmitter();
formPromise: Promise<string>;
masterPassword: string;
format: 'json' | 'encrypted_json' | 'csv' = 'json';
showPassword = false;
disabledByPolicy: boolean = false;
exportForm = this.fb.group({
format: ['json'],
secret: [''],
});
formatOptions = [
{ name: '.json', value: 'json' },
{ name: '.csv', value: 'csv' },
{ name: '.json (Encrypted)', value: 'encrypted_json' },
];
constructor(protected cryptoService: CryptoService, protected i18nService: I18nService,
protected platformUtilsService: PlatformUtilsService, protected exportService: ExportService,
protected eventService: EventService, private policyService: PolicyService, protected win: Window,
private logService: LogService) { }
private logService: LogService, private userVerificationService: UserVerificationService,
private fb: FormBuilder) { }
async ngOnInit() {
await this.checkExportDisabled();
@@ -37,6 +48,9 @@ export class ExportComponent implements OnInit {
async checkExportDisabled() {
this.disabledByPolicy = await this.policyService.policyAppliesToUser(PolicyType.DisablePersonalVaultExport);
if (this.disabledByPolicy) {
this.exportForm.disable();
}
}
get encryptedFormat() {
@@ -49,31 +63,25 @@ export class ExportComponent implements OnInit {
return;
}
if (this.masterPassword == null || this.masterPassword === '') {
this.platformUtilsService.showToast('error', this.i18nService.t('errorOccurred'),
this.i18nService.t('invalidMasterPassword'));
return;
}
const acceptedWarning = await this.warningDialog();
if (!acceptedWarning) {
return;
}
const passwordValid = await this.cryptoService.compareAndUpdateKeyHash(this.masterPassword, null);
if (passwordValid) {
try {
this.formPromise = this.getExportData();
const data = await this.formPromise;
this.downloadFile(data);
this.saved();
await this.collectEvent();
} catch (e) {
this.logService.error(e);
}
} else {
this.platformUtilsService.showToast('error', this.i18nService.t('errorOccurred'),
this.i18nService.t('invalidMasterPassword'));
const secret = this.exportForm.get('secret').value;
if (!await this.userVerificationService.verifyUser(secret)) {
return;
}
try {
this.formPromise = this.getExportData();
const data = await this.formPromise;
this.downloadFile(data);
this.saved();
await this.collectEvent();
this.exportForm.get('secret').setValue('');
} catch (e) {
this.logService.error(e);
}
}
@@ -93,11 +101,6 @@ export class ExportComponent implements OnInit {
}
}
togglePassword() {
this.showPassword = !this.showPassword;
document.getElementById('masterPassword').focus();
}
protected saved() {
this.onSaved.emit();
}
@@ -123,6 +126,10 @@ export class ExportComponent implements OnInit {
await this.eventService.collect(EventType.User_ClientExportedVault);
}
get format() {
return this.exportForm.get('format').value;
}
private downloadFile(csv: string): void {
const fileName = this.getFileName();
this.platformUtilsService.saveFile(this.win, csv, { type: 'text/plain' }, fileName);