1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-20 02:03:39 +00:00

[PM-1071] Display import-details-dialog on successful import (#4817)

* Prefer callback over error-flow to prompt for password

Remove error-flow to request file password
Prefer callback, which has to be provided when retrieving/creating an instance.
Delete ImportError
Call BitwardenPasswordProtector for all Bitwarden json imports, as it extends BitwardenJsonImporter
Throw errors instead of returning
Return ImportResult
Fix and extend tests import.service
Replace "@fluffy-spoon/substitute" with "jest-mock-extended"

* Fix up test cases

Delete bitwarden-json-importer.spec.ts
Add test case to ensure bitwarden-json-importer.ts is called given unencrypted or account-protected files

* Move file-password-prompt into dialog-folder

* Add import success dialog

* Fix typo

* Only list the type when at least one got imported

* update copy based on design feedback

* Remove unnecessary /index import

* Remove promptForPassword_callback from interface

PR feedback from @MGibson1 that giving every importer the ability to request a password is unnecessary. Instead, we can pass the callback into the constructor for every importer that needs this functionality

* Remove unneeded import of BitwardenJsonImporter

* Fix spec constructor

* Fixed organizational import

Added an else statement, or else we'd import into an org and then also import into an individual vault
This commit is contained in:
Daniel James Smith
2023-04-06 22:41:09 +02:00
committed by GitHub
parent 19626a7837
commit cf2d8b266a
24 changed files with 397 additions and 287 deletions

View File

@@ -13,7 +13,10 @@ export class BitwardenJsonImporter extends BaseImporter implements Importer {
private results: any;
private result: ImportResult;
constructor(protected cryptoService: CryptoService, protected i18nService: I18nService) {
protected constructor(
protected cryptoService: CryptoService,
protected i18nService: I18nService
) {
super();
}
@@ -21,13 +24,6 @@ export class BitwardenJsonImporter extends BaseImporter implements Importer {
this.result = new ImportResult();
this.results = JSON.parse(data);
if (this.results == null || this.results.items == null) {
if (this.results?.passwordProtected) {
this.result.success = false;
this.result.missingPassword = true;
this.result.errorMessage = this.i18nService.t("importPasswordRequired");
return this.result;
}
this.result.success = false;
return this.result;
}

View File

@@ -13,19 +13,41 @@ import { BitwardenPasswordProtectedFileFormat } from "./bitwarden-password-prote
export class BitwardenPasswordProtectedImporter extends BitwardenJsonImporter implements Importer {
private key: SymmetricCryptoKey;
constructor(cryptoService: CryptoService, i18nService: I18nService, private password: string) {
constructor(
cryptoService: CryptoService,
i18nService: I18nService,
private promptForPassword_callback: () => Promise<string>
) {
super(cryptoService, i18nService);
}
async parse(data: string): Promise<ImportResult> {
const result = new ImportResult();
const parsedData = JSON.parse(data);
const parsedData: BitwardenPasswordProtectedFileFormat = JSON.parse(data);
if (!parsedData) {
result.success = false;
return result;
}
// File is unencrypted
if (!parsedData?.encrypted) {
return await super.parse(data);
}
// File is account-encrypted
if (!parsedData?.passwordProtected) {
return await super.parse(data);
}
if (this.cannotParseFile(parsedData)) {
result.success = false;
return result;
}
if (!(await this.checkPassword(parsedData))) {
// File is password-protected
const password = await this.promptForPassword_callback();
if (!(await this.checkPassword(parsedData, password))) {
result.success = false;
result.errorMessage = this.i18nService.t("invalidFilePassword");
return result;
@@ -36,9 +58,12 @@ export class BitwardenPasswordProtectedImporter extends BitwardenJsonImporter im
return await super.parse(clearTextData);
}
private async checkPassword(jdoc: BitwardenPasswordProtectedFileFormat): Promise<boolean> {
private async checkPassword(
jdoc: BitwardenPasswordProtectedFileFormat,
password: string
): Promise<boolean> {
this.key = await this.cryptoService.makePinKey(
this.password,
password,
jdoc.salt,
jdoc.kdfType,
new KdfConfig(jdoc.kdfIterations, jdoc.kdfMemory, jdoc.kdfParallelism)