import via textarea

This commit is contained in:
Kyle Spearrin 2017-03-30 00:07:26 -04:00
parent 61cce7e8e7
commit 1db6d7f32b
3 changed files with 130 additions and 139 deletions

View File

@ -182,6 +182,28 @@
} }
} }
function getFileContents(file, contentsCallback, errorCallback) {
if (typeof file === 'string') {
contentsCallback(file);
}
else {
var reader = new FileReader();
reader.readAsText(file, 'utf-8');
reader.onload = function (evt) {
contentsCallback(evt.target.result);
};
reader.onerror = function (evt) {
errorCallback();
};
}
}
function getXmlFileContents(file, xmlCallback, errorCallback) {
getFileContents(file, function (fileContents) {
xmlCallback($.parseXML(fileContents));
}, errorCallback);
}
function importBitwardenCsv(file, success, error) { function importBitwardenCsv(file, success, error) {
Papa.parse(file, { Papa.parse(file, {
header: true, header: true,
@ -239,7 +261,7 @@
} }
function importLastPass(file, success, error) { function importLastPass(file, success, error) {
if (file.type === 'text/html') { if (typeof file !== 'string' && file.type && file.type === 'text/html') {
var reader = new FileReader(); var reader = new FileReader();
reader.readAsText(file, 'utf-8'); reader.readAsText(file, 'utf-8');
reader.onload = function (evt) { reader.onload = function (evt) {
@ -344,16 +366,14 @@
var folders = [], var folders = [],
logins = [], logins = [],
loginRelationships = [], loginRelationships = [],
foldersIndex = []; foldersIndex = [],
i = 0,
var i = 0,
j = 0; j = 0;
var reader = new FileReader(); getXmlFileContents(file, parse, error);
reader.readAsText(file, 'utf-8');
reader.onload = function (evt) { function parse(xmlDoc) {
var xmlDoc = $.parseXML(evt.target.result), var xml = $(xmlDoc);
xml = $(xmlDoc);
var db = xml.find('database'); var db = xml.find('database');
if (db.length) { if (db.length) {
@ -429,11 +449,7 @@
else { else {
error(); error();
} }
}; }
reader.onerror = function (evt) {
error();
};
} }
function importPadlockCsv(file, success, error) { function importPadlockCsv(file, success, error) {
@ -535,11 +551,10 @@
logins = [], logins = [],
loginRelationships = []; loginRelationships = [];
var reader = new FileReader(); getXmlFileContents(file, parse, error);
reader.readAsText(file, 'utf-8');
reader.onload = function (evt) { function parse(xmlDoc) {
var xmlDoc = $.parseXML(evt.target.result), var xml = $(xmlDoc);
xml = $(xmlDoc);
var root = xml.find('Root'); var root = xml.find('Root');
if (root.length) { if (root.length) {
@ -552,11 +567,7 @@
else { else {
error(); error();
} }
}; }
reader.onerror = function (evt) {
error();
};
function traverse(node, isRootNode, groupNamePrefix) { function traverse(node, isRootNode, groupNamePrefix) {
var nodeEntries = []; var nodeEntries = [];
@ -745,10 +756,9 @@
} }
} }
var reader = new FileReader(); getXmlFileContents(file, parse, error);
reader.readAsText(file, 'utf-8');
reader.onload = function (evt) { function parse(fileContent) {
var fileContent = evt.target.result;
var fileLines = fileContent.split(/(?:\r\n|\r|\n)/); var fileLines = fileContent.split(/(?:\r\n|\r|\n)/);
for (i = 0; i < fileLines.length; i++) { for (i = 0; i < fileLines.length; i++) {
@ -790,11 +800,7 @@
} }
success(folders, logins, loginRelationships); success(folders, logins, loginRelationships);
}; }
reader.onerror = function (evt) {
error();
};
} }
function import1Password6WinCsv(file, success, error) { function import1Password6WinCsv(file, success, error) {
@ -922,12 +928,8 @@
return name; return name;
} }
if (file.type === 'text/xml') { function parseXml(xmlDoc) {
var reader = new FileReader(); var xml = $(xmlDoc);
reader.readAsText(file, 'utf-8');
reader.onload = function (evt) {
var xmlDoc = $.parseXML(evt.target.result),
xml = $(xmlDoc);
var entries = xml.find('entry'); var entries = xml.find('entry');
for (var i = 0; i < entries.length; i++) { for (var i = 0; i < entries.length; i++) {
@ -951,11 +953,10 @@
} }
success(folders, logins, loginRelationships); success(folders, logins, loginRelationships);
}; }
reader.onerror = function (evt) { if (file.type && file.type === 'text/xml') {
error(); getXmlFileContents(file, parseXml, error);
};
} }
else { else {
// currently bugged due to the comment // currently bugged due to the comment
@ -1100,11 +1101,10 @@
foldersIndex = [], foldersIndex = [],
j = 0; j = 0;
var reader = new FileReader(); getXmlFileContents(file, parseXml, error);
reader.readAsText(file, 'utf-8');
reader.onload = function (evt) { function parseXml(xmlDoc) {
var xmlDoc = $.parseXML(evt.target.result), var xml = $(xmlDoc);
xml = $(xmlDoc);
var pwManager = xml.find('PasswordManager'); var pwManager = xml.find('PasswordManager');
if (pwManager.length) { if (pwManager.length) {
@ -1205,11 +1205,7 @@
else { else {
error(); error();
} }
}; }
reader.onerror = function (evt) {
error();
};
} }
function importEnpassCsv(file, success, error) { function importEnpassCsv(file, success, error) {
@ -1283,11 +1279,10 @@
foldersIndex = [], foldersIndex = [],
j = 0; j = 0;
var reader = new FileReader(); getXmlFileContents(file, parseXml, error);
reader.readAsText(file, 'utf-8');
reader.onload = function (evt) { function parseXml(xmlDoc) {
var xmlDoc = $.parseXML(evt.target.result), var xml = $(xmlDoc);
xml = $(xmlDoc);
var pwsafe = xml.find('passwordsafe'); var pwsafe = xml.find('passwordsafe');
if (pwsafe.length) { if (pwsafe.length) {
@ -1371,11 +1366,7 @@
else { else {
error(); error();
} }
}; }
reader.onerror = function (evt) {
error();
};
} }
function importDashlaneCsv(file, success, error) { function importDashlaneCsv(file, success, error) {
@ -1509,11 +1500,10 @@
return groupText; return groupText;
} }
var reader = new FileReader(); getXmlFileContents(file, parseXml, error);
reader.readAsText(file, 'utf-8');
reader.onload = function (evt) { function parseXml(xmlDoc) {
var xmlDoc = $.parseXML(evt.target.result), var xml = $(xmlDoc);
xml = $(xmlDoc);
var database = xml.find('root > Database'); var database = xml.find('root > Database');
if (database.length) { if (database.length) {
@ -1599,11 +1589,7 @@
else { else {
error(); error();
} }
}; }
reader.onerror = function (evt) {
error();
};
} }
function importmSecureCsv(file, success, error) { function importmSecureCsv(file, success, error) {
@ -1764,10 +1750,10 @@
logins = [], logins = [],
loginRelationships = []; loginRelationships = [];
var reader = new FileReader(); getFileContents(file, parse, error);
reader.readAsText(file, 'utf-8');
reader.onload = function (evt) { function parse(fileContents) {
var doc = $(evt.target.result); var doc = $(fileContents);
var textarea = doc.find('textarea'); var textarea = doc.find('textarea');
var json = textarea && textarea.length ? textarea.val() : null; var json = textarea && textarea.length ? textarea.val() : null;
var entries = json ? JSON.parse(json) : null; var entries = json ? JSON.parse(json) : null;
@ -1836,11 +1822,7 @@
} }
success(folders, logins, loginRelationships); success(folders, logins, loginRelationships);
}; }
reader.onerror = function (evt) {
error();
};
} }
function importAviraJson(file, success, error) { function importAviraJson(file, success, error) {
@ -1849,10 +1831,9 @@
loginRelationships = [], loginRelationships = [],
i = 0; i = 0;
var reader = new FileReader(); getFileContents(file, parseJson, error);
reader.readAsText(file, 'utf-8');
reader.onload = function (evt) { function parseJson(fileContent) {
var fileContent = evt.target.result;
var fileJson = JSON.parse(fileContent); var fileJson = JSON.parse(fileContent);
if (fileJson) { if (fileJson) {
if (fileJson.accounts) { if (fileJson.accounts) {
@ -1886,11 +1867,7 @@
} }
success(folders, logins, loginRelationships); success(folders, logins, loginRelationships);
}; }
reader.onerror = function (evt) {
error();
};
} }
function importRoboFormHtml(file, success, error) { function importRoboFormHtml(file, success, error) {
@ -1898,10 +1875,10 @@
logins = [], logins = [],
loginRelationships = []; loginRelationships = [];
var reader = new FileReader(); getFileContents(file, parse, error);
reader.readAsText(file, 'utf-8');
reader.onload = function (evt) { function parse(fileContents) {
var doc = $(evt.target.result.split('&shy;').join('').split('<WBR>').join('')); var doc = $(fileContents.split('&shy;').join('').split('<WBR>').join(''));
var outterTables = doc.find('table.nobr'); var outterTables = doc.find('table.nobr');
if (outterTables.length) { if (outterTables.length) {
for (var i = 0; i < outterTables.length; i++) { for (var i = 0; i < outterTables.length; i++) {
@ -1962,11 +1939,7 @@
} }
success(folders, logins, loginRelationships); success(folders, logins, loginRelationships);
}; }
reader.onerror = function (evt) {
error();
};
} }
function importSaferPassCsv(file, success, error) { function importSaferPassCsv(file, success, error) {
@ -2075,10 +2048,9 @@
loginRelationships = [], loginRelationships = [],
i = 0; i = 0;
var reader = new FileReader(); getFileContents(file, parseJson, error);
reader.readAsText(file, 'utf-8');
reader.onload = function (evt) { function parseJson(fileContent) {
var fileContent = evt.target.result;
var fileJson = JSON.parse(fileContent); var fileJson = JSON.parse(fileContent);
if (fileJson && fileJson.length) { if (fileJson && fileJson.length) {
for (i = 0; i < fileJson.length; i++) { for (i = 0; i < fileJson.length; i++) {
@ -2133,11 +2105,7 @@
} }
success(folders, logins, loginRelationships); success(folders, logins, loginRelationships);
}; }
reader.onerror = function (evt) {
error();
};
} }
function importZohoVaultCsv(file, success, error) { function importZohoVaultCsv(file, success, error) {

View File

@ -1,9 +1,10 @@
angular angular
.module('bit.tools') .module('bit.tools')
.controller('toolsImportController', function ($scope, $state, apiService, $uibModalInstance, cryptoService, cipherService, toastr, importService, $analytics, $sce) { .controller('toolsImportController', function ($scope, $state, apiService, $uibModalInstance, cryptoService, cipherService,
toastr, importService, $analytics, $sce, validationService) {
$analytics.eventTrack('toolsImportController', { category: 'Modal' }); $analytics.eventTrack('toolsImportController', { category: 'Modal' });
$scope.model = { source: 'bitwardencsv' }; $scope.model = { source: '' };
$scope.source = {}; $scope.source = {};
$scope.options = [ $scope.options = [
@ -202,10 +203,20 @@
}; };
$scope.setSource(); $scope.setSource();
$scope.import = function (model) { $scope.import = function (model, form) {
$scope.processing = true; if (!model.source || model.source === '') {
validationService.addError(form, 'source', 'Select the format of the import file.', true);
return;
}
var file = document.getElementById('file').files[0]; var file = document.getElementById('file').files[0];
importService.import(model.source, file, importSuccess, importError); if (!file && (!model.fileContents || model.fileContents === '')) {
validationService.addError(form, 'file', 'Select the import file or copy/paste the import file contents.', true);
return;
}
$scope.processing = true;
importService.import(model.source, file || model.fileContents, importSuccess, importError);
}; };
function importSuccess(folders, logins, folderRelationships) { function importSuccess(folders, logins, folderRelationships) {

View File

@ -2,21 +2,33 @@
<button type="button" class="close" ng-click="close()" aria-label="Close"><span aria-hidden="true">&times;</span></button> <button type="button" class="close" ng-click="close()" aria-label="Close"><span aria-hidden="true">&times;</span></button>
<h4 class="modal-title" id="importModelLabel"><i class="fa fa-cloud-upload"></i> Import</h4> <h4 class="modal-title" id="importModelLabel"><i class="fa fa-cloud-upload"></i> Import</h4>
</div> </div>
<form name="importForm" ng-submit="importForm.$valid && import(model)" ng-show="!processing"> <form name="importForm" ng-submit="importForm.$valid && import(model, importForm)" ng-show="!processing">
<div class="modal-body"> <div class="modal-body">
<div class="callout callout-danger validation-errors" ng-show="importForm.$errors">
<h4>Errors have occured</h4>
<ul>
<li ng-repeat="e in importForm.$errors">{{e}}</li>
</ul>
</div>
<div class="form-group"> <div class="form-group">
<label for="source">1. Select the source of this import file</label> <label for="source">1. Select the format of the import file</label>
<select id="source" name="source" class="form-control" ng-model="model.source" ng-change="setSource()"> <select id="source" name="source" class="form-control" ng-model="model.source" ng-change="setSource()" required>
<option value="">-- Select --</option>
<option ng-repeat="option in options" value="{{option.id}}">{{option.name}}</option> <option ng-repeat="option in options" value="{{option.id}}">{{option.name}}</option>
</select> </select>
</div> </div>
<div class="callout callout-default"> <div class="callout callout-default" ng-show="model.source">
<h4><i class="fa fa-info-circle"></i> {{source.name}} Instructions</h4> <h4><i class="fa fa-info-circle"></i> {{source.name}} Instructions</h4>
<div ng-bind-html="source.instructions"></div> <div ng-bind-html="source.instructions"></div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="file">2. Select the import file</label> <label for="file">2. Select the import file</label>
<input type="file" id="file" name="file" required /> <input type="file" id="file" name="file" />
</div>
<div class="form-group">
<label for="fileContents">or copy/paste the import file contents</label>
<textarea id="fileContents" class="form-control" name="fileContents" ng-model="model.fileContents"
style="height: 150px;"></textarea>
</div> </div>
</div> </div>
<div class="modal-footer"> <div class="modal-footer">