bitwarden-estensione-browser/common/src/importers/bitwardenJsonImporter.ts

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

173 lines
5.9 KiB
TypeScript
Raw Normal View History

2022-02-22 15:39:11 +01:00
import { CryptoService } from "../abstractions/crypto.service";
import { I18nService } from "../abstractions/i18n.service";
import { EncString } from "../models/domain/encString";
2018-12-17 19:21:06 +01:00
import { ImportResult } from "../models/domain/importResult";
import { CipherWithIds } from "../models/export/cipherWithIds";
import { CollectionWithId } from "../models/export/collectionWithId";
import { FolderWithId } from "../models/export/folderWithId";
2022-02-22 15:39:11 +01:00
import { BaseImporter } from "./baseImporter";
import { Importer } from "./importer";
2018-12-17 19:21:06 +01:00
export class BitwardenJsonImporter extends BaseImporter implements Importer {
private results: any;
private result: ImportResult;
2021-12-16 13:36:21 +01:00
constructor(private cryptoService: CryptoService, private i18nService: I18nService) {
super();
2021-12-16 13:36:21 +01:00
}
async parse(data: string): Promise<ImportResult> {
this.result = new ImportResult();
this.results = JSON.parse(data);
if (this.results == null || this.results.items == null || this.results.items.length === 0) {
this.result.success = false;
return this.result;
}
if (this.results.encrypted) {
await this.parseEncrypted();
} else {
this.parseDecrypted();
2018-12-17 19:21:06 +01:00
}
return this.result;
2021-12-16 13:36:21 +01:00
}
private async parseEncrypted() {
if (this.results.encKeyValidation_DO_NOT_EDIT != null) {
const orgKey = await this.cryptoService.getOrgKey(this.organizationId);
const encKeyValidation = new EncString(this.results.encKeyValidation_DO_NOT_EDIT);
const encKeyValidationDecrypt = await this.cryptoService.decryptToUtf8(
encKeyValidation,
2021-12-16 13:36:21 +01:00
orgKey
);
if (encKeyValidationDecrypt === null) {
this.result.success = false;
this.result.errorMessage = this.i18nService.t("importEncKeyError");
2021-12-16 13:36:21 +01:00
return;
}
}
const groupingsMap = new Map<string, number>();
2021-12-16 13:36:21 +01:00
if (this.organization && this.results.collections != null) {
for (const c of this.results.collections as CollectionWithId[]) {
const collection = CollectionWithId.toDomain(c);
if (collection != null) {
collection.id = null;
collection.organizationId = this.organizationId;
const view = await collection.decrypt();
groupingsMap.set(c.id, this.result.collections.length);
this.result.collections.push(view);
}
2021-12-16 13:36:21 +01:00
}
} else if (!this.organization && this.results.folders != null) {
for (const f of this.results.folders as FolderWithId[]) {
const folder = FolderWithId.toDomain(f);
if (folder != null) {
folder.id = null;
const view = await folder.decrypt();
groupingsMap.set(f.id, this.result.folders.length);
this.result.folders.push(view);
}
2021-12-16 13:36:21 +01:00
}
}
for (const c of this.results.items as CipherWithIds[]) {
const cipher = CipherWithIds.toDomain(c);
// reset ids incase they were set for some reason
cipher.id = null;
cipher.folderId = null;
cipher.organizationId = this.organizationId;
cipher.collectionIds = null;
2021-12-16 13:36:21 +01:00
// make sure password history is limited
if (cipher.passwordHistory != null && cipher.passwordHistory.length > 5) {
cipher.passwordHistory = cipher.passwordHistory.slice(0, 5);
}
2021-12-16 13:36:21 +01:00
if (!this.organization && c.folderId != null && groupingsMap.has(c.folderId)) {
this.result.folderRelationships.push([
this.result.ciphers.length,
groupingsMap.get(c.folderId),
]);
} else if (this.organization && c.collectionIds != null) {
c.collectionIds.forEach((cId) => {
if (groupingsMap.has(cId)) {
this.result.collectionRelationships.push([
this.result.ciphers.length,
groupingsMap.get(cId),
]);
}
});
}
const view = await cipher.decrypt();
this.cleanupCipher(view);
this.result.ciphers.push(view);
}
this.result.success = true;
2021-12-16 13:36:21 +01:00
}
private parseDecrypted() {
const groupingsMap = new Map<string, number>();
if (this.organization && this.results.collections != null) {
this.results.collections.forEach((c: CollectionWithId) => {
2018-12-17 19:21:06 +01:00
const collection = CollectionWithId.toView(c);
if (collection != null) {
collection.id = null;
collection.organizationId = null;
groupingsMap.set(c.id, this.result.collections.length);
this.result.collections.push(collection);
2018-12-17 19:21:06 +01:00
}
});
} else if (!this.organization && this.results.folders != null) {
this.results.folders.forEach((f: FolderWithId) => {
2018-12-17 19:21:06 +01:00
const folder = FolderWithId.toView(f);
if (folder != null) {
folder.id = null;
groupingsMap.set(f.id, this.result.folders.length);
this.result.folders.push(folder);
2018-12-17 19:21:06 +01:00
}
2021-12-16 13:36:21 +01:00
});
}
2018-12-17 19:21:06 +01:00
this.results.items.forEach((c: CipherWithIds) => {
2018-12-17 19:21:06 +01:00
const cipher = CipherWithIds.toView(c);
// reset ids incase they were set for some reason
cipher.id = null;
cipher.folderId = null;
cipher.organizationId = null;
cipher.collectionIds = null;
2021-12-16 13:36:21 +01:00
2019-03-25 14:15:38 +01:00
// make sure password history is limited
if (cipher.passwordHistory != null && cipher.passwordHistory.length > 5) {
cipher.passwordHistory = cipher.passwordHistory.slice(0, 5);
}
2021-12-16 13:36:21 +01:00
2018-12-17 19:21:06 +01:00
if (!this.organization && c.folderId != null && groupingsMap.has(c.folderId)) {
this.result.folderRelationships.push([
this.result.ciphers.length,
groupingsMap.get(c.folderId),
]);
2018-12-17 19:21:06 +01:00
} else if (this.organization && c.collectionIds != null) {
c.collectionIds.forEach((cId) => {
2018-12-17 19:21:06 +01:00
if (groupingsMap.has(cId)) {
this.result.collectionRelationships.push([
this.result.ciphers.length,
groupingsMap.get(cId),
]);
2018-12-17 19:21:06 +01:00
}
});
2021-12-16 13:36:21 +01:00
}
2018-12-17 19:21:06 +01:00
this.cleanupCipher(cipher);
this.result.ciphers.push(cipher);
2021-12-16 13:36:21 +01:00
});
this.result.success = true;
2018-12-17 19:21:06 +01:00
}
}