mirror of
https://github.com/bitwarden/browser.git
synced 2024-11-22 11:45:59 +01:00
[EC-142] Fix error during import of 1pux containing new email field format (#758)
* Add support for complex email field type * Ensure complex email field type gets imported on identities
This commit is contained in:
parent
5f4a8c18fe
commit
3b9ef68f4b
@ -11,6 +11,9 @@ import { CreditCardData } from "./testData/onePassword1Pux/CreditCard";
|
||||
import { DatabaseData } from "./testData/onePassword1Pux/Database";
|
||||
import { DriversLicenseData } from "./testData/onePassword1Pux/DriversLicense";
|
||||
import { EmailAccountData } from "./testData/onePassword1Pux/EmailAccount";
|
||||
import { EmailFieldData } from "./testData/onePassword1Pux/Emailfield";
|
||||
import { EmailFieldOnIdentityData } from "./testData/onePassword1Pux/EmailfieldOnIdentity";
|
||||
import { EmailFieldOnIdentityPrefilledData } from "./testData/onePassword1Pux/EmailfieldOnIdentity_Prefilled";
|
||||
import { IdentityData } from "./testData/onePassword1Pux/IdentityData";
|
||||
import { LoginData } from "./testData/onePassword1Pux/LoginData";
|
||||
import { MedicalRecordData } from "./testData/onePassword1Pux/MedicalRecord";
|
||||
@ -102,6 +105,25 @@ describe("1Password 1Pux Importer", () => {
|
||||
expect(cipher.fields[1].type).toBe(FieldType.Boolean);
|
||||
});
|
||||
|
||||
it("should add fields of type email as custom fields", async () => {
|
||||
const importer = new Importer();
|
||||
const EmailFieldDataJson = JSON.stringify(EmailFieldData);
|
||||
const result = await importer.parse(EmailFieldDataJson);
|
||||
expect(result != null).toBe(true);
|
||||
|
||||
const ciphers = result.ciphers;
|
||||
expect(ciphers.length).toEqual(1);
|
||||
const cipher = ciphers.shift();
|
||||
|
||||
expect(cipher.fields[0].name).toEqual("reg_email");
|
||||
expect(cipher.fields[0].value).toEqual("kriddler@nullvalue.test");
|
||||
expect(cipher.fields[0].type).toBe(FieldType.Text);
|
||||
|
||||
expect(cipher.fields[1].name).toEqual("provider");
|
||||
expect(cipher.fields[1].value).toEqual("myEmailProvider");
|
||||
expect(cipher.fields[1].type).toBe(FieldType.Text);
|
||||
});
|
||||
|
||||
it('should create concealed field as "hidden" type', async () => {
|
||||
const importer = new Importer();
|
||||
const result = await importer.parse(OnePuxExampleFileJson);
|
||||
@ -205,6 +227,46 @@ describe("1Password 1Pux Importer", () => {
|
||||
validateCustomField(cipher.fields, "forumsig", "super cool guy");
|
||||
});
|
||||
|
||||
it("emails fields on identity types should be added to the identity email field", async () => {
|
||||
const importer = new Importer();
|
||||
const EmailFieldOnIdentityDataJson = JSON.stringify(EmailFieldOnIdentityData);
|
||||
const result = await importer.parse(EmailFieldOnIdentityDataJson);
|
||||
expect(result != null).toBe(true);
|
||||
|
||||
const ciphers = result.ciphers;
|
||||
expect(ciphers.length).toEqual(1);
|
||||
const cipher = ciphers.shift();
|
||||
|
||||
const identity = cipher.identity;
|
||||
expect(identity.email).toEqual("gengels@nullvalue.test");
|
||||
|
||||
expect(cipher.fields[0].name).toEqual("provider");
|
||||
expect(cipher.fields[0].value).toEqual("myEmailProvider");
|
||||
expect(cipher.fields[0].type).toBe(FieldType.Text);
|
||||
});
|
||||
|
||||
it("emails fields on identity types should be added to custom fields if identity.email has been filled", async () => {
|
||||
const importer = new Importer();
|
||||
const EmailFieldOnIdentityPrefilledDataJson = JSON.stringify(EmailFieldOnIdentityPrefilledData);
|
||||
const result = await importer.parse(EmailFieldOnIdentityPrefilledDataJson);
|
||||
expect(result != null).toBe(true);
|
||||
|
||||
const ciphers = result.ciphers;
|
||||
expect(ciphers.length).toEqual(1);
|
||||
const cipher = ciphers.shift();
|
||||
|
||||
const identity = cipher.identity;
|
||||
expect(identity.email).toEqual("gengels@nullvalue.test");
|
||||
|
||||
expect(cipher.fields[0].name).toEqual("2nd_email");
|
||||
expect(cipher.fields[0].value).toEqual("kriddler@nullvalue.test");
|
||||
expect(cipher.fields[0].type).toBe(FieldType.Text);
|
||||
|
||||
expect(cipher.fields[1].name).toEqual("provider");
|
||||
expect(cipher.fields[1].value).toEqual("myEmailProvider");
|
||||
expect(cipher.fields[1].type).toBe(FieldType.Text);
|
||||
});
|
||||
|
||||
it("should parse category 005 - Password (Legacy)", async () => {
|
||||
const importer = new Importer();
|
||||
const jsonString = JSON.stringify(PasswordData);
|
||||
|
91
common/spec/importers/testData/onePassword1Pux/Emailfield.ts
Normal file
91
common/spec/importers/testData/onePassword1Pux/Emailfield.ts
Normal file
@ -0,0 +1,91 @@
|
||||
import { ExportData } from "jslib-common/importers/onepasswordImporters/types/onepassword1PuxImporterTypes";
|
||||
|
||||
export const EmailFieldData: ExportData = {
|
||||
accounts: [
|
||||
{
|
||||
attrs: {
|
||||
accountName: "1Password Customer",
|
||||
name: "1Password Customer",
|
||||
avatar: "",
|
||||
email: "username123123123@gmail.com",
|
||||
uuid: "TRIZ3XV4JJFRXJ3BARILLTUA6E",
|
||||
domain: "https://my.1password.com/",
|
||||
},
|
||||
vaults: [
|
||||
{
|
||||
attrs: {
|
||||
uuid: "pqcgbqjxr4tng2hsqt5ffrgwju",
|
||||
desc: "Just test entries",
|
||||
avatar: "ke7i5rxnjrh3tj6uesstcosspu.png",
|
||||
name: "T's Test Vault",
|
||||
type: "U",
|
||||
},
|
||||
items: [
|
||||
{
|
||||
uuid: "47hvppiuwbanbza7bq6jpdjfxu",
|
||||
favIndex: 1,
|
||||
createdAt: 1619467985,
|
||||
updatedAt: 1619468230,
|
||||
trashed: false,
|
||||
categoryUuid: "100",
|
||||
details: {
|
||||
loginFields: [],
|
||||
notesPlain: "My Software License",
|
||||
sections: [
|
||||
{
|
||||
title: "",
|
||||
fields: [],
|
||||
},
|
||||
{
|
||||
title: "Customer",
|
||||
name: "customer",
|
||||
fields: [
|
||||
{
|
||||
title: "registered email",
|
||||
id: "reg_email",
|
||||
value: {
|
||||
email: {
|
||||
email_address: "kriddler@nullvalue.test",
|
||||
provider: "myEmailProvider",
|
||||
},
|
||||
},
|
||||
indexAtSource: 1,
|
||||
guarded: false,
|
||||
multiline: false,
|
||||
dontGenerate: false,
|
||||
inputTraits: {
|
||||
keyboard: "emailAddress",
|
||||
correction: "default",
|
||||
capitalization: "default",
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "Publisher",
|
||||
name: "publisher",
|
||||
fields: [],
|
||||
},
|
||||
{
|
||||
title: "Order",
|
||||
name: "order",
|
||||
fields: [],
|
||||
},
|
||||
],
|
||||
passwordHistory: [],
|
||||
},
|
||||
overview: {
|
||||
subtitle: "5.10.1000",
|
||||
title: "Limux Product Key",
|
||||
url: "",
|
||||
ps: 0,
|
||||
pbe: 0.0,
|
||||
pgrng: false,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
@ -0,0 +1,87 @@
|
||||
import { ExportData } from "jslib-common/importers/onepasswordImporters/types/onepassword1PuxImporterTypes";
|
||||
|
||||
export const EmailFieldOnIdentityData: ExportData = {
|
||||
accounts: [
|
||||
{
|
||||
attrs: {
|
||||
accountName: "1Password Customer",
|
||||
name: "1Password Customer",
|
||||
avatar: "",
|
||||
email: "username123123123@gmail.com",
|
||||
uuid: "TRIZ3XV4JJFRXJ3BARILLTUA6E",
|
||||
domain: "https://my.1password.com/",
|
||||
},
|
||||
vaults: [
|
||||
{
|
||||
attrs: {
|
||||
uuid: "pqcgbqjxr4tng2hsqt5ffrgwju",
|
||||
desc: "Just test entries",
|
||||
avatar: "ke7i5rxnjrh3tj6uesstcosspu.png",
|
||||
name: "T's Test Vault",
|
||||
type: "U",
|
||||
},
|
||||
items: [
|
||||
{
|
||||
uuid: "45mjttbbq3owgij2uis55pfrlq",
|
||||
favIndex: 0,
|
||||
createdAt: 1619465450,
|
||||
updatedAt: 1619465789,
|
||||
trashed: false,
|
||||
categoryUuid: "004",
|
||||
details: {
|
||||
loginFields: [],
|
||||
notesPlain: "",
|
||||
sections: [
|
||||
{
|
||||
title: "Identification",
|
||||
name: "name",
|
||||
fields: [],
|
||||
},
|
||||
{
|
||||
title: "Address",
|
||||
name: "address",
|
||||
fields: [],
|
||||
},
|
||||
{
|
||||
title: "Internet Details",
|
||||
name: "internet",
|
||||
fields: [
|
||||
{
|
||||
title: "E-mail",
|
||||
id: "E-mail",
|
||||
value: {
|
||||
email: {
|
||||
email_address: "gengels@nullvalue.test",
|
||||
provider: "myEmailProvider",
|
||||
},
|
||||
},
|
||||
indexAtSource: 4,
|
||||
guarded: false,
|
||||
multiline: false,
|
||||
dontGenerate: false,
|
||||
inputTraits: {
|
||||
keyboard: "emailAddress",
|
||||
correction: "default",
|
||||
capitalization: "default",
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
passwordHistory: [],
|
||||
},
|
||||
overview: {
|
||||
subtitle: "George Engels",
|
||||
title: "George Engels",
|
||||
url: "",
|
||||
ps: 0,
|
||||
pbe: 0.0,
|
||||
pgrng: false,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
@ -0,0 +1,103 @@
|
||||
import { ExportData } from "jslib-common/importers/onepasswordImporters/types/onepassword1PuxImporterTypes";
|
||||
|
||||
export const EmailFieldOnIdentityPrefilledData: ExportData = {
|
||||
accounts: [
|
||||
{
|
||||
attrs: {
|
||||
accountName: "1Password Customer",
|
||||
name: "1Password Customer",
|
||||
avatar: "",
|
||||
email: "username123123123@gmail.com",
|
||||
uuid: "TRIZ3XV4JJFRXJ3BARILLTUA6E",
|
||||
domain: "https://my.1password.com/",
|
||||
},
|
||||
vaults: [
|
||||
{
|
||||
attrs: {
|
||||
uuid: "pqcgbqjxr4tng2hsqt5ffrgwju",
|
||||
desc: "Just test entries",
|
||||
avatar: "ke7i5rxnjrh3tj6uesstcosspu.png",
|
||||
name: "T's Test Vault",
|
||||
type: "U",
|
||||
},
|
||||
items: [
|
||||
{
|
||||
uuid: "45mjttbbq3owgij2uis55pfrlq",
|
||||
favIndex: 0,
|
||||
createdAt: 1619465450,
|
||||
updatedAt: 1619465789,
|
||||
trashed: false,
|
||||
categoryUuid: "004",
|
||||
details: {
|
||||
loginFields: [],
|
||||
notesPlain: "",
|
||||
sections: [
|
||||
{
|
||||
title: "Identification",
|
||||
name: "name",
|
||||
fields: [],
|
||||
},
|
||||
{
|
||||
title: "Address",
|
||||
name: "address",
|
||||
fields: [],
|
||||
},
|
||||
{
|
||||
title: "Internet Details",
|
||||
name: "internet",
|
||||
fields: [
|
||||
{
|
||||
title: "email",
|
||||
id: "email",
|
||||
value: {
|
||||
string: "gengels@nullvalue.test",
|
||||
},
|
||||
indexAtSource: 4,
|
||||
guarded: false,
|
||||
multiline: false,
|
||||
dontGenerate: false,
|
||||
inputTraits: {
|
||||
keyboard: "emailAddress",
|
||||
correction: "default",
|
||||
capitalization: "default",
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "2nd email",
|
||||
id: "2nd_email",
|
||||
value: {
|
||||
email: {
|
||||
email_address: "kriddler@nullvalue.test",
|
||||
provider: "myEmailProvider",
|
||||
},
|
||||
},
|
||||
indexAtSource: 1,
|
||||
guarded: false,
|
||||
multiline: false,
|
||||
dontGenerate: false,
|
||||
inputTraits: {
|
||||
keyboard: "emailAddress",
|
||||
correction: "default",
|
||||
capitalization: "default",
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
passwordHistory: [],
|
||||
},
|
||||
overview: {
|
||||
subtitle: "George Engels",
|
||||
title: "George Engels",
|
||||
url: "",
|
||||
ps: 0,
|
||||
pbe: 0.0,
|
||||
pgrng: false,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
@ -344,7 +344,10 @@ export const SanitizedExport: ExportData = {
|
||||
title: "",
|
||||
id: "irpvnshg5kjpkmj5jwy4xxkfom",
|
||||
value: {
|
||||
email: "plexuser@nullvalue.test",
|
||||
email: {
|
||||
email_address: "plexuser@nullvalue.test",
|
||||
provider: null,
|
||||
},
|
||||
},
|
||||
indexAtSource: 0,
|
||||
guarded: false,
|
||||
@ -1434,7 +1437,10 @@ export const SanitizedExport: ExportData = {
|
||||
title: "registered email",
|
||||
id: "reg_email",
|
||||
value: {
|
||||
email: "kriddler@nullvalue.test",
|
||||
email: {
|
||||
email_address: "kriddler@nullvalue.test",
|
||||
provider: null,
|
||||
},
|
||||
},
|
||||
indexAtSource: 1,
|
||||
guarded: false,
|
||||
@ -1536,7 +1542,10 @@ export const SanitizedExport: ExportData = {
|
||||
title: "support email",
|
||||
id: "support_email",
|
||||
value: {
|
||||
email: "support@nullvalue.test",
|
||||
email: {
|
||||
email_address: "support@nullvalue.test",
|
||||
provider: null,
|
||||
},
|
||||
},
|
||||
indexAtSource: 4,
|
||||
guarded: false,
|
||||
@ -4014,7 +4023,10 @@ export const SanitizedExport: ExportData = {
|
||||
title: "registered email",
|
||||
id: "reg_email",
|
||||
value: {
|
||||
email: "",
|
||||
email: {
|
||||
email_address: "",
|
||||
provider: null,
|
||||
},
|
||||
},
|
||||
indexAtSource: 1,
|
||||
guarded: false,
|
||||
@ -4116,7 +4128,10 @@ export const SanitizedExport: ExportData = {
|
||||
title: "support email",
|
||||
id: "support_email",
|
||||
value: {
|
||||
email: "",
|
||||
email: {
|
||||
email_address: "",
|
||||
provider: null,
|
||||
},
|
||||
},
|
||||
indexAtSource: 4,
|
||||
guarded: false,
|
||||
|
@ -93,7 +93,10 @@ export const SoftwareLicenseData: ExportData = {
|
||||
title: "registered email",
|
||||
id: "reg_email",
|
||||
value: {
|
||||
email: "kriddler@nullvalue.test",
|
||||
email: {
|
||||
email_address: "kriddler@nullvalue.test",
|
||||
provider: null,
|
||||
},
|
||||
},
|
||||
indexAtSource: 1,
|
||||
guarded: false,
|
||||
@ -195,7 +198,10 @@ export const SoftwareLicenseData: ExportData = {
|
||||
title: "support email",
|
||||
id: "support_email",
|
||||
value: {
|
||||
email: "support@nullvalue.test",
|
||||
email: {
|
||||
email_address: "support@nullvalue.test",
|
||||
provider: null,
|
||||
},
|
||||
},
|
||||
indexAtSource: 4,
|
||||
guarded: false,
|
||||
|
@ -258,7 +258,7 @@ export class OnePassword1PuxImporter extends BaseImporter implements Importer {
|
||||
}
|
||||
}
|
||||
} else if (cipher.type === CipherType.Identity) {
|
||||
if (this.fillIdentity(field, fieldValue, cipher)) {
|
||||
if (this.fillIdentity(field, fieldValue, cipher, valueKey)) {
|
||||
return;
|
||||
}
|
||||
if (valueKey === "address") {
|
||||
@ -312,6 +312,14 @@ export class OnePassword1PuxImporter extends BaseImporter implements Importer {
|
||||
}
|
||||
}
|
||||
|
||||
if (valueKey === "email") {
|
||||
// fieldValue is an object casted into a string, so access the plain value instead
|
||||
const { email_address, provider } = field.value.email;
|
||||
this.processKvp(cipher, fieldName, email_address, FieldType.Text);
|
||||
this.processKvp(cipher, "provider", provider, FieldType.Text);
|
||||
return;
|
||||
}
|
||||
|
||||
// Do not include a password field if it's already in the history
|
||||
if (
|
||||
field.title === "password" &&
|
||||
@ -440,7 +448,12 @@ export class OnePassword1PuxImporter extends BaseImporter implements Importer {
|
||||
return false;
|
||||
}
|
||||
|
||||
private fillIdentity(field: FieldsEntity, fieldValue: string, cipher: CipherView): boolean {
|
||||
private fillIdentity(
|
||||
field: FieldsEntity,
|
||||
fieldValue: string,
|
||||
cipher: CipherView,
|
||||
valueKey: string
|
||||
): boolean {
|
||||
if (this.isNullOrWhitespace(cipher.identity.firstName) && field.id === "firstname") {
|
||||
cipher.identity.firstName = fieldValue;
|
||||
return true;
|
||||
@ -466,9 +479,18 @@ export class OnePassword1PuxImporter extends BaseImporter implements Importer {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (this.isNullOrWhitespace(cipher.identity.email) && field.id === "email") {
|
||||
cipher.identity.email = fieldValue;
|
||||
return true;
|
||||
if (this.isNullOrWhitespace(cipher.identity.email)) {
|
||||
if (valueKey === "email") {
|
||||
const { email_address, provider } = field.value.email;
|
||||
cipher.identity.email = this.getValueOrDefault(email_address);
|
||||
this.processKvp(cipher, "provider", provider, FieldType.Text);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (field.id === "email") {
|
||||
cipher.identity.email = fieldValue;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (this.isNullOrWhitespace(cipher.identity.username) && field.id === "username") {
|
||||
|
@ -106,7 +106,7 @@ export interface Value {
|
||||
date?: number | null;
|
||||
string?: string | null;
|
||||
concealed?: string | null;
|
||||
email?: string | null;
|
||||
email?: Email | null;
|
||||
phone?: string | null;
|
||||
menu?: string | null;
|
||||
gender?: string | null;
|
||||
@ -117,6 +117,12 @@ export interface Value {
|
||||
creditCardNumber?: string | null;
|
||||
reference?: string | null;
|
||||
}
|
||||
|
||||
export interface Email {
|
||||
email_address: string;
|
||||
provider: string;
|
||||
}
|
||||
|
||||
export interface Address {
|
||||
street: string;
|
||||
city: string;
|
||||
|
Loading…
Reference in New Issue
Block a user