1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-17 08:43:33 +00:00

Enhance SafeInCloud import (#307)

* don't import deleted cards

* keep favourite status while importing from saveInCloud

* import all passwords from saveInCloud

* add test data
This commit is contained in:
Paul Sieben
2021-03-16 21:06:12 +01:00
committed by GitHub
parent 7cc23dab72
commit a36f1c25d8
2 changed files with 100 additions and 4 deletions

View File

@@ -9,6 +9,9 @@ import { SecureNoteView } from '../models/view/secureNoteView';
import { CipherType } from '../enums/cipherType';
import { SecureNoteType } from '../enums/secureNoteType';
import { FieldType } from '../enums';
import { CipherView, FieldView } from '../models/view';
export class SafeInCloudXmlImporter extends BaseImporter implements Importer {
parse(data: string): Promise<ImportResult> {
const result = new ImportResult();
@@ -39,7 +42,7 @@ export class SafeInCloudXmlImporter extends BaseImporter implements Importer {
});
Array.from(doc.querySelectorAll('database > card')).forEach(cardEl => {
if (cardEl.getAttribute('template') === 'true') {
if (cardEl.getAttribute('template') === 'true' || cardEl.getAttribute('deleted') === 'true') {
return;
}
@@ -54,6 +57,10 @@ export class SafeInCloudXmlImporter extends BaseImporter implements Importer {
const cipher = this.initLoginCipher();
cipher.name = this.getValueOrDefault(cardEl.getAttribute('title'), '--');
if (cardEl.getAttribute('star') === 'true') {
cipher.favorite = true;
}
const cardType = cardEl.getAttribute('type');
if (cardType === 'note') {
cipher.type = CipherType.SecureNote;
@@ -69,15 +76,17 @@ export class SafeInCloudXmlImporter extends BaseImporter implements Importer {
const fieldType = this.getValueOrDefault(fieldEl.getAttribute('type'), '').toLowerCase();
if (fieldType === 'login') {
cipher.login.username = text;
} else if (fieldType === 'password') {
cipher.login.password = text;
} else if (fieldType === 'password' || fieldType === 'secret') {
// safeInCloud allows for more than one password. we just insert them here and find the one used as password later
this.processKvp(cipher, name, text, FieldType.Hidden);
} else if (fieldType === 'one_time_password') {
cipher.login.totp = text;
} else if (fieldType === 'notes') {
cipher.notes += (text + '\n');
} else if (fieldType === 'weblogin' || fieldType === 'website') {
cipher.login.uris = this.makeUriArray(text);
} else {
}
else {
this.processKvp(cipher, name, text);
}
});
@@ -87,6 +96,7 @@ export class SafeInCloudXmlImporter extends BaseImporter implements Importer {
cipher.notes += (notesEl.textContent + '\n');
});
this.setPassword(cipher);
this.cleanupCipher(cipher);
result.ciphers.push(cipher);
});
@@ -98,4 +108,28 @@ export class SafeInCloudXmlImporter extends BaseImporter implements Importer {
result.success = true;
return Promise.resolve(result);
}
// Choose a password from all passwords. Take one that has password in its name, or the first one if there is no such entry
// if its name is password, we can safely remove it form the fields. otherwise, it would maybe be best to keep it as a hidden field
setPassword(cipher: CipherView) {
const candidates = cipher.fields.filter(field => field.type === FieldType.Hidden);
if (!candidates.length) {
return;
}
let choice: FieldView;
for (const field of candidates) {
if (this.passwordFieldNames.includes(field.name.toLowerCase())) {
choice = field;
cipher.fields = cipher.fields.filter(f => f !== choice);
break;
}
}
if (!choice) {
choice = candidates[0];
}
cipher.login.password = choice.value;
}
}