mirror of
https://github.com/nextcloud/passman.git
synced 2025-11-08 13:11:31 +08:00
Add reading keepass csv
This commit is contained in:
parent
b123ac850f
commit
9f5f00c91c
8 changed files with 184 additions and 15 deletions
|
|
@ -8,7 +8,44 @@
|
||||||
* Controller of the passmanApp
|
* Controller of the passmanApp
|
||||||
*/
|
*/
|
||||||
angular.module('passmanApp')
|
angular.module('passmanApp')
|
||||||
.controller('ImportCtrl', ['$scope', function ($scope) {
|
.controller('ImportCtrl', ['$scope', '$window', function ($scope, $window) {
|
||||||
|
//@TODo read the available importers from $window.PassmanImporter
|
||||||
|
$scope.available_importers = [
|
||||||
|
{
|
||||||
|
name: 'KeePass CSV',
|
||||||
|
value: 'keepassCsv'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'LastPass CSV',
|
||||||
|
value: 'lastpassCsv'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Passman CSV',
|
||||||
|
value: 'passmanCsv'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Passman JSON',
|
||||||
|
value: 'passmanJson'
|
||||||
|
}
|
||||||
|
];
|
||||||
|
var file_data;
|
||||||
|
$scope.fileLoaded = function (file) {
|
||||||
|
file_data = file.data.split(',');
|
||||||
|
file_data = decodeURIComponent(escape(window.atob( file_data[1] ))); //window.atob();
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.fileLoadError = function (file) {
|
||||||
|
console.error('Error loading file');
|
||||||
|
};
|
||||||
|
$scope.fileSelectProgress = function (progress) {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.startImport = function(importerType){
|
||||||
|
if(file_data){
|
||||||
|
var parsed_data = $window.PassmanImporter[importerType].readFile(file_data);
|
||||||
|
console.log('Data parsed!', parsed_data);
|
||||||
|
}
|
||||||
|
}
|
||||||
}]);
|
}]);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,14 +11,16 @@ angular.module('passmanApp')
|
||||||
.controller('SettingsCtrl', ['$scope', '$rootScope', 'SettingsService', 'VaultService', 'CredentialService', '$location', '$routeParams', '$http',
|
.controller('SettingsCtrl', ['$scope', '$rootScope', 'SettingsService', 'VaultService', 'CredentialService', '$location', '$routeParams', '$http',
|
||||||
function ($scope, $rootScope, SettingsService, VaultService, CredentialService, $location, $routeParams, $http) {
|
function ($scope, $rootScope, SettingsService, VaultService, CredentialService, $location, $routeParams, $http) {
|
||||||
|
|
||||||
$scope.tabs = [{
|
$scope.tabs = [
|
||||||
title: 'General settings',
|
{
|
||||||
url: 'views/partials/forms/settings/general_settings.html'
|
title: 'General settings',
|
||||||
}, {
|
url: 'views/partials/forms/settings/general_settings.html'
|
||||||
title: 'Password Tool',
|
},
|
||||||
url: 'views/partials/forms/settings/tool.html'
|
{
|
||||||
|
title: 'Password Tool',
|
||||||
|
url: 'views/partials/forms/settings/tool.html'
|
||||||
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Import credentials',
|
title: 'Import credentials',
|
||||||
url: 'views/partials/forms/settings/import.html'
|
url: 'views/partials/forms/settings/import.html'
|
||||||
|
|
@ -30,7 +32,7 @@ angular.module('passmanApp')
|
||||||
|
|
||||||
}];
|
}];
|
||||||
|
|
||||||
$scope.currentTab = $scope.tabs[0];
|
$scope.currentTab = $scope.tabs[2];
|
||||||
|
|
||||||
$scope.onClickTab = function (tab) {
|
$scope.onClickTab = function (tab) {
|
||||||
$scope.currentTab = tab;
|
$scope.currentTab = tab;
|
||||||
|
|
@ -42,7 +44,7 @@ angular.module('passmanApp')
|
||||||
|
|
||||||
var getPassmanVersion = function () {
|
var getPassmanVersion = function () {
|
||||||
var url = OC.generateUrl('apps/passman/api/internal/version');
|
var url = OC.generateUrl('apps/passman/api/internal/version');
|
||||||
$http.get(url).then(function(result){
|
$http.get(url).then(function (result) {
|
||||||
$scope.passman_version = result.data.version;
|
$scope.passman_version = result.data.version;
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
|
||||||
77
js/importers/import-main.js
Normal file
77
js/importers/import-main.js
Normal file
|
|
@ -0,0 +1,77 @@
|
||||||
|
// Importers should always start with this
|
||||||
|
if(!window['PassmanImporter']){
|
||||||
|
var PassmanImporter = {}
|
||||||
|
}
|
||||||
|
|
||||||
|
PassmanImporter.parseRow_ = function(row, isHeading) {
|
||||||
|
// Strip leading quote.
|
||||||
|
row = row.trim();
|
||||||
|
if (row.charAt(0) == '"') {
|
||||||
|
row = row.substring(1);
|
||||||
|
}
|
||||||
|
if (row.charAt(row.length - 2) == '"') {
|
||||||
|
row = row.substring(0, row.length - 2);
|
||||||
|
}
|
||||||
|
// Strip trailing quote. There seems to be a character between the last quote
|
||||||
|
// and the line ending, hence 2 instead of 1.
|
||||||
|
|
||||||
|
row = row.split('","');
|
||||||
|
return row;
|
||||||
|
};
|
||||||
|
|
||||||
|
PassmanImporter.toObject_ = function(headings, row) {
|
||||||
|
var result = {};
|
||||||
|
for (var i = 0, ii = row.length; i < ii; i++) {
|
||||||
|
headings[i] = headings[i].replace(',','_')
|
||||||
|
.toLowerCase().replace(' ','_')
|
||||||
|
.replace('(','').replace(')','')
|
||||||
|
.replace('"','');
|
||||||
|
result[headings[i]] = row[i];
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
|
PassmanImporter.join_ = function(arr, sep) {
|
||||||
|
var parts = [];
|
||||||
|
for (var i = 0, ii = arr.length; i < ii; i++) {
|
||||||
|
arr[i] && parts.push(arr[i]);
|
||||||
|
}
|
||||||
|
return parts.join(sep);
|
||||||
|
};
|
||||||
|
|
||||||
|
PassmanImporter.newCredential = function () {
|
||||||
|
var credential = {
|
||||||
|
'credential_id': null,
|
||||||
|
'guid': null,
|
||||||
|
'vault_id': null,
|
||||||
|
'label': null,
|
||||||
|
'description': null,
|
||||||
|
'created': null,
|
||||||
|
'changed': null,
|
||||||
|
'tags': [],
|
||||||
|
'email': null,
|
||||||
|
'username': null,
|
||||||
|
'password': null,
|
||||||
|
'url': null,
|
||||||
|
'favicon': null,
|
||||||
|
'renew_interval': null,
|
||||||
|
'expire_time': 0,
|
||||||
|
'delete_time': 0,
|
||||||
|
'files': [],
|
||||||
|
'custom_fields': [],
|
||||||
|
'otp': {},
|
||||||
|
'hidden': false
|
||||||
|
};
|
||||||
|
return credential;
|
||||||
|
};
|
||||||
|
|
||||||
|
PassmanImporter.readCsv = function( csv ){
|
||||||
|
var lines = [];
|
||||||
|
var rows = csv.split('\n');
|
||||||
|
var headings = this.parseRow_(rows[0]);
|
||||||
|
for (var i = 1, row; row = rows[i]; i++) {
|
||||||
|
row = this.toObject_(headings, this.parseRow_(row));
|
||||||
|
lines.push(row);
|
||||||
|
}
|
||||||
|
return lines;
|
||||||
|
};
|
||||||
39
js/importers/importer-keepasscsv.js
Normal file
39
js/importers/importer-keepasscsv.js
Normal file
|
|
@ -0,0 +1,39 @@
|
||||||
|
// Importers should always start with this
|
||||||
|
if (!window['PassmanImporter']) {
|
||||||
|
var PassmanImporter = {}
|
||||||
|
}
|
||||||
|
// Define the importer
|
||||||
|
PassmanImporter.keepassCsv = {
|
||||||
|
info: {
|
||||||
|
name: 'KeePass csv',
|
||||||
|
id: 'keepassCsv',
|
||||||
|
description: 'Create an csv export with the following options enabled: http://i.imgur.com/CaeTA4d.png'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
PassmanImporter.keepassCsv.readFile = function (file_data) {
|
||||||
|
var parsed_csv = PassmanImporter.readCsv(file_data);
|
||||||
|
var credential_list = [];
|
||||||
|
for (var i = 0; i < parsed_csv.length; i++) {
|
||||||
|
var row = parsed_csv[i];
|
||||||
|
var _credential = PassmanImporter.newCredential();
|
||||||
|
_credential.label = row.account;
|
||||||
|
_credential.username = row.login_name;
|
||||||
|
_credential.password = row.password;
|
||||||
|
_credential.url = row.web_site;
|
||||||
|
if (row.hasOwnProperty('expires')) {
|
||||||
|
row.expires = row.expires.replace('"','');
|
||||||
|
_credential.expire_time = new Date(row.expires).getTime() / 1000;
|
||||||
|
}
|
||||||
|
var tags = [{text: row.group}];
|
||||||
|
if (row.hasOwnProperty('group_tree')) {
|
||||||
|
var exploded_tree = row.group_tree.split('\\\\');
|
||||||
|
for (var t = 0; t < exploded_tree.length; t++) {
|
||||||
|
tags.push({text: exploded_tree[t]});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_credential.tags = tags;
|
||||||
|
credential_list.push(_credential);
|
||||||
|
}
|
||||||
|
return credential_list;
|
||||||
|
};
|
||||||
|
|
@ -51,13 +51,13 @@ angular.module('views/partials/forms/settings/export.html', []).run(['$templateC
|
||||||
angular.module('views/partials/forms/settings/general_settings.html', []).run(['$templateCache', function($templateCache) {
|
angular.module('views/partials/forms/settings/general_settings.html', []).run(['$templateCache', function($templateCache) {
|
||||||
'use strict';
|
'use strict';
|
||||||
$templateCache.put('views/partials/forms/settings/general_settings.html',
|
$templateCache.put('views/partials/forms/settings/general_settings.html',
|
||||||
'<div class="row"><div class="col-xs-12 col-md-6"><h3>Change vault key</h3><label>Old vault password</label><input type="password" ng-model="oldVaultPass"><label>New vault password</label><password-gen ng-model="newVaultPass"></password-gen><ng-password-meter password="newVaultPass"></ng-password-meter><label>New vault password</label><input type="password" ng-model="newVaultPass2"> <button ng-click="changeVaultPassword(oldVaultPass,newVaultPass,newVaultPass2)" tooltip="\'Not working :P\'">Change</button></div><div class="col-xs-12 col-md-6"><h3>About passman</h3><p>Version: <b>{{passman_version}}</b><br>Bla bla about passman, our vision, and donate link.</p></div></div>');
|
'<div class="row"><div class="col-xs-12 col-md-6"><h3>Change vault key</h3><label>Old vault password</label><input type="password" ng-model="oldVaultPass"><label>New vault password</label><password-gen ng-model="newVaultPass"></password-gen><ng-password-meter password="newVaultPass"></ng-password-meter><label>New vault password</label><input type="password" ng-model="newVaultPass2"> <button ng-click="changeVaultPassword(oldVaultPass,newVaultPass,newVaultPass2)" tooltip="\'Not working :P\'">Change</button></div><div class="col-xs-12 col-md-6"><h3>About passman</h3><p>Version: <b>{{passman_version}}</b><br>Bla bla about passman, changelog.<br><a href="https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=6YS8F97PETVU2" target="_blank" class="link">Donate to support development</a></p></div></div>');
|
||||||
}]);
|
}]);
|
||||||
|
|
||||||
angular.module('views/partials/forms/settings/import.html', []).run(['$templateCache', function($templateCache) {
|
angular.module('views/partials/forms/settings/import.html', []).run(['$templateCache', function($templateCache) {
|
||||||
'use strict';
|
'use strict';
|
||||||
$templateCache.put('views/partials/forms/settings/import.html',
|
$templateCache.put('views/partials/forms/settings/import.html',
|
||||||
'<div ng-controller="ImportCtrl">Import credentials</div>');
|
'<div ng-controller="ImportCtrl"><div class="row"><div class="col-xs-12" ng-init="importerType"><label>Import type<select ng-model="importerType"><option ng-repeat="importer in available_importers" value="{{importer.value}}">{{importer.name}}</option></select></label><input ng-if="importerType" type="file" file-select success="fileLoaded" error="fileLoadError" progress="fileSelectProgress"><br><button class="button" ng-click="startImport(importerType)" ng-if="importerType">Import</button></div></div></div>');
|
||||||
}]);
|
}]);
|
||||||
|
|
||||||
angular.module('views/partials/forms/settings/tool.html', []).run(['$templateCache', function($templateCache) {
|
angular.module('views/partials/forms/settings/tool.html', []).run(['$templateCache', function($templateCache) {
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,8 @@ script('passman', 'app/directives/tooltip');
|
||||||
script('passman', 'app/directives/use-theme');
|
script('passman', 'app/directives/use-theme');
|
||||||
script('passman', 'app/directives/credentialfield');
|
script('passman', 'app/directives/credentialfield');
|
||||||
script('passman', 'app/directives/ngenter');
|
script('passman', 'app/directives/ngenter');
|
||||||
|
script('passman', 'importers/import-main');
|
||||||
|
script('passman', 'importers/importer-keepasscsv');
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Styles
|
* Styles
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,9 @@
|
||||||
<h3>About passman</h3>
|
<h3>About passman</h3>
|
||||||
<p>
|
<p>
|
||||||
Version: <b>{{passman_version}}</b><br />
|
Version: <b>{{passman_version}}</b><br />
|
||||||
Bla bla about passman, our vision, and donate link.
|
Bla bla about passman, changelog.
|
||||||
|
<br />
|
||||||
|
<a href="https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=6YS8F97PETVU2" target="_blank" class="link">Donate to support development</a>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -1,3 +1,14 @@
|
||||||
<div ng-controller="ImportCtrl">
|
<div ng-controller="ImportCtrl">
|
||||||
Import credentials
|
<div class="row">
|
||||||
|
<div class="col-xs-12" ng-init="importerType">
|
||||||
|
<label>Import type
|
||||||
|
<select ng-model="importerType">
|
||||||
|
<option ng-repeat="importer in available_importers" value="{{importer.value}}">
|
||||||
|
{{importer.name}}
|
||||||
|
</option>
|
||||||
|
</select></label>
|
||||||
|
<input ng-if="importerType" type="file" file-select success="fileLoaded" error="fileLoadError" progress="fileSelectProgress"><br />
|
||||||
|
<button class="button" ng-click="startImport(importerType)" ng-if="importerType">Import</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
Loading…
Add table
Reference in a new issue