1password 1pif: import password history (#33)
* 1password 1pif import password history * 1password 1pif importer: process windows password history * linter fix
This commit is contained in:
parent
df429fe178
commit
8ed27eeeec
|
@ -49,6 +49,12 @@ const TestData: string = '***aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee***\n' +
|
||||||
name: 'admin_console',
|
name: 'admin_console',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
passwordHistory: [
|
||||||
|
{
|
||||||
|
value: 'old-password',
|
||||||
|
time: 1447791421,
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
URLs: [
|
URLs: [
|
||||||
{
|
{
|
||||||
|
@ -61,6 +67,76 @@ const TestData: string = '***aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee***\n' +
|
||||||
typeName: 'webforms.WebForm',
|
typeName: 'webforms.WebForm',
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const WindowsTestData = JSON.stringify({
|
||||||
|
category: '001',
|
||||||
|
created: 1544823719,
|
||||||
|
hmac: 'NtyBmTTPOb88HV3JUKPx1xl/vcMhac9kvCfe/NtszY0=',
|
||||||
|
k: 'XC/z20QveYCoV8xQ4tCJZZp/uum77xLkMSMEhlUULndryXgSmkG+VBtkW7AfuerfKc8Rtu43a4Sd078j7XfZTcwUCEKtBECUTDNbEgv4+4hoFVk1EzZgEUy/0bW1Ap+jNLmmdSU9h74+REu6pdxsvQ==',
|
||||||
|
tx: 1553395669,
|
||||||
|
updated: 1553395669,
|
||||||
|
uuid: '528AB076FB5F4FBF960884B8E01619AC',
|
||||||
|
overview: {
|
||||||
|
title: 'Google',
|
||||||
|
URLs: [
|
||||||
|
{
|
||||||
|
u: 'google.com',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
url: 'google.com',
|
||||||
|
ps: 26,
|
||||||
|
ainfo: 'googluser',
|
||||||
|
},
|
||||||
|
details: {
|
||||||
|
passwordHistory: [
|
||||||
|
{
|
||||||
|
value: 'oldpass2',
|
||||||
|
time: 1553394449,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'oldpass1',
|
||||||
|
time: 1553394457,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
type: 'T',
|
||||||
|
id: 'username',
|
||||||
|
name: 'username',
|
||||||
|
value: 'googluser',
|
||||||
|
designation: 'username',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'P',
|
||||||
|
id: 'password',
|
||||||
|
name: 'password',
|
||||||
|
value: '12345678901',
|
||||||
|
designation: 'password',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
notesPlain: 'This is a note\r\n\r\nline1\r\nline2',
|
||||||
|
sections: [
|
||||||
|
{
|
||||||
|
title: 'test',
|
||||||
|
name: '1214FD88CD30405D9EED14BEB4D61B60',
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
k: 'string',
|
||||||
|
n: '6CC3BD77482D4559A4B8BB2D360F821B',
|
||||||
|
v: 'fgfg',
|
||||||
|
t: 'fgggf',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
k: 'concealed',
|
||||||
|
n: '5CFE7BCAA1DF4578BBF7EB508959BFF3',
|
||||||
|
v: 'dfgdfgfdg',
|
||||||
|
t: 'pwfield',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
const IdentityTestData = JSON.stringify({
|
const IdentityTestData = JSON.stringify({
|
||||||
uuid: 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
|
uuid: 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
|
||||||
updatedAt: 1553365894,
|
updatedAt: 1553365894,
|
||||||
|
@ -393,4 +469,30 @@ describe('1Password 1Pif Importer', () => {
|
||||||
// remaining fields as custom fields
|
// remaining fields as custom fields
|
||||||
expect(cipher.fields.length).toEqual(6);
|
expect(cipher.fields.length).toEqual(6);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should create password history', async () => {
|
||||||
|
const importer = new Importer();
|
||||||
|
const result = importer.parse(TestData);
|
||||||
|
const cipher = result.ciphers.shift();
|
||||||
|
|
||||||
|
expect(cipher.passwordHistory.length).toEqual(1);
|
||||||
|
const ph = cipher.passwordHistory.shift();
|
||||||
|
expect(ph.password).toEqual('old-password');
|
||||||
|
expect(ph.lastUsedDate.toISOString()).toEqual('2015-11-17T20:17:01.000Z');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create password history from windows 1pif format', async () => {
|
||||||
|
const importer = new Importer();
|
||||||
|
const result = importer.parse(WindowsTestData);
|
||||||
|
const cipher = result.ciphers.shift();
|
||||||
|
|
||||||
|
expect(cipher.passwordHistory.length).toEqual(2);
|
||||||
|
let ph = cipher.passwordHistory.shift();
|
||||||
|
expect(ph.password).toEqual('oldpass2');
|
||||||
|
expect(ph.lastUsedDate.toISOString()).toEqual('2019-03-24T02:27:29.000Z');
|
||||||
|
|
||||||
|
ph = cipher.passwordHistory.shift();
|
||||||
|
expect(ph.password).toEqual('oldpass1');
|
||||||
|
expect(ph.lastUsedDate.toISOString()).toEqual('2019-03-24T02:27:37.000Z');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { throttle } from '../../../src/misc/throttle';
|
|
||||||
import { sequentialize } from '../../../src/misc/sequentialize';
|
import { sequentialize } from '../../../src/misc/sequentialize';
|
||||||
|
import { throttle } from '../../../src/misc/throttle';
|
||||||
|
|
||||||
describe('throttle decorator', () => {
|
describe('throttle decorator', () => {
|
||||||
it('should call the function once at a time', async () => {
|
it('should call the function once at a time', async () => {
|
||||||
|
|
|
@ -6,6 +6,7 @@ import { ImportResult } from '../models/domain/importResult';
|
||||||
import { CardView } from '../models/view/cardView';
|
import { CardView } from '../models/view/cardView';
|
||||||
import { CipherView } from '../models/view/cipherView';
|
import { CipherView } from '../models/view/cipherView';
|
||||||
import { IdentityView } from '../models/view/identityView';
|
import { IdentityView } from '../models/view/identityView';
|
||||||
|
import { PasswordHistoryView } from '../models/view/passwordHistoryView';
|
||||||
import { SecureNoteView } from '../models/view/secureNoteView';
|
import { SecureNoteView } from '../models/view/secureNoteView';
|
||||||
|
|
||||||
import { CipherType } from '../enums/cipherType';
|
import { CipherType } from '../enums/cipherType';
|
||||||
|
@ -77,8 +78,21 @@ export class OnePassword1PifImporter extends BaseImporter implements Importer {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
if (item.details.passwordHistory != null) {
|
||||||
|
this.processPasswordHistory(item.details.passwordHistory, cipher);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private processPasswordHistory(items: any[], cipher: CipherView) {
|
||||||
|
cipher.passwordHistory = cipher.passwordHistory || [];
|
||||||
|
items.forEach((entry: any) => {
|
||||||
|
const phv = new PasswordHistoryView();
|
||||||
|
phv.password = entry.value;
|
||||||
|
phv.lastUsedDate = new Date(entry.time * 1000);
|
||||||
|
cipher.passwordHistory.push(phv);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private processStandardItem(item: any, cipher: CipherView) {
|
private processStandardItem(item: any, cipher: CipherView) {
|
||||||
cipher.favorite = item.openContents && item.openContents.faveIndex ? true : false;
|
cipher.favorite = item.openContents && item.openContents.faveIndex ? true : false;
|
||||||
|
@ -128,6 +142,9 @@ export class OnePassword1PifImporter extends BaseImporter implements Importer {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
if (item.secureContents.passwordHistory != null) {
|
||||||
|
this.processPasswordHistory(item.secureContents.passwordHistory, cipher);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue