From e7b5868aadf8412f49bfaba378d05c692124e265 Mon Sep 17 00:00:00 2001 From: Kyle Spearrin Date: Mon, 17 Dec 2018 10:32:02 -0500 Subject: [PATCH] export to json --- src/abstractions/export.service.ts | 2 +- src/services/export.service.ts | 139 +++++++++++++++++++---------- 2 files changed, 91 insertions(+), 50 deletions(-) diff --git a/src/abstractions/export.service.ts b/src/abstractions/export.service.ts index 7f9f27234b..a6b719e8b3 100644 --- a/src/abstractions/export.service.ts +++ b/src/abstractions/export.service.ts @@ -1,5 +1,5 @@ export abstract class ExportService { getExport: (format?: 'csv' | 'json') => Promise; getOrganizationExport: (organizationId: string, format?: 'csv' | 'json') => Promise; - getFileName: (prefix?: string) => string; + getFileName: (prefix?: string, extension?: string) => string; } diff --git a/src/services/export.service.ts b/src/services/export.service.ts index 68f5a7e1d8..a105be6d8b 100644 --- a/src/services/export.service.ts +++ b/src/services/export.service.ts @@ -18,6 +18,10 @@ import { CipherData } from '../models/data/cipherData'; import { CollectionData } from '../models/data/collectionData'; import { CollectionDetailsResponse } from '../models/response/collectionResponse'; +import { CipherWithIds as CipherExport } from '../models/export/cipherWithIds'; +import { CollectionWithId as CollectionExport } from '../models/export/collectionWithId'; +import { FolderWithId as FolderExport } from '../models/export/folderWithId'; + export class ExportService implements ExportServiceAbstraction { constructor(private folderService: FolderService, private cipherService: CipherService, private apiService: ApiService) { } @@ -37,33 +41,54 @@ export class ExportService implements ExportServiceAbstraction { await Promise.all(promises); - const foldersMap = new Map(); - decFolders.forEach((f) => { - foldersMap.set(f.id, f); - }); - - const exportCiphers: any[] = []; - decCiphers.forEach((c) => { - // only export logins and secure notes - if (c.type !== CipherType.Login && c.type !== CipherType.SecureNote) { - return; - } - - if (c.organizationId != null) { - return; - } - - const cipher: any = {}; - cipher.folder = c.folderId != null && foldersMap.has(c.folderId) ? foldersMap.get(c.folderId).name : null; - cipher.favorite = c.favorite ? 1 : null; - this.buildCommonCipher(cipher, c); - exportCiphers.push(cipher); - }); - if (format === 'csv') { + const foldersMap = new Map(); + decFolders.forEach((f) => { + foldersMap.set(f.id, f); + }); + + const exportCiphers: any[] = []; + decCiphers.forEach((c) => { + // only export logins and secure notes + if (c.type !== CipherType.Login && c.type !== CipherType.SecureNote) { + return; + } + if (c.organizationId != null) { + return; + } + + const cipher: any = {}; + cipher.folder = c.folderId != null && foldersMap.has(c.folderId) ? + foldersMap.get(c.folderId).name : null; + cipher.favorite = c.favorite ? 1 : null; + this.buildCommonCipher(cipher, c); + exportCiphers.push(cipher); + }); + return papa.unparse(exportCiphers); } else { - return JSON.stringify(exportCiphers, null, ' '); + const jsonDoc: any = { + folders: [], + items: [], + }; + + decFolders.forEach((f) => { + const folder = new FolderExport(); + folder.build(f); + jsonDoc.folders.push(folder); + }); + + decCiphers.forEach((c) => { + if (c.organizationId != null) { + return; + } + const cipher = new CipherExport(); + cipher.build(c); + cipher.collectionIds = null; + jsonDoc.items.push(cipher); + }); + + return JSON.stringify(jsonDoc, null, ' '); } } @@ -100,43 +125,59 @@ export class ExportService implements ExportServiceAbstraction { await Promise.all(promises); - const collectionsMap = new Map(); - decCollections.forEach((c) => { - collectionsMap.set(c.id, c); - }); - - const exportCiphers: any[] = []; - decCiphers.forEach((c) => { - // only export logins and secure notes - if (c.type !== CipherType.Login && c.type !== CipherType.SecureNote) { - return; - } - - const cipher: any = {}; - cipher.collections = []; - if (c.collectionIds != null) { - cipher.collections = c.collectionIds.filter((id) => collectionsMap.has(id)) - .map((id) => collectionsMap.get(id).name); - } - this.buildCommonCipher(cipher, c); - exportCiphers.push(cipher); - }); - if (format === 'csv') { + const collectionsMap = new Map(); + decCollections.forEach((c) => { + collectionsMap.set(c.id, c); + }); + + const exportCiphers: any[] = []; + decCiphers.forEach((c) => { + // only export logins and secure notes + if (c.type !== CipherType.Login && c.type !== CipherType.SecureNote) { + return; + } + + const cipher: any = {}; + cipher.collections = []; + if (c.collectionIds != null) { + cipher.collections = c.collectionIds.filter((id) => collectionsMap.has(id)) + .map((id) => collectionsMap.get(id).name); + } + this.buildCommonCipher(cipher, c); + exportCiphers.push(cipher); + }); + return papa.unparse(exportCiphers); } else { - return JSON.stringify(exportCiphers, null, ' '); + const jsonDoc: any = { + collections: [], + items: [], + }; + + decCollections.forEach((c) => { + const collection = new CollectionExport(); + collection.build(c); + jsonDoc.collections.push(collection); + }); + + decCiphers.forEach((c) => { + const cipher = new CipherExport(); + cipher.build(c); + jsonDoc.items.push(cipher); + }); + return JSON.stringify({}, null, ' '); } } - getFileName(prefix: string = null): string { + getFileName(prefix: string = null, extension: string = 'csv'): string { const now = new Date(); const dateString = now.getFullYear() + '' + this.padNumber(now.getMonth() + 1, 2) + '' + this.padNumber(now.getDate(), 2) + this.padNumber(now.getHours(), 2) + '' + this.padNumber(now.getMinutes(), 2) + this.padNumber(now.getSeconds(), 2); - return 'bitwarden' + (prefix ? ('_' + prefix) : '') + '_export_' + dateString + '.csv'; + return 'bitwarden' + (prefix ? ('_' + prefix) : '') + '_export_' + dateString + '.' + extension; } private padNumber(num: number, width: number, padCharacter: string = '0'): string {