Merge branch 'master' of github.com:nextcloud/passman

This commit is contained in:
Marcos Zuriaga 2016-09-25 17:47:29 +02:00
commit d4088e8fbe
20 changed files with 316 additions and 41 deletions

View file

@ -371,6 +371,13 @@
padding-left: 0px;
padding-right: 15px; }
.import_log {
max-height: 600px;
overflow-y: auto; }
.import_log textarea {
width: 90%;
height: 200px; }
#app-settings-content:not(.ng-hide) {
height: 60px;
display: inherit !important;

File diff suppressed because one or more lines are too long

View file

@ -88,7 +88,7 @@ jQuery(document).ready(function () {
angular.element('#app-content-wrapper').scope().deleteCredential(credential);
angular.element('#app-content-wrapper').scope().$apply();
});
var adjustControlsWidth = function() {
var adjustControlsWidth = function(r) {
if($('#controls').length) {
var controlsWidth;
// if there is a scrollbar …
@ -111,12 +111,17 @@ jQuery(document).ready(function () {
controlsWidth = $('#content').width();
}
}
$('#controls').css('width', controlsWidth);
$('#controls').css('min-width', controlsWidth);
if(r){
var magic = 0;
} else {
var magic = 85;
}
$('#controls').css('width', controlsWidth+magic);
$('#controls').css('min-width', controlsWidth+magic);
}
};
$(window).resize(_.debounce(adjustControlsWidth, 256));
$(window).resize(_.debounce(adjustControlsWidth, 400));
setTimeout(function(){
adjustControlsWidth()
adjustControlsWidth(true)
},200)
});

View file

@ -9,8 +9,8 @@
*/
angular.module('passmanApp')
.controller('CredentialCtrl', ['$scope', 'VaultService', 'SettingsService', '$location', 'CredentialService',
'$rootScope', 'FileService', 'EncryptService', 'TagService', '$timeout', 'NotificationService',
function ($scope, VaultService, SettingsService, $location, CredentialService, $rootScope, FileService, EncryptService, TagService, $timeout, NotificationService) {
'$rootScope', 'FileService', 'EncryptService', 'TagService', '$timeout', 'NotificationService', 'CacheService',
function ($scope, VaultService, SettingsService, $location, CredentialService, $rootScope, FileService, EncryptService, TagService, $timeout, NotificationService, CacheService) {
$scope.active_vault = VaultService.getActiveVault();
if (!SettingsService.getSetting('defaultVault') || !SettingsService.getSetting('defaultVaultPass')) {
if (!$scope.active_vault) {
@ -125,9 +125,12 @@ angular.module('passmanApp')
});
};
$scope.itemFilter = {
label: ''
$scope.filterOptions = {
filterText: '',
fields: ['label', 'username', 'email', 'password', 'custom_fields']
};
$scope.selectedtags = [];
var to;
$rootScope.$on('selected_tags_updated', function (evt, _sTags) {
@ -177,7 +180,7 @@ angular.module('passmanApp')
$scope.selectedCredential = false;
$scope.selectCredential = function (credential) {
$scope.selectedCredential = CredentialService.decryptCredential(angular.copy(credential));
$scope.selectedCredential = angular.copy(credential);
$rootScope.$emit('app_menu', true);
};
@ -194,17 +197,31 @@ angular.module('passmanApp')
});
try {
var credential_cache = JSON.parse(CacheService.get('credential_cache_'+ $scope.active_vault.vault_id));
if(credential_cache.length > 0){
$scope.credentials = credential_cache;
for (var i = 0; i < credential_cache.length; i++) {
TagService.addTags(credential_cache[i].tags_raw);
}
}
} catch (e){
}
var fetchCredentials = function () {
VaultService.getVault($scope.active_vault).then(function (credentials) {
var _credentials = [];
for (var i = 0; i < credentials.length; i++) {
var credential = angular.copy(credentials[i]);
var _tags = CredentialService.decryptCredential(angular.copy(credentials[i])).tags;
TagService.addTags(_tags);
credential.tags_raw = _tags;
_credentials.push(credential);
var _c = CredentialService.decryptCredential(angular.copy(credentials[i]));
_c.tags_raw = _c.tags;
TagService.addTags( _c.tags);
_credentials.push(_c);
}
$scope.credentials = _credentials;
CacheService.set('credential_cache_'+ $scope.active_vault.vault_id, JSON.stringify(_credentials));
});
};

View file

@ -8,11 +8,12 @@
* Controller of the passmanApp
*/
angular.module('passmanApp')
.controller('ImportCtrl', ['$scope', '$window', function ($scope, $window) {
.controller('ImportCtrl', ['$scope', '$window', 'CredentialService', 'VaultService', function ($scope, $window, CredentialService, VaultService) {
//@TODo read the available importers from $window.PassmanImporter
$scope.available_importers = [
];
$scope.active_vault = VaultService.getActiveVault();
$scope.$watch(function(){
@ -25,16 +26,21 @@ angular.module('passmanApp')
}
}
}, true);
$scope.log = [];
$scope.setImporter = function (importer) {
importer = JSON.parse(importer);
$scope.selectedImporter = importer;
};
var _log = function(str){
$scope.log.push(str);
};
var file_data;
$scope.fileLoaded = function (file) {
file_data = file.data.split(',');
file_data = decodeURIComponent(escape(window.atob( file_data[1] ))); //window.atob();
_log('File read successfully!')
$scope.$apply();
};
$scope.fileLoadError = function (file) {
@ -44,11 +50,49 @@ angular.module('passmanApp')
};
var parsed_data;
$scope.current_import_index = 0;
$scope.current_import_length = 0;
var addCredential = function(parsed_data_index){
if(!parsed_data[parsed_data_index]){
return;
}
var _credential = parsed_data[parsed_data_index];
if(!_credential.label){
if(parsed_data[ parsed_data_index +1]) {
_log('Credential has no label, skipping');
addCredential(parsed_data_index +1)
}
return
}
_log('Adding '+ _credential.label);
$scope.current_import_index = parsed_data_index;
_credential.vault_id = $scope.active_vault.vault_id;
CredentialService.createCredential(_credential).then(function (result) {
if(result.credential_id){
_log('Added '+ _credential.label);
if(parsed_data[ parsed_data_index +1]) {
addCredential(parsed_data_index +1)
} else {
_log('DONE!');
}
}
})
};
$scope.startImport = function(){
if(file_data){
var parsed_data = $window.PassmanImporter[$scope.selectedImporter.id].readFile(file_data);
console.log('Data parsed!', parsed_data);
parsed_data = $window.PassmanImporter[$scope.selectedImporter.id].readFile(file_data);
_log('Parsed '+ parsed_data.length + ' credentials, starting to import');
$scope.current_import_length = parsed_data.length;
if( parsed_data.length > 0){
addCredential(0);
} else {
// @TODO Show message no data found
}
}
}
}]);

View file

@ -10,7 +10,7 @@
angular.module('passmanApp')
.controller('SettingsCtrl', ['$scope', '$rootScope', 'SettingsService', 'VaultService', 'CredentialService', '$location', '$routeParams', '$http',
function ($scope, $rootScope, SettingsService, VaultService, CredentialService, $location, $routeParams, $http) {
$scope.active_vault = VaultService.getActiveVault();
$scope.tabs = [
{
title: 'General settings',
@ -58,7 +58,9 @@ angular.module('passmanApp')
$scope.$watch(function () {
return VaultService.getActiveVault()
}, function (vault) {
$scope.active_vault = vault;
if(vault) {
$scope.active_vault = vault;
}
});
if (!SettingsService.getSetting('defaultVault') || !SettingsService.getSetting('defaultVaultPass')) {

View file

@ -0,0 +1,22 @@
'use strict';
/**
* @ngdoc directive
* @name passmanApp.directive:autoScroll
* @description
* # autoScroll
*/
angular.module('passmanApp')
.directive('autoScroll', function () {
return {
restrict: 'A',
scope: {
autoScroll: '='
},
link: function postLink(scope, element, attrs) {
scope.$watch('autoScroll', function () {
$('#import_log').scrollTop($('#import_log')[0].scrollHeight);
}, true);
}
};
});

View file

@ -0,0 +1,41 @@
'use strict';
/**
* @ngdoc filter
* @name passmanApp.filter:selectedTags
* @function
* @description
* # selectedTags
* Filter in the passmanApp.
*/
angular.module('passmanApp')
.filter('credentialSearch', function () {
return function (credentials, filter) {
var _credentials = [];
if(credentials) {
if (filter.filterText == "") {
return credentials
}
for (var ci = 0; ci < credentials.length; ci++) {
var c = credentials[ci];
for(var f = 0; f < filter.fields.length; f++){
var field = filter.fields[f];
if(typeof c[field] === 'string' ){
if(c[field].indexOf(filter.filterText) >= 0){
_credentials.push(c);
break;
}
} else {
var t = JSON.stringify(c[field]);
if(t.indexOf(filter.filterText) >= 0){
_credentials.push(c);
break;
}
}
}
}
return _credentials;
}
};
});

View file

@ -8,6 +8,14 @@
* Service in the passmanApp.
*/
angular.module('passmanApp')
.service('CacheService', [function () {
// AngularJS will instantiate a singleton by calling "new" on this function
.service('CacheService', ['localStorageService', 'EncryptService', function (localStorageService, EncryptService) {
return {
get: function(name){
return EncryptService.decryptString(localStorageService.get(name));
},
set: function (key, value) {
value = EncryptService.encryptString(value);
localStorageService.set(key, value);
}
}
}]);

View file

@ -8,7 +8,7 @@
* Service in the passmanApp.
*/
angular.module('passmanApp')
.service('VaultService', ['$http', 'CacheService', function ($http, CacheService) {
.service('VaultService', ['$http', function ($http) {
// AngularJS will instantiate a singleton by calling "new" on this function
var _activeVault;
return {

View file

@ -24,7 +24,11 @@ PassmanImporter.parseRow_ = function(row, isHeading) {
}
return row;
};
PassmanImporter.htmlDecode = function(input){
var e = document.createElement('div');
e.innerHTML = input;
return e.childNodes[0].nodeValue;
};
PassmanImporter.toObject_ = function(headings, row) {
var result = {};
for (var i = 0, ii = row.length; i < ii; i++) {
@ -87,4 +91,8 @@ PassmanImporter.readCsv = function( csv, hasHeadings ){
}
}
return lines;
};
PassmanImporter.readJson = function (string){
return JSON.parse(string);
};

View file

@ -31,7 +31,9 @@ PassmanImporter.dashLaneCsv.readFile = function (file_data) {
_credential.password = row_data[row_data.length - 2];
_credential.url = row_data[0];
_credential.description = row_data[row_data.length - 1];
credential_list.push(_credential);
if(_credential.label){
credential_list.push(_credential);
}
}
return credential_list;
};

View file

@ -17,13 +17,15 @@ PassmanImporter.lastpassCsv.readFile = function (file_data) {
for (var i = 0; i < parsed_csv.length; i++) {
var row = parsed_csv[i];
var _credential = PassmanImporter.newCredential();
_credential.label = row.name;
_credential.label = PassmanImporter.htmlDecode(row.name);
_credential.username = row.username;
_credential.password = row.password;
_credential.url = row.url;
_credential.tags = [{text: row.grouping}];
_credential.description = row.extra;
credential_list.push(_credential);
if(_credential.label){
credential_list.push(_credential);
}
}
return credential_list;
};

View file

@ -0,0 +1,60 @@
// Importers should always start with this
if (!window['PassmanImporter']) {
var PassmanImporter = {}
}
// Define the importer
PassmanImporter.passmanJson = {
info: {
name: 'Passman JSON',
id: 'passmanJson',
description: 'Export the item in passman as passman json, with all fields enabled'
}
};
PassmanImporter.passmanJson.readFile = function (file_data) {
var parsed_json = PassmanImporter.readJson(file_data);
var credential_list = [];
for (var i = 0; i < parsed_json.length; i++) {
var item = parsed_json[i];
var _credential = PassmanImporter.newCredential();
_credential.label = item.label;
_credential.username = item.account;
_credential.password = item.password;
_credential.email = item.email;
_credential.url = item.url;
_credential.tags = item.tags;
//Check for custom fields
if (item.hasOwnProperty('customFields')) {
//Check for otp
if (item.customFields.length > 0) {
for (var cf = 0; cf < item.customFields.length; cf++) {
_credential.custom_fields.push(
{
'label': item.customFields[cf].label,
'value': item.customFields[cf].value,
'secret': (item.customFields[cf].clicktoshow == '1')
}
)
}
}
}
if (item.hasOwnProperty('otpsecret')) {
if (item.otpsecret) {
_credential.otp = {
'issuer': item.otpsecret.issuer,
'label': item.otpsecret.label,
'qr_uri': {
'image': item.otpsecret.qrCode,
'qrData': ''
},
'secret': item.otpsecret.secret,
'type': item.otpsecret.type
}
}
}
if(_credential.label){
credential_list.push(_credential);
}
}
return credential_list;
};

View file

@ -0,0 +1,30 @@
// Importers should always start with this
if (!window['PassmanImporter']) {
var PassmanImporter = {}
}
// Define the importer
PassmanImporter.zohoCsv = {
info: {
name: 'ZOHO csv',
id: 'zohoCsv',
description: 'Create an csv export. Go to Tools -> Export secrets -> Select "General CSV" and click "Export Secrets"'
}
};
PassmanImporter.zohoCsv.readFile = function (file_data) {
var parsed_csv = PassmanImporter.readCsv(file_data, false);
var credential_list = [];
for (var i = 0; i < parsed_csv.length; i++) {
var row = parsed_csv[i];
var _credential = PassmanImporter.newCredential();
_credential.label = row[0];
_credential.username = row[3];
_credential.password = row[4];
_credential.url = row[1];
_credential.description = row[2];
if(_credential.label){
credential_list.push(_credential);
}
}
return credential_list;
};

View file

@ -57,7 +57,7 @@ angular.module('views/partials/forms/settings/general_settings.html', []).run(['
angular.module('views/partials/forms/settings/import.html', []).run(['$templateCache', function($templateCache) {
'use strict';
$templateCache.put('views/partials/forms/settings/import.html',
'<div ng-controller="ImportCtrl"><div class="row"><div class="col-xs-12"><label>Import type<select ng-init="importerType" ng-model="importerType" ng-change="setImporter(importerType)"><option ng-repeat="importer in available_importers" value="{{importer}}">{{importer.name}}</option></select></label><div><b>{{selectedImporter.description}}</b></div><input ng-if="selectedImporter" type="file" file-select success="fileLoaded" error="fileLoadError" progress="fileSelectProgress"><br><button class="button" ng-click="startImport()" ng-if="selectedImporter">Import</button></div></div></div>');
'<div ng-controller="ImportCtrl"><div class="row"><div class="col-xs-6"><label>Import type<select ng-init="importerType" ng-model="importerType" ng-change="setImporter(importerType)"><option ng-repeat="importer in available_importers" value="{{importer}}">{{importer.name}}</option></select></label><div><b>{{selectedImporter.description}}</b></div><input ng-if="selectedImporter" type="file" file-select success="fileLoaded" error="fileLoadError" progress="fileSelectProgress"><br><button class="button" ng-click="startImport()" ng-if="selectedImporter">Import</button><div ng-if="current_import_length">{{ current_import_index }} / {{ current_import_length - 1}}</div></div><div class="col-xs-6"><div ng-if="log" class="import_log"><textarea id="import_log" auto-scroll="log">{{log.join(\'\\n\')}}</textarea></div></div></div></div>');
}]);
angular.module('views/partials/forms/settings/sharing.html', []).run(['$templateCache', function($templateCache) {
@ -107,7 +107,7 @@ angular.module('views/share_credential.html', []).run(['$templateCache', functio
angular.module('views/show_vault.html', []).run(['$templateCache', function($templateCache) {
'use strict';
$templateCache.put('views/show_vault.html',
'<div id="controls"><div class="breadcrumb"><div class="breadcrumb"><div class="crumb svg ui-droppable" data-dir="/"><a><i class="fa fa-home"></i></a></div><div class="crumb svg last"><a>{{active_vault.name}}</a></div></div></div><div class="actions creatable"><span ng-click="menuOpen = !menuOpen" class="button new" ng-init="menuOpen = false" off-click="menuOpen = false;"><span>+</span></span><div class="actionList popovermenu bubble menu" ng-show="menuOpen"><ul><li><span ng-click="addCredential()" class="menuitem action"><span class="icon icon-rename"></span> <span>New credential</span></span></li><li><span href="#" class="menuitem action"><span class="icon icon-shared"></span> <span>New shared credential</span></span>w</li></ul></div><div class="searchboxContainer"><input type="text" ng-model="itemFilter.label" class="searchbox" placeholder="Search credential..."></div><span class="title" ng-if="delete_time">Showing deleted since: <span ng-if="delete_time == 1">All time</span> <span ng-if="delete_time > 1">{{delete_time | date:\'dd-MM-yyyy @ HH:mm:ss\'}}</span></span></div></div><div off-click="closeSelected()"><table class="credential-table" ng-init="menuOpen = false;"><tr ng-repeat="credential in credentials | filter:itemFilter | tagFilter:selectedtags | as:this:\'filtered_credentials\'" ng-if="credential.hidden == 0 && showCredentialRow(credential)" ng-click="selectCredential(credential)" ng-class="{\'selected\': selectedCredential.credential_id == credential.credential_id}"><td><span class="icon"><i class="fa fa-lock"></i></span> <span class="label">{{credential.label}}</span> <span class="tags"><span class="tag" ng-repeat="tag in credential.tags_raw">{{tag.text}}</span></span></td></tr></table><div id="app-sidebar" class="detailsView scroll-container app_sidebar" ng-show="selectedCredential"><span class="close icon-close" ng-click="closeSelected()" alt="Close"></span><table><tr ng-show="selectedCredential.label"><td>Label</td><td>{{selectedCredential.label}}</td></tr><tr ng-show="selectedCredential.username"><td>Account</td><td><span credential-field value="selectedCredential.username"></span></td></tr><tr ng-show="selectedCredential.password"><td>Password</td><td><span credential-field value="selectedCredential.password" secret="\'true\'"></span></td></tr><tr ng-show="selectedCredential.otp.secret"><td>OTP</td><td><span otp-generator secret="selectedCredential.otp.secret"></span></td></tr><tr ng-show="selectedCredential.email"><td>E-mail</td><td><span credential-field value="selectedCredential.email"></span></td></tr><tr ng-show="selectedCredential.url"><td>URL</td><td><span credential-field value="selectedCredential.url"></span></td></tr><tr ng-show="selectedCredential.files.length > 0"><td>Files</td><td><div ng-repeat="file in selectedCredential.files" class="link" ng-click="downloadFile(file)">{{file.filename}} ({{file.size | bytes}})</div></td></tr><tr ng-repeat="field in selectedCredential.custom_fields"><td>{{field.label}}</td><td><span credential-field value="field.value" secret="field.secret"></span></td></tr><tr ng-show="selectedCredential.expire_time > 0"><td>Expire time</td><td>{{selectedCredential.expire_time * 1000 | date:\'dd-MM-yyyy @ HH:mm:ss\'}}</td></tr><tr ng-show="selectedCredential.changed"><td>Changed</td><td>{{selectedCredential.changed * 1000 | date:\'dd-MM-yyyy @ HH:mm:ss\'}}</td></tr><tr ng-show="selectedCredential.created"><td>Created</td><td>{{selectedCredential.created * 1000 | date:\'dd-MM-yyyy @ HH:mm:ss\'}}</td></tr></table><div class="tags"><span class="tag" ng-repeat="tag in selectedCredential.tags">{{tag.text}}</span></div><div ng-show="selectedCredential"><button class="button" ng-click="editCredential(selectedCredential)" ng-if="selectedCredential.delete_time == 0"><span class="fa fa-edit"></span> Edit</button> <button class="button" ng-click="deleteCredential(selectedCredential)" ng-if="selectedCredential.delete_time == 0"><span class="fa fa-trash"></span> Delete</button> <button class="button" ng-click="shareCredential(selectedCredential)" ng-if="selectedCredential.delete_time == 0"><span class="fa fa-share"></span> Share</button> <button class="button" ng-click="getRevisions(selectedCredential)" ng-if="selectedCredential.delete_time == 0"><span class="fa fa-undo"></span> Revisions</button> <button class="button" ng-if="selectedCredential.delete_time > 0" ng-click="recoverCredential(selectedCredential)"><span class="fa fa-recycle"></span> Recover</button> <button class="button" ng-if="selectedCredential.delete_time > 0" ng-click="destroyCredential(selectedCredential)"><span class="fa fa-bomb"></span> Destroy</button></div></div></div>');
'<div id="controls"><div class="breadcrumb"><div class="breadcrumb"><div class="crumb svg ui-droppable" data-dir="/"><a><i class="fa fa-home"></i></a></div><div class="crumb svg last"><a>{{active_vault.name}}</a></div></div></div><div class="actions creatable"><span ng-click="menuOpen = !menuOpen" class="button new" ng-init="menuOpen = false" off-click="menuOpen = false;"><span>+</span></span><div class="actionList popovermenu bubble menu" ng-show="menuOpen"><ul><li><span ng-click="addCredential()" class="menuitem action"><span class="icon icon-rename"></span> <span>New credential</span></span></li><li><span href="#" class="menuitem action"><span class="icon icon-shared"></span> <span>New shared credential</span></span>w</li></ul></div><div class="searchboxContainer"><input type="text" ng-model="filterOptions.filterText" class="searchbox" placeholder="Search credential..."></div><span class="title" ng-if="delete_time">Showing deleted since: <span ng-if="delete_time == 1">All time</span> <span ng-if="delete_time > 1">{{delete_time | date:\'dd-MM-yyyy @ HH:mm:ss\'}}</span></span></div></div><div off-click="closeSelected()"><table class="credential-table" ng-init="menuOpen = false;"><tr ng-repeat="credential in credentials | credentialSearch:filterOptions | tagFilter:selectedtags | as:this:\'filtered_credentials\'" ng-if="credential.hidden == 0 && showCredentialRow(credential)" ng-click="selectCredential(credential)" ng-class="{\'selected\': selectedCredential.credential_id == credential.credential_id}"><td><span class="icon"><i class="fa fa-lock"></i></span> <span class="label">{{credential.label}}</span> <span class="tags"><span class="tag" ng-repeat="tag in credential.tags_raw">{{tag.text}}</span></span></td></tr></table><div id="app-sidebar" class="detailsView scroll-container app_sidebar" ng-show="selectedCredential"><span class="close icon-close" ng-click="closeSelected()" alt="Close"></span><table><tr ng-show="selectedCredential.label"><td>Label</td><td>{{selectedCredential.label}}</td></tr><tr ng-show="selectedCredential.username"><td>Account</td><td><span credential-field value="selectedCredential.username"></span></td></tr><tr ng-show="selectedCredential.password"><td>Password</td><td><span credential-field value="selectedCredential.password" secret="\'true\'"></span></td></tr><tr ng-show="selectedCredential.otp.secret"><td>OTP</td><td><span otp-generator secret="selectedCredential.otp.secret"></span></td></tr><tr ng-show="selectedCredential.email"><td>E-mail</td><td><span credential-field value="selectedCredential.email"></span></td></tr><tr ng-show="selectedCredential.url"><td>URL</td><td><span credential-field value="selectedCredential.url"></span></td></tr><tr ng-show="selectedCredential.files.length > 0"><td>Files</td><td><div ng-repeat="file in selectedCredential.files" class="link" ng-click="downloadFile(file)">{{file.filename}} ({{file.size | bytes}})</div></td></tr><tr ng-repeat="field in selectedCredential.custom_fields"><td>{{field.label}}</td><td><span credential-field value="field.value" secret="field.secret"></span></td></tr><tr ng-show="selectedCredential.expire_time > 0"><td>Expire time</td><td>{{selectedCredential.expire_time * 1000 | date:\'dd-MM-yyyy @ HH:mm:ss\'}}</td></tr><tr ng-show="selectedCredential.changed"><td>Changed</td><td>{{selectedCredential.changed * 1000 | date:\'dd-MM-yyyy @ HH:mm:ss\'}}</td></tr><tr ng-show="selectedCredential.created"><td>Created</td><td>{{selectedCredential.created * 1000 | date:\'dd-MM-yyyy @ HH:mm:ss\'}}</td></tr></table><div class="tags"><span class="tag" ng-repeat="tag in selectedCredential.tags">{{tag.text}}</span></div><div ng-show="selectedCredential"><button class="button" ng-click="editCredential(selectedCredential)" ng-if="selectedCredential.delete_time == 0"><span class="fa fa-edit"></span> Edit</button> <button class="button" ng-click="deleteCredential(selectedCredential)" ng-if="selectedCredential.delete_time == 0"><span class="fa fa-trash"></span> Delete</button> <button class="button" ng-click="shareCredential(selectedCredential)" ng-if="selectedCredential.delete_time == 0"><span class="fa fa-share"></span> Share</button> <button class="button" ng-click="getRevisions(selectedCredential)" ng-if="selectedCredential.delete_time == 0"><span class="fa fa-undo"></span> Revisions</button> <button class="button" ng-if="selectedCredential.delete_time > 0" ng-click="recoverCredential(selectedCredential)"><span class="fa fa-recycle"></span> Recover</button> <button class="button" ng-if="selectedCredential.delete_time > 0" ng-click="destroyCredential(selectedCredential)"><span class="fa fa-bomb"></span> Destroy</button></div></div></div>');
}]);
angular.module('views/vaults.html', []).run(['$templateCache', function($templateCache) {

View file

@ -4,4 +4,13 @@
padding-left: 0px;
padding-right: 15px;
}
}
.import_log {
max-height: 600px;
overflow-y: auto;
textarea{
width: 90%;
height: 200px;
}
}

View file

@ -42,6 +42,7 @@ script('passman', 'app/filters/propsfilter');
script('passman', 'app/filters/byte');
script('passman', 'app/filters/tagfilter');
script('passman', 'app/filters/as');
script('passman', 'app/filters/credentialsearch');
script('passman', 'app/services/cacheservice');
script('passman', 'app/services/vaultservice');
script('passman', 'app/services/credentialservice');
@ -60,10 +61,13 @@ script('passman', 'app/directives/tooltip');
script('passman', 'app/directives/use-theme');
script('passman', 'app/directives/credentialfield');
script('passman', 'app/directives/ngenter');
script('passman', 'app/directives/autoscroll');
script('passman', 'importers/import-main');
script('passman', 'importers/importer-keepasscsv');
script('passman', 'importers/importer-lastpasscsv');
script('passman', 'importers/importer-dashlanecsv');
script('passman', 'importers/importer-zohocsv');
script('passman', 'importers/importer-passmanjson');
/*
* Styles

View file

@ -1,15 +1,29 @@
<div ng-controller="ImportCtrl">
<div class="row">
<div class="col-xs-12" >
<div class="col-xs-6">
<label>Import type
<select ng-init="importerType" ng-model="importerType" ng-change="setImporter(importerType)">
<option ng-repeat="importer in available_importers" value="{{importer}}">
{{importer.name}}
</option>
</select></label>
<select ng-init="importerType" ng-model="importerType"
ng-change="setImporter(importerType)">
<option ng-repeat="importer in available_importers"
value="{{importer}}">
{{importer.name}}
</option>
</select></label>
<div><b>{{selectedImporter.description}}</b></div>
<input ng-if="selectedImporter" type="file" file-select success="fileLoaded" error="fileLoadError" progress="fileSelectProgress"><br />
<button class="button" ng-click="startImport()" ng-if="selectedImporter">Import</button>
<input ng-if="selectedImporter" type="file" file-select
success="fileLoaded" error="fileLoadError"
progress="fileSelectProgress"><br/>
<button class="button" ng-click="startImport()"
ng-if="selectedImporter">Import
</button>
<div ng-if="current_import_length">
{{ current_import_index }} / {{ current_import_length - 1}}
</div>
</div>
<div class="col-xs-6">
<div ng-if="log" class="import_log">
<textarea id="import_log" auto-scroll="log">{{log.join('\n')}}</textarea>
</div>
</div>
</div>
</div>

View file

@ -33,7 +33,7 @@
</ul>
</div>
<div class="searchboxContainer">
<input type="text" ng-model="itemFilter.label" class="searchbox"
<input type="text" ng-model="filterOptions.filterText" class="searchbox"
placeholder="Search credential...">
</div>
<span class="title" ng-if="delete_time">
@ -46,7 +46,7 @@
</div>
<div off-click="closeSelected()">
<table class="credential-table" ng-init="menuOpen = false;">
<tr ng-repeat="credential in credentials | filter:itemFilter | tagFilter:selectedtags | as:this:'filtered_credentials'"
<tr ng-repeat="credential in credentials | credentialSearch:filterOptions | tagFilter:selectedtags | as:this:'filtered_credentials'"
ng-if="credential.hidden == 0 && showCredentialRow(credential)"
ng-click="selectCredential(credential)"
ng-class="{'selected': selectedCredential.credential_id == credential.credential_id}">