From 85efba92e64c8807ee0080fedf52c4d094d8292f Mon Sep 17 00:00:00 2001 From: Kyle Spearrin Date: Wed, 12 Oct 2016 22:14:39 -0400 Subject: [PATCH] added importer for keypass 2.x xml --- src/Web/wwwroot/app/services/importService.js | 121 +++++++++++++++++- .../wwwroot/app/tools/views/toolsImport.html | 7 +- 2 files changed, 122 insertions(+), 6 deletions(-) diff --git a/src/Web/wwwroot/app/services/importService.js b/src/Web/wwwroot/app/services/importService.js index 0eb4390ca3..94325bd453 100644 --- a/src/Web/wwwroot/app/services/importService.js +++ b/src/Web/wwwroot/app/services/importService.js @@ -12,8 +12,11 @@ case 'lastpass': importLastPass(file, success, error); break; - case 'safeincloud': - importSafeInCloud(file, success, error); + case 'safeincloudcsv': + importSafeInCloudCsv(file, success, error); + break; + case 'keypassxml': + importKeyPassXml(file, success, error); break; default: error(); @@ -135,7 +138,7 @@ }); } - function importSafeInCloud(file, success, error) { + function importSafeInCloudCsv(file, success, error) { Papa.parse(file, { header: true, complete: function (results) { @@ -159,5 +162,117 @@ }); } + function importKeyPassXml(file, success, error) { + var folders = [], + sites = [], + siteRelationships = []; + + var reader = new FileReader(); + reader.readAsText(file, 'utf-8'); + reader.onload = function (evt) { + var xmlDoc = $.parseXML(evt.target.result), + xml = $(xmlDoc); + + var root = xml.find('Root'); + if (root.length) { + var group = root.find('> Group'); + if (group.length) { + traverse($(group[0]), true, ''); + success(folders, sites, siteRelationships); + } + } + }; + + reader.onerror = function (evt) { + error(); + }; + + function traverse(node, isRootNode, groupNamePrefix) { + var nodeEntries = []; + var folderIndex = folders.length; + var groupName = groupNamePrefix; + + if (!isRootNode) { + if (groupName !== '') { + groupName += ' > '; + } + groupName += node.find('> Name').text(); + folders.push({ + name: groupName + }); + } + + var entries = node.find('> Entry'); + if (entries.length) { + for (var i = 0; i < entries.length; i++) { + var entry = $(entries[i]); + var siteIndex = sites.length; + var site = { + favorite: false, + uri: '', + username: '', + password: '', + notes: '', + name: '' + }; + + var entryStrings = entry.find('> String'); + for (var j = 0; j < entryStrings.length; j++) { + var entryString = $(entryStrings[j]); + + var key = entryString.find('> Key').text(); + var value = entryString.find('> Value').text(); + if (value === '') { + continue; + } + + switch (key) { + case 'URL': + site.uri = value; + break; + case 'UserName': + site.username = value; + break; + case 'Password': + site.password = value; + break; + case 'Title': + site.name = value; + break; + case 'Notes': + site.notes = site.notes == null ? value + '\n' : site.notes + value + '\n'; + break; + default: + // other custom fields + site.notes = site.notes == null ? key + ': ' + value + '\n' + : site.notes + key + ': ' + value + '\n'; + break; + } + } + + if (site.name === '') { + site.name = '--'; + } + + sites.push(site); + + if (!isRootNode) { + siteRelationships.push({ + key: siteIndex, + value: folderIndex + }); + } + } + } + + var groups = node.find('> Group'); + if (groups.length) { + for (var i = 0; i < groups.length; i++) { + traverse($(groups[i]), false, groupName); + } + } + } + } + return _service; }); diff --git a/src/Web/wwwroot/app/tools/views/toolsImport.html b/src/Web/wwwroot/app/tools/views/toolsImport.html index 7ed03b32f7..8ac3b45d29 100644 --- a/src/Web/wwwroot/app/tools/views/toolsImport.html +++ b/src/Web/wwwroot/app/tools/views/toolsImport.html @@ -7,9 +7,10 @@