зеркало из https://github.com/nextcloud/passman.git
Add JSHint, solve all problems
This commit is contained in:
Родитель
e818e40f2f
Коммит
15b32b7e5e
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"maxerr" : 50,
|
||||
"jquery" : true, // jQuery
|
||||
"globals" : {
|
||||
"angular": true,
|
||||
"PassmanImporter": true,
|
||||
"OC": true,
|
||||
"window": true
|
||||
} // additional predefined global variables
|
||||
}
|
27
Gruntfile.js
27
Gruntfile.js
|
@ -25,7 +25,30 @@ module.exports = function (grunt) {
|
|||
dest: 'js/templates.js'
|
||||
}
|
||||
},
|
||||
|
||||
jshint: {
|
||||
options: {
|
||||
curly: false,
|
||||
eqeqeq: true,
|
||||
eqnull: true,
|
||||
browser: true,
|
||||
globals: {
|
||||
"angular": true,
|
||||
"PassmanImporter": true,
|
||||
"OC": true,
|
||||
"window": true,
|
||||
"console": true,
|
||||
"CRYPTO": true,
|
||||
"C_Promise": true,
|
||||
"forge": true,
|
||||
"sjcl": true,
|
||||
"jQuery": true,
|
||||
"$": true,
|
||||
"_": true,
|
||||
"oc_requesttoken": true
|
||||
}
|
||||
},
|
||||
all: ['Gruntfile.js', 'js/app/**/*.js']
|
||||
},
|
||||
sass: {
|
||||
dist: {
|
||||
files: [
|
||||
|
@ -82,7 +105,9 @@ module.exports = function (grunt) {
|
|||
grunt.loadNpmTasks('grunt-contrib-uglify');
|
||||
grunt.loadNpmTasks('grunt-html2js');
|
||||
grunt.loadNpmTasks('grunt-contrib-watch');
|
||||
grunt.loadNpmTasks('grunt-contrib-jshint');
|
||||
// Default task(s).
|
||||
grunt.registerTask('default', ['html2js', 'sass']);
|
||||
grunt.registerTask('hint', ['jshint']);
|
||||
|
||||
};
|
262
js/app/app.js
262
js/app/app.js
|
@ -1,145 +1,147 @@
|
|||
'use strict';
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* @ngdoc overview
|
||||
* @name passmanApp
|
||||
* @description
|
||||
* # passmanApp
|
||||
*
|
||||
* Main module of the application.
|
||||
*/
|
||||
angular
|
||||
.module('passmanApp', [
|
||||
'ngAnimate',
|
||||
'ngCookies',
|
||||
'ngResource',
|
||||
'ngRoute',
|
||||
'ngSanitize',
|
||||
'ngTouch',
|
||||
'templates-main',
|
||||
'LocalStorageModule',
|
||||
'offClick',
|
||||
'ngPasswordMeter',
|
||||
'ngclipboard',
|
||||
'xeditable',
|
||||
'ngTagsInput',
|
||||
'angularjs-datetime-picker'
|
||||
])
|
||||
.config(function ($routeProvider) {
|
||||
$routeProvider
|
||||
.when('/', {
|
||||
templateUrl: 'views/vaults.html',
|
||||
controller: 'VaultCtrl'
|
||||
})
|
||||
.when('/vault/:vault_id', {
|
||||
templateUrl: 'views/show_vault.html',
|
||||
controller: 'CredentialCtrl'
|
||||
})
|
||||
.when('/vault/:vault_id/new', {
|
||||
templateUrl: 'views/edit_credential.html',
|
||||
controller: 'CredentialEditCtrl'
|
||||
})
|
||||
.when('/vault/:vault_id/edit/:credential_id', {
|
||||
templateUrl: 'views/edit_credential.html',
|
||||
controller: 'CredentialEditCtrl'
|
||||
}).when('/vault/:vault_id/:credential_id/share', {
|
||||
/**
|
||||
* @ngdoc overview
|
||||
* @name passmanApp
|
||||
* @description
|
||||
* # passmanApp
|
||||
*
|
||||
* Main module of the application.
|
||||
*/
|
||||
angular
|
||||
.module('passmanApp', [
|
||||
'ngAnimate',
|
||||
'ngCookies',
|
||||
'ngResource',
|
||||
'ngRoute',
|
||||
'ngSanitize',
|
||||
'ngTouch',
|
||||
'templates-main',
|
||||
'LocalStorageModule',
|
||||
'offClick',
|
||||
'ngPasswordMeter',
|
||||
'ngclipboard',
|
||||
'xeditable',
|
||||
'ngTagsInput',
|
||||
'angularjs-datetime-picker'
|
||||
])
|
||||
.config(function ($routeProvider) {
|
||||
$routeProvider
|
||||
.when('/', {
|
||||
templateUrl: 'views/vaults.html',
|
||||
controller: 'VaultCtrl'
|
||||
})
|
||||
.when('/vault/:vault_id', {
|
||||
templateUrl: 'views/show_vault.html',
|
||||
controller: 'CredentialCtrl'
|
||||
})
|
||||
.when('/vault/:vault_id/new', {
|
||||
templateUrl: 'views/edit_credential.html',
|
||||
controller: 'CredentialEditCtrl'
|
||||
})
|
||||
.when('/vault/:vault_id/edit/:credential_id', {
|
||||
templateUrl: 'views/edit_credential.html',
|
||||
controller: 'CredentialEditCtrl'
|
||||
}).when('/vault/:vault_id/:credential_id/share', {
|
||||
templateUrl: 'views/share_credential.html',
|
||||
controller: 'ShareCtrl'
|
||||
}).when('/vault/:vault_id/:credential_id/revisions', {
|
||||
templateUrl: 'views/credential_revisions.html',
|
||||
controller: 'RevisionCtrl'
|
||||
})
|
||||
.when('/vault/:vault_id/settings', {
|
||||
templateUrl: 'views/settings.html',
|
||||
controller: 'SettingsCtrl'
|
||||
})
|
||||
.otherwise({
|
||||
redirectTo: '/'
|
||||
});
|
||||
}).config(['$httpProvider', function ($httpProvider) {
|
||||
$httpProvider.defaults.headers.common.requesttoken = oc_requesttoken;
|
||||
}]).config(function (localStorageServiceProvider) {
|
||||
localStorageServiceProvider
|
||||
.setNotify(true, true);
|
||||
});
|
||||
.when('/vault/:vault_id/settings', {
|
||||
templateUrl: 'views/settings.html',
|
||||
controller: 'SettingsCtrl'
|
||||
})
|
||||
.otherwise({
|
||||
redirectTo: '/'
|
||||
});
|
||||
}).config(['$httpProvider', function ($httpProvider) {
|
||||
$httpProvider.defaults.headers.common.requesttoken = oc_requesttoken;
|
||||
}]).config(function (localStorageServiceProvider) {
|
||||
localStorageServiceProvider
|
||||
.setNotify(true, true);
|
||||
});
|
||||
|
||||
/**
|
||||
* jQuery for notification handling D:
|
||||
**/
|
||||
jQuery(document).ready(function () {
|
||||
var findItemByID = function(id){
|
||||
var credentials,foundItem=false;
|
||||
credentials = angular.element('#app-content-wrapper').scope().credentials;
|
||||
console.log(id, credentials)
|
||||
angular.forEach(credentials, function(credential){
|
||||
if(credential.credential_id == id){
|
||||
foundItem = credential;
|
||||
}
|
||||
/**
|
||||
* jQuery for notification handling D:
|
||||
**/
|
||||
jQuery(document).ready(function () {
|
||||
var findItemByID = function (id) {
|
||||
var credentials, foundItem = false;
|
||||
credentials = angular.element('#app-content-wrapper').scope().credentials;
|
||||
angular.forEach(credentials, function (credential) {
|
||||
if (credential.credential_id === id) {
|
||||
foundItem = credential;
|
||||
}
|
||||
});
|
||||
return foundItem;
|
||||
};
|
||||
jQuery(document).on('click', '.undoDelete', function () {
|
||||
var credential = findItemByID($(this).attr('data-item-id'));
|
||||
angular.element('#app-content-wrapper').scope().recoverCredential(credential);
|
||||
//Outside anglular we need $apply
|
||||
angular.element('#app-content-wrapper').scope().$apply();
|
||||
});
|
||||
return foundItem;
|
||||
};
|
||||
jQuery(document).on('click', '.undoDelete', function () {
|
||||
var credential = findItemByID($(this).attr('data-item-id'));
|
||||
angular.element('#app-content-wrapper').scope().recoverCredential(credential);
|
||||
//Outside anglular we need $apply
|
||||
angular.element('#app-content-wrapper').scope().$apply();
|
||||
});
|
||||
jQuery(document).on('click', '.undoRestore', function () {
|
||||
var credential = findItemByID($(this).attr('data-item-id'));
|
||||
angular.element('#app-content-wrapper').scope().deleteCredential(credential);
|
||||
//Outside anglular we need $apply
|
||||
angular.element('#app-content-wrapper').scope().$apply();
|
||||
});
|
||||
var adjustControlsWidth = function(r) {
|
||||
if($('#controls').length) {
|
||||
var controlsWidth;
|
||||
// if there is a scrollbar …
|
||||
if($('#app-content').get(0)) {
|
||||
if ($('#app-content').get(0).scrollHeight > $('#app-content').height()) {
|
||||
if ($(window).width() > 768) {
|
||||
controlsWidth = $('#content').width() - $('#app-navigation').width() - OC.Util.getScrollBarWidth();
|
||||
if (!$('#app-sidebar').hasClass('hidden') && !$('#app-sidebar').hasClass('disappear')) {
|
||||
controlsWidth -= $('#app-sidebar').width();
|
||||
jQuery(document).on('click', '.undoRestore', function () {
|
||||
var credential = findItemByID($(this).attr('data-item-id'));
|
||||
angular.element('#app-content-wrapper').scope().deleteCredential(credential);
|
||||
//Outside anglular we need $apply
|
||||
angular.element('#app-content-wrapper').scope().$apply();
|
||||
});
|
||||
var adjustControlsWidth = function (r) {
|
||||
if ($('#controls').length) {
|
||||
var controlsWidth;
|
||||
// if there is a scrollbar …
|
||||
if ($('#app-content').get(0)) {
|
||||
if ($('#app-content').get(0).scrollHeight > $('#app-content').height()) {
|
||||
if ($(window).width() > 768) {
|
||||
controlsWidth = $('#content').width() - $('#app-navigation').width() - OC.Util.getScrollBarWidth();
|
||||
if (!$('#app-sidebar').hasClass('hidden') && !$('#app-sidebar').hasClass('disappear')) {
|
||||
controlsWidth -= $('#app-sidebar').width();
|
||||
}
|
||||
} else {
|
||||
controlsWidth = $('#content').width() - OC.Util.getScrollBarWidth();
|
||||
}
|
||||
} else {
|
||||
controlsWidth = $('#content').width() - OC.Util.getScrollBarWidth();
|
||||
}
|
||||
} else { // if there is none
|
||||
if ($(window).width() > 768) {
|
||||
controlsWidth = $('#content').width() - $('#app-navigation').width();
|
||||
if (!$('#app-sidebar').hasClass('hidden') && !$('#app-sidebar').hasClass('disappear')) {
|
||||
//controlsWidth -= $('#app-sidebar').width();
|
||||
} else { // if there is none
|
||||
if ($(window).width() > 768) {
|
||||
controlsWidth = $('#content').width() - $('#app-navigation').width();
|
||||
if (!$('#app-sidebar').hasClass('hidden') && !$('#app-sidebar').hasClass('disappear')) {
|
||||
//controlsWidth -= $('#app-sidebar').width();
|
||||
}
|
||||
} else {
|
||||
controlsWidth = $('#content').width();
|
||||
}
|
||||
} else {
|
||||
controlsWidth = $('#content').width();
|
||||
}
|
||||
}
|
||||
var magic;
|
||||
if (r) {
|
||||
magic = 0;
|
||||
} else {
|
||||
magic = 85;
|
||||
}
|
||||
$('#controls').css('width', controlsWidth + magic);
|
||||
$('#controls').css('min-width', controlsWidth + magic);
|
||||
}
|
||||
if(r){
|
||||
var magic = 0;
|
||||
} else {
|
||||
var magic = 85;
|
||||
}
|
||||
$('#controls').css('width', controlsWidth+magic);
|
||||
$('#controls').css('min-width', controlsWidth+magic);
|
||||
}
|
||||
};
|
||||
$(window).resize(_.debounce(adjustControlsWidth, 400));
|
||||
setTimeout(function(){
|
||||
adjustControlsWidth(true)
|
||||
},200);
|
||||
};
|
||||
$(window).resize(_.debounce(adjustControlsWidth, 400));
|
||||
setTimeout(function () {
|
||||
adjustControlsWidth(true);
|
||||
}, 200);
|
||||
|
||||
//@Fack this
|
||||
$(document).on('click', '#app-navigation-toggle', function(){
|
||||
setTimeout(function(){
|
||||
if($('#app-content').css('transform').toString().indexOf('matrix') >= 0){
|
||||
$('#passman-controls').css('width', 'calc( 100% - 245px)');
|
||||
$('#passman-controls').css('top', '0');
|
||||
} else {
|
||||
$('#passman-controls').css('left', 0);
|
||||
$('#passman-controls').css('top', '44px');
|
||||
$('#passman-controls').css('width', '100%');
|
||||
}
|
||||
}, 350);
|
||||
})
|
||||
});
|
||||
//@Fack this
|
||||
$(document).on('click', '#app-navigation-toggle', function () {
|
||||
setTimeout(function () {
|
||||
if ($('#app-content').css('transform').toString().indexOf('matrix') >= 0) {
|
||||
$('#passman-controls').css('width', 'calc( 100% - 245px)');
|
||||
$('#passman-controls').css('top', '0');
|
||||
} else {
|
||||
$('#passman-controls').css('left', 0);
|
||||
$('#passman-controls').css('top', '44px');
|
||||
$('#passman-controls').css('width', '100%');
|
||||
}
|
||||
}, 350);
|
||||
});
|
||||
});
|
||||
}());
|
|
@ -1,14 +1,17 @@
|
|||
'use strict';
|
||||
angular
|
||||
.module('passmanApp', [
|
||||
'ngAnimate',
|
||||
'ngCookies',
|
||||
'ngResource',
|
||||
'ngRoute',
|
||||
'ngSanitize',
|
||||
'ngTouch',
|
||||
'ngclipboard',
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
]).config(['$httpProvider', function ($httpProvider) {
|
||||
$httpProvider.defaults.headers.common.requesttoken = oc_requesttoken;
|
||||
}]);
|
||||
angular
|
||||
.module('passmanApp', [
|
||||
'ngAnimate',
|
||||
'ngCookies',
|
||||
'ngResource',
|
||||
'ngRoute',
|
||||
'ngSanitize',
|
||||
'ngTouch',
|
||||
'ngclipboard',
|
||||
|
||||
]).config(['$httpProvider', function ($httpProvider) {
|
||||
$httpProvider.defaults.headers.common.requesttoken = oc_requesttoken;
|
||||
}]);
|
||||
}());
|
|
@ -1,360 +1,363 @@
|
|||
'use strict';
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* @ngdoc function
|
||||
* @name passmanApp.controller:MainCtrl
|
||||
* @description
|
||||
* # MainCtrl
|
||||
* Controller of the passmanApp
|
||||
*/
|
||||
angular.module('passmanApp')
|
||||
.controller('BookmarkletCtrl', ['$scope', '$rootScope', '$location', 'VaultService', 'CredentialService', 'SettingsService', 'NotificationService', 'EncryptService', 'TagService', 'FileService',
|
||||
function ($scope, $rootScope, $location, VaultService, CredentialService, SettingsService, NotificationService, EncryptService, TagService, FileService) {
|
||||
$scope.active_vault = false;
|
||||
|
||||
$scope.http_warning_hidden = true;
|
||||
if ($location.$$protocol === 'http') {
|
||||
$scope.using_http = true;
|
||||
//$scope.http_warning_hidden = false;
|
||||
|
||||
}
|
||||
|
||||
$scope.logout = function () {
|
||||
/**
|
||||
* @ngdoc function
|
||||
* @name passmanApp.controller:MainCtrl
|
||||
* @description
|
||||
* # MainCtrl
|
||||
* Controller of the passmanApp
|
||||
*/
|
||||
angular.module('passmanApp')
|
||||
.controller('BookmarkletCtrl', ['$scope', '$rootScope', '$location', 'VaultService', 'CredentialService', 'SettingsService', 'NotificationService', 'EncryptService', 'TagService', 'FileService',
|
||||
function ($scope, $rootScope, $location, VaultService, CredentialService, SettingsService, NotificationService, EncryptService, TagService, FileService) {
|
||||
$scope.active_vault = false;
|
||||
};
|
||||
if (SettingsService.getSetting('defaultVault') && SettingsService.getSetting('defaultVaultPass')) {
|
||||
var _vault = angular.copy(SettingsService.getSetting('defaultVault'));
|
||||
VaultService.getVault(_vault).then(function (vault) {
|
||||
vault.vaultKey = angular.copy(SettingsService.getSetting('defaultVaultPass'));
|
||||
VaultService.setActiveVault(vault);
|
||||
$scope.active_vault = vault;
|
||||
|
||||
$scope.pwSettings = VaultService.getVaultSetting('pwSettings',
|
||||
{
|
||||
'length': 12,
|
||||
'useUppercase': true,
|
||||
'useLowercase': true,
|
||||
'useDigits': true,
|
||||
'useSpecialChars': true,
|
||||
'minimumDigitCount': 3,
|
||||
'avoidAmbiguousCharacters': false,
|
||||
'requireEveryCharType': true,
|
||||
'generateOnCreate': true
|
||||
})
|
||||
})
|
||||
}
|
||||
/**
|
||||
* Vault selection stuff
|
||||
*/
|
||||
VaultService.getVaults().then(function (vaults) {
|
||||
$scope.vaults = vaults;
|
||||
$scope.http_warning_hidden = true;
|
||||
if ($location.$$protocol === 'http') {
|
||||
$scope.using_http = true;
|
||||
//$scope.http_warning_hidden = false;
|
||||
|
||||
});
|
||||
$scope.default_vault = false;
|
||||
$scope.remember_vault_password = false;
|
||||
$scope.list_selected_vault = false;
|
||||
|
||||
|
||||
$scope.toggleDefaultVault = function () {
|
||||
$scope.default_vault = !$scope.default_vault;
|
||||
if ($scope.default_vault == true) {
|
||||
SettingsService.setSetting('defaultVault', $scope.list_selected_vault);
|
||||
} else {
|
||||
SettingsService.setSetting('defaultVault', null);
|
||||
}
|
||||
};
|
||||
|
||||
$scope.toggleRememberPassword = function () {
|
||||
$scope.remember_vault_password = !$scope.remember_vault_password;
|
||||
if ($scope.remember_vault_password) {
|
||||
SettingsService.setSetting('defaultVault', $scope.list_selected_vault);
|
||||
$scope.default_vault = true;
|
||||
$scope.logout = function () {
|
||||
$scope.active_vault = false;
|
||||
};
|
||||
if (SettingsService.getSetting('defaultVault') && SettingsService.getSetting('defaultVaultPass')) {
|
||||
var _vault = angular.copy(SettingsService.getSetting('defaultVault'));
|
||||
VaultService.getVault(_vault).then(function (vault) {
|
||||
vault.vaultKey = angular.copy(SettingsService.getSetting('defaultVaultPass'));
|
||||
VaultService.setActiveVault(vault);
|
||||
$scope.active_vault = vault;
|
||||
|
||||
$scope.pwSettings = VaultService.getVaultSetting('pwSettings',
|
||||
{
|
||||
'length': 12,
|
||||
'useUppercase': true,
|
||||
'useLowercase': true,
|
||||
'useDigits': true,
|
||||
'useSpecialChars': true,
|
||||
'minimumDigitCount': 3,
|
||||
'avoidAmbiguousCharacters': false,
|
||||
'requireEveryCharType': true,
|
||||
'generateOnCreate': true
|
||||
});
|
||||
});
|
||||
}
|
||||
if ($scope.remember_vault_password != true) {
|
||||
SettingsService.setSetting('defaultVault', null);
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Vault selection stuff
|
||||
*/
|
||||
VaultService.getVaults().then(function (vaults) {
|
||||
$scope.vaults = vaults;
|
||||
|
||||
$scope.clearState = function () {
|
||||
$scope.list_selected_vault = false;
|
||||
$scope.creating_vault = false;
|
||||
$scope.error = false;
|
||||
};
|
||||
|
||||
$scope.selectVault = function (vault) {
|
||||
$scope.list_selected_vault = vault;
|
||||
};
|
||||
$scope.sharing_keys = {};
|
||||
$scope.newVault = function () {
|
||||
$scope.creating_vault = true;
|
||||
var _vault = {};
|
||||
var key_size = 1024;
|
||||
ShareService.generateRSAKeys(key_size).progress(function (progress) {
|
||||
var p = progress > 0 ? 2 : 1;
|
||||
$scope.creating_keys = 'Generating sharing keys (' + p + ' / 2)';
|
||||
$scope.$digest();
|
||||
}).then(function (kp) {
|
||||
var pem = ShareService.rsaKeyPairToPEM(kp);
|
||||
$scope.creating_keys = false;
|
||||
$scope.sharing_keys.private_sharing_key = pem.privateKey;
|
||||
$scope.sharing_keys.public_sharing_key = pem.publicKey;
|
||||
$scope.$digest();
|
||||
});
|
||||
$scope.default_vault = false;
|
||||
$scope.remember_vault_password = false;
|
||||
$scope.list_selected_vault = false;
|
||||
|
||||
};
|
||||
|
||||
var _loginToVault = function (vault, vault_key) {
|
||||
var _vault = angular.copy(vault);
|
||||
_vault.vaultKey = angular.copy(vault_key);
|
||||
delete _vault.credentials;
|
||||
$scope.active_vault = _vault;
|
||||
|
||||
};
|
||||
|
||||
$scope.vaultDecryptionKey = '';
|
||||
$scope.loginToVault = function (vault, vault_key) {
|
||||
$scope.error = false;
|
||||
var _vault = angular.copy(vault);
|
||||
_vault.vaultKey = angular.copy(vault_key);
|
||||
|
||||
VaultService.setActiveVault(_vault);
|
||||
try {
|
||||
var c = EncryptService.decryptString(vault.challenge_password);
|
||||
if ($scope.remember_vault_password) {
|
||||
SettingsService.setSetting('defaultVaultPass', vault_key);
|
||||
$scope.toggleDefaultVault = function () {
|
||||
$scope.default_vault = !$scope.default_vault;
|
||||
if ($scope.default_vault === true) {
|
||||
SettingsService.setSetting('defaultVault', $scope.list_selected_vault);
|
||||
} else {
|
||||
SettingsService.setSetting('defaultVault', null);
|
||||
}
|
||||
_loginToVault(vault, vault_key);
|
||||
};
|
||||
|
||||
} catch (e) {
|
||||
$scope.error = 'Incorrect vault password!'
|
||||
}
|
||||
$scope.toggleRememberPassword = function () {
|
||||
$scope.remember_vault_password = !$scope.remember_vault_password;
|
||||
if ($scope.remember_vault_password) {
|
||||
SettingsService.setSetting('defaultVault', $scope.list_selected_vault);
|
||||
$scope.default_vault = true;
|
||||
}
|
||||
if ($scope.remember_vault_password !== true) {
|
||||
SettingsService.setSetting('defaultVault', null);
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
$scope.clearState = function () {
|
||||
$scope.list_selected_vault = false;
|
||||
$scope.creating_vault = false;
|
||||
$scope.error = false;
|
||||
};
|
||||
|
||||
$scope.selectVault = function (vault) {
|
||||
$scope.list_selected_vault = vault;
|
||||
};
|
||||
$scope.sharing_keys = {};
|
||||
$scope.newVault = function () {
|
||||
$scope.creating_vault = true;
|
||||
var _vault = {};
|
||||
var key_size = 1024;
|
||||
ShareService.generateRSAKeys(key_size).progress(function (progress) {
|
||||
var p = progress > 0 ? 2 : 1;
|
||||
$scope.creating_keys = 'Generating sharing keys (' + p + ' / 2)';
|
||||
$scope.$digest();
|
||||
}).then(function (kp) {
|
||||
var pem = ShareService.rsaKeyPairToPEM(kp);
|
||||
$scope.creating_keys = false;
|
||||
$scope.sharing_keys.private_sharing_key = pem.privateKey;
|
||||
$scope.sharing_keys.public_sharing_key = pem.publicKey;
|
||||
$scope.$digest();
|
||||
});
|
||||
|
||||
$scope.createVault = function (vault_name, vault_key, vault_key2) {
|
||||
if (vault_key != vault_key2) {
|
||||
$scope.error = 'Passwords do not match';
|
||||
return;
|
||||
}
|
||||
VaultService.createVault(vault_name).then(function (vault) {
|
||||
$scope.vaults.push(vault);
|
||||
};
|
||||
|
||||
var _loginToVault = function (vault, vault_key) {
|
||||
var _vault = angular.copy(vault);
|
||||
_vault.vaultKey = angular.copy(vault_key);
|
||||
VaultService.setActiveVault(_vault);
|
||||
var test_credential = CredentialService.newCredential();
|
||||
test_credential.label = 'Test key for vault ' + vault_name;
|
||||
test_credential.hidden = true;
|
||||
test_credential.vault_id = vault.vault_id;
|
||||
test_credential.password = 'lorum ipsum';
|
||||
CredentialService.createCredential(test_credential).then(function (result) {
|
||||
_vault.public_sharing_key = angular.copy($scope.sharing_keys.public_sharing_key);
|
||||
_vault.private_sharing_key = EncryptService.encryptString(angular.copy($scope.sharing_keys.private_sharing_key));
|
||||
VaultService.updateSharingKeys(_vault).then(function (result) {
|
||||
_loginToVault(vault, vault_key);
|
||||
})
|
||||
})
|
||||
});
|
||||
};
|
||||
delete _vault.credentials;
|
||||
$scope.active_vault = _vault;
|
||||
|
||||
};
|
||||
|
||||
$scope.vaultDecryptionKey = '';
|
||||
$scope.loginToVault = function (vault, vault_key) {
|
||||
$scope.error = false;
|
||||
var _vault = angular.copy(vault);
|
||||
_vault.vaultKey = angular.copy(vault_key);
|
||||
|
||||
VaultService.setActiveVault(_vault);
|
||||
try {
|
||||
var c = EncryptService.decryptString(vault.challenge_password);
|
||||
if ($scope.remember_vault_password) {
|
||||
SettingsService.setSetting('defaultVaultPass', vault_key);
|
||||
}
|
||||
_loginToVault(vault, vault_key);
|
||||
|
||||
} catch (e) {
|
||||
$scope.error = 'Incorrect vault password!';
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* End vault selection stiff
|
||||
*/
|
||||
$scope.storedCredential = CredentialService.newCredential();
|
||||
|
||||
var QueryString = function () {
|
||||
// This function is anonymous, is executed immediately and
|
||||
// the return value is assigned to QueryString!
|
||||
var query_string = {};
|
||||
var query = window.location.search.substring(1);
|
||||
var vars = query.split("&");
|
||||
for (var i = 0; i < vars.length; i++) {
|
||||
var pair = vars[i].split("=");
|
||||
// If first entry with this name
|
||||
if (typeof query_string[pair[0]] === "undefined") {
|
||||
query_string[pair[0]] = decodeURIComponent(pair[1]);
|
||||
// If second entry with this name
|
||||
} else if (typeof query_string[pair[0]] === "string") {
|
||||
var arr = [query_string[pair[0]], decodeURIComponent(pair[1])];
|
||||
query_string[pair[0]] = arr;
|
||||
// If third or later entry with this name
|
||||
} else {
|
||||
query_string[pair[0]].push(decodeURIComponent(pair[1]));
|
||||
}
|
||||
}
|
||||
return query_string;
|
||||
}();
|
||||
var query_string = QueryString;
|
||||
$scope.storedCredential.label = query_string.title
|
||||
$scope.storedCredential.url = query_string.url
|
||||
|
||||
$scope.setHttpWarning = function (state) {
|
||||
$scope.http_warning_hidden = state;
|
||||
};
|
||||
|
||||
$scope.currentTab = {
|
||||
title: 'General',
|
||||
url: 'views/partials/forms/edit_credential/basics.html',
|
||||
color: 'blue'
|
||||
};
|
||||
|
||||
$scope.tabs = [{
|
||||
title: 'General',
|
||||
url: 'views/partials/forms/edit_credential/basics.html',
|
||||
color: 'blue'
|
||||
}, {
|
||||
title: 'Password',
|
||||
url: 'views/partials/forms/edit_credential/password.html',
|
||||
color: 'green'
|
||||
}, {
|
||||
title: 'Custom fields',
|
||||
url: 'views/partials/forms/edit_credential/custom_fields.html',
|
||||
color: 'orange'
|
||||
}, {
|
||||
title: 'Files',
|
||||
url: 'views/partials/forms/edit_credential/files.html',
|
||||
color: 'yellow'
|
||||
}, {
|
||||
title: 'OTP',
|
||||
url: 'views/partials/forms/edit_credential/otp.html',
|
||||
color: 'purple'
|
||||
}];
|
||||
|
||||
|
||||
$scope.getTags = function ($query) {
|
||||
return TagService.searchTag($query);
|
||||
};
|
||||
|
||||
$scope.currentTab = {
|
||||
title: 'General',
|
||||
url: 'views/partials/forms/edit_credential/basics.html',
|
||||
color: 'blue'
|
||||
};
|
||||
|
||||
$scope.onClickTab = function (tab) {
|
||||
$scope.currentTab = tab;
|
||||
};
|
||||
|
||||
$scope.isActiveTab = function (tab) {
|
||||
return tab.url == $scope.currentTab.url;
|
||||
};
|
||||
|
||||
/**
|
||||
* Below general edit functions
|
||||
*/
|
||||
|
||||
$scope.pwGenerated = function (pass) {
|
||||
$scope.storedCredential.password_repeat = pass;
|
||||
};
|
||||
|
||||
var _customField = {
|
||||
label: '',
|
||||
value: '',
|
||||
secret: false
|
||||
};
|
||||
$scope.new_custom_field = angular.copy(_customField);
|
||||
|
||||
$scope.addCustomField = function () {
|
||||
if (!$scope.new_custom_field.label) {
|
||||
NotificationService.showNotification('Please fill in a label', 3000);
|
||||
}
|
||||
if (!$scope.new_custom_field.value) {
|
||||
NotificationService.showNotification('Please fill in a value!', 3000);
|
||||
}
|
||||
if (!$scope.new_custom_field.label || !$scope.new_custom_field.value) {
|
||||
return;
|
||||
}
|
||||
$scope.storedCredential.custom_fields.push(angular.copy($scope.new_custom_field));
|
||||
$scope.new_custom_field = angular.copy(_customField);
|
||||
};
|
||||
|
||||
$scope.deleteCustomField = function (field) {
|
||||
var idx = $scope.storedCredential.custom_fields.indexOf(field);
|
||||
$scope.storedCredential.custom_fields.splice(idx, 1);
|
||||
};
|
||||
|
||||
$scope.new_file = {
|
||||
name: '',
|
||||
data: null
|
||||
};
|
||||
|
||||
$scope.deleteFile = function (file) {
|
||||
var idx = $scope.storedCredential.files.indexOf(file);
|
||||
FileService.deleteFile(file).then(function () {
|
||||
$scope.storedCredential.files.splice(idx, 1);
|
||||
});
|
||||
};
|
||||
|
||||
$scope.fileLoaded = function (file) {
|
||||
var _file = {
|
||||
filename: file.name,
|
||||
size: file.size,
|
||||
mimetype: file.type,
|
||||
data: file.data
|
||||
};
|
||||
FileService.uploadFile(_file).then(function (result) {
|
||||
delete result.file_data;
|
||||
result.filename = EncryptService.decryptString(result.filename);
|
||||
$scope.storedCredential.files.push(result);
|
||||
});
|
||||
|
||||
|
||||
$scope.$digest()
|
||||
};
|
||||
$scope.createVault = function (vault_name, vault_key, vault_key2) {
|
||||
if (vault_key !== vault_key2) {
|
||||
$scope.error = 'Passwords do not match';
|
||||
return;
|
||||
}
|
||||
VaultService.createVault(vault_name).then(function (vault) {
|
||||
$scope.vaults.push(vault);
|
||||
var _vault = angular.copy(vault);
|
||||
_vault.vaultKey = angular.copy(vault_key);
|
||||
VaultService.setActiveVault(_vault);
|
||||
var test_credential = CredentialService.newCredential();
|
||||
test_credential.label = 'Test key for vault ' + vault_name;
|
||||
test_credential.hidden = true;
|
||||
test_credential.vault_id = vault.vault_id;
|
||||
test_credential.password = 'lorum ipsum';
|
||||
CredentialService.createCredential(test_credential).then(function (result) {
|
||||
_vault.public_sharing_key = angular.copy($scope.sharing_keys.public_sharing_key);
|
||||
_vault.private_sharing_key = EncryptService.encryptString(angular.copy($scope.sharing_keys.private_sharing_key));
|
||||
VaultService.updateSharingKeys(_vault).then(function (result) {
|
||||
_loginToVault(vault, vault_key);
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
$scope.fileLoadError = function (error, file) {
|
||||
console.log(error, file)
|
||||
};
|
||||
|
||||
$scope.selected_file = '';
|
||||
$scope.fileprogress = [];
|
||||
$scope.fileSelectProgress = function (progress) {
|
||||
if (progress) {
|
||||
$scope.fileprogress = progress;
|
||||
$scope.$digest()
|
||||
/**
|
||||
* End vault selection stiff
|
||||
*/
|
||||
$scope.storedCredential = CredentialService.newCredential();
|
||||
|
||||
}
|
||||
};
|
||||
$scope.renewIntervalValue = 0;
|
||||
$scope.renewIntervalModifier = '0';
|
||||
var QueryString = function () {
|
||||
// This function is anonymous, is executed immediately and
|
||||
// the return value is assigned to QueryString!
|
||||
var query_string = {};
|
||||
var query = window.location.search.substring(1);
|
||||
var vars = query.split("&");
|
||||
for (var i = 0; i < vars.length; i++) {
|
||||
var pair = vars[i].split("=");
|
||||
// If first entry with this name
|
||||
if (typeof query_string[pair[0]] === "undefined") {
|
||||
query_string[pair[0]] = decodeURIComponent(pair[1]);
|
||||
// If second entry with this name
|
||||
} else if (typeof query_string[pair[0]] === "string") {
|
||||
var arr = [query_string[pair[0]], decodeURIComponent(pair[1])];
|
||||
query_string[pair[0]] = arr;
|
||||
// If third or later entry with this name
|
||||
} else {
|
||||
query_string[pair[0]].push(decodeURIComponent(pair[1]));
|
||||
}
|
||||
}
|
||||
return query_string;
|
||||
}();
|
||||
var query_string = QueryString;
|
||||
$scope.storedCredential.label = query_string.title;
|
||||
$scope.storedCredential.url = query_string.url;
|
||||
|
||||
$scope.updateInterval = function (renewIntervalValue, renewIntervalModifier) {
|
||||
var value = parseInt(renewIntervalValue);
|
||||
var modifier = parseInt(renewIntervalModifier);
|
||||
if (value && modifier) {
|
||||
$scope.storedCredential.renew_interval = value * modifier;
|
||||
}
|
||||
};
|
||||
$scope.setHttpWarning = function (state) {
|
||||
$scope.http_warning_hidden = state;
|
||||
};
|
||||
|
||||
$scope.parseQR = function (QRCode) {
|
||||
var re = /otpauth:\/\/(totp|hotp)\/(.*)\?(secret|issuer)=(.*)&(issuer|secret)=(.*)/, parsedQR, qrInfo;
|
||||
parsedQR = (QRCode.qrData.match(re));
|
||||
if (parsedQR)
|
||||
qrInfo = {
|
||||
type: parsedQR[1],
|
||||
label: decodeURIComponent(parsedQR[2]),
|
||||
qr_uri: QRCode
|
||||
$scope.currentTab = {
|
||||
title: 'General',
|
||||
url: 'views/partials/forms/edit_credential/basics.html',
|
||||
color: 'blue'
|
||||
};
|
||||
|
||||
$scope.tabs = [{
|
||||
title: 'General',
|
||||
url: 'views/partials/forms/edit_credential/basics.html',
|
||||
color: 'blue'
|
||||
}, {
|
||||
title: 'Password',
|
||||
url: 'views/partials/forms/edit_credential/password.html',
|
||||
color: 'green'
|
||||
}, {
|
||||
title: 'Custom fields',
|
||||
url: 'views/partials/forms/edit_credential/custom_fields.html',
|
||||
color: 'orange'
|
||||
}, {
|
||||
title: 'Files',
|
||||
url: 'views/partials/forms/edit_credential/files.html',
|
||||
color: 'yellow'
|
||||
}, {
|
||||
title: 'OTP',
|
||||
url: 'views/partials/forms/edit_credential/otp.html',
|
||||
color: 'purple'
|
||||
}];
|
||||
|
||||
|
||||
$scope.getTags = function ($query) {
|
||||
return TagService.searchTag($query);
|
||||
};
|
||||
|
||||
$scope.currentTab = {
|
||||
title: 'General',
|
||||
url: 'views/partials/forms/edit_credential/basics.html',
|
||||
color: 'blue'
|
||||
};
|
||||
|
||||
$scope.onClickTab = function (tab) {
|
||||
$scope.currentTab = tab;
|
||||
};
|
||||
|
||||
$scope.isActiveTab = function (tab) {
|
||||
return tab.url === $scope.currentTab.url;
|
||||
};
|
||||
|
||||
/**
|
||||
* Below general edit functions
|
||||
*/
|
||||
|
||||
$scope.pwGenerated = function (pass) {
|
||||
$scope.storedCredential.password_repeat = pass;
|
||||
};
|
||||
|
||||
var _customField = {
|
||||
label: '',
|
||||
value: '',
|
||||
secret: false
|
||||
};
|
||||
$scope.new_custom_field = angular.copy(_customField);
|
||||
|
||||
$scope.addCustomField = function () {
|
||||
if (!$scope.new_custom_field.label) {
|
||||
NotificationService.showNotification('Please fill in a label', 3000);
|
||||
}
|
||||
if (!$scope.new_custom_field.value) {
|
||||
NotificationService.showNotification('Please fill in a value!', 3000);
|
||||
}
|
||||
if (!$scope.new_custom_field.label || !$scope.new_custom_field.value) {
|
||||
return;
|
||||
}
|
||||
$scope.storedCredential.custom_fields.push(angular.copy($scope.new_custom_field));
|
||||
$scope.new_custom_field = angular.copy(_customField);
|
||||
};
|
||||
|
||||
$scope.deleteCustomField = function (field) {
|
||||
var idx = $scope.storedCredential.custom_fields.indexOf(field);
|
||||
$scope.storedCredential.custom_fields.splice(idx, 1);
|
||||
};
|
||||
|
||||
$scope.new_file = {
|
||||
name: '',
|
||||
data: null
|
||||
};
|
||||
|
||||
$scope.deleteFile = function (file) {
|
||||
var idx = $scope.storedCredential.files.indexOf(file);
|
||||
FileService.deleteFile(file).then(function () {
|
||||
$scope.storedCredential.files.splice(idx, 1);
|
||||
});
|
||||
};
|
||||
|
||||
$scope.fileLoaded = function (file) {
|
||||
var _file = {
|
||||
filename: file.name,
|
||||
size: file.size,
|
||||
mimetype: file.type,
|
||||
data: file.data
|
||||
};
|
||||
qrInfo[parsedQR[3]] = parsedQR[4];
|
||||
qrInfo[parsedQR[5]] = parsedQR[6];
|
||||
$scope.storedCredential.otp = qrInfo;
|
||||
$scope.$digest()
|
||||
};
|
||||
FileService.uploadFile(_file).then(function (result) {
|
||||
delete result.file_data;
|
||||
result.filename = EncryptService.decryptString(result.filename);
|
||||
$scope.storedCredential.files.push(result);
|
||||
});
|
||||
|
||||
|
||||
$scope.saveCredential = function () {
|
||||
//@TODO validation
|
||||
delete $scope.storedCredential.password_repeat;
|
||||
if (!$scope.storedCredential.credential_id) {
|
||||
$scope.storedCredential.vault_id = $scope.active_vault.vault_id;
|
||||
$scope.$digest();
|
||||
};
|
||||
|
||||
CredentialService.createCredential($scope.storedCredential).then(function (result) {
|
||||
NotificationService.showNotification('Credential created!', 5000)
|
||||
})
|
||||
}
|
||||
};
|
||||
$scope.fileLoadError = function (error, file) {
|
||||
console.log(error, file);
|
||||
};
|
||||
|
||||
}
|
||||
]);
|
||||
$scope.selected_file = '';
|
||||
$scope.fileprogress = [];
|
||||
$scope.fileSelectProgress = function (progress) {
|
||||
if (progress) {
|
||||
$scope.fileprogress = progress;
|
||||
$scope.$digest();
|
||||
|
||||
}
|
||||
};
|
||||
$scope.renewIntervalValue = 0;
|
||||
$scope.renewIntervalModifier = '0';
|
||||
|
||||
$scope.updateInterval = function (renewIntervalValue, renewIntervalModifier) {
|
||||
var value = parseInt(renewIntervalValue);
|
||||
var modifier = parseInt(renewIntervalModifier);
|
||||
if (value && modifier) {
|
||||
$scope.storedCredential.renew_interval = value * modifier;
|
||||
}
|
||||
};
|
||||
|
||||
$scope.parseQR = function (QRCode) {
|
||||
var re = /otpauth:\/\/(totp|hotp)\/(.*)\?(secret|issuer)=(.*)&(issuer|secret)=(.*)/, parsedQR, qrInfo;
|
||||
parsedQR = (QRCode.qrData.match(re));
|
||||
if (parsedQR)
|
||||
qrInfo = {
|
||||
type: parsedQR[1],
|
||||
label: decodeURIComponent(parsedQR[2]),
|
||||
qr_uri: QRCode
|
||||
};
|
||||
qrInfo[parsedQR[3]] = parsedQR[4];
|
||||
qrInfo[parsedQR[5]] = parsedQR[6];
|
||||
$scope.storedCredential.otp = qrInfo;
|
||||
$scope.$digest();
|
||||
};
|
||||
|
||||
|
||||
$scope.saveCredential = function () {
|
||||
//@TODO validation
|
||||
delete $scope.storedCredential.password_repeat;
|
||||
if (!$scope.storedCredential.credential_id) {
|
||||
$scope.storedCredential.vault_id = $scope.active_vault.vault_id;
|
||||
|
||||
CredentialService.createCredential($scope.storedCredential).then(function (result) {
|
||||
NotificationService.showNotification('Credential created!', 5000);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
]);
|
||||
|
||||
}());
|
|
@ -1,410 +1,399 @@
|
|||
'use strict';
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* @ngdoc function
|
||||
* @name passmanApp.controller:MainCtrl
|
||||
* @description
|
||||
* # MainCtrl
|
||||
* Controller of the passmanApp
|
||||
*/
|
||||
angular.module('passmanApp')
|
||||
.controller('CredentialCtrl', ['$scope', 'VaultService', 'SettingsService', '$location', 'CredentialService',
|
||||
'$rootScope', 'FileService', 'EncryptService', 'TagService', '$timeout', 'NotificationService', 'CacheService', 'ShareService', 'SharingACL', '$interval', '$filter', '$routeParams',
|
||||
function ($scope, VaultService, SettingsService, $location, CredentialService, $rootScope, FileService, EncryptService, TagService, $timeout, NotificationService, CacheService, ShareService, SharingACL, $interval, $filter, $routeParams) {
|
||||
$scope.active_vault = VaultService.getActiveVault();
|
||||
if (!SettingsService.getSetting('defaultVault') || !SettingsService.getSetting('defaultVaultPass')) {
|
||||
if (!$scope.active_vault) {
|
||||
$location.path('/')
|
||||
}
|
||||
} else {
|
||||
if (SettingsService.getSetting('defaultVault') && SettingsService.getSetting('defaultVaultPass')) {
|
||||
var _vault = angular.copy(SettingsService.getSetting('defaultVault'));
|
||||
_vault.vaultKey = angular.copy(SettingsService.getSetting('defaultVaultPass'));
|
||||
VaultService.setActiveVault(_vault);
|
||||
$scope.active_vault = _vault;
|
||||
//@TODO check if vault exists
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$scope.show_spinner = true;
|
||||
var fetchCredentials = function () {
|
||||
VaultService.getVault({guid: $routeParams.vault_id}).then(function (vault) {
|
||||
var vaultKey = angular.copy($scope.active_vault.vaultKey);
|
||||
var _credentials = angular.copy(vault.credentials);
|
||||
vault.credentials = [];
|
||||
$scope.active_vault = vault;
|
||||
$scope.active_vault.vaultKey = vaultKey;
|
||||
VaultService.setActiveVault($scope.active_vault);
|
||||
for (var i = 0; i < _credentials.length; i++) {
|
||||
var _credential = _credentials[i];
|
||||
try {
|
||||
if (!_credential.shared_key) {
|
||||
_credential = CredentialService.decryptCredential(angular.copy(_credential));
|
||||
|
||||
} else {
|
||||
var enc_key = EncryptService.decryptString(_credential.shared_key);
|
||||
_credential = ShareService.decryptSharedCredential(angular.copy(_credential), enc_key);
|
||||
}
|
||||
_credential.tags_raw = _credential.tags;
|
||||
} catch (e) {
|
||||
NotificationService.showNotification('An error happend during decryption', 5000);
|
||||
//$rootScope.$broadcast('logout');
|
||||
//SettingsService.setSetting('defaultVaultPass', null);
|
||||
//.setSetting('defaultVault', null);
|
||||
//$location.path('/')
|
||||
|
||||
}
|
||||
if (_credential.tags) {
|
||||
TagService.addTags(_credential.tags);
|
||||
}
|
||||
_credentials[i] = _credential;
|
||||
/**
|
||||
* @ngdoc function
|
||||
* @name passmanApp.controller:MainCtrl
|
||||
* @description
|
||||
* # MainCtrl
|
||||
* Controller of the passmanApp
|
||||
*/
|
||||
angular.module('passmanApp')
|
||||
.controller('CredentialCtrl', ['$scope', 'VaultService', 'SettingsService', '$location', 'CredentialService',
|
||||
'$rootScope', 'FileService', 'EncryptService', 'TagService', '$timeout', 'NotificationService', 'CacheService', 'ShareService', 'SharingACL', '$interval', '$filter', '$routeParams',
|
||||
function ($scope, VaultService, SettingsService, $location, CredentialService, $rootScope, FileService, EncryptService, TagService, $timeout, NotificationService, CacheService, ShareService, SharingACL, $interval, $filter, $routeParams) {
|
||||
$scope.active_vault = VaultService.getActiveVault();
|
||||
if (!SettingsService.getSetting('defaultVault') || !SettingsService.getSetting('defaultVaultPass')) {
|
||||
if (!$scope.active_vault) {
|
||||
$location.path('/');
|
||||
}
|
||||
} else {
|
||||
if (SettingsService.getSetting('defaultVault') && SettingsService.getSetting('defaultVaultPass')) {
|
||||
var _vault = angular.copy(SettingsService.getSetting('defaultVault'));
|
||||
_vault.vaultKey = angular.copy(SettingsService.getSetting('defaultVaultPass'));
|
||||
VaultService.setActiveVault(_vault);
|
||||
$scope.active_vault = _vault;
|
||||
//@TODO check if vault exists
|
||||
}
|
||||
|
||||
ShareService.getCredendialsSharedWithUs(vault.guid).then(function (shared_credentials) {
|
||||
console.log('Shared credentials', shared_credentials);
|
||||
for (var c = 0; c < shared_credentials.length; c++) {
|
||||
var _shared_credential = shared_credentials[c];
|
||||
var decrypted_key = EncryptService.decryptString(_shared_credential.shared_key);
|
||||
}
|
||||
|
||||
$scope.show_spinner = true;
|
||||
var fetchCredentials = function () {
|
||||
VaultService.getVault({guid: $routeParams.vault_id}).then(function (vault) {
|
||||
var vaultKey = angular.copy($scope.active_vault.vaultKey);
|
||||
var _credentials = angular.copy(vault.credentials);
|
||||
vault.credentials = [];
|
||||
$scope.active_vault = vault;
|
||||
$scope.active_vault.vaultKey = vaultKey;
|
||||
VaultService.setActiveVault($scope.active_vault);
|
||||
for (var i = 0; i < _credentials.length; i++) {
|
||||
var _credential = _credentials[i];
|
||||
try {
|
||||
var _shared_credential_data = ShareService.decryptSharedCredential(_shared_credential.credential_data, decrypted_key);
|
||||
if (!_credential.shared_key) {
|
||||
_credential = CredentialService.decryptCredential(angular.copy(_credential));
|
||||
|
||||
} else {
|
||||
var enc_key = EncryptService.decryptString(_credential.shared_key);
|
||||
_credential = ShareService.decryptSharedCredential(angular.copy(_credential), enc_key);
|
||||
}
|
||||
_credential.tags_raw = _credential.tags;
|
||||
} catch (e) {
|
||||
NotificationService.showNotification('An error happend during decryption', 5000);
|
||||
//$rootScope.$broadcast('logout');
|
||||
//SettingsService.setSetting('defaultVaultPass', null);
|
||||
//.setSetting('defaultVault', null);
|
||||
//$location.path('/')
|
||||
|
||||
}
|
||||
if (_shared_credential_data) {
|
||||
delete _shared_credential.credential_data;
|
||||
_shared_credential_data.acl = _shared_credential;
|
||||
_shared_credential_data.acl.permissions = new SharingACL(_shared_credential_data.acl.permissions);
|
||||
_shared_credential_data.tags_raw = _shared_credential_data.tags;
|
||||
if (_shared_credential_data.tags) {
|
||||
TagService.addTags(_shared_credential_data.tags);
|
||||
if (_credential.tags) {
|
||||
TagService.addTags(_credential.tags);
|
||||
}
|
||||
_credentials[i] = _credential;
|
||||
}
|
||||
|
||||
ShareService.getCredendialsSharedWithUs(vault.guid).then(function (shared_credentials) {
|
||||
console.log('Shared credentials', shared_credentials);
|
||||
for (var c = 0; c < shared_credentials.length; c++) {
|
||||
var _shared_credential = shared_credentials[c];
|
||||
var decrypted_key = EncryptService.decryptString(_shared_credential.shared_key);
|
||||
var _shared_credential_data;
|
||||
try {
|
||||
_shared_credential_data = ShareService.decryptSharedCredential(_shared_credential.credential_data, decrypted_key);
|
||||
} catch (e) {
|
||||
|
||||
}
|
||||
_credentials.push(_shared_credential_data);
|
||||
}
|
||||
}
|
||||
angular.merge($scope.active_vault.credentials, _credentials);
|
||||
$scope.show_spinner = false;
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
var getPendingShareRequests = function () {
|
||||
ShareService.getPendingRequests().then(function (shareRequests) {
|
||||
if (shareRequests.length > 0) {
|
||||
$scope.incoming_share_requests = shareRequests;
|
||||
jQuery('.share_popup').dialog({
|
||||
width: 600,
|
||||
position: ['center', 90]
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
var refresh_data_interval = null;
|
||||
if ($scope.active_vault) {
|
||||
$scope.$parent.selectedVault = true;
|
||||
fetchCredentials();
|
||||
getPendingShareRequests();
|
||||
refresh_data_interval = $interval(function () {
|
||||
fetchCredentials();
|
||||
getPendingShareRequests();
|
||||
}, 60000 * 5)
|
||||
}
|
||||
$scope.$on('$destroy', function() {
|
||||
$interval.cancel(refresh_data_interval);
|
||||
});
|
||||
|
||||
|
||||
$scope.permissions = new SharingACL(0);
|
||||
|
||||
$scope.hasPermission = function (acl, permission) {
|
||||
if (acl) {
|
||||
var tmp = new SharingACL(acl.permission);
|
||||
return tmp.hasPermission(permission);
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
$scope.acceptShareRequest = function (share_request) {
|
||||
console.log('Accepted share request', share_request);
|
||||
var crypted_shared_key = share_request.shared_key;
|
||||
var private_key = EncryptService.decryptString(VaultService.getActiveVault().private_sharing_key);
|
||||
|
||||
private_key = ShareService.rsaPrivateKeyFromPEM(private_key);
|
||||
crypted_shared_key = private_key.decrypt(forge.util.decode64(crypted_shared_key));
|
||||
crypted_shared_key = EncryptService.encryptString(crypted_shared_key);
|
||||
|
||||
ShareService.saveSharingRequest(share_request, crypted_shared_key).then(function (result) {
|
||||
var idx = $scope.incoming_share_requests.indexOf(share_request);
|
||||
$scope.incoming_share_requests.splice(idx, 1);
|
||||
var active_share_requests = false;
|
||||
for (var v = 0; v < $scope.incoming_share_requests.length; v++) {
|
||||
if ($scope.incoming_share_requests[v].target_vault_id == $scope.active_vault.vault_id) {
|
||||
active_share_requests = true;
|
||||
}
|
||||
}
|
||||
if (active_share_requests === false) {
|
||||
jQuery('.ui-dialog').remove();
|
||||
fetchCredentials();
|
||||
}
|
||||
console.log(result)
|
||||
})
|
||||
};
|
||||
|
||||
$scope.declineShareRequest = function(share_request){
|
||||
ShareService.declineSharingRequest(share_request).then(function () {
|
||||
var idx = $scope.incoming_share_requests.indexOf(share_request);
|
||||
$scope.incoming_share_requests.splice(idx, 1);
|
||||
var active_share_requests = false;
|
||||
for (var v = 0; v < $scope.incoming_share_requests.length; v++) {
|
||||
if ($scope.incoming_share_requests[v].target_vault_id == $scope.active_vault.vault_id) {
|
||||
active_share_requests = true;
|
||||
}
|
||||
}
|
||||
if (active_share_requests === false) {
|
||||
jQuery('.ui-dialog').remove();
|
||||
fetchCredentials();
|
||||
}
|
||||
})
|
||||
};
|
||||
|
||||
|
||||
$scope.addCredential = function () {
|
||||
var new_credential = CredentialService.newCredential();
|
||||
var enc_c = CredentialService.encryptCredential(new_credential);
|
||||
SettingsService.setSetting('edit_credential', enc_c);
|
||||
$location.path('/vault/' + $scope.active_vault.guid + '/new')
|
||||
};
|
||||
|
||||
$scope.editCredential = function (credential) {
|
||||
var _credential = angular.copy(credential);
|
||||
$rootScope.$emit('app_menu', false);
|
||||
SettingsService.setSetting('edit_credential', CredentialService.encryptCredential(_credential));
|
||||
$location.path('/vault/' + $scope.active_vault.guid + '/edit/' + _credential.guid)
|
||||
};
|
||||
|
||||
$scope.getRevisions = function (credential) {
|
||||
var _credential = angular.copy(credential);
|
||||
$rootScope.$emit('app_menu', false);
|
||||
SettingsService.setSetting('revision_credential', CredentialService.encryptCredential(_credential));
|
||||
$location.path('/vault/' + $scope.active_vault.guid + '/' + _credential.guid + '/revisions')
|
||||
};
|
||||
|
||||
$scope.shareCredential = function (credential) {
|
||||
var _credential = angular.copy(credential);
|
||||
$rootScope.$emit('app_menu', false);
|
||||
SettingsService.setSetting('share_credential', CredentialService.encryptCredential(_credential));
|
||||
$location.path('/vault/' + $scope.active_vault.guid + '/' + _credential.guid + '/share')
|
||||
};
|
||||
|
||||
var notification;
|
||||
$scope.deleteCredential = function (credential) {
|
||||
var _credential = angular.copy(credential);
|
||||
try {
|
||||
_credential = CredentialService.decryptCredential(angular.copy(credential));
|
||||
} catch (e) {
|
||||
|
||||
}
|
||||
_credential.delete_time = new Date().getTime() / 1000;
|
||||
for (var i = 0; i < $scope.active_vault.credentials.length; i++) {
|
||||
if ($scope.active_vault.credentials[i].credential_id == credential.credential_id) {
|
||||
$scope.active_vault.credentials[i].delete_time = _credential.delete_time;
|
||||
}
|
||||
}
|
||||
$scope.closeSelected();
|
||||
if (notification) {
|
||||
NotificationService.hideNotification(notification);
|
||||
}
|
||||
notification = NotificationService.showNotification('Credential deleted', 5000,
|
||||
function () {
|
||||
CredentialService.updateCredential(_credential).then(function (result) {
|
||||
if (result.delete_time > 0) {
|
||||
notification = false;
|
||||
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
$scope.recoverCredential = function (credential) {
|
||||
var _credential = angular.copy(credential);
|
||||
try {
|
||||
_credential = CredentialService.decryptCredential(angular.copy(credential));
|
||||
} catch (e) {
|
||||
|
||||
}
|
||||
for (var i = 0; i < $scope.active_vault.credentials.length; i++) {
|
||||
if ($scope.active_vault.credentials[i].credential_id == credential.credential_id) {
|
||||
$scope.active_vault.credentials[i].delete_time = 0;
|
||||
}
|
||||
}
|
||||
_credential.delete_time = 0;
|
||||
$scope.closeSelected();
|
||||
if (notification) {
|
||||
NotificationService.hideNotification(notification);
|
||||
}
|
||||
NotificationService.showNotification('Credential recovered', 5000,
|
||||
function () {
|
||||
CredentialService.updateCredential(_credential).then(function (result) {
|
||||
notification = false;
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
$scope.destroyCredential = function (credential) {
|
||||
var _credential = angular.copy(credential);
|
||||
CredentialService.destroyCredential(_credential.credential_id).then(function (result) {
|
||||
for (var i = 0; i < $scope.active_vault.credentials.length; i++) {
|
||||
if ($scope.active_vault.credentials[i].credential_id == credential.credential_id) {
|
||||
$scope.active_vault.credentials.splice(i, 1);
|
||||
NotificationService.showNotification('Credential destroyed', 5000);
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
$scope.view_mode = 'list'; //@TODO make this a setting
|
||||
$scope.switchViewMode = function (viewMode) {
|
||||
$scope.view_mode = viewMode;
|
||||
};
|
||||
|
||||
$scope.filterOptions = {
|
||||
filterText: '',
|
||||
fields: ['label', 'username', 'email', 'password', 'custom_fields']
|
||||
};
|
||||
|
||||
|
||||
$scope.filtered_credentials = [];
|
||||
$scope.$watch('[selectedtags, filterOptions, delete_time, active_vault.credentials]', function(){
|
||||
if(!$scope.active_vault){
|
||||
return;
|
||||
}
|
||||
if($scope.active_vault.credentials) {
|
||||
var credentials = angular.copy($scope.active_vault.credentials);
|
||||
var filtered_credentials = $filter('credentialSearch')(credentials, $scope.filterOptions);
|
||||
filtered_credentials = $filter('tagFilter')(filtered_credentials, $scope.selectedtags);
|
||||
filtered_credentials = $filter('filter')(filtered_credentials, {hidden: 0});
|
||||
$scope.filtered_credentials = filtered_credentials;
|
||||
}
|
||||
}, true);
|
||||
|
||||
$scope.selectedtags = [];
|
||||
var to;
|
||||
$rootScope.$on('selected_tags_updated', function (evt, _sTags) {
|
||||
var _selectedTags = [];
|
||||
for (var x = 0; x < _sTags.length; x++) {
|
||||
_selectedTags.push(_sTags[x].text)
|
||||
}
|
||||
$scope.selectedtags = _selectedTags;
|
||||
$timeout.cancel(to);
|
||||
if (_selectedTags.length > 0) {
|
||||
to = $timeout(function () {
|
||||
if ($scope.filtered_credentials) {
|
||||
var _filtered_tags = [];
|
||||
for (var i = 0; i < $scope.filtered_credentials.length; i++) {
|
||||
var tags = $scope.filtered_credentials[i].tags_raw;
|
||||
for (var x = 0; x < tags.length; x++) {
|
||||
var tag = tags[x].text;
|
||||
if (_filtered_tags.indexOf(tag) === -1) {
|
||||
_filtered_tags.push(tag);
|
||||
if (_shared_credential_data) {
|
||||
delete _shared_credential.credential_data;
|
||||
_shared_credential_data.acl = _shared_credential;
|
||||
_shared_credential_data.acl.permissions = new SharingACL(_shared_credential_data.acl.permissions);
|
||||
_shared_credential_data.tags_raw = _shared_credential_data.tags;
|
||||
if (_shared_credential_data.tags) {
|
||||
TagService.addTags(_shared_credential_data.tags);
|
||||
}
|
||||
_credentials.push(_shared_credential_data);
|
||||
}
|
||||
}
|
||||
|
||||
$rootScope.$emit('limit_tags_in_list', _filtered_tags);
|
||||
}
|
||||
}, 50)
|
||||
}
|
||||
});
|
||||
|
||||
$scope.delete_time = 0;
|
||||
$scope.showCredentialRow = function (credential) {
|
||||
if ($scope.delete_time == 0) {
|
||||
return credential.delete_time == 0
|
||||
} else {
|
||||
return credential.delete_time > $scope.delete_time;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
$rootScope.$on('set_delete_time', function (event, time) {
|
||||
$scope.delete_time = time;
|
||||
});
|
||||
|
||||
$scope.setDeleteTime = function (delete_time) {
|
||||
$scope.delete_time = delete_time;
|
||||
};
|
||||
|
||||
$scope.selectedCredential = false;
|
||||
$scope.selectCredential = function (credential) {
|
||||
$scope.selectedCredential = angular.copy(credential);
|
||||
$rootScope.$emit('app_menu', true);
|
||||
};
|
||||
|
||||
$scope.closeSelected = function () {
|
||||
$rootScope.$emit('app_menu', false);
|
||||
$scope.selectedCredential = false;
|
||||
};
|
||||
|
||||
$rootScope.$on('logout', function () {
|
||||
console.log('Logout received, clean up');
|
||||
$scope.active_vault = null;
|
||||
$scope.credentials = [];
|
||||
// $scope.$parent.selectedVault = false;
|
||||
|
||||
});
|
||||
|
||||
|
||||
$scope.downloadFile = function (credential, file) {
|
||||
console.log(credential, file);
|
||||
var callback = function (result) {
|
||||
var key = null;
|
||||
if (!result.hasOwnProperty('file_data')) {
|
||||
NotificationService.showNotification('Error downloading file, you probably don\'t have enough permissions', 5000);
|
||||
return;
|
||||
|
||||
}
|
||||
if (!credential.hasOwnProperty('acl') && credential.hasOwnProperty('shared_key')) {
|
||||
if (credential.shared_key) {
|
||||
key = EncryptService.decryptString(angular.copy(credential.shared_key));
|
||||
}
|
||||
}
|
||||
if (credential.hasOwnProperty('acl')) {
|
||||
key = EncryptService.decryptString(angular.copy(credential.acl.shared_key));
|
||||
}
|
||||
|
||||
var file_data = EncryptService.decryptString(result.file_data, key);
|
||||
download(file_data, escapeHTML(file.filename), file.mimetype)
|
||||
//file.mimetype
|
||||
//var uriContent = FileService.dataURItoBlob(file_data, file.mimetype), a = document.createElement("a");
|
||||
// a.href = uriContent;
|
||||
// a.download = escapeHTML(file.filename);
|
||||
// var event = document.createEvent("MouseEvents");
|
||||
// event.initMouseEvent(
|
||||
// "click", true, false, window, 0, 0, 0, 0, 0
|
||||
// , false, false, false, false, 0, null
|
||||
// );
|
||||
// window.URL.revokeObjectURL(uriContent);
|
||||
// a.dispatchEvent(event);
|
||||
// jQuery('#downloadLink').remove();
|
||||
setTimeout(function () {
|
||||
$scope.selectedCredential = credential;
|
||||
}, 1000)
|
||||
angular.merge($scope.active_vault.credentials, _credentials);
|
||||
$scope.show_spinner = false;
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
if (!credential.hasOwnProperty('acl')) {
|
||||
FileService.getFile(file).then(callback);
|
||||
} else {
|
||||
ShareService.downloadSharedFile(credential, file).then(callback);
|
||||
var getPendingShareRequests = function () {
|
||||
ShareService.getPendingRequests().then(function (shareRequests) {
|
||||
if (shareRequests.length > 0) {
|
||||
$scope.incoming_share_requests = shareRequests;
|
||||
jQuery('.share_popup').dialog({
|
||||
width: 600,
|
||||
position: ['center', 90]
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
var refresh_data_interval = null;
|
||||
if ($scope.active_vault) {
|
||||
$scope.$parent.selectedVault = true;
|
||||
fetchCredentials();
|
||||
getPendingShareRequests();
|
||||
refresh_data_interval = $interval(function () {
|
||||
fetchCredentials();
|
||||
getPendingShareRequests();
|
||||
}, 60000 * 5);
|
||||
}
|
||||
$scope.$on('$destroy', function () {
|
||||
$interval.cancel(refresh_data_interval);
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
}]);
|
||||
$scope.permissions = new SharingACL(0);
|
||||
|
||||
$scope.hasPermission = function (acl, permission) {
|
||||
if (acl) {
|
||||
var tmp = new SharingACL(acl.permission);
|
||||
return tmp.hasPermission(permission);
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
$scope.acceptShareRequest = function (share_request) {
|
||||
console.log('Accepted share request', share_request);
|
||||
var crypted_shared_key = share_request.shared_key;
|
||||
var private_key = EncryptService.decryptString(VaultService.getActiveVault().private_sharing_key);
|
||||
|
||||
private_key = ShareService.rsaPrivateKeyFromPEM(private_key);
|
||||
crypted_shared_key = private_key.decrypt(forge.util.decode64(crypted_shared_key));
|
||||
crypted_shared_key = EncryptService.encryptString(crypted_shared_key);
|
||||
|
||||
ShareService.saveSharingRequest(share_request, crypted_shared_key).then(function (result) {
|
||||
var idx = $scope.incoming_share_requests.indexOf(share_request);
|
||||
$scope.incoming_share_requests.splice(idx, 1);
|
||||
var active_share_requests = false;
|
||||
for (var v = 0; v < $scope.incoming_share_requests.length; v++) {
|
||||
if ($scope.incoming_share_requests[v].target_vault_id === $scope.active_vault.vault_id) {
|
||||
active_share_requests = true;
|
||||
}
|
||||
}
|
||||
if (active_share_requests === false) {
|
||||
jQuery('.ui-dialog').remove();
|
||||
fetchCredentials();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
$scope.declineShareRequest = function (share_request) {
|
||||
ShareService.declineSharingRequest(share_request).then(function () {
|
||||
var idx = $scope.incoming_share_requests.indexOf(share_request);
|
||||
$scope.incoming_share_requests.splice(idx, 1);
|
||||
var active_share_requests = false;
|
||||
for (var v = 0; v < $scope.incoming_share_requests.length; v++) {
|
||||
if ($scope.incoming_share_requests[v].target_vault_id === $scope.active_vault.vault_id) {
|
||||
active_share_requests = true;
|
||||
}
|
||||
}
|
||||
if (active_share_requests === false) {
|
||||
jQuery('.ui-dialog').remove();
|
||||
fetchCredentials();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
$scope.addCredential = function () {
|
||||
var new_credential = CredentialService.newCredential();
|
||||
var enc_c = CredentialService.encryptCredential(new_credential);
|
||||
SettingsService.setSetting('edit_credential', enc_c);
|
||||
$location.path('/vault/' + $scope.active_vault.guid + '/new');
|
||||
};
|
||||
|
||||
$scope.editCredential = function (credential) {
|
||||
var _credential = angular.copy(credential);
|
||||
$rootScope.$emit('app_menu', false);
|
||||
SettingsService.setSetting('edit_credential', CredentialService.encryptCredential(_credential));
|
||||
$location.path('/vault/' + $scope.active_vault.guid + '/edit/' + _credential.guid);
|
||||
};
|
||||
|
||||
$scope.getRevisions = function (credential) {
|
||||
var _credential = angular.copy(credential);
|
||||
$rootScope.$emit('app_menu', false);
|
||||
SettingsService.setSetting('revision_credential', CredentialService.encryptCredential(_credential));
|
||||
$location.path('/vault/' + $scope.active_vault.guid + '/' + _credential.guid + '/revisions');
|
||||
};
|
||||
|
||||
$scope.shareCredential = function (credential) {
|
||||
var _credential = angular.copy(credential);
|
||||
$rootScope.$emit('app_menu', false);
|
||||
SettingsService.setSetting('share_credential', CredentialService.encryptCredential(_credential));
|
||||
$location.path('/vault/' + $scope.active_vault.guid + '/' + _credential.guid + '/share');
|
||||
};
|
||||
|
||||
var notification;
|
||||
$scope.deleteCredential = function (credential) {
|
||||
var _credential = angular.copy(credential);
|
||||
try {
|
||||
_credential = CredentialService.decryptCredential(angular.copy(credential));
|
||||
} catch (e) {
|
||||
|
||||
}
|
||||
_credential.delete_time = new Date().getTime() / 1000;
|
||||
for (var i = 0; i < $scope.active_vault.credentials.length; i++) {
|
||||
if ($scope.active_vault.credentials[i].credential_id === credential.credential_id) {
|
||||
$scope.active_vault.credentials[i].delete_time = _credential.delete_time;
|
||||
}
|
||||
}
|
||||
$scope.closeSelected();
|
||||
if (notification) {
|
||||
NotificationService.hideNotification(notification);
|
||||
}
|
||||
notification = NotificationService.showNotification('Credential deleted', 5000,
|
||||
function () {
|
||||
CredentialService.updateCredential(_credential).then(function (result) {
|
||||
if (result.delete_time > 0) {
|
||||
notification = false;
|
||||
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
$scope.recoverCredential = function (credential) {
|
||||
var _credential = angular.copy(credential);
|
||||
try {
|
||||
_credential = CredentialService.decryptCredential(angular.copy(credential));
|
||||
} catch (e) {
|
||||
|
||||
}
|
||||
for (var i = 0; i < $scope.active_vault.credentials.length; i++) {
|
||||
if ($scope.active_vault.credentials[i].credential_id === credential.credential_id) {
|
||||
$scope.active_vault.credentials[i].delete_time = 0;
|
||||
}
|
||||
}
|
||||
_credential.delete_time = 0;
|
||||
$scope.closeSelected();
|
||||
if (notification) {
|
||||
NotificationService.hideNotification(notification);
|
||||
}
|
||||
NotificationService.showNotification('Credential recovered', 5000,
|
||||
function () {
|
||||
CredentialService.updateCredential(_credential).then(function (result) {
|
||||
notification = false;
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
$scope.destroyCredential = function (credential) {
|
||||
var _credential = angular.copy(credential);
|
||||
CredentialService.destroyCredential(_credential.credential_id).then(function (result) {
|
||||
for (var i = 0; i < $scope.active_vault.credentials.length; i++) {
|
||||
if ($scope.active_vault.credentials[i].credential_id === credential.credential_id) {
|
||||
$scope.active_vault.credentials.splice(i, 1);
|
||||
NotificationService.showNotification('Credential destroyed', 5000);
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
$scope.view_mode = 'list'; //@TODO make this a setting
|
||||
$scope.switchViewMode = function (viewMode) {
|
||||
$scope.view_mode = viewMode;
|
||||
};
|
||||
|
||||
$scope.filterOptions = {
|
||||
filterText: '',
|
||||
fields: ['label', 'username', 'email', 'password', 'custom_fields']
|
||||
};
|
||||
|
||||
|
||||
$scope.filtered_credentials = [];
|
||||
$scope.$watch('[selectedtags, filterOptions, delete_time, active_vault.credentials]', function () {
|
||||
if (!$scope.active_vault) {
|
||||
return;
|
||||
}
|
||||
if ($scope.active_vault.credentials) {
|
||||
var credentials = angular.copy($scope.active_vault.credentials);
|
||||
var filtered_credentials = $filter('credentialSearch')(credentials, $scope.filterOptions);
|
||||
filtered_credentials = $filter('tagFilter')(filtered_credentials, $scope.selectedtags);
|
||||
filtered_credentials = $filter('filter')(filtered_credentials, {hidden: 0});
|
||||
$scope.filtered_credentials = filtered_credentials;
|
||||
}
|
||||
}, true);
|
||||
|
||||
$scope.selectedtags = [];
|
||||
var to;
|
||||
$rootScope.$on('selected_tags_updated', function (evt, _sTags) {
|
||||
var _selectedTags = [];
|
||||
for (var x = 0; x < _sTags.length; x++) {
|
||||
_selectedTags.push(_sTags[x].text);
|
||||
}
|
||||
$scope.selectedtags = _selectedTags;
|
||||
$timeout.cancel(to);
|
||||
if (_selectedTags.length > 0) {
|
||||
to = $timeout(function () {
|
||||
if ($scope.filtered_credentials) {
|
||||
var _filtered_tags = [];
|
||||
for (var i = 0; i < $scope.filtered_credentials.length; i++) {
|
||||
var tags = $scope.filtered_credentials[i].tags_raw;
|
||||
for (var x = 0; x < tags.length; x++) {
|
||||
var tag = tags[x].text;
|
||||
if (_filtered_tags.indexOf(tag) === -1) {
|
||||
_filtered_tags.push(tag);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$rootScope.$emit('limit_tags_in_list', _filtered_tags);
|
||||
}
|
||||
}, 50);
|
||||
}
|
||||
});
|
||||
|
||||
$scope.delete_time = 0;
|
||||
$scope.showCredentialRow = function (credential) {
|
||||
if ($scope.delete_time === 0) {
|
||||
return credential.delete_time === 0;
|
||||
} else {
|
||||
return credential.delete_time > $scope.delete_time;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
$rootScope.$on('set_delete_time', function (event, time) {
|
||||
$scope.delete_time = time;
|
||||
});
|
||||
|
||||
$scope.setDeleteTime = function (delete_time) {
|
||||
$scope.delete_time = delete_time;
|
||||
};
|
||||
|
||||
$scope.selectedCredential = false;
|
||||
$scope.selectCredential = function (credential) {
|
||||
$scope.selectedCredential = angular.copy(credential);
|
||||
$rootScope.$emit('app_menu', true);
|
||||
};
|
||||
|
||||
$scope.closeSelected = function () {
|
||||
$rootScope.$emit('app_menu', false);
|
||||
$scope.selectedCredential = false;
|
||||
};
|
||||
|
||||
$rootScope.$on('logout', function () {
|
||||
console.log('Logout received, clean up');
|
||||
$scope.active_vault = null;
|
||||
$scope.credentials = [];
|
||||
// $scope.$parent.selectedVault = false;
|
||||
|
||||
});
|
||||
|
||||
|
||||
$scope.downloadFile = function (credential, file) {
|
||||
console.log(credential, file);
|
||||
var callback = function (result) {
|
||||
var key = null;
|
||||
if (!result.hasOwnProperty('file_data')) {
|
||||
NotificationService.showNotification('Error downloading file, you probably don\'t have enough permissions', 5000);
|
||||
return;
|
||||
|
||||
}
|
||||
if (!credential.hasOwnProperty('acl') && credential.hasOwnProperty('shared_key')) {
|
||||
if (credential.shared_key) {
|
||||
key = EncryptService.decryptString(angular.copy(credential.shared_key));
|
||||
}
|
||||
}
|
||||
if (credential.hasOwnProperty('acl')) {
|
||||
key = EncryptService.decryptString(angular.copy(credential.acl.shared_key));
|
||||
}
|
||||
|
||||
var file_data = EncryptService.decryptString(result.file_data, key);
|
||||
download(file_data, escapeHTML(file.filename), file.mimetype);
|
||||
|
||||
};
|
||||
|
||||
if (!credential.hasOwnProperty('acl')) {
|
||||
FileService.getFile(file).then(callback);
|
||||
} else {
|
||||
ShareService.downloadSharedFile(credential, file).then(callback);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}]);
|
||||
}());
|
|
@ -1,250 +1,157 @@
|
|||
'use strict';
|
||||
|
||||
/**
|
||||
* @ngdoc function
|
||||
* @name passmanApp.controller:MainCtrl
|
||||
* @description
|
||||
* # MainCtrl
|
||||
* Controller of the passmanApp
|
||||
*/
|
||||
angular.module('passmanApp')
|
||||
.controller('CredentialEditCtrl', ['$scope', 'VaultService', 'CredentialService', 'SettingsService', '$location', '$routeParams', 'FileService', 'EncryptService', 'TagService', 'NotificationService', 'ShareService',
|
||||
function ($scope, VaultService, CredentialService, SettingsService, $location, $routeParams, FileService, EncryptService, TagService, NotificationService, ShareService) {
|
||||
$scope.active_vault = VaultService.getActiveVault();
|
||||
if (!SettingsService.getSetting('defaultVault') || !SettingsService.getSetting('defaultVaultPass')) {
|
||||
if (!$scope.active_vault) {
|
||||
$location.path('/')
|
||||
}
|
||||
} else {
|
||||
if (SettingsService.getSetting('defaultVault') && SettingsService.getSetting('defaultVaultPass')) {
|
||||
var _vault = angular.copy(SettingsService.getSetting('defaultVault'));
|
||||
VaultService.getVault(_vault).then(function (vault) {
|
||||
vault.vaultKey = angular.copy(SettingsService.getSetting('defaultVaultPass'));
|
||||
VaultService.setActiveVault(vault);
|
||||
$scope.active_vault = vault;
|
||||
|
||||
$scope.pwSettings = VaultService.getVaultSetting('pwSettings',
|
||||
{
|
||||
'length': 12,
|
||||
'useUppercase': true,
|
||||
'useLowercase': true,
|
||||
'useDigits': true,
|
||||
'useSpecialChars': true,
|
||||
'minimumDigitCount': 3,
|
||||
'avoidAmbiguousCharacters': false,
|
||||
'requireEveryCharType': true,
|
||||
'generateOnCreate': true
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
$scope.tabs = [{
|
||||
title: 'General',
|
||||
url: 'views/partials/forms/edit_credential/basics.html',
|
||||
color: 'blue'
|
||||
}, {
|
||||
title: 'Password',
|
||||
url: 'views/partials/forms/edit_credential/password.html',
|
||||
color: 'green'
|
||||
}, {
|
||||
title: 'Custom fields',
|
||||
url: 'views/partials/forms/edit_credential/custom_fields.html',
|
||||
color: 'orange'
|
||||
}, {
|
||||
title: 'Files',
|
||||
url: 'views/partials/forms/edit_credential/files.html',
|
||||
color: 'yellow'
|
||||
}, {
|
||||
title: 'OTP',
|
||||
url: 'views/partials/forms/edit_credential/otp.html',
|
||||
color: 'purple'
|
||||
}];
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
|
||||
if (!SettingsService.getSetting('defaultVault') || !SettingsService.getSetting('defaultVaultPass')) {
|
||||
if (!$scope.active_vault) {
|
||||
$location.path('/')
|
||||
}
|
||||
} else {
|
||||
if (SettingsService.getSetting('defaultVault') && SettingsService.getSetting('defaultVaultPass')) {
|
||||
var _vault = angular.copy(SettingsService.getSetting('defaultVault'))
|
||||
_vault.vaultKey = angular.copy(SettingsService.getSetting('defaultVaultPass'));
|
||||
VaultService.setActiveVault(_vault);
|
||||
$scope.active_vault = _vault;
|
||||
/**
|
||||
* @ngdoc function
|
||||
* @name passmanApp.controller:MainCtrl
|
||||
* @description
|
||||
* # MainCtrl
|
||||
* Controller of the passmanApp
|
||||
*/
|
||||
angular.module('passmanApp')
|
||||
.controller('CredentialEditCtrl', ['$scope', 'VaultService', 'CredentialService', 'SettingsService', '$location', '$routeParams', 'FileService', 'EncryptService', 'TagService', 'NotificationService', 'ShareService',
|
||||
function ($scope, VaultService, CredentialService, SettingsService, $location, $routeParams, FileService, EncryptService, TagService, NotificationService, ShareService) {
|
||||
$scope.active_vault = VaultService.getActiveVault();
|
||||
if (!SettingsService.getSetting('defaultVault') || !SettingsService.getSetting('defaultVaultPass')) {
|
||||
if (!$scope.active_vault) {
|
||||
$location.path('/');
|
||||
}
|
||||
} else {
|
||||
if (SettingsService.getSetting('defaultVault') && SettingsService.getSetting('defaultVaultPass')) {
|
||||
var _vault = angular.copy(SettingsService.getSetting('defaultVault'));
|
||||
VaultService.getVault(_vault).then(function (vault) {
|
||||
vault.vaultKey = angular.copy(SettingsService.getSetting('defaultVaultPass'));
|
||||
VaultService.setActiveVault(vault);
|
||||
$scope.active_vault = vault;
|
||||
|
||||
}
|
||||
}
|
||||
if ($scope.active_vault) {
|
||||
$scope.$parent.selectedVault = true;
|
||||
}
|
||||
var storedCredential = SettingsService.getSetting('edit_credential');
|
||||
|
||||
if (!storedCredential) {
|
||||
CredentialService.getCredential($routeParams.credential_id).then(function (result) {
|
||||
$scope.storedCredential = CredentialService.decryptCredential(angular.copy(result));
|
||||
});
|
||||
} else {
|
||||
$scope.storedCredential = CredentialService.decryptCredential(angular.copy(storedCredential));
|
||||
$scope.storedCredential.password_repeat = angular.copy($scope.storedCredential.password);
|
||||
$scope.storedCredential.expire_time = $scope.storedCredential.expire_time * 1000;
|
||||
}
|
||||
|
||||
$scope.getTags = function ($query) {
|
||||
return TagService.searchTag($query);
|
||||
};
|
||||
|
||||
$scope.currentTab = {
|
||||
title: 'General',
|
||||
url: 'views/partials/forms/edit_credential/basics.html',
|
||||
color: 'blue'
|
||||
};
|
||||
|
||||
$scope.onClickTab = function (tab) {
|
||||
$scope.currentTab = tab;
|
||||
};
|
||||
|
||||
$scope.isActiveTab = function (tab) {
|
||||
return tab.url == $scope.currentTab.url;
|
||||
};
|
||||
|
||||
/**
|
||||
* Below general edit functions
|
||||
*/
|
||||
|
||||
$scope.pwGenerated = function (pass) {
|
||||
$scope.storedCredential.password_repeat = pass;
|
||||
};
|
||||
|
||||
var _customField = {
|
||||
label: '',
|
||||
value: '',
|
||||
secret: false
|
||||
};
|
||||
$scope.new_custom_field = angular.copy(_customField);
|
||||
|
||||
$scope.addCustomField = function () {
|
||||
if (!$scope.new_custom_field.label) {
|
||||
NotificationService.showNotification('Please fill in a label', 3000);
|
||||
}
|
||||
if (!$scope.new_custom_field.value) {
|
||||
NotificationService.showNotification('Please fill in a value!', 3000);
|
||||
}
|
||||
if (!$scope.new_custom_field.label || !$scope.new_custom_field.value) {
|
||||
return;
|
||||
}
|
||||
$scope.storedCredential.custom_fields.push(angular.copy($scope.new_custom_field));
|
||||
$scope.new_custom_field = angular.copy(_customField);
|
||||
};
|
||||
|
||||
$scope.deleteCustomField = function (field) {
|
||||
var idx = $scope.storedCredential.custom_fields.indexOf(field);
|
||||
$scope.storedCredential.custom_fields.splice(idx, 1);
|
||||
};
|
||||
|
||||
$scope.new_file = {
|
||||
name: '',
|
||||
data: null
|
||||
};
|
||||
|
||||
$scope.deleteFile = function (file) {
|
||||
var idx = $scope.storedCredential.files.indexOf(file);
|
||||
FileService.deleteFile(file).then(function () {
|
||||
$scope.storedCredential.files.splice(idx, 1);
|
||||
});
|
||||
};
|
||||
|
||||
$scope.fileLoaded = function (file) {
|
||||
var key;
|
||||
var _file = {
|
||||
filename: file.name,
|
||||
size: file.size,
|
||||
mimetype: file.type,
|
||||
data: file.data
|
||||
};
|
||||
|
||||
if (!$scope.storedCredential.hasOwnProperty('acl') && $scope.storedCredential.hasOwnProperty('shared_key')) {
|
||||
|
||||
if ($scope.storedCredential.shared_key) {
|
||||
key = EncryptService.decryptString(angular.copy($scope.storedCredential.shared_key));
|
||||
$scope.pwSettings = VaultService.getVaultSetting('pwSettings',
|
||||
{
|
||||
'length': 12,
|
||||
'useUppercase': true,
|
||||
'useLowercase': true,
|
||||
'useDigits': true,
|
||||
'useSpecialChars': true,
|
||||
'minimumDigitCount': 3,
|
||||
'avoidAmbiguousCharacters': false,
|
||||
'requireEveryCharType': true,
|
||||
'generateOnCreate': true
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if ($scope.storedCredential.hasOwnProperty('acl')) {
|
||||
key = EncryptService.decryptString(angular.copy($scope.storedCredential.acl.shared_key));
|
||||
$scope.tabs = [{
|
||||
title: 'General',
|
||||
url: 'views/partials/forms/edit_credential/basics.html',
|
||||
color: 'blue'
|
||||
}, {
|
||||
title: 'Password',
|
||||
url: 'views/partials/forms/edit_credential/password.html',
|
||||
color: 'green'
|
||||
}, {
|
||||
title: 'Custom fields',
|
||||
url: 'views/partials/forms/edit_credential/custom_fields.html',
|
||||
color: 'orange'
|
||||
}, {
|
||||
title: 'Files',
|
||||
url: 'views/partials/forms/edit_credential/files.html',
|
||||
color: 'yellow'
|
||||
}, {
|
||||
title: 'OTP',
|
||||
url: 'views/partials/forms/edit_credential/otp.html',
|
||||
color: 'purple'
|
||||
}];
|
||||
|
||||
|
||||
if ($scope.active_vault) {
|
||||
$scope.$parent.selectedVault = true;
|
||||
}
|
||||
var storedCredential = SettingsService.getSetting('edit_credential');
|
||||
|
||||
|
||||
FileService.uploadFile(_file, key).then(function (result) {
|
||||
delete result.file_data;
|
||||
result.filename = EncryptService.decryptString(result.filename, key);
|
||||
$scope.storedCredential.files.push(result);
|
||||
});
|
||||
|
||||
|
||||
$scope.$digest()
|
||||
};
|
||||
|
||||
$scope.fileLoadError = function (error, file) {
|
||||
console.log(error, file)
|
||||
};
|
||||
|
||||
$scope.selected_file = '';
|
||||
$scope.fileprogress = [];
|
||||
$scope.fileSelectProgress = function (progress) {
|
||||
if (progress) {
|
||||
$scope.fileprogress = progress;
|
||||
$scope.$digest()
|
||||
|
||||
}
|
||||
};
|
||||
$scope.renewIntervalValue = 0;
|
||||
$scope.renewIntervalModifier = '0';
|
||||
|
||||
$scope.updateInterval = function (renewIntervalValue, renewIntervalModifier) {
|
||||
var value = parseInt(renewIntervalValue);
|
||||
var modifier = parseInt(renewIntervalModifier);
|
||||
if (value && modifier) {
|
||||
$scope.storedCredential.renew_interval = value * modifier;
|
||||
}
|
||||
};
|
||||
|
||||
$scope.parseQR = function (QRCode) {
|
||||
var re = /otpauth:\/\/(totp|hotp)\/(.*)\?(secret|issuer)=(.*)&(issuer|secret)=(.*)/, parsedQR, qrInfo;
|
||||
parsedQR = (QRCode.qrData.match(re));
|
||||
if (parsedQR)
|
||||
qrInfo = {
|
||||
type: parsedQR[1],
|
||||
label: decodeURIComponent(parsedQR[2]),
|
||||
qr_uri: QRCode
|
||||
};
|
||||
qrInfo[parsedQR[3]] = parsedQR[4];
|
||||
qrInfo[parsedQR[5]] = parsedQR[6];
|
||||
$scope.storedCredential.otp = qrInfo;
|
||||
$scope.$digest()
|
||||
};
|
||||
|
||||
$scope.saveCredential = function () {
|
||||
|
||||
|
||||
if ($scope.new_custom_field.label && $scope.new_custom_field.value) {
|
||||
$scope.storedCredential.custom_fields.push(angular.copy($scope.new_custom_field));
|
||||
}
|
||||
|
||||
|
||||
//@TODO validation
|
||||
//@TODO When credential is expired and has renew interval set, calc new expire time.
|
||||
delete $scope.storedCredential.password_repeat;
|
||||
console.log($scope.storedCredential);
|
||||
if (!$scope.storedCredential.credential_id) {
|
||||
$scope.storedCredential.vault_id = $scope.active_vault.vault_id;
|
||||
CredentialService.createCredential($scope.storedCredential).then(function (result) {
|
||||
$location.path('/vault/' + $routeParams.vault_id);
|
||||
NotificationService.showNotification('Credential created!', 5000)
|
||||
})
|
||||
if (!storedCredential) {
|
||||
CredentialService.getCredential($routeParams.credential_id).then(function (result) {
|
||||
$scope.storedCredential = CredentialService.decryptCredential(angular.copy(result));
|
||||
});
|
||||
} else {
|
||||
$scope.storedCredential = CredentialService.decryptCredential(angular.copy(storedCredential));
|
||||
$scope.storedCredential.password_repeat = angular.copy($scope.storedCredential.password);
|
||||
$scope.storedCredential.expire_time = $scope.storedCredential.expire_time * 1000;
|
||||
}
|
||||
|
||||
$scope.getTags = function ($query) {
|
||||
return TagService.searchTag($query);
|
||||
};
|
||||
|
||||
$scope.currentTab = {
|
||||
title: 'General',
|
||||
url: 'views/partials/forms/edit_credential/basics.html',
|
||||
color: 'blue'
|
||||
};
|
||||
|
||||
$scope.onClickTab = function (tab) {
|
||||
$scope.currentTab = tab;
|
||||
};
|
||||
|
||||
$scope.isActiveTab = function (tab) {
|
||||
return tab.url === $scope.currentTab.url;
|
||||
};
|
||||
|
||||
/**
|
||||
* Below general edit functions
|
||||
*/
|
||||
|
||||
$scope.pwGenerated = function (pass) {
|
||||
$scope.storedCredential.password_repeat = pass;
|
||||
};
|
||||
|
||||
var _customField = {
|
||||
label: '',
|
||||
value: '',
|
||||
secret: false
|
||||
};
|
||||
$scope.new_custom_field = angular.copy(_customField);
|
||||
|
||||
$scope.addCustomField = function () {
|
||||
if (!$scope.new_custom_field.label) {
|
||||
NotificationService.showNotification('Please fill in a label', 3000);
|
||||
}
|
||||
if (!$scope.new_custom_field.value) {
|
||||
NotificationService.showNotification('Please fill in a value!', 3000);
|
||||
}
|
||||
if (!$scope.new_custom_field.label || !$scope.new_custom_field.value) {
|
||||
return;
|
||||
}
|
||||
$scope.storedCredential.custom_fields.push(angular.copy($scope.new_custom_field));
|
||||
$scope.new_custom_field = angular.copy(_customField);
|
||||
};
|
||||
|
||||
$scope.deleteCustomField = function (field) {
|
||||
var idx = $scope.storedCredential.custom_fields.indexOf(field);
|
||||
$scope.storedCredential.custom_fields.splice(idx, 1);
|
||||
};
|
||||
|
||||
$scope.new_file = {
|
||||
name: '',
|
||||
data: null
|
||||
};
|
||||
|
||||
$scope.deleteFile = function (file) {
|
||||
var idx = $scope.storedCredential.files.indexOf(file);
|
||||
FileService.deleteFile(file).then(function () {
|
||||
$scope.storedCredential.files.splice(idx, 1);
|
||||
});
|
||||
};
|
||||
|
||||
$scope.fileLoaded = function (file) {
|
||||
var key;
|
||||
var _file = {
|
||||
filename: file.name,
|
||||
size: file.size,
|
||||
mimetype: file.type,
|
||||
data: file.data
|
||||
};
|
||||
|
||||
var key, _credential;
|
||||
if (!$scope.storedCredential.hasOwnProperty('acl') && $scope.storedCredential.hasOwnProperty('shared_key')) {
|
||||
|
||||
if ($scope.storedCredential.shared_key) {
|
||||
|
@ -256,25 +163,108 @@ angular.module('passmanApp')
|
|||
key = EncryptService.decryptString(angular.copy($scope.storedCredential.acl.shared_key));
|
||||
}
|
||||
|
||||
if (key) {
|
||||
_credential = ShareService.encryptSharedCredential($scope.storedCredential, key);
|
||||
} else {
|
||||
_credential = angular.copy($scope.storedCredential);
|
||||
|
||||
FileService.uploadFile(_file, key).then(function (result) {
|
||||
delete result.file_data;
|
||||
result.filename = EncryptService.decryptString(result.filename, key);
|
||||
$scope.storedCredential.files.push(result);
|
||||
});
|
||||
|
||||
|
||||
$scope.$digest();
|
||||
};
|
||||
|
||||
$scope.fileLoadError = function (error, file) {
|
||||
console.log(error, file);
|
||||
};
|
||||
|
||||
$scope.selected_file = '';
|
||||
$scope.fileprogress = [];
|
||||
$scope.fileSelectProgress = function (progress) {
|
||||
if (progress) {
|
||||
$scope.fileprogress = progress;
|
||||
$scope.$digest();
|
||||
|
||||
}
|
||||
};
|
||||
$scope.renewIntervalValue = 0;
|
||||
$scope.renewIntervalModifier = '0';
|
||||
|
||||
$scope.updateInterval = function (renewIntervalValue, renewIntervalModifier) {
|
||||
var value = parseInt(renewIntervalValue);
|
||||
var modifier = parseInt(renewIntervalModifier);
|
||||
if (value && modifier) {
|
||||
$scope.storedCredential.renew_interval = value * modifier;
|
||||
}
|
||||
};
|
||||
|
||||
$scope.parseQR = function (QRCode) {
|
||||
var re = /otpauth:\/\/(totp|hotp)\/(.*)\?(secret|issuer)=(.*)&(issuer|secret)=(.*)/, parsedQR, qrInfo;
|
||||
parsedQR = (QRCode.qrData.match(re));
|
||||
if (parsedQR)
|
||||
qrInfo = {
|
||||
type: parsedQR[1],
|
||||
label: decodeURIComponent(parsedQR[2]),
|
||||
qr_uri: QRCode
|
||||
};
|
||||
qrInfo[parsedQR[3]] = parsedQR[4];
|
||||
qrInfo[parsedQR[5]] = parsedQR[6];
|
||||
$scope.storedCredential.otp = qrInfo;
|
||||
$scope.$digest();
|
||||
};
|
||||
|
||||
$scope.saveCredential = function () {
|
||||
|
||||
|
||||
if ($scope.new_custom_field.label && $scope.new_custom_field.value) {
|
||||
$scope.storedCredential.custom_fields.push(angular.copy($scope.new_custom_field));
|
||||
}
|
||||
|
||||
delete _credential.shared_key;
|
||||
var _useKey = (key != null);
|
||||
|
||||
CredentialService.updateCredential(_credential, _useKey).then(function (result) {
|
||||
SettingsService.setSetting('edit_credential', null);
|
||||
$location.path('/vault/' + $routeParams.vault_id);
|
||||
NotificationService.showNotification('Credential updated!', 5000)
|
||||
})
|
||||
}
|
||||
//@TODO validation
|
||||
//@TODO When credential is expired and has renew interval set, calc new expire time.
|
||||
delete $scope.storedCredential.password_repeat;
|
||||
console.log($scope.storedCredential);
|
||||
if (!$scope.storedCredential.credential_id) {
|
||||
$scope.storedCredential.vault_id = $scope.active_vault.vault_id;
|
||||
CredentialService.createCredential($scope.storedCredential).then(function (result) {
|
||||
$location.path('/vault/' + $routeParams.vault_id);
|
||||
NotificationService.showNotification('Credential created!', 5000);
|
||||
});
|
||||
} else {
|
||||
|
||||
};
|
||||
var key, _credential;
|
||||
if (!$scope.storedCredential.hasOwnProperty('acl') && $scope.storedCredential.hasOwnProperty('shared_key')) {
|
||||
|
||||
$scope.cancel = function () {
|
||||
$location.path('/vault/' + $routeParams.vault_id);
|
||||
}
|
||||
}]);
|
||||
if ($scope.storedCredential.shared_key) {
|
||||
key = EncryptService.decryptString(angular.copy($scope.storedCredential.shared_key));
|
||||
}
|
||||
}
|
||||
|
||||
if ($scope.storedCredential.hasOwnProperty('acl')) {
|
||||
key = EncryptService.decryptString(angular.copy($scope.storedCredential.acl.shared_key));
|
||||
}
|
||||
|
||||
if (key) {
|
||||
_credential = ShareService.encryptSharedCredential($scope.storedCredential, key);
|
||||
} else {
|
||||
_credential = angular.copy($scope.storedCredential);
|
||||
}
|
||||
|
||||
delete _credential.shared_key;
|
||||
var _useKey = (key != null);
|
||||
|
||||
CredentialService.updateCredential(_credential, _useKey).then(function (result) {
|
||||
SettingsService.setSetting('edit_credential', null);
|
||||
$location.path('/vault/' + $routeParams.vault_id);
|
||||
NotificationService.showNotification('Credential updated!', 5000);
|
||||
});
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
$scope.cancel = function () {
|
||||
$location.path('/vault/' + $routeParams.vault_id);
|
||||
};
|
||||
}]);
|
||||
}());
|
|
@ -1,14 +1,17 @@
|
|||
'use strict';
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* @ngdoc function
|
||||
* @name passmanApp.controller:ImportCtrl
|
||||
* @description
|
||||
* # ImportCtrl
|
||||
* Controller of the passmanApp
|
||||
*/
|
||||
angular.module('passmanApp')
|
||||
.controller('ExportCtrl', ['$scope', function ($scope) {
|
||||
|
||||
}]);
|
||||
/**
|
||||
* @ngdoc function
|
||||
* @name passmanApp.controller:ImportCtrl
|
||||
* @description
|
||||
* # ImportCtrl
|
||||
* Controller of the passmanApp
|
||||
*/
|
||||
angular.module('passmanApp')
|
||||
.controller('ExportCtrl', ['$scope', function ($scope) {
|
||||
|
||||
}]);
|
||||
|
||||
}());
|
|
@ -1,129 +1,129 @@
|
|||
'use strict';
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* @ngdoc function
|
||||
* @name passmanApp.controller:ImportCtrl
|
||||
* @description
|
||||
* # ImportCtrl
|
||||
* Controller of the passmanApp
|
||||
*/
|
||||
angular.module('passmanApp')
|
||||
.controller('ImportCtrl', ['$scope', '$window', 'CredentialService', 'VaultService', function ($scope, $window, CredentialService, VaultService) {
|
||||
$scope.available_importers = [
|
||||
|
||||
];
|
||||
$scope.active_vault = VaultService.getActiveVault();
|
||||
/**
|
||||
* @ngdoc function
|
||||
* @name passmanApp.controller:ImportCtrl
|
||||
* @description
|
||||
* # ImportCtrl
|
||||
* Controller of the passmanApp
|
||||
*/
|
||||
angular.module('passmanApp')
|
||||
.controller('ImportCtrl', ['$scope', '$window', 'CredentialService', 'VaultService', function ($scope, $window, CredentialService, VaultService) {
|
||||
$scope.available_importers = [];
|
||||
$scope.active_vault = VaultService.getActiveVault();
|
||||
|
||||
|
||||
$scope.$watch(function(){
|
||||
return $window.PassmanImporter;
|
||||
}, function (importers) {
|
||||
for(var key in importers){
|
||||
var importer = importers[key];
|
||||
if(importer.hasOwnProperty('info')){
|
||||
$scope.available_importers.push(importer.info);
|
||||
}
|
||||
}
|
||||
}, 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.$digest();
|
||||
};
|
||||
|
||||
$scope.fileLoadError = function (file) {
|
||||
console.error('Error loading file');
|
||||
};
|
||||
$scope.fileSelectProgress = function (progress) {
|
||||
|
||||
};
|
||||
|
||||
var parsed_data;
|
||||
|
||||
$scope.import_progress = {
|
||||
progress: 0,
|
||||
loaded: 0,
|
||||
total: 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);
|
||||
_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]) {
|
||||
$scope.import_progress = {
|
||||
progress: parsed_data_index / parsed_data.length * 100,
|
||||
loaded: parsed_data_index,
|
||||
total: parsed_data.length
|
||||
};
|
||||
|
||||
addCredential(parsed_data_index +1)
|
||||
} else {
|
||||
$scope.import_progress = {
|
||||
progress: 100,
|
||||
loaded: parsed_data.length,
|
||||
total: parsed_data.length
|
||||
};
|
||||
_log('DONE!');
|
||||
$scope.$watch(function () {
|
||||
return $window.PassmanImporter;
|
||||
}, function (importers) {
|
||||
for (var key in importers) {
|
||||
var importer = importers[key];
|
||||
if (importer.hasOwnProperty('info')) {
|
||||
$scope.available_importers.push(importer.info);
|
||||
}
|
||||
}
|
||||
})
|
||||
};
|
||||
}, 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.$digest();
|
||||
};
|
||||
|
||||
$scope.file_read_progress = {
|
||||
percent: 0,
|
||||
loaded: 0,
|
||||
total: 0
|
||||
};
|
||||
$scope.startImport = function(){
|
||||
$scope.import_progress = 0;
|
||||
$scope.file_read_percent = 0;
|
||||
if(file_data){
|
||||
$window.PassmanImporter[$scope.selectedImporter.id]
|
||||
.readFile(file_data)
|
||||
.then(function(parseddata){
|
||||
parsed_data = parseddata;
|
||||
$scope.file_read_progress = {
|
||||
percent: 100,
|
||||
loaded: parsed_data.length,
|
||||
total: parsed_data.length
|
||||
};
|
||||
_log('Parsed '+ parsed_data.length + ' credentials, starting to import');
|
||||
if( parsed_data.length > 0){
|
||||
addCredential(0);
|
||||
} else {
|
||||
// @TODO Show message no data found
|
||||
$scope.fileLoadError = function (file) {
|
||||
console.error('Error loading file');
|
||||
};
|
||||
$scope.fileSelectProgress = function (progress) {
|
||||
|
||||
};
|
||||
|
||||
var parsed_data;
|
||||
|
||||
$scope.import_progress = {
|
||||
progress: 0,
|
||||
loaded: 0,
|
||||
total: 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);
|
||||
_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]) {
|
||||
$scope.import_progress = {
|
||||
progress: parsed_data_index / parsed_data.length * 100,
|
||||
loaded: parsed_data_index,
|
||||
total: parsed_data.length
|
||||
};
|
||||
|
||||
addCredential(parsed_data_index + 1);
|
||||
} else {
|
||||
$scope.import_progress = {
|
||||
progress: 100,
|
||||
loaded: parsed_data.length,
|
||||
total: parsed_data.length
|
||||
};
|
||||
_log('DONE!');
|
||||
}
|
||||
}
|
||||
}).progress(function(progress){
|
||||
$scope.file_read_progress = progress;
|
||||
$scope.$digest();
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
}]);
|
||||
|
||||
$scope.file_read_progress = {
|
||||
percent: 0,
|
||||
loaded: 0,
|
||||
total: 0
|
||||
};
|
||||
$scope.startImport = function () {
|
||||
$scope.import_progress = 0;
|
||||
$scope.file_read_percent = 0;
|
||||
if (file_data) {
|
||||
$window.PassmanImporter[$scope.selectedImporter.id]
|
||||
.readFile(file_data)
|
||||
.then(function (parseddata) {
|
||||
parsed_data = parseddata;
|
||||
$scope.file_read_progress = {
|
||||
percent: 100,
|
||||
loaded: parsed_data.length,
|
||||
total: parsed_data.length
|
||||
};
|
||||
_log('Parsed ' + parsed_data.length + ' credentials, starting to import');
|
||||
if (parsed_data.length > 0) {
|
||||
addCredential(0);
|
||||
} else {
|
||||
// @TODO Show message no data found
|
||||
}
|
||||
}).progress(function (progress) {
|
||||
$scope.file_read_progress = progress;
|
||||
$scope.$digest();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
}]);
|
||||
|
||||
}());
|
|
@ -1,33 +1,35 @@
|
|||
'use strict';
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* @ngdoc function
|
||||
* @name passmanApp.controller:MainCtrl
|
||||
* @description
|
||||
* # MainCtrl
|
||||
* Controller of the passmanApp
|
||||
*/
|
||||
angular.module('passmanApp')
|
||||
.controller('MainCtrl', ['$scope', '$rootScope', '$location', function ($scope, $rootScope, $location) {
|
||||
$scope.selectedVault = false;
|
||||
|
||||
$scope.http_warning_hidden = true;
|
||||
if($location.$$protocol === 'http'){
|
||||
$scope.using_http = true;
|
||||
$scope.http_warning_hidden = false;
|
||||
|
||||
}
|
||||
|
||||
$rootScope.setHttpWarning = function(state){
|
||||
$scope.http_warning_hidden = state;
|
||||
};
|
||||
|
||||
$rootScope.$on('app_menu', function(evt, shown){
|
||||
$scope.app_sidebar = shown;
|
||||
});
|
||||
|
||||
$rootScope.$on('logout', function () {
|
||||
/**
|
||||
* @ngdoc function
|
||||
* @name passmanApp.controller:MainCtrl
|
||||
* @description
|
||||
* # MainCtrl
|
||||
* Controller of the passmanApp
|
||||
*/
|
||||
angular.module('passmanApp')
|
||||
.controller('MainCtrl', ['$scope', '$rootScope', '$location', function ($scope, $rootScope, $location) {
|
||||
$scope.selectedVault = false;
|
||||
})
|
||||
}]);
|
||||
|
||||
$scope.http_warning_hidden = true;
|
||||
if ($location.$$protocol === 'http') {
|
||||
$scope.using_http = true;
|
||||
$scope.http_warning_hidden = false;
|
||||
|
||||
}
|
||||
|
||||
$rootScope.setHttpWarning = function (state) {
|
||||
$scope.http_warning_hidden = state;
|
||||
};
|
||||
|
||||
$rootScope.$on('app_menu', function (evt, shown) {
|
||||
$scope.app_sidebar = shown;
|
||||
});
|
||||
|
||||
$rootScope.$on('logout', function () {
|
||||
$scope.selectedVault = false;
|
||||
});
|
||||
}]);
|
||||
|
||||
}());
|
|
@ -1,79 +1,82 @@
|
|||
'use strict';
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* @ngdoc function
|
||||
* @name passmanApp.controller:MenuCtrl
|
||||
* @description
|
||||
* # MenuCtrl
|
||||
* Controller of the passmanApp
|
||||
*/
|
||||
angular.module('passmanApp')
|
||||
.controller('MenuCtrl', ['$scope', 'VaultService', 'SettingsService', '$location', '$rootScope', 'TagService',
|
||||
function ($scope, VaultService, SettingsService, $location, $rootScope, TagService) {
|
||||
$rootScope.logout = function () {
|
||||
SettingsService.setSetting('defaultVaultPass', false);
|
||||
$rootScope.$broadcast('logout');
|
||||
$location.path('/');
|
||||
};
|
||||
|
||||
$scope.selectedTags = [];
|
||||
$scope.getTags = function ($query) {
|
||||
return TagService.searchTag($query);
|
||||
};
|
||||
/**
|
||||
* @ngdoc function
|
||||
* @name passmanApp.controller:MenuCtrl
|
||||
* @description
|
||||
* # MenuCtrl
|
||||
* Controller of the passmanApp
|
||||
*/
|
||||
angular.module('passmanApp')
|
||||
.controller('MenuCtrl', ['$scope', 'VaultService', 'SettingsService', '$location', '$rootScope', 'TagService',
|
||||
function ($scope, VaultService, SettingsService, $location, $rootScope, TagService) {
|
||||
$rootScope.logout = function () {
|
||||
SettingsService.setSetting('defaultVaultPass', false);
|
||||
$rootScope.$broadcast('logout');
|
||||
$location.path('/');
|
||||
};
|
||||
|
||||
$scope.$watch(function(){
|
||||
return VaultService.getActiveVault()
|
||||
}, function(vault){
|
||||
$scope.active_vault = vault;
|
||||
});
|
||||
$scope.selectedTags = [];
|
||||
$scope.getTags = function ($query) {
|
||||
return TagService.searchTag($query);
|
||||
};
|
||||
|
||||
$scope.$watch(function () {
|
||||
return VaultService.getActiveVault();
|
||||
}, function (vault) {
|
||||
$scope.active_vault = vault;
|
||||
});
|
||||
|
||||
$scope.filtered_tags = [];
|
||||
$rootScope.$on('limit_tags_in_list', function (evt, tags) {
|
||||
$scope.filtered_tags = [];
|
||||
for (var i = 0; i < tags.length; i++) {
|
||||
var tag = {
|
||||
text: tags[i]
|
||||
};
|
||||
$rootScope.$on('limit_tags_in_list', function (evt, tags) {
|
||||
$scope.filtered_tags = [];
|
||||
for (var i = 0; i < tags.length; i++) {
|
||||
var tag = {
|
||||
text: tags[i]
|
||||
};
|
||||
|
||||
var found = false;
|
||||
for (var x = 0; x < $scope.selectedTags.length; x++) {
|
||||
if($scope.selectedTags[x].text === tag.text){
|
||||
found = true;
|
||||
var found = false;
|
||||
for (var x = 0; x < $scope.selectedTags.length; x++) {
|
||||
if ($scope.selectedTags[x].text === tag.text) {
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
if (found === false) {
|
||||
$scope.filtered_tags.push(tag);
|
||||
}
|
||||
|
||||
}
|
||||
if(found === false){
|
||||
$scope.filtered_tags.push(tag);
|
||||
});
|
||||
|
||||
$scope.$watch('selectedTags', function () {
|
||||
$rootScope.$broadcast('selected_tags_updated', $scope.selectedTags);
|
||||
}, true);
|
||||
|
||||
$scope.tagClicked = function (tag) {
|
||||
$scope.selectedTags.push(tag);
|
||||
};
|
||||
|
||||
$scope.available_tags = TagService.getTags();
|
||||
|
||||
$scope.$watch(function () {
|
||||
if ($scope.selectedTags.length === 0) {
|
||||
return TagService.getTags();
|
||||
} else {
|
||||
return $scope.filtered_tags;
|
||||
}
|
||||
}, function (tags) {
|
||||
$scope.available_tags = tags;
|
||||
}, true);
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
$scope.$watch('selectedTags', function () {
|
||||
$rootScope.$broadcast('selected_tags_updated', $scope.selectedTags)
|
||||
}, true);
|
||||
|
||||
$scope.tagClicked = function (tag) {
|
||||
$scope.selectedTags.push(tag)
|
||||
};
|
||||
|
||||
$scope.available_tags = TagService.getTags();
|
||||
|
||||
$scope.$watch(function () {
|
||||
if ($scope.selectedTags.length === 0) {
|
||||
return TagService.getTags();
|
||||
} else {
|
||||
return $scope.filtered_tags;
|
||||
}
|
||||
}, function (tags) {
|
||||
$scope.available_tags = tags;
|
||||
}, true);
|
||||
|
||||
$scope.toggleDeleteTime = function () {
|
||||
if ($scope.delete_time > 0) {
|
||||
$scope.delete_time = 0;
|
||||
} else {
|
||||
$scope.delete_time = 1;
|
||||
}
|
||||
$rootScope.$broadcast('set_delete_time', $scope.delete_time);
|
||||
};
|
||||
}]);
|
||||
$scope.toggleDeleteTime = function () {
|
||||
if ($scope.delete_time > 0) {
|
||||
$scope.delete_time = 0;
|
||||
} else {
|
||||
$scope.delete_time = 1;
|
||||
}
|
||||
$rootScope.$broadcast('set_delete_time', $scope.delete_time);
|
||||
};
|
||||
}]);
|
||||
}());
|
|
@ -1,32 +1,34 @@
|
|||
/**
|
||||
* @ngdoc function
|
||||
* @name passmanApp.controller:MainCtrl
|
||||
* @description
|
||||
* # MainCtrl
|
||||
* Controller of the passmanApp
|
||||
*/
|
||||
angular.module('passmanApp')
|
||||
.controller('PublicSharedCredential', ['$scope', 'ShareService','$window', function ($scope, ShareService, $window) {
|
||||
$scope.test = 'hello world';
|
||||
//@TODO Add download files
|
||||
$scope.loading = false;
|
||||
$scope.loadSharedCredential = function () {
|
||||
$scope.loading = true;
|
||||
var data = window.atob($window.location.hash.replace('#','')).split('<::>');
|
||||
var guid = data[0];
|
||||
var _key = data[1];
|
||||
ShareService.getPublicSharedCredential(guid).then(function (sharedCredential) {
|
||||
$scope.loading = false;
|
||||
if(sharedCredential.status === 200){
|
||||
var _credential = ShareService.decryptSharedCredential(sharedCredential.data.credential_data, _key);
|
||||
$scope.shared_credential = _credential;
|
||||
} else {
|
||||
$scope.expired = true;
|
||||
}
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
})
|
||||
/**
|
||||
* @ngdoc function
|
||||
* @name passmanApp.controller:MainCtrl
|
||||
* @description
|
||||
* # MainCtrl
|
||||
* Controller of the passmanApp
|
||||
*/
|
||||
angular.module('passmanApp')
|
||||
.controller('PublicSharedCredential', ['$scope', 'ShareService', '$window', function ($scope, ShareService, $window) {
|
||||
$scope.test = 'hello world';
|
||||
//@TODO Add download files
|
||||
$scope.loading = false;
|
||||
$scope.loadSharedCredential = function () {
|
||||
$scope.loading = true;
|
||||
var data = window.atob($window.location.hash.replace('#', '')).split('<::>');
|
||||
var guid = data[0];
|
||||
var _key = data[1];
|
||||
ShareService.getPublicSharedCredential(guid).then(function (sharedCredential) {
|
||||
$scope.loading = false;
|
||||
if (sharedCredential.status === 200) {
|
||||
var _credential = ShareService.decryptSharedCredential(sharedCredential.data.credential_data, _key);
|
||||
$scope.shared_credential = _credential;
|
||||
} else {
|
||||
$scope.expired = true;
|
||||
}
|
||||
|
||||
}
|
||||
}])
|
||||
;
|
||||
});
|
||||
|
||||
};
|
||||
}]);
|
||||
}());
|
||||
|
|
|
@ -1,127 +1,130 @@
|
|||
'use strict';
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* @ngdoc function
|
||||
* @name passmanApp.controller:RevisionCtrl
|
||||
* @description
|
||||
* # RevisionCtrl
|
||||
* Controller of the passmanApp
|
||||
*/
|
||||
angular.module('passmanApp')
|
||||
.controller('RevisionCtrl', ['$scope', 'SettingsService', 'VaultService', 'CredentialService', '$location', '$routeParams', '$rootScope', 'NotificationService', '$filter', 'ShareService','EncryptService',
|
||||
function ($scope, SettingsService, VaultService, CredentialService, $location, $routeParams, $rootScope, NotificationService, $filter, ShareService, EncryptService) {
|
||||
$scope.active_vault = VaultService.getActiveVault();
|
||||
if (!SettingsService.getSetting('defaultVault') || !SettingsService.getSetting('defaultVaultPass')) {
|
||||
if (!$scope.active_vault) {
|
||||
$location.path('/')
|
||||
}
|
||||
} else {
|
||||
if (SettingsService.getSetting('defaultVault') && SettingsService.getSetting('defaultVaultPass')) {
|
||||
var _vault = angular.copy(SettingsService.getSetting('defaultVault'));
|
||||
_vault.vaultKey = SettingsService.getSetting('defaultVaultPass');
|
||||
VaultService.setActiveVault(_vault);
|
||||
VaultService.getVault(_vault).then(function (vault) {
|
||||
vault.vaultKey = SettingsService.getSetting('defaultVaultPass');
|
||||
VaultService.setActiveVault(vault);
|
||||
$scope.active_vault = vault;
|
||||
$scope.$parent.selectedVault = true;
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
if ($scope.active_vault) {
|
||||
$scope.$parent.selectedVault = true;
|
||||
}
|
||||
var storedCredential = SettingsService.getSetting('revision_credential');
|
||||
|
||||
var getRevisions = function () {
|
||||
CredentialService.getRevisions($scope.storedCredential.guid).then(function (revisions) {
|
||||
$scope.revisions = revisions;
|
||||
})
|
||||
};
|
||||
|
||||
if (!storedCredential) {
|
||||
CredentialService.getCredential($routeParams.credential_id).then(function (result) {
|
||||
$scope.storedCredential = CredentialService.decryptCredential(angular.copy(result));
|
||||
getRevisions();
|
||||
});
|
||||
} else {
|
||||
$scope.storedCredential = CredentialService.decryptCredential(angular.copy(storedCredential));
|
||||
getRevisions();
|
||||
}
|
||||
|
||||
$scope.selectRevision = function (revision) {
|
||||
var key;
|
||||
$scope.selectedRevision = angular.copy(revision);
|
||||
|
||||
if(!$scope.storedCredential.hasOwnProperty('acl') && $scope.storedCredential.hasOwnProperty('shared_key')){
|
||||
if($scope.storedCredential.shared_key) {
|
||||
key = EncryptService.decryptString(angular.copy($scope.storedCredential.shared_key));
|
||||
/**
|
||||
* @ngdoc function
|
||||
* @name passmanApp.controller:RevisionCtrl
|
||||
* @description
|
||||
* # RevisionCtrl
|
||||
* Controller of the passmanApp
|
||||
*/
|
||||
angular.module('passmanApp')
|
||||
.controller('RevisionCtrl', ['$scope', 'SettingsService', 'VaultService', 'CredentialService', '$location', '$routeParams', '$rootScope', 'NotificationService', '$filter', 'ShareService', 'EncryptService',
|
||||
function ($scope, SettingsService, VaultService, CredentialService, $location, $routeParams, $rootScope, NotificationService, $filter, ShareService, EncryptService) {
|
||||
$scope.active_vault = VaultService.getActiveVault();
|
||||
if (!SettingsService.getSetting('defaultVault') || !SettingsService.getSetting('defaultVaultPass')) {
|
||||
if (!$scope.active_vault) {
|
||||
$location.path('/');
|
||||
}
|
||||
} else {
|
||||
if (SettingsService.getSetting('defaultVault') && SettingsService.getSetting('defaultVaultPass')) {
|
||||
var _vault = angular.copy(SettingsService.getSetting('defaultVault'));
|
||||
_vault.vaultKey = SettingsService.getSetting('defaultVaultPass');
|
||||
VaultService.setActiveVault(_vault);
|
||||
VaultService.getVault(_vault).then(function (vault) {
|
||||
vault.vaultKey = SettingsService.getSetting('defaultVaultPass');
|
||||
VaultService.setActiveVault(vault);
|
||||
$scope.active_vault = vault;
|
||||
$scope.$parent.selectedVault = true;
|
||||
});
|
||||
}
|
||||
}
|
||||
if($scope.storedCredential.hasOwnProperty('acl')){
|
||||
key = EncryptService.decryptString(angular.copy($scope.storedCredential.acl.shared_key));
|
||||
}
|
||||
|
||||
if(key){
|
||||
$scope.selectedRevision.credential_data = ShareService.decryptSharedCredential(angular.copy(revision.credential_data), key);
|
||||
if ($scope.active_vault) {
|
||||
$scope.$parent.selectedVault = true;
|
||||
}
|
||||
var storedCredential = SettingsService.getSetting('revision_credential');
|
||||
|
||||
var getRevisions = function () {
|
||||
CredentialService.getRevisions($scope.storedCredential.guid).then(function (revisions) {
|
||||
$scope.revisions = revisions;
|
||||
});
|
||||
};
|
||||
|
||||
if (!storedCredential) {
|
||||
CredentialService.getCredential($routeParams.credential_id).then(function (result) {
|
||||
$scope.storedCredential = CredentialService.decryptCredential(angular.copy(result));
|
||||
getRevisions();
|
||||
});
|
||||
} else {
|
||||
$scope.selectedRevision.credential_data = CredentialService.decryptCredential(angular.copy(revision.credential_data));
|
||||
$scope.storedCredential = CredentialService.decryptCredential(angular.copy(storedCredential));
|
||||
getRevisions();
|
||||
}
|
||||
|
||||
$rootScope.$emit('app_menu', true);
|
||||
};
|
||||
$scope.selectRevision = function (revision) {
|
||||
var key;
|
||||
$scope.selectedRevision = angular.copy(revision);
|
||||
|
||||
$scope.closeSelected = function () {
|
||||
$rootScope.$emit('app_menu', false);
|
||||
$scope.selectedRevision = false;
|
||||
};
|
||||
|
||||
$scope.deleteRevision = function (revision) {
|
||||
CredentialService.deleteRevision($scope.storedCredential.guid, revision.revision_id).then(function () {
|
||||
for (var i = 0; i < $scope.revisions.length; i++) {
|
||||
if ($scope.revisions[i].revision_id == revision.revision_id) {
|
||||
$scope.revisions.splice(i, 1);
|
||||
NotificationService.showNotification('Revision deleted', 5000);
|
||||
break;
|
||||
if (!$scope.storedCredential.hasOwnProperty('acl') && $scope.storedCredential.hasOwnProperty('shared_key')) {
|
||||
if ($scope.storedCredential.shared_key) {
|
||||
key = EncryptService.decryptString(angular.copy($scope.storedCredential.shared_key));
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
$scope.restoreRevision = function (revision) {
|
||||
var key;
|
||||
var _revision = angular.copy(revision);
|
||||
var _credential = _revision.credential_data;
|
||||
|
||||
if(!$scope.storedCredential.hasOwnProperty('acl') && $scope.storedCredential.hasOwnProperty('shared_key')){
|
||||
if ($scope.storedCredential.shared_key) {
|
||||
key = EncryptService.decryptString(angular.copy($scope.storedCredential.shared_key));
|
||||
if ($scope.storedCredential.hasOwnProperty('acl')) {
|
||||
key = EncryptService.decryptString(angular.copy($scope.storedCredential.acl.shared_key));
|
||||
}
|
||||
}
|
||||
if($scope.storedCredential.hasOwnProperty('acl')){
|
||||
key = EncryptService.decryptString(angular.copy($scope.storedCredential.acl.shared_key));
|
||||
}
|
||||
if(key){
|
||||
_credential = ShareService.encryptSharedCredential(_credential, key);
|
||||
}
|
||||
delete _credential.shared_key;
|
||||
|
||||
//Used in activity
|
||||
_credential.revision_created = $filter('date')(_revision.created * 1000 , "dd-MM-yyyy @ HH:mm:ss");
|
||||
CredentialService.updateCredential(_credential, (key)).then(function (result) {
|
||||
SettingsService.setSetting('revision_credential', null);
|
||||
if (key) {
|
||||
$scope.selectedRevision.credential_data = ShareService.decryptSharedCredential(angular.copy(revision.credential_data), key);
|
||||
} else {
|
||||
$scope.selectedRevision.credential_data = CredentialService.decryptCredential(angular.copy(revision.credential_data));
|
||||
}
|
||||
|
||||
$rootScope.$emit('app_menu', true);
|
||||
};
|
||||
|
||||
$scope.closeSelected = function () {
|
||||
$rootScope.$emit('app_menu', false);
|
||||
$scope.selectedRevision = false;
|
||||
};
|
||||
|
||||
$scope.deleteRevision = function (revision) {
|
||||
CredentialService.deleteRevision($scope.storedCredential.guid, revision.revision_id).then(function () {
|
||||
for (var i = 0; i < $scope.revisions.length; i++) {
|
||||
if ($scope.revisions[i].revision_id === revision.revision_id) {
|
||||
$scope.revisions.splice(i, 1);
|
||||
NotificationService.showNotification('Revision deleted', 5000);
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
$scope.restoreRevision = function (revision) {
|
||||
var key;
|
||||
var _revision = angular.copy(revision);
|
||||
var _credential = _revision.credential_data;
|
||||
|
||||
if (!$scope.storedCredential.hasOwnProperty('acl') && $scope.storedCredential.hasOwnProperty('shared_key')) {
|
||||
if ($scope.storedCredential.shared_key) {
|
||||
key = EncryptService.decryptString(angular.copy($scope.storedCredential.shared_key));
|
||||
}
|
||||
}
|
||||
if ($scope.storedCredential.hasOwnProperty('acl')) {
|
||||
key = EncryptService.decryptString(angular.copy($scope.storedCredential.acl.shared_key));
|
||||
}
|
||||
if (key) {
|
||||
_credential = ShareService.encryptSharedCredential(_credential, key);
|
||||
}
|
||||
delete _credential.shared_key;
|
||||
|
||||
//Used in activity
|
||||
_credential.revision_created = $filter('date')(_revision.created * 1000, "dd-MM-yyyy @ HH:mm:ss");
|
||||
CredentialService.updateCredential(_credential, (key)).then(function (result) {
|
||||
SettingsService.setSetting('revision_credential', null);
|
||||
$rootScope.$emit('app_menu', false);
|
||||
$location.path('/vault/' + $routeParams.vault_id);
|
||||
NotificationService.showNotification('Revision restored!', 5000);
|
||||
});
|
||||
};
|
||||
|
||||
$scope.cancel = function () {
|
||||
$location.path('/vault/' + $routeParams.vault_id);
|
||||
NotificationService.showNotification('Revision restored!', 5000)
|
||||
})
|
||||
};
|
||||
$scope.storedCredential = null;
|
||||
SettingsService.setSetting('revision_credential', null);
|
||||
};
|
||||
|
||||
$scope.cancel = function () {
|
||||
$location.path('/vault/' + $routeParams.vault_id);
|
||||
$scope.storedCredential = null;
|
||||
SettingsService.setSetting('revision_credential', null);
|
||||
}
|
||||
|
||||
}]);
|
||||
}]);
|
||||
|
||||
}());
|
|
@ -1,220 +1,222 @@
|
|||
'use strict';
|
||||
|
||||
/**
|
||||
* @ngdoc function
|
||||
* @name passmanApp.controller:SettingsCtrl
|
||||
* @description
|
||||
* # SettingsCtrl
|
||||
* Controller of the passmanApp
|
||||
*/
|
||||
angular.module('passmanApp')
|
||||
.controller('SettingsCtrl', ['$scope', '$rootScope', 'SettingsService', 'VaultService', 'CredentialService', '$location', '$routeParams', '$http', 'EncryptService','NotificationService','$sce',
|
||||
function ($scope, $rootScope, SettingsService, VaultService, CredentialService, $location, $routeParams, $http, EncryptService, NotificationService, $sce) {
|
||||
$scope.vault_settings = {};
|
||||
$scope.new_vault_name = '';
|
||||
$scope.active_vault = VaultService.getActiveVault();
|
||||
if (!SettingsService.getSetting('defaultVault') || !SettingsService.getSetting('defaultVaultPass')) {
|
||||
if (!$scope.active_vault) {
|
||||
$location.path('/')
|
||||
}
|
||||
} else {
|
||||
if (SettingsService.getSetting('defaultVault') && SettingsService.getSetting('defaultVaultPass')) {
|
||||
var _vault = angular.copy(SettingsService.getSetting('defaultVault'));
|
||||
VaultService.getVault(_vault).then(function (vault) {
|
||||
vault.vaultKey = SettingsService.getSetting('defaultVaultPass');
|
||||
VaultService.setActiveVault(vault);
|
||||
$scope.active_vault = vault;
|
||||
$scope.$parent.selectedVault = true;
|
||||
$scope.vault_settings.pwSettings = VaultService.getVaultSetting('pwSettings',
|
||||
{
|
||||
'length': 12,
|
||||
'useUppercase': true,
|
||||
'useLowercase': true,
|
||||
'useDigits': true,
|
||||
'useSpecialChars': true,
|
||||
'minimumDigitCount': 3,
|
||||
'avoidAmbiguousCharacters': false,
|
||||
'requireEveryCharType': true,
|
||||
'generateOnCreate': true
|
||||
});
|
||||
$scope.new_vault_name = angular.copy($scope.active_vault.name);
|
||||
})
|
||||
}
|
||||
}
|
||||
var http = location.protocol, slashes = http.concat("//"), host = slashes.concat(window.location.hostname), complete = host + location.pathname;
|
||||
$scope.bookmarklet = $sce.trustAsHtml("<a class=\"button\" href=\"javascript:(function(){var a=window,b=document,c=encodeURIComponent,e=c(document.title),d=a.open('" + complete + "bookmarklet?url='+c(b.location)+'&title='+e,'bkmk_popup','left='+((a.screenX||a.screenLeft)+10)+',top='+((a.screenY||a.screenTop)+10)+',height=750px,width=475px,resizable=0,alwaysRaised=1');a.setTimeout(function(){d.focus()},300);})();\">Save in passman</a>");
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
|
||||
|
||||
$scope.saveVaultSettings = function () {
|
||||
var _vault = $scope.active_vault;
|
||||
_vault.name = $scope.new_vault_name;
|
||||
_vault.vault_settings = angular.copy($scope.vault_settings);
|
||||
VaultService.updateVault(_vault).then(function () {
|
||||
VaultService.setActiveVault(_vault);
|
||||
$scope.active_vault.name = angular.copy(_vault.name);
|
||||
NotificationService.showNotification('Settings saved', 5000);
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
$scope.tabs = [
|
||||
{
|
||||
title: 'General settings',
|
||||
url: 'views/partials/forms/settings/general_settings.html'
|
||||
},
|
||||
{
|
||||
title: 'Password Audit',
|
||||
url: 'views/partials/forms/settings/tool.html'
|
||||
|
||||
},
|
||||
{
|
||||
title: 'Password settings',
|
||||
url: 'views/partials/forms/settings/password_settings.html'
|
||||
|
||||
},
|
||||
{
|
||||
title: 'Import credentials',
|
||||
url: 'views/partials/forms/settings/import.html'
|
||||
|
||||
},
|
||||
{
|
||||
title: 'Export credentials',
|
||||
url: 'views/partials/forms/settings/export.html'
|
||||
|
||||
},
|
||||
{
|
||||
title: 'Sharing',
|
||||
url: 'views/partials/forms/settings/sharing.html'
|
||||
}
|
||||
];
|
||||
|
||||
$scope.currentTab = $scope.tabs[0];
|
||||
|
||||
$scope.onClickTab = function (tab) {
|
||||
$scope.currentTab = tab;
|
||||
};
|
||||
|
||||
$scope.isActiveTab = function (tab) {
|
||||
return tab.url == $scope.currentTab.url;
|
||||
};
|
||||
|
||||
var getPassmanVersion = function () {
|
||||
var url = OC.generateUrl('apps/passman/api/internal/version');
|
||||
$http.get(url).then(function (result) {
|
||||
$scope.passman_version = result.data.version;
|
||||
})
|
||||
};
|
||||
getPassmanVersion();
|
||||
|
||||
$scope.$watch(function () {
|
||||
return VaultService.getActiveVault()
|
||||
}, function (vault) {
|
||||
if (vault) {
|
||||
$scope.active_vault = vault;
|
||||
}
|
||||
});
|
||||
|
||||
if ($scope.active_vault) {
|
||||
|
||||
}
|
||||
|
||||
$rootScope.$on('logout', function () {
|
||||
$scope.selectedVault = false;
|
||||
});
|
||||
$scope.startScan = function (minStrength) {
|
||||
VaultService.getVault($scope.active_vault).then(function (vault) {
|
||||
var results = [];
|
||||
for (var i = 0; i < vault.credentials.length; i++) {
|
||||
var c = angular.copy(vault.credentials[i]);
|
||||
if (c.password && c.hidden == 0) {
|
||||
c = CredentialService.decryptCredential(c);
|
||||
if(c.password){
|
||||
var zxcvbn_result = zxcvbn(c.password);
|
||||
if (zxcvbn_result.score <= minStrength) {
|
||||
results.push({
|
||||
credential_id: c.credential_id,
|
||||
label: c.label,
|
||||
password: c.password,
|
||||
password_zxcvbn_result: zxcvbn_result
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
//@todo loop custom fields (if any and check secret fields
|
||||
}
|
||||
$scope.scan_result = results;
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
$scope.cur_state = {};
|
||||
|
||||
$scope.changeVaultPassword = function (oldVaultPass,newVaultPass,newVaultPass2) {
|
||||
if(oldVaultPass != VaultService.getActiveVault().vaultKey){
|
||||
$scope.error ='Your old password is incorrect!'
|
||||
return;
|
||||
}
|
||||
if(newVaultPass != newVaultPass2){
|
||||
$scope.error ='New passwords do not match!';
|
||||
return;
|
||||
}
|
||||
VaultService.getVault($scope.active_vault).then(function (vault) {
|
||||
var _selected_credentials = [];
|
||||
if(vault.credentials.length === 0){
|
||||
/**
|
||||
* @ngdoc function
|
||||
* @name passmanApp.controller:SettingsCtrl
|
||||
* @description
|
||||
* # SettingsCtrl
|
||||
* Controller of the passmanApp
|
||||
*/
|
||||
angular.module('passmanApp')
|
||||
.controller('SettingsCtrl', ['$scope', '$rootScope', 'SettingsService', 'VaultService', 'CredentialService', '$location', '$routeParams', '$http', 'EncryptService', 'NotificationService', '$sce',
|
||||
function ($scope, $rootScope, SettingsService, VaultService, CredentialService, $location, $routeParams, $http, EncryptService, NotificationService, $sce) {
|
||||
$scope.vault_settings = {};
|
||||
$scope.new_vault_name = '';
|
||||
$scope.active_vault = VaultService.getActiveVault();
|
||||
if (!SettingsService.getSetting('defaultVault') || !SettingsService.getSetting('defaultVaultPass')) {
|
||||
if (!$scope.active_vault) {
|
||||
$location.path('/');
|
||||
}
|
||||
for(var i =0; i < vault.credentials.length; i++){
|
||||
var _credential = vault.credentials[i];
|
||||
if(_credential.shared_key == null || _credential.shared_key == ''){
|
||||
_selected_credentials.push(_credential);
|
||||
}
|
||||
}
|
||||
$scope.change_pw = {
|
||||
percent: 0,
|
||||
done: 0,
|
||||
total: _selected_credentials.length
|
||||
};
|
||||
var changeCredential = function(index, oldVaultPass, newVaultPass){
|
||||
CredentialService.reencryptCredential(_selected_credentials[index].guid, oldVaultPass, newVaultPass).progress(function(data){
|
||||
$scope.cur_state = data;
|
||||
}).then(function(data){
|
||||
var percent = index / _selected_credentials.length * 100;
|
||||
$scope.change_pw = {
|
||||
percent: percent,
|
||||
done: index+1,
|
||||
total: _selected_credentials.length
|
||||
};
|
||||
if(index < _selected_credentials.length -1){
|
||||
changeCredential(index+1, oldVaultPass, newVaultPass);
|
||||
} else {
|
||||
console.log('Update complete!');
|
||||
|
||||
vault.private_sharing_key = EncryptService.decryptString(angular.copy(vault.private_sharing_key), oldVaultPass);
|
||||
vault.private_sharing_key = EncryptService.encryptString(vault.private_sharing_key, newVaultPass);
|
||||
VaultService.updateSharingKeys(vault).then(function (result) {
|
||||
$rootScope.$broadcast('logout')
|
||||
NotificationService.showNotification('Please login with your new vault password', 5000);
|
||||
} else {
|
||||
if (SettingsService.getSetting('defaultVault') && SettingsService.getSetting('defaultVaultPass')) {
|
||||
var _vault = angular.copy(SettingsService.getSetting('defaultVault'));
|
||||
VaultService.getVault(_vault).then(function (vault) {
|
||||
vault.vaultKey = SettingsService.getSetting('defaultVaultPass');
|
||||
VaultService.setActiveVault(vault);
|
||||
$scope.active_vault = vault;
|
||||
$scope.$parent.selectedVault = true;
|
||||
$scope.vault_settings.pwSettings = VaultService.getVaultSetting('pwSettings',
|
||||
{
|
||||
'length': 12,
|
||||
'useUppercase': true,
|
||||
'useLowercase': true,
|
||||
'useDigits': true,
|
||||
'useSpecialChars': true,
|
||||
'minimumDigitCount': 3,
|
||||
'avoidAmbiguousCharacters': false,
|
||||
'requireEveryCharType': true,
|
||||
'generateOnCreate': true
|
||||
});
|
||||
}
|
||||
$scope.new_vault_name = angular.copy($scope.active_vault.name);
|
||||
});
|
||||
};
|
||||
changeCredential(0, VaultService.getActiveVault().vaultKey, newVaultPass);
|
||||
}
|
||||
}
|
||||
var http = location.protocol, slashes = http.concat("//"), host = slashes.concat(window.location.hostname), complete = host + location.pathname;
|
||||
$scope.bookmarklet = $sce.trustAsHtml("<a class=\"button\" href=\"javascript:(function(){var a=window,b=document,c=encodeURIComponent,e=c(document.title),d=a.open('" + complete + "bookmarklet?url='+c(b.location)+'&title='+e,'bkmk_popup','left='+((a.screenX||a.screenLeft)+10)+',top='+((a.screenY||a.screenTop)+10)+',height=750px,width=475px,resizable=0,alwaysRaised=1');a.setTimeout(function(){d.focus()},300);})();\">Save in passman</a>");
|
||||
|
||||
})
|
||||
};
|
||||
|
||||
$rootScope.$on('logout', function () {
|
||||
$scope.active_vault = null;
|
||||
VaultService.setActiveVault(null);
|
||||
$location.path('/');
|
||||
$scope.saveVaultSettings = function () {
|
||||
var _vault = $scope.active_vault;
|
||||
_vault.name = $scope.new_vault_name;
|
||||
_vault.vault_settings = angular.copy($scope.vault_settings);
|
||||
VaultService.updateVault(_vault).then(function () {
|
||||
VaultService.setActiveVault(_vault);
|
||||
$scope.active_vault.name = angular.copy(_vault.name);
|
||||
NotificationService.showNotification('Settings saved', 5000);
|
||||
});
|
||||
};
|
||||
|
||||
});
|
||||
|
||||
$scope.cancel = function () {
|
||||
$location.path('/vault/' + $routeParams.vault_id);
|
||||
};
|
||||
$scope.tabs = [
|
||||
{
|
||||
title: 'General settings',
|
||||
url: 'views/partials/forms/settings/general_settings.html'
|
||||
},
|
||||
{
|
||||
title: 'Password Audit',
|
||||
url: 'views/partials/forms/settings/tool.html'
|
||||
|
||||
}]);
|
||||
},
|
||||
{
|
||||
title: 'Password settings',
|
||||
url: 'views/partials/forms/settings/password_settings.html'
|
||||
|
||||
},
|
||||
{
|
||||
title: 'Import credentials',
|
||||
url: 'views/partials/forms/settings/import.html'
|
||||
|
||||
},
|
||||
{
|
||||
title: 'Export credentials',
|
||||
url: 'views/partials/forms/settings/export.html'
|
||||
|
||||
},
|
||||
{
|
||||
title: 'Sharing',
|
||||
url: 'views/partials/forms/settings/sharing.html'
|
||||
}
|
||||
];
|
||||
|
||||
$scope.currentTab = $scope.tabs[0];
|
||||
|
||||
$scope.onClickTab = function (tab) {
|
||||
$scope.currentTab = tab;
|
||||
};
|
||||
|
||||
$scope.isActiveTab = function (tab) {
|
||||
return tab.url === $scope.currentTab.url;
|
||||
};
|
||||
|
||||
var getPassmanVersion = function () {
|
||||
var url = OC.generateUrl('apps/passman/api/internal/version');
|
||||
$http.get(url).then(function (result) {
|
||||
$scope.passman_version = result.data.version;
|
||||
});
|
||||
};
|
||||
getPassmanVersion();
|
||||
|
||||
$scope.$watch(function () {
|
||||
return VaultService.getActiveVault();
|
||||
}, function (vault) {
|
||||
if (vault) {
|
||||
$scope.active_vault = vault;
|
||||
}
|
||||
});
|
||||
|
||||
if ($scope.active_vault) {
|
||||
|
||||
}
|
||||
|
||||
$rootScope.$on('logout', function () {
|
||||
$scope.selectedVault = false;
|
||||
});
|
||||
$scope.startScan = function (minStrength) {
|
||||
VaultService.getVault($scope.active_vault).then(function (vault) {
|
||||
var results = [];
|
||||
for (var i = 0; i < vault.credentials.length; i++) {
|
||||
var c = angular.copy(vault.credentials[i]);
|
||||
if (c.password && c.hidden === 0) {
|
||||
c = CredentialService.decryptCredential(c);
|
||||
if (c.password) {
|
||||
var zxcvbn_result = zxcvbn(c.password);
|
||||
if (zxcvbn_result.score <= minStrength) {
|
||||
results.push({
|
||||
credential_id: c.credential_id,
|
||||
label: c.label,
|
||||
password: c.password,
|
||||
password_zxcvbn_result: zxcvbn_result
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
//@todo loop custom fields (if any and check secret fields
|
||||
}
|
||||
$scope.scan_result = results;
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
$scope.cur_state = {};
|
||||
|
||||
$scope.changeVaultPassword = function (oldVaultPass, newVaultPass, newVaultPass2) {
|
||||
if (oldVaultPass !== VaultService.getActiveVault().vaultKey) {
|
||||
$scope.error = 'Your old password is incorrect!';
|
||||
return;
|
||||
}
|
||||
if (newVaultPass !== newVaultPass2) {
|
||||
$scope.error = 'New passwords do not match!';
|
||||
return;
|
||||
}
|
||||
VaultService.getVault($scope.active_vault).then(function (vault) {
|
||||
var _selected_credentials = [];
|
||||
if (vault.credentials.length === 0) {
|
||||
$location.path('/');
|
||||
}
|
||||
for (var i = 0; i < vault.credentials.length; i++) {
|
||||
var _credential = vault.credentials[i];
|
||||
if (_credential.shared_key === null || _credential.shared_key === '') {
|
||||
_selected_credentials.push(_credential);
|
||||
}
|
||||
}
|
||||
$scope.change_pw = {
|
||||
percent: 0,
|
||||
done: 0,
|
||||
total: _selected_credentials.length
|
||||
};
|
||||
var changeCredential = function (index, oldVaultPass, newVaultPass) {
|
||||
CredentialService.reencryptCredential(_selected_credentials[index].guid, oldVaultPass, newVaultPass).progress(function (data) {
|
||||
$scope.cur_state = data;
|
||||
}).then(function (data) {
|
||||
var percent = index / _selected_credentials.length * 100;
|
||||
$scope.change_pw = {
|
||||
percent: percent,
|
||||
done: index + 1,
|
||||
total: _selected_credentials.length
|
||||
};
|
||||
if (index < _selected_credentials.length - 1) {
|
||||
changeCredential(index + 1, oldVaultPass, newVaultPass);
|
||||
} else {
|
||||
console.log('Update complete!');
|
||||
|
||||
vault.private_sharing_key = EncryptService.decryptString(angular.copy(vault.private_sharing_key), oldVaultPass);
|
||||
vault.private_sharing_key = EncryptService.encryptString(vault.private_sharing_key, newVaultPass);
|
||||
VaultService.updateSharingKeys(vault).then(function (result) {
|
||||
$rootScope.$broadcast('logout');
|
||||
NotificationService.showNotification('Please login with your new vault password', 5000);
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
changeCredential(0, VaultService.getActiveVault().vaultKey, newVaultPass);
|
||||
|
||||
});
|
||||
};
|
||||
|
||||
$rootScope.$on('logout', function () {
|
||||
$scope.active_vault = null;
|
||||
VaultService.setActiveVault(null);
|
||||
$location.path('/');
|
||||
|
||||
});
|
||||
|
||||
$scope.cancel = function () {
|
||||
$location.path('/vault/' + $routeParams.vault_id);
|
||||
};
|
||||
|
||||
}]);
|
||||
|
||||
}());
|
|
@ -1,325 +1,264 @@
|
|||
'use strict';
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* @ngdoc function
|
||||
* @name passmanApp.controller:MainCtrl
|
||||
* @description
|
||||
* # MainCtrl
|
||||
* Controller of the passmanApp
|
||||
* This file is part of passman, licensed under AGPLv3
|
||||
*/
|
||||
angular.module('passmanApp')
|
||||
.controller('ShareCtrl', ['$scope', 'VaultService', 'CredentialService', 'SettingsService', '$location', '$routeParams', 'ShareService', 'NotificationService', 'SharingACL', 'EncryptService', 'FileService',
|
||||
function ($scope, VaultService, CredentialService, SettingsService, $location, $routeParams, ShareService, NotificationService, SharingACL, EncryptService, FileService) {
|
||||
$scope.active_vault = VaultService.getActiveVault();
|
||||
/**
|
||||
* @ngdoc function
|
||||
* @name passmanApp.controller:MainCtrl
|
||||
* @description
|
||||
* # MainCtrl
|
||||
* Controller of the passmanApp
|
||||
* This file is part of passman, licensed under AGPLv3
|
||||
*/
|
||||
angular.module('passmanApp')
|
||||
.controller('ShareCtrl', ['$scope', 'VaultService', 'CredentialService', 'SettingsService', '$location', '$routeParams', 'ShareService', 'NotificationService', 'SharingACL', 'EncryptService', 'FileService',
|
||||
function ($scope, VaultService, CredentialService, SettingsService, $location, $routeParams, ShareService, NotificationService, SharingACL, EncryptService, FileService) {
|
||||
$scope.active_vault = VaultService.getActiveVault();
|
||||
|
||||
$scope.tabs = [{
|
||||
title: 'Share with users and groups',
|
||||
url: 'views/partials/forms/share_credential/basics.html',
|
||||
}, {
|
||||
title: 'Share link',
|
||||
url: 'views/partials/forms/share_credential/link_sharing.html',
|
||||
color: 'green'
|
||||
}];
|
||||
$scope.currentTab = {
|
||||
title: 'General',
|
||||
url: 'views/partials/forms/share_credential/basics.html'
|
||||
};
|
||||
$scope.tabs = [{
|
||||
title: 'Share with users and groups',
|
||||
url: 'views/partials/forms/share_credential/basics.html'
|
||||
}, {
|
||||
title: 'Share link',
|
||||
url: 'views/partials/forms/share_credential/link_sharing.html',
|
||||
color: 'green'
|
||||
}];
|
||||
$scope.currentTab = {
|
||||
title: 'General',
|
||||
url: 'views/partials/forms/share_credential/basics.html'
|
||||
};
|
||||
|
||||
$scope.onClickTab = function (tab) {
|
||||
$scope.currentTab = tab;
|
||||
};
|
||||
$scope.onClickTab = function (tab) {
|
||||
$scope.currentTab = tab;
|
||||
};
|
||||
|
||||
$scope.isActiveTab = function (tab) {
|
||||
return tab.url == $scope.currentTab.url;
|
||||
};
|
||||
$scope.isActiveTab = function (tab) {
|
||||
return tab.url === $scope.currentTab.url;
|
||||
};
|
||||
|
||||
if (!SettingsService.getSetting('defaultVault') || !SettingsService.getSetting('defaultVaultPass')) {
|
||||
if (!$scope.active_vault) {
|
||||
$location.path('/')
|
||||
}
|
||||
} else {
|
||||
if (SettingsService.getSetting('defaultVault') && SettingsService.getSetting('defaultVaultPass')) {
|
||||
var _vault = angular.copy(SettingsService.getSetting('defaultVault'));
|
||||
_vault.vaultKey = angular.copy(SettingsService.getSetting('defaultVaultPass'));
|
||||
VaultService.setActiveVault(_vault);
|
||||
$scope.active_vault = _vault;
|
||||
|
||||
}
|
||||
}
|
||||
var storedCredential = SettingsService.getSetting('share_credential');
|
||||
|
||||
if (!storedCredential) {
|
||||
$location.path('/vault/' + $routeParams.vault_id);
|
||||
} else {
|
||||
$scope.storedCredential = CredentialService.decryptCredential(angular.copy(storedCredential));
|
||||
}
|
||||
|
||||
if ($scope.active_vault) {
|
||||
$scope.$parent.selectedVault = true;
|
||||
}
|
||||
$scope.cancel = function () {
|
||||
SettingsService.setSetting('share_credential', null);
|
||||
$location.path('/vault/' + $routeParams.vault_id);
|
||||
};
|
||||
|
||||
|
||||
$scope.default_permissions = new SharingACL(0);
|
||||
$scope.default_permissions.addPermission(
|
||||
$scope.default_permissions.permissions.READ |
|
||||
$scope.default_permissions.permissions.WRITE |
|
||||
$scope.default_permissions.permissions.FILES
|
||||
);
|
||||
|
||||
var link_acl = angular.copy($scope.default_permissions);
|
||||
link_acl.removePermission($scope.default_permissions.permissions.WRITE)
|
||||
|
||||
$scope.share_settings = {
|
||||
linkSharing: {
|
||||
enabled: false,
|
||||
settings: {
|
||||
expire_time: new Date("2999-12-31T22:59:59"),
|
||||
expire_views: 5,
|
||||
acl: link_acl
|
||||
if (!SettingsService.getSetting('defaultVault') || !SettingsService.getSetting('defaultVaultPass')) {
|
||||
if (!$scope.active_vault) {
|
||||
$location.path('/');
|
||||
}
|
||||
},
|
||||
credentialSharedWithUserAndGroup: [],
|
||||
cypher_progress: {
|
||||
done: 0,
|
||||
total: 0
|
||||
},
|
||||
upload_progress: {
|
||||
done: 0,
|
||||
total: 0
|
||||
}
|
||||
};
|
||||
|
||||
var getAcl = function () {
|
||||
ShareService.getSharedCredentialACL($scope.storedCredential).then(function (aclList) {
|
||||
var _list = []
|
||||
var enc_key = ($scope.storedCredential.shared_key) ? EncryptService.decryptString(angular.copy($scope.storedCredential.shared_key)) : false;
|
||||
for (var i = 0; i < aclList.length; i++) {
|
||||
var acl = aclList[i];
|
||||
if (acl.user_id === null) {
|
||||
$scope.share_settings.linkSharing = {
|
||||
enabled: true,
|
||||
settings: {
|
||||
expire_time: new Date(acl.expire * 1000),
|
||||
expire_views: acl.expire_views,
|
||||
acl: new SharingACL(acl.permissions)
|
||||
}
|
||||
};
|
||||
if (enc_key) {
|
||||
var hash = window.btoa($scope.storedCredential.guid + '<::>' + enc_key)
|
||||
$scope.share_link = $location.$$protocol + '://' + $location.$$host + OC.generateUrl('apps/passman/share/public#') + hash;
|
||||
}
|
||||
} else {
|
||||
var obj = {
|
||||
userId: acl.user_id,
|
||||
displayName: acl.user_id,
|
||||
type: 'user',
|
||||
acl: new SharingACL(acl.permissions),
|
||||
acl_id: acl.acl_id,
|
||||
pending: acl.pending,
|
||||
credential_guid: acl.item_guid,
|
||||
created: acl.created
|
||||
};
|
||||
|
||||
_list.push(obj);
|
||||
}
|
||||
|
||||
}
|
||||
$scope.share_settings.credentialSharedWithUserAndGroup = _list;
|
||||
});
|
||||
};
|
||||
getAcl();
|
||||
var acl = new SharingACL(0);
|
||||
|
||||
|
||||
$scope.$watch('share_settings.upload_progress.done', function () {
|
||||
console.log();
|
||||
if ($scope.share_settings.upload_progress.done == $scope.share_settings.upload_progress.total && $scope.share_settings.upload_progress.total > 0) {
|
||||
getAcl()
|
||||
}
|
||||
});
|
||||
|
||||
$scope.inputSharedWith = [];
|
||||
$scope.selectedAccessLevel = '1';
|
||||
|
||||
$scope.searchUsers = function ($query) {
|
||||
return ShareService.search($query)
|
||||
};
|
||||
|
||||
$scope.hasPermission = function (acl, permission) {
|
||||
return acl.hasPermission(permission);
|
||||
};
|
||||
|
||||
$scope.setPermission = function (acl, permission) {
|
||||
acl.togglePermission(permission);
|
||||
};
|
||||
$scope.shareWith = function (shareWith, selectedAccessLevel) {
|
||||
$scope.inputSharedWith = [];
|
||||
if (shareWith.length > 0) {
|
||||
for (var i = 0; i < shareWith.length; i++) {
|
||||
var obj = {
|
||||
userId: shareWith[i].uid,
|
||||
displayName: shareWith[i].text,
|
||||
type: shareWith[i].type,
|
||||
acl: angular.copy($scope.default_permissions),
|
||||
pending: true,
|
||||
credential_guid: $scope.storedCredential.guid
|
||||
};
|
||||
var found = false;
|
||||
for(var z = 0; z < $scope.share_settings.credentialSharedWithUserAndGroup.length; z++){
|
||||
if($scope.share_settings.credentialSharedWithUserAndGroup[z].userId == shareWith[z].uid){
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
if (found === false) {
|
||||
$scope.share_settings.credentialSharedWithUserAndGroup.push(obj)
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
$scope.unshareUser = function(user){
|
||||
ShareService.unshareCredentialFromUser($scope.storedCredential, user.userId).then(function (result) {
|
||||
if(result.result === true){
|
||||
var idx = $scope.share_settings.credentialSharedWithUserAndGroup.indexOf(user);
|
||||
$scope.share_settings.credentialSharedWithUserAndGroup.splice(idx, 1);
|
||||
}
|
||||
})
|
||||
};
|
||||
|
||||
$scope.unshareCredential = function (credential) {
|
||||
ShareService.unshareCredential(credential);
|
||||
var _credential = angular.copy(credential);
|
||||
var old_key = EncryptService.decryptString(angular.copy(_credential.shared_key));
|
||||
var new_key = VaultService.getActiveVault().vaultKey;
|
||||
_credential.shared_key = null;
|
||||
_credential.unshare_action = true;
|
||||
_credential.skip_revision = true;
|
||||
|
||||
_credential = CredentialService.encryptCredential(_credential, old_key);
|
||||
CredentialService.updateCredential(_credential, true).then(function () {
|
||||
NotificationService.showNotification('Credential unshared', 4000);
|
||||
CredentialService.reencryptCredential(_credential.guid, old_key, new_key).progress(function(data){
|
||||
console.log(data);
|
||||
}).then(function(data){
|
||||
getAcl();
|
||||
});
|
||||
})
|
||||
};
|
||||
|
||||
/**
|
||||
* Apply a share to a new user
|
||||
* @param user A user object to who we should share the data
|
||||
* @param enc_key The shared key we are going to ecnrypt with his public rsa key
|
||||
*/
|
||||
$scope.applyShareToUser = function (user, enc_key) {
|
||||
ShareService.getVaultsByUser(user.userId).then(function (data) {
|
||||
$scope.share_settings.cypher_progress.total += data.length;
|
||||
|
||||
user.vaults = data;
|
||||
var start = new Date().getTime() / 1000;
|
||||
ShareService.cypherRSAStringWithPublicKeyBulkAsync(user.vaults, enc_key)
|
||||
.progress(function (data) {
|
||||
$scope.share_settings.cypher_progress.done++;
|
||||
$scope.share_settings.cypher_progress.percent = $scope.share_settings.cypher_progress.done / $scope.share_settings.cypher_progress.total * 100;
|
||||
$scope.$digest();
|
||||
})
|
||||
.then(function (result) {
|
||||
console.log("Took: " + ((new Date().getTime() / 1000) - start) + "s to cypher the string for user [" + data[0].user_id + "]");
|
||||
$scope.share_settings.cypher_progress.times.push({
|
||||
time: ((new Date().getTime() / 1000) - start),
|
||||
user: data[0].user_id
|
||||
});
|
||||
user.vaults = result;
|
||||
if (!user.hasOwnProperty('acl_id')) {
|
||||
$scope.uploadChanges(user);
|
||||
}
|
||||
$scope.$digest();
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
$scope.sharing_complete = true;
|
||||
$scope.applyShare = function () {
|
||||
$scope.sharing_complete = false;
|
||||
$scope.share_settings.cypher_progress.percent = 0;
|
||||
$scope.share_settings.cypher_progress.done = 0;
|
||||
$scope.share_settings.cypher_progress.total = 0;
|
||||
$scope.share_settings.cypher_progress.times = [];
|
||||
$scope.share_settings.cypher_progress.times_total = [];
|
||||
$scope.share_settings.upload_progress.done = 0;
|
||||
$scope.share_settings.upload_progress.total = 0;
|
||||
//Credential is already shared
|
||||
if ($scope.storedCredential.shared_key && $scope.storedCredential.shared_key != '' && $scope.storedCredential.shared_key != null) {
|
||||
console.log('Shared key found');
|
||||
var enc_key = EncryptService.decryptString(angular.copy($scope.storedCredential.shared_key));
|
||||
if ($scope.share_settings.linkSharing.enabled) {
|
||||
var expire_time = new Date(angular.copy($scope.share_settings.linkSharing.settings.expire_time)).getTime() / 1000;
|
||||
var shareObj = {
|
||||
item_id: $scope.storedCredential.credential_id,
|
||||
item_guid: $scope.storedCredential.guid,
|
||||
permissions: $scope.share_settings.linkSharing.settings.acl.getAccessLevel(),
|
||||
expire_timestamp: expire_time,
|
||||
expire_views: $scope.share_settings.linkSharing.settings.expire_views
|
||||
};
|
||||
ShareService.createPublicSharedCredential(shareObj).then(function () {
|
||||
var hash = window.btoa($scope.storedCredential.guid + '<::>' + enc_key);
|
||||
$scope.share_link = $location.$$protocol + '://' + $location.$$host + OC.generateUrl('apps/passman/share/public#') + hash;
|
||||
})
|
||||
}
|
||||
|
||||
var list = $scope.share_settings.credentialSharedWithUserAndGroup;
|
||||
|
||||
for (var i = 0; i < list.length; i++) {
|
||||
var iterator = i;
|
||||
var target_user = list[i];
|
||||
if (target_user.hasOwnProperty('created')) {
|
||||
console.log('Updating permissions')
|
||||
var acl = {
|
||||
user_id: target_user.userId,
|
||||
permission: target_user.acl.getAccessLevel()
|
||||
};
|
||||
ShareService.updateCredentialAcl($scope.storedCredential, acl);
|
||||
} else {
|
||||
console.log('Creating new share')
|
||||
$scope.applyShareToUser(list[iterator], enc_key);
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
if (SettingsService.getSetting('defaultVault') && SettingsService.getSetting('defaultVaultPass')) {
|
||||
var _vault = angular.copy(SettingsService.getSetting('defaultVault'));
|
||||
_vault.vaultKey = angular.copy(SettingsService.getSetting('defaultVaultPass'));
|
||||
VaultService.setActiveVault(_vault);
|
||||
$scope.active_vault = _vault;
|
||||
|
||||
ShareService.generateSharedKey(20).then(function (key) {
|
||||
}
|
||||
}
|
||||
var storedCredential = SettingsService.getSetting('share_credential');
|
||||
|
||||
var encryptedSharedCredential = angular.copy($scope.storedCredential);
|
||||
var old_key = VaultService.getActiveVault().vaultKey;
|
||||
if (!storedCredential) {
|
||||
$location.path('/vault/' + $routeParams.vault_id);
|
||||
} else {
|
||||
$scope.storedCredential = CredentialService.decryptCredential(angular.copy(storedCredential));
|
||||
}
|
||||
|
||||
CredentialService.reencryptCredential(encryptedSharedCredential.guid, old_key, key).progress(function(data){
|
||||
console.log(data);
|
||||
}).then(function(data){
|
||||
console.log(data);
|
||||
//This is here is not called
|
||||
var _credential = data.cryptogram;
|
||||
_credential.set_share_key = true;
|
||||
_credential.skip_revision = true;
|
||||
_credential.shared_key = EncryptService.encryptString(key);
|
||||
CredentialService.updateCredential(_credential, true).then(function () {
|
||||
NotificationService.showNotification('Credential shared', 4000);
|
||||
$scope.sharing_complete = true;
|
||||
})
|
||||
});
|
||||
if ($scope.active_vault) {
|
||||
$scope.$parent.selectedVault = true;
|
||||
}
|
||||
$scope.cancel = function () {
|
||||
SettingsService.setSetting('share_credential', null);
|
||||
$location.path('/vault/' + $routeParams.vault_id);
|
||||
};
|
||||
|
||||
var list = $scope.share_settings.credentialSharedWithUserAndGroup;
|
||||
for (var i = 0; i < list.length; i++) {
|
||||
if (list[i].type == "user") {
|
||||
$scope.applyShareToUser(list[i], key);
|
||||
|
||||
$scope.default_permissions = new SharingACL(0);
|
||||
$scope.default_permissions.addPermission(
|
||||
$scope.default_permissions.permissions.READ |
|
||||
$scope.default_permissions.permissions.WRITE |
|
||||
$scope.default_permissions.permissions.FILES
|
||||
);
|
||||
|
||||
var link_acl = angular.copy($scope.default_permissions);
|
||||
link_acl.removePermission($scope.default_permissions.permissions.WRITE);
|
||||
|
||||
$scope.share_settings = {
|
||||
linkSharing: {
|
||||
enabled: false,
|
||||
settings: {
|
||||
expire_time: new Date("2999-12-31T22:59:59"),
|
||||
expire_views: 5,
|
||||
acl: link_acl
|
||||
}
|
||||
},
|
||||
credentialSharedWithUserAndGroup: [],
|
||||
cypher_progress: {
|
||||
done: 0,
|
||||
total: 0
|
||||
},
|
||||
upload_progress: {
|
||||
done: 0,
|
||||
total: 0
|
||||
}
|
||||
};
|
||||
|
||||
var getAcl = function () {
|
||||
ShareService.getSharedCredentialACL($scope.storedCredential).then(function (aclList) {
|
||||
var _list = [];
|
||||
var enc_key = ($scope.storedCredential.shared_key) ? EncryptService.decryptString(angular.copy($scope.storedCredential.shared_key)) : false;
|
||||
for (var i = 0; i < aclList.length; i++) {
|
||||
var acl = aclList[i];
|
||||
if (acl.user_id === null) {
|
||||
$scope.share_settings.linkSharing = {
|
||||
enabled: true,
|
||||
settings: {
|
||||
expire_time: new Date(acl.expire * 1000),
|
||||
expire_views: acl.expire_views,
|
||||
acl: new SharingACL(acl.permissions)
|
||||
}
|
||||
};
|
||||
if (enc_key) {
|
||||
var hash = window.btoa($scope.storedCredential.guid + '<::>' + enc_key);
|
||||
$scope.share_link = $location.$$protocol + '://' + $location.$$host + OC.generateUrl('apps/passman/share/public#') + hash;
|
||||
}
|
||||
} else {
|
||||
var obj = {
|
||||
userId: acl.user_id,
|
||||
displayName: acl.user_id,
|
||||
type: 'user',
|
||||
acl: new SharingACL(acl.permissions),
|
||||
acl_id: acl.acl_id,
|
||||
pending: acl.pending,
|
||||
credential_guid: acl.item_guid,
|
||||
created: acl.created
|
||||
};
|
||||
|
||||
_list.push(obj);
|
||||
}
|
||||
|
||||
}
|
||||
$scope.share_settings.credentialSharedWithUserAndGroup = _list;
|
||||
});
|
||||
};
|
||||
getAcl();
|
||||
var acl = new SharingACL(0);
|
||||
|
||||
|
||||
$scope.$watch('share_settings.upload_progress.done', function () {
|
||||
console.log();
|
||||
if ($scope.share_settings.upload_progress.done === $scope.share_settings.upload_progress.total && $scope.share_settings.upload_progress.total > 0) {
|
||||
getAcl();
|
||||
}
|
||||
});
|
||||
|
||||
$scope.inputSharedWith = [];
|
||||
$scope.selectedAccessLevel = '1';
|
||||
|
||||
$scope.searchUsers = function ($query) {
|
||||
return ShareService.search($query);
|
||||
};
|
||||
|
||||
$scope.hasPermission = function (acl, permission) {
|
||||
return acl.hasPermission(permission);
|
||||
};
|
||||
|
||||
$scope.setPermission = function (acl, permission) {
|
||||
acl.togglePermission(permission);
|
||||
};
|
||||
$scope.shareWith = function (shareWith, selectedAccessLevel) {
|
||||
$scope.inputSharedWith = [];
|
||||
if (shareWith.length > 0) {
|
||||
for (var i = 0; i < shareWith.length; i++) {
|
||||
var obj = {
|
||||
userId: shareWith[i].uid,
|
||||
displayName: shareWith[i].text,
|
||||
type: shareWith[i].type,
|
||||
acl: angular.copy($scope.default_permissions),
|
||||
pending: true,
|
||||
credential_guid: $scope.storedCredential.guid
|
||||
};
|
||||
var found = false;
|
||||
for (var z = 0; z < $scope.share_settings.credentialSharedWithUserAndGroup.length; z++) {
|
||||
if ($scope.share_settings.credentialSharedWithUserAndGroup[z].userId === shareWith[z].uid) {
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
if (found === false) {
|
||||
$scope.share_settings.credentialSharedWithUserAndGroup.push(obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
$scope.unshareUser = function (user) {
|
||||
ShareService.unshareCredentialFromUser($scope.storedCredential, user.userId).then(function (result) {
|
||||
if (result.result === true) {
|
||||
var idx = $scope.share_settings.credentialSharedWithUserAndGroup.indexOf(user);
|
||||
$scope.share_settings.credentialSharedWithUserAndGroup.splice(idx, 1);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
$scope.unshareCredential = function (credential) {
|
||||
ShareService.unshareCredential(credential);
|
||||
var _credential = angular.copy(credential);
|
||||
var old_key = EncryptService.decryptString(angular.copy(_credential.shared_key));
|
||||
var new_key = VaultService.getActiveVault().vaultKey;
|
||||
_credential.shared_key = null;
|
||||
_credential.unshare_action = true;
|
||||
_credential.skip_revision = true;
|
||||
|
||||
_credential = CredentialService.encryptCredential(_credential, old_key);
|
||||
CredentialService.updateCredential(_credential, true).then(function () {
|
||||
NotificationService.showNotification('Credential unshared', 4000);
|
||||
CredentialService.reencryptCredential(_credential.guid, old_key, new_key).progress(function (data) {
|
||||
console.log(data);
|
||||
}).then(function (data) {
|
||||
getAcl();
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Apply a share to a new user
|
||||
* @param user A user object to who we should share the data
|
||||
* @param enc_key The shared key we are going to ecnrypt with his public rsa key
|
||||
*/
|
||||
$scope.applyShareToUser = function (user, enc_key) {
|
||||
ShareService.getVaultsByUser(user.userId).then(function (data) {
|
||||
$scope.share_settings.cypher_progress.total += data.length;
|
||||
|
||||
user.vaults = data;
|
||||
var start = new Date().getTime() / 1000;
|
||||
ShareService.cypherRSAStringWithPublicKeyBulkAsync(user.vaults, enc_key)
|
||||
.progress(function (data) {
|
||||
$scope.share_settings.cypher_progress.done++;
|
||||
$scope.share_settings.cypher_progress.percent = $scope.share_settings.cypher_progress.done / $scope.share_settings.cypher_progress.total * 100;
|
||||
$scope.$digest();
|
||||
})
|
||||
.then(function (result) {
|
||||
console.log("Took: " + ((new Date().getTime() / 1000) - start) + "s to cypher the string for user [" + data[0].user_id + "]");
|
||||
$scope.share_settings.cypher_progress.times.push({
|
||||
time: ((new Date().getTime() / 1000) - start),
|
||||
user: data[0].user_id
|
||||
});
|
||||
user.vaults = result;
|
||||
if (!user.hasOwnProperty('acl_id')) {
|
||||
$scope.uploadChanges(user);
|
||||
}
|
||||
$scope.$digest();
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
$scope.sharing_complete = true;
|
||||
$scope.applyShare = function () {
|
||||
$scope.sharing_complete = false;
|
||||
$scope.share_settings.cypher_progress.percent = 0;
|
||||
$scope.share_settings.cypher_progress.done = 0;
|
||||
$scope.share_settings.cypher_progress.total = 0;
|
||||
$scope.share_settings.cypher_progress.times = [];
|
||||
$scope.share_settings.cypher_progress.times_total = [];
|
||||
$scope.share_settings.upload_progress.done = 0;
|
||||
$scope.share_settings.upload_progress.total = 0;
|
||||
//Credential is already shared
|
||||
if ($scope.storedCredential.shared_key && $scope.storedCredential.shared_key !== '' && $scope.storedCredential.shared_key !== null) {
|
||||
console.log('Shared key found');
|
||||
var enc_key = EncryptService.decryptString(angular.copy($scope.storedCredential.shared_key));
|
||||
if ($scope.share_settings.linkSharing.enabled) {
|
||||
var expire_time = new Date(angular.copy($scope.share_settings.linkSharing.settings.expire_time)).getTime() / 1000;
|
||||
var shareObj = {
|
||||
|
@ -330,33 +269,94 @@ angular.module('passmanApp')
|
|||
expire_views: $scope.share_settings.linkSharing.settings.expire_views
|
||||
};
|
||||
ShareService.createPublicSharedCredential(shareObj).then(function () {
|
||||
var hash = window.btoa($scope.storedCredential.guid + '<::>' + key);
|
||||
var hash = window.btoa($scope.storedCredential.guid + '<::>' + enc_key);
|
||||
$scope.share_link = $location.$$protocol + '://' + $location.$$host + OC.generateUrl('apps/passman/share/public#') + hash;
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
};
|
||||
var list = $scope.share_settings.credentialSharedWithUserAndGroup;
|
||||
|
||||
$scope.uploadChanges = function (user) {
|
||||
$scope.share_settings.upload_progress.total++;
|
||||
for (var i = 0; i < list.length; i++) {
|
||||
var iterator = i;
|
||||
var target_user = list[i];
|
||||
if (target_user.hasOwnProperty('created')) {
|
||||
var acl = {
|
||||
user_id: target_user.userId,
|
||||
permission: target_user.acl.getAccessLevel()
|
||||
};
|
||||
ShareService.updateCredentialAcl($scope.storedCredential, acl);
|
||||
} else {
|
||||
$scope.applyShareToUser(list[iterator], enc_key);
|
||||
}
|
||||
}
|
||||
|
||||
user.accessLevel = angular.copy(user.acl.getAccessLevel());
|
||||
ShareService.shareWithUser(storedCredential, user)
|
||||
.then(function (data) {
|
||||
$scope.share_settings.upload_progress.done++;
|
||||
$scope.share_settings.upload_progress.percent = $scope.share_settings.upload_progress.done / $scope.share_settings.upload_progress.total * 100;
|
||||
});
|
||||
};
|
||||
} else {
|
||||
|
||||
$scope.calculate_total_time = function () {
|
||||
$scope.share_settings.cypher_progress.times = $scope.share_settings.cypher_progress.times || [];
|
||||
var total = 0;
|
||||
for (var i = 0; i < $scope.share_settings.cypher_progress.times.length; i++) {
|
||||
total += $scope.share_settings.cypher_progress.times[i].time;
|
||||
}
|
||||
return total;
|
||||
}
|
||||
}]);
|
||||
ShareService.generateSharedKey(20).then(function (key) {
|
||||
|
||||
var encryptedSharedCredential = angular.copy($scope.storedCredential);
|
||||
var old_key = VaultService.getActiveVault().vaultKey;
|
||||
|
||||
CredentialService.reencryptCredential(encryptedSharedCredential.guid, old_key, key).progress(function (data) {
|
||||
console.log(data);
|
||||
}).then(function (data) {
|
||||
console.log(data);
|
||||
//This is here is not called
|
||||
var _credential = data.cryptogram;
|
||||
_credential.set_share_key = true;
|
||||
_credential.skip_revision = true;
|
||||
_credential.shared_key = EncryptService.encryptString(key);
|
||||
CredentialService.updateCredential(_credential, true).then(function () {
|
||||
NotificationService.showNotification('Credential shared', 4000);
|
||||
$scope.sharing_complete = true;
|
||||
});
|
||||
});
|
||||
|
||||
var list = $scope.share_settings.credentialSharedWithUserAndGroup;
|
||||
for (var i = 0; i < list.length; i++) {
|
||||
if (list[i].type === "user") {
|
||||
$scope.applyShareToUser(list[i], key);
|
||||
}
|
||||
}
|
||||
|
||||
if ($scope.share_settings.linkSharing.enabled) {
|
||||
var expire_time = new Date(angular.copy($scope.share_settings.linkSharing.settings.expire_time)).getTime() / 1000;
|
||||
var shareObj = {
|
||||
item_id: $scope.storedCredential.credential_id,
|
||||
item_guid: $scope.storedCredential.guid,
|
||||
permissions: $scope.share_settings.linkSharing.settings.acl.getAccessLevel(),
|
||||
expire_timestamp: expire_time,
|
||||
expire_views: $scope.share_settings.linkSharing.settings.expire_views
|
||||
};
|
||||
ShareService.createPublicSharedCredential(shareObj).then(function () {
|
||||
var hash = window.btoa($scope.storedCredential.guid + '<::>' + key);
|
||||
$scope.share_link = $location.$$protocol + '://' + $location.$$host + OC.generateUrl('apps/passman/share/public#') + hash;
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
$scope.uploadChanges = function (user) {
|
||||
$scope.share_settings.upload_progress.total++;
|
||||
|
||||
user.accessLevel = angular.copy(user.acl.getAccessLevel());
|
||||
ShareService.shareWithUser(storedCredential, user)
|
||||
.then(function (data) {
|
||||
$scope.share_settings.upload_progress.done++;
|
||||
$scope.share_settings.upload_progress.percent = $scope.share_settings.upload_progress.done / $scope.share_settings.upload_progress.total * 100;
|
||||
});
|
||||
};
|
||||
|
||||
$scope.calculate_total_time = function () {
|
||||
$scope.share_settings.cypher_progress.times = $scope.share_settings.cypher_progress.times || [];
|
||||
var total = 0;
|
||||
for (var i = 0; i < $scope.share_settings.cypher_progress.times.length; i++) {
|
||||
total += $scope.share_settings.cypher_progress.times[i].time;
|
||||
}
|
||||
return total;
|
||||
};
|
||||
}]);
|
||||
}());
|
|
@ -1,62 +1,64 @@
|
|||
/**
|
||||
* Created by wolfi on 25/09/16.
|
||||
*/
|
||||
angular.module('passmanApp')
|
||||
.controller('SharingSettingsCtrl', ['$scope', 'VaultService', 'CredentialService', 'SettingsService', '$location', '$routeParams', 'ShareService', 'EncryptService',
|
||||
function ($scope, VaultService, CredentialService, SettingsService, $location, $routeParams, ShareService, EncryptService) {
|
||||
$scope.active_vault = VaultService.getActiveVault();
|
||||
$scope.sharing_keys = ShareService.getSharingKeys();
|
||||
(function () {
|
||||
'use strict';
|
||||
/**
|
||||
* Created by wolfi on 25/09/16.
|
||||
*/
|
||||
angular.module('passmanApp')
|
||||
.controller('SharingSettingsCtrl', ['$scope', 'VaultService', 'CredentialService', 'SettingsService', '$location', '$routeParams', 'ShareService', 'EncryptService',
|
||||
function ($scope, VaultService, CredentialService, SettingsService, $location, $routeParams, ShareService, EncryptService) {
|
||||
$scope.active_vault = VaultService.getActiveVault();
|
||||
$scope.sharing_keys = ShareService.getSharingKeys();
|
||||
|
||||
$scope.progress = 1;
|
||||
$scope.generating = false;
|
||||
$scope.progress = 1;
|
||||
$scope.generating = false;
|
||||
|
||||
|
||||
$scope.available_sizes = [
|
||||
{
|
||||
size: 1024,
|
||||
name: 1024
|
||||
},
|
||||
{
|
||||
size: 2048,
|
||||
name: 2048
|
||||
},
|
||||
{
|
||||
size: 4096,
|
||||
name: 4096
|
||||
}
|
||||
];
|
||||
|
||||
$scope.available_sizes = [
|
||||
{
|
||||
size: 1024,
|
||||
name: 1024
|
||||
},
|
||||
{
|
||||
size: 2048,
|
||||
name: 2048
|
||||
},
|
||||
{
|
||||
size: 4096,
|
||||
name: 4096
|
||||
}
|
||||
];
|
||||
$scope.setKeySize = function (size) {
|
||||
for (var i = 0; i < $scope.available_sizes.length; i++) {
|
||||
if ($scope.available_sizes[i].size === size) {
|
||||
$scope.key_size = $scope.available_sizes[i];
|
||||
return;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
$scope.setKeySize = function (size) {
|
||||
for (var i = 0; i < $scope.available_sizes.length; i++) {
|
||||
if ($scope.available_sizes[i].size == size) {
|
||||
$scope.key_size = $scope.available_sizes[i];
|
||||
return;
|
||||
}
|
||||
}
|
||||
};
|
||||
$scope.setKeySize(2048);
|
||||
|
||||
$scope.setKeySize(2048);
|
||||
$scope.generateKeys = function (length) {
|
||||
$scope.progress = 1;
|
||||
$scope.generating = true;
|
||||
|
||||
$scope.generateKeys = function (length) {
|
||||
$scope.progress = 1;
|
||||
$scope.generating = true;
|
||||
ShareService.generateRSAKeys(length).progress(function (progress) {
|
||||
$scope.progress = progress > 0 ? 2 : 1;
|
||||
$scope.$digest();
|
||||
}).then(function (kp) {
|
||||
console.log('stuff done');
|
||||
$scope.generating = false;
|
||||
|
||||
ShareService.generateRSAKeys(length).progress(function(progress){
|
||||
$scope.progress = progress > 0 ? 2:1;
|
||||
$scope.$digest();
|
||||
}).then(function(kp){
|
||||
console.log('stuff done');
|
||||
$scope.generating = false;
|
||||
var pem = ShareService.rsaKeyPairToPEM(kp);
|
||||
|
||||
var pem = ShareService.rsaKeyPairToPEM(kp)
|
||||
$scope.active_vault.private_sharing_key = EncryptService.encryptString(pem.privateKey);
|
||||
$scope.active_vault.public_sharing_key = pem.publicKey;
|
||||
|
||||
$scope.active_vault.private_sharing_key = EncryptService.encryptString(pem.privateKey);
|
||||
$scope.active_vault.public_sharing_key = pem.publicKey;
|
||||
|
||||
VaultService.updateSharingKeys($scope.active_vault).then(function (result) {
|
||||
$scope.sharing_keys = ShareService.getSharingKeys();
|
||||
})
|
||||
});
|
||||
}
|
||||
}]);
|
||||
VaultService.updateSharingKeys($scope.active_vault).then(function (result) {
|
||||
$scope.sharing_keys = ShareService.getSharingKeys();
|
||||
});
|
||||
});
|
||||
};
|
||||
}]);
|
||||
}());
|
|
@ -1,144 +1,146 @@
|
|||
'use strict';
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* @ngdoc function
|
||||
* @name passmanApp.controller:MainCtrl
|
||||
* @description
|
||||
* # MainCtrl
|
||||
* Controller of the passmanApp
|
||||
*/
|
||||
angular.module('passmanApp')
|
||||
.controller('VaultCtrl', ['$scope', 'VaultService', 'SettingsService', 'CredentialService', '$location', 'ShareService', 'EncryptService', function ($scope, VaultService, SettingsService, CredentialService, $location, ShareService, EncryptService) {
|
||||
VaultService.getVaults().then(function (vaults) {
|
||||
$scope.vaults = vaults;
|
||||
if (SettingsService.getSetting('defaultVault') != null) {
|
||||
var default_vault = SettingsService.getSetting('defaultVault');
|
||||
/**
|
||||
* @ngdoc function
|
||||
* @name passmanApp.controller:MainCtrl
|
||||
* @description
|
||||
* # MainCtrl
|
||||
* Controller of the passmanApp
|
||||
*/
|
||||
angular.module('passmanApp')
|
||||
.controller('VaultCtrl', ['$scope', 'VaultService', 'SettingsService', 'CredentialService', '$location', 'ShareService', 'EncryptService', function ($scope, VaultService, SettingsService, CredentialService, $location, ShareService, EncryptService) {
|
||||
VaultService.getVaults().then(function (vaults) {
|
||||
$scope.vaults = vaults;
|
||||
if (SettingsService.getSetting('defaultVault') != null) {
|
||||
var default_vault = SettingsService.getSetting('defaultVault');
|
||||
|
||||
/**
|
||||
* Using a native for loop for preformance reasons.
|
||||
* More info see http://stackoverflow.com/questions/13843972/angular-js-break-foreach
|
||||
*/
|
||||
for (var i = 0; i < vaults.length; i++) {
|
||||
var vault = vaults[i];
|
||||
if (vault.guid == default_vault.guid) {
|
||||
$scope.default_vault = true;
|
||||
$scope.list_selected_vault = vault;
|
||||
SettingsService.setSetting('defaultVault', vault);
|
||||
if (SettingsService.getSetting('defaultVaultPass')) {
|
||||
$location.path('/vault/' + vault.guid);
|
||||
/**
|
||||
* Using a native for loop for preformance reasons.
|
||||
* More info see http://stackoverflow.com/questions/13843972/angular-js-break-foreach
|
||||
*/
|
||||
for (var i = 0; i < vaults.length; i++) {
|
||||
var vault = vaults[i];
|
||||
if (vault.guid === default_vault.guid) {
|
||||
$scope.default_vault = true;
|
||||
$scope.list_selected_vault = vault;
|
||||
SettingsService.setSetting('defaultVault', vault);
|
||||
if (SettingsService.getSetting('defaultVaultPass')) {
|
||||
$location.path('/vault/' + vault.guid);
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
$scope.default_vault = false;
|
||||
$scope.remember_vault_password = false;
|
||||
$scope.list_selected_vault = false;
|
||||
|
||||
$scope.toggleDefaultVault = function () {
|
||||
$scope.default_vault = !$scope.default_vault;
|
||||
if ($scope.default_vault == true) {
|
||||
SettingsService.setSetting('defaultVault', $scope.list_selected_vault);
|
||||
} else {
|
||||
SettingsService.setSetting('defaultVault', null);
|
||||
}
|
||||
};
|
||||
|
||||
$scope.toggleRememberPassword = function () {
|
||||
$scope.remember_vault_password = !$scope.remember_vault_password;
|
||||
if ($scope.remember_vault_password) {
|
||||
SettingsService.setSetting('defaultVault', $scope.list_selected_vault);
|
||||
$scope.default_vault = true;
|
||||
}
|
||||
if ($scope.remember_vault_password != true) {
|
||||
SettingsService.setSetting('defaultVault', null);
|
||||
}
|
||||
};
|
||||
|
||||
$scope.clearState = function () {
|
||||
$scope.list_selected_vault = false;
|
||||
$scope.creating_vault = false;
|
||||
$scope.error = false;
|
||||
};
|
||||
|
||||
$scope.selectVault = function (vault) {
|
||||
$scope.list_selected_vault = vault;
|
||||
};
|
||||
$scope.sharing_keys = {};
|
||||
$scope.newVault = function () {
|
||||
$scope.creating_vault = true;
|
||||
var _vault = {};
|
||||
var key_size = 1024;
|
||||
ShareService.generateRSAKeys(key_size).progress(function (progress) {
|
||||
var p = progress > 0 ? 2 : 1;
|
||||
$scope.creating_keys = 'Generating sharing keys (' + p + ' / 2)';
|
||||
$scope.$digest();
|
||||
}).then(function (kp) {
|
||||
var pem = ShareService.rsaKeyPairToPEM(kp);
|
||||
$scope.creating_keys = false;
|
||||
$scope.sharing_keys.private_sharing_key = pem.privateKey;
|
||||
$scope.sharing_keys.public_sharing_key = pem.publicKey;
|
||||
$scope.$digest();
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
var _loginToVault = function (vault, vault_key) {
|
||||
var _vault = angular.copy(vault);
|
||||
_vault.vaultKey = angular.copy(vault_key);
|
||||
delete _vault.credentials;
|
||||
VaultService.setActiveVault(_vault);
|
||||
$location.path('/vault/' + vault.guid);
|
||||
};
|
||||
$scope.default_vault = false;
|
||||
$scope.remember_vault_password = false;
|
||||
$scope.list_selected_vault = false;
|
||||
|
||||
$scope.vaultDecryptionKey = '';
|
||||
$scope.loginToVault = function (vault, vault_key) {
|
||||
$scope.error = false;
|
||||
var _vault = angular.copy(vault);
|
||||
_vault.vaultKey = angular.copy(vault_key);
|
||||
|
||||
VaultService.setActiveVault(_vault);
|
||||
try {
|
||||
var c = EncryptService.decryptString(vault.challenge_password);
|
||||
if ($scope.remember_vault_password) {
|
||||
SettingsService.setSetting('defaultVaultPass', vault_key);
|
||||
$scope.toggleDefaultVault = function () {
|
||||
$scope.default_vault = !$scope.default_vault;
|
||||
if ($scope.default_vault === true) {
|
||||
SettingsService.setSetting('defaultVault', $scope.list_selected_vault);
|
||||
} else {
|
||||
SettingsService.setSetting('defaultVault', null);
|
||||
}
|
||||
_loginToVault(vault, vault_key);
|
||||
};
|
||||
|
||||
} catch (e) {
|
||||
$scope.error = 'Incorrect vault password!'
|
||||
}
|
||||
$scope.toggleRememberPassword = function () {
|
||||
$scope.remember_vault_password = !$scope.remember_vault_password;
|
||||
if ($scope.remember_vault_password) {
|
||||
SettingsService.setSetting('defaultVault', $scope.list_selected_vault);
|
||||
$scope.default_vault = true;
|
||||
}
|
||||
if ($scope.remember_vault_password !== true) {
|
||||
SettingsService.setSetting('defaultVault', null);
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
$scope.clearState = function () {
|
||||
$scope.list_selected_vault = false;
|
||||
$scope.creating_vault = false;
|
||||
$scope.error = false;
|
||||
};
|
||||
|
||||
$scope.selectVault = function (vault) {
|
||||
$scope.list_selected_vault = vault;
|
||||
};
|
||||
$scope.sharing_keys = {};
|
||||
$scope.newVault = function () {
|
||||
$scope.creating_vault = true;
|
||||
var _vault = {};
|
||||
var key_size = 1024;
|
||||
ShareService.generateRSAKeys(key_size).progress(function (progress) {
|
||||
var p = progress > 0 ? 2 : 1;
|
||||
$scope.creating_keys = 'Generating sharing keys (' + p + ' / 2)';
|
||||
$scope.$digest();
|
||||
}).then(function (kp) {
|
||||
var pem = ShareService.rsaKeyPairToPEM(kp);
|
||||
$scope.creating_keys = false;
|
||||
$scope.sharing_keys.private_sharing_key = pem.privateKey;
|
||||
$scope.sharing_keys.public_sharing_key = pem.publicKey;
|
||||
$scope.$digest();
|
||||
});
|
||||
|
||||
$scope.createVault = function (vault_name, vault_key, vault_key2) {
|
||||
if (vault_key != vault_key2) {
|
||||
$scope.error = 'Passwords do not match';
|
||||
return;
|
||||
}
|
||||
VaultService.createVault(vault_name).then(function (vault) {
|
||||
$scope.vaults.push(vault);
|
||||
};
|
||||
|
||||
var _loginToVault = function (vault, vault_key) {
|
||||
var _vault = angular.copy(vault);
|
||||
_vault.vaultKey = angular.copy(vault_key);
|
||||
delete _vault.credentials;
|
||||
VaultService.setActiveVault(_vault);
|
||||
SettingsService.setSetting('defaultVaultPass', null);
|
||||
SettingsService.setSetting('defaultVault', null);
|
||||
var test_credential = CredentialService.newCredential();
|
||||
test_credential.label = 'Test key for vault ' + vault_name;
|
||||
test_credential.hidden = true;
|
||||
test_credential.vault_id = vault.vault_id;
|
||||
test_credential.password = 'lorum ipsum';
|
||||
CredentialService.createCredential(test_credential).then(function (result) {
|
||||
_vault.public_sharing_key = angular.copy($scope.sharing_keys.public_sharing_key);
|
||||
_vault.private_sharing_key = EncryptService.encryptString(angular.copy($scope.sharing_keys.private_sharing_key));
|
||||
VaultService.updateSharingKeys(_vault).then(function (result) {
|
||||
_loginToVault(vault, vault_key);
|
||||
})
|
||||
})
|
||||
});
|
||||
};
|
||||
}]);
|
||||
$location.path('/vault/' + vault.guid);
|
||||
};
|
||||
|
||||
$scope.vaultDecryptionKey = '';
|
||||
$scope.loginToVault = function (vault, vault_key) {
|
||||
$scope.error = false;
|
||||
var _vault = angular.copy(vault);
|
||||
_vault.vaultKey = angular.copy(vault_key);
|
||||
|
||||
VaultService.setActiveVault(_vault);
|
||||
try {
|
||||
var c = EncryptService.decryptString(vault.challenge_password);
|
||||
if ($scope.remember_vault_password) {
|
||||
SettingsService.setSetting('defaultVaultPass', vault_key);
|
||||
}
|
||||
_loginToVault(vault, vault_key);
|
||||
|
||||
} catch (e) {
|
||||
$scope.error = 'Incorrect vault password!';
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
$scope.createVault = function (vault_name, vault_key, vault_key2) {
|
||||
if (vault_key !== vault_key2) {
|
||||
$scope.error = 'Passwords do not match';
|
||||
return;
|
||||
}
|
||||
VaultService.createVault(vault_name).then(function (vault) {
|
||||
$scope.vaults.push(vault);
|
||||
var _vault = angular.copy(vault);
|
||||
_vault.vaultKey = angular.copy(vault_key);
|
||||
VaultService.setActiveVault(_vault);
|
||||
SettingsService.setSetting('defaultVaultPass', null);
|
||||
SettingsService.setSetting('defaultVault', null);
|
||||
var test_credential = CredentialService.newCredential();
|
||||
test_credential.label = 'Test key for vault ' + vault_name;
|
||||
test_credential.hidden = true;
|
||||
test_credential.vault_id = vault.vault_id;
|
||||
test_credential.password = 'lorum ipsum';
|
||||
CredentialService.createCredential(test_credential).then(function (result) {
|
||||
_vault.public_sharing_key = angular.copy($scope.sharing_keys.public_sharing_key);
|
||||
_vault.private_sharing_key = EncryptService.encryptString(angular.copy($scope.sharing_keys.private_sharing_key));
|
||||
VaultService.updateSharingKeys(_vault).then(function (result) {
|
||||
_loginToVault(vault, vault_key);
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
}]);
|
||||
}());
|
|
@ -1,22 +1,24 @@
|
|||
'use strict';
|
||||
(function () {
|
||||
'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);
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
/**
|
||||
* @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);
|
||||
}
|
||||
};
|
||||
});
|
||||
}());
|
|
@ -1,22 +1,23 @@
|
|||
'use strict';
|
||||
|
||||
/**
|
||||
* @ngdoc directive
|
||||
* @name passmanApp.directive:selectOnClick
|
||||
* @description
|
||||
* # selectOnClick
|
||||
*/
|
||||
angular.module('passmanApp')
|
||||
.directive('selectOnClick', ['$window', function ($window) {
|
||||
return {
|
||||
restrict: 'A',
|
||||
link: function (scope, element, attrs) {
|
||||
element.on('click', function () {
|
||||
if (!$window.getSelection().toString()) {
|
||||
// Required for mobile Safari
|
||||
this.setSelectionRange(0, this.value.length)
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
}]);
|
||||
(function () {
|
||||
'use strict';
|
||||
/**
|
||||
* @ngdoc directive
|
||||
* @name passmanApp.directive:selectOnClick
|
||||
* @description
|
||||
* # selectOnClick
|
||||
*/
|
||||
angular.module('passmanApp')
|
||||
.directive('selectOnClick', ['$window', function ($window) {
|
||||
return {
|
||||
restrict: 'A',
|
||||
link: function (scope, element, attrs) {
|
||||
element.on('click', function () {
|
||||
if (!$window.getSelection().toString()) {
|
||||
// Required for mobile Safari
|
||||
this.setSelectionRange(0, this.value.length);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
}]);
|
||||
}());
|
|
@ -1,5 +1,5 @@
|
|||
'use strict';
|
||||
|
||||
(function () {
|
||||
'use strict';
|
||||
/**
|
||||
* @ngdoc directive
|
||||
* @name passmanApp.directive:passwordGen
|
||||
|
@ -26,9 +26,10 @@ angular.module('passmanApp')
|
|||
return '#' + '00000'.substring(0, 6 - c.length) + c;
|
||||
}
|
||||
scope.$watch('string', function(){
|
||||
$(el).css('border-color', genColor(scope.string));
|
||||
})
|
||||
jQuery(el).css('border-color', genColor(scope.string));
|
||||
});
|
||||
|
||||
}
|
||||
};
|
||||
}]);
|
||||
}());
|
|
@ -1,66 +1,67 @@
|
|||
'use strict';
|
||||
(function () {
|
||||
'use strict';
|
||||
/**
|
||||
* @ngdoc directive
|
||||
* @name passmanApp.directive:passwordGen
|
||||
* @description
|
||||
* # passwordGen
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ngdoc directive
|
||||
* @name passmanApp.directive:passwordGen
|
||||
* @description
|
||||
* # passwordGen
|
||||
*/
|
||||
angular.module('passmanApp')
|
||||
.directive('credentialField', ['$timeout', function ($timeout) {
|
||||
return {
|
||||
scope: {
|
||||
value: '=value',
|
||||
secret: '=secret'
|
||||
},
|
||||
restrict: 'A',
|
||||
replace: 'true',
|
||||
template: "" +
|
||||
'<span class="credential_field">' +
|
||||
'<div class="value" ng-class="{\'ellipsis\': isLink}">' +
|
||||
'<span ng-repeat="n in [] | range:value.length" ng-if="!valueVisible">*</span>' +
|
||||
'<span ng-if="valueVisible">{{value}}</span>' +
|
||||
'</div>' +
|
||||
'<div class="tools">' +
|
||||
'<div class="cell" ng-if="toggle" tooltip="\'Toggle visibility\'" ng-click="toggleVisibility()"><i class="fa" ng-class="{\'fa-eye\': !valueVisible, \'fa-eye-slash\': valueVisible }"></i></div>' +
|
||||
'<div class="cell" ng-if="isLink"><a ng-href="{{value}}" target="_blank"><i tooltip="\'Open in new window\'" class="link fa fa-external-link"></i></a></div>' +
|
||||
'<div class="cell" ngclipboard-success="onSuccess(e);" ngclipboard-error="onError(e);" ngclipboard data-clipboard-text="{{value}}"><i tooltip="copy_msg" class="fa fa-clipboard"></i></div>' +
|
||||
'</div></span>',
|
||||
link: function (scope, elem, attrs, modelCtrl) {
|
||||
var expression = /(https?:\/\/(?:www\.|(?!www))[^\s\.]+\.[^\s]{2,}|www\.[^\s]+\.[^\s]{2,})/gi;
|
||||
var regex = new RegExp(expression);
|
||||
|
||||
angular.module('passmanApp')
|
||||
.directive('credentialField', ['$timeout', function ($timeout) {
|
||||
return {
|
||||
scope: {
|
||||
value: '=value',
|
||||
secret: '=secret'
|
||||
},
|
||||
restrict: 'A',
|
||||
replace: 'true',
|
||||
template: "" +
|
||||
'<span class="credential_field">' +
|
||||
'<div class="value" ng-class="{\'ellipsis\': isLink}">' +
|
||||
'<span ng-repeat="n in [] | range:value.length" ng-if="!valueVisible">*</span>' +
|
||||
'<span ng-if="valueVisible">{{value}}</span>' +
|
||||
'</div>' +
|
||||
'<div class="tools">' +
|
||||
'<div class="cell" ng-if="toggle" tooltip="\'Toggle visibility\'" ng-click="toggleVisibility()"><i class="fa" ng-class="{\'fa-eye\': !valueVisible, \'fa-eye-slash\': valueVisible }"></i></div>' +
|
||||
'<div class="cell" ng-if="isLink"><a ng-href="{{value}}" target="_blank"><i tooltip="\'Open in new window\'" class="link fa fa-external-link"></i></a></div>' +
|
||||
'<div class="cell" ngclipboard-success="onSuccess(e);" ngclipboard-error="onError(e);" ngclipboard data-clipboard-text="{{value}}"><i tooltip="copy_msg" class="fa fa-clipboard"></i></div>' +
|
||||
'</div></span>',
|
||||
link: function (scope, elem, attrs, modelCtrl) {
|
||||
var expression = /(https?:\/\/(?:www\.|(?!www))[^\s\.]+\.[^\s]{2,}|www\.[^\s]+\.[^\s]{2,})/gi;
|
||||
var regex = new RegExp(expression);
|
||||
scope.$watch("value", function () {
|
||||
if (scope.value) {
|
||||
if (scope.secret) {
|
||||
scope.valueVisible = false;
|
||||
}
|
||||
if (scope.value.match(regex)) {
|
||||
scope.isLink = true;
|
||||
|
||||
scope.$watch("value", function () {
|
||||
if(scope.value) {
|
||||
}
|
||||
}
|
||||
});
|
||||
if (!scope.toggle) {
|
||||
if (scope.secret) {
|
||||
scope.valueVisible = false;
|
||||
scope.toggle = true;
|
||||
}
|
||||
if (scope.value.match(regex)) {
|
||||
console.log('is link')
|
||||
scope.isLink = true;
|
||||
}
|
||||
scope.copy_msg = 'Copy to clipboard';
|
||||
var timer;
|
||||
scope.onSuccess = function () {
|
||||
scope.copy_msg = 'Copied to clipboard!';
|
||||
$timeout.cancel(timer);
|
||||
timer = $timeout(function () {
|
||||
scope.copy_msg = 'Copy to clipboard';
|
||||
}, 5000);
|
||||
};
|
||||
scope.valueVisible = true;
|
||||
scope.toggleVisibility = function () {
|
||||
scope.valueVisible = !scope.valueVisible;
|
||||
};
|
||||
}
|
||||
};
|
||||
}]);
|
||||
|
||||
}
|
||||
}
|
||||
});
|
||||
if (!scope.toggle) {
|
||||
if (scope.secret) {
|
||||
scope.toggle = true;
|
||||
}
|
||||
}
|
||||
scope.copy_msg = 'Copy to clipboard';
|
||||
var timer;
|
||||
scope.onSuccess = function () {
|
||||
scope.copy_msg = 'Copied to clipboard!';
|
||||
$timeout.cancel(timer);
|
||||
timer = $timeout(function () {
|
||||
scope.copy_msg = 'Copy to clipboard';
|
||||
}, 5000)
|
||||
}
|
||||
scope.valueVisible = true;
|
||||
scope.toggleVisibility = function () {
|
||||
scope.valueVisible = !scope.valueVisible;
|
||||
};
|
||||
}
|
||||
};
|
||||
}]);
|
||||
}());
|
|
@ -1,65 +1,67 @@
|
|||
'use strict';
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* @ngdoc directive
|
||||
* @name passmanApp.directive:passwordGen
|
||||
* @description
|
||||
* # passwordGen
|
||||
*/
|
||||
angular.module('passmanApp')
|
||||
.directive('fileSelect', ['$window', function ($window) {
|
||||
return {
|
||||
restrict: 'A',
|
||||
scope: {
|
||||
success: '&success',
|
||||
error: '&error',
|
||||
progress: '&progress'
|
||||
},
|
||||
/**
|
||||
* @ngdoc directive
|
||||
* @name passmanApp.directive:passwordGen
|
||||
* @description
|
||||
* # passwordGen
|
||||
*/
|
||||
angular.module('passmanApp')
|
||||
.directive('fileSelect', ['$window', function ($window) {
|
||||
return {
|
||||
restrict: 'A',
|
||||
scope: {
|
||||
success: '&success',
|
||||
error: '&error',
|
||||
progress: '&progress'
|
||||
},
|
||||
|
||||
link: function (scope, el, attr, ctrl) {
|
||||
scope.success = scope.success();
|
||||
scope.error = scope.error();
|
||||
scope.progress = scope.progress();
|
||||
var fileReader = new $window.FileReader();
|
||||
var _currentFile;
|
||||
link: function (scope, el, attr, ctrl) {
|
||||
scope.success = scope.success();
|
||||
scope.error = scope.error();
|
||||
scope.progress = scope.progress();
|
||||
var fileReader = new $window.FileReader();
|
||||
var _currentFile;
|
||||
|
||||
fileReader.onload = function () {
|
||||
_currentFile.data = fileReader.result;
|
||||
scope.success(_currentFile)
|
||||
};
|
||||
fileReader.onload = function () {
|
||||
_currentFile.data = fileReader.result;
|
||||
scope.success(_currentFile);
|
||||
};
|
||||
|
||||
fileReader.onprogress = function (event) {
|
||||
var percent = (event.loaded / event.total * 100);
|
||||
scope.$apply(scope.progress({
|
||||
file_total: event.total,
|
||||
file_loaded: event.loaded,
|
||||
file_percent: percent
|
||||
}));
|
||||
};
|
||||
fileReader.onprogress = function (event) {
|
||||
var percent = (event.loaded / event.total * 100);
|
||||
scope.$apply(scope.progress({
|
||||
file_total: event.total,
|
||||
file_loaded: event.loaded,
|
||||
file_percent: percent
|
||||
}));
|
||||
};
|
||||
|
||||
fileReader.onerror = function () {
|
||||
scope.error()
|
||||
};
|
||||
fileReader.onerror = function () {
|
||||
scope.error();
|
||||
};
|
||||
|
||||
el.bind('change', function (e) {
|
||||
var _queueTotalFileSize = 0;
|
||||
var _queueProgressBytes = 0;
|
||||
|
||||
//Calcutate total size
|
||||
for (var i = 0; i < e.target.files.length; i++) {
|
||||
_queueTotalFileSize += e.target.files[i].size;
|
||||
}
|
||||
//Now load the files
|
||||
for (var i = 0; i < e.target.files.length; i++) {
|
||||
_currentFile = e.target.files[i];
|
||||
var mb_limit = 5;
|
||||
if (_currentFile.size > (mb_limit * 1024 * 1024)) {
|
||||
scope.error('TO_BIG', _currentFile);
|
||||
el.bind('change', function (e) {
|
||||
var _queueTotalFileSize = 0;
|
||||
var _queueProgressBytes = 0;
|
||||
var i;
|
||||
//Calcutate total size
|
||||
for (i = 0; i < e.target.files.length; i++) {
|
||||
_queueTotalFileSize += e.target.files[i].size;
|
||||
}
|
||||
fileReader.readAsDataURL(_currentFile);
|
||||
//Now load the files
|
||||
for (i = 0; i < e.target.files.length; i++) {
|
||||
_currentFile = e.target.files[i];
|
||||
var mb_limit = 5;
|
||||
if (_currentFile.size > (mb_limit * 1024 * 1024)) {
|
||||
scope.error('TO_BIG', _currentFile);
|
||||
}
|
||||
fileReader.readAsDataURL(_currentFile);
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
}]);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
}]);
|
||||
}());
|
|
@ -1,22 +1,24 @@
|
|||
'use strict';
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* @ngdoc directive
|
||||
* @name passmanApp.directive:passwordGen
|
||||
* @description
|
||||
* # passwordGen
|
||||
*/
|
||||
angular.module('passmanApp')
|
||||
.directive('ngEnter', function () {
|
||||
return function (scope, element, attrs) {
|
||||
element.bind("keydown keypress", function (event) {
|
||||
if (event.which === 13) {
|
||||
scope.$apply(function () {
|
||||
scope.$eval(attrs.ngEnter);
|
||||
});
|
||||
/**
|
||||
* @ngdoc directive
|
||||
* @name passmanApp.directive:passwordGen
|
||||
* @description
|
||||
* # passwordGen
|
||||
*/
|
||||
angular.module('passmanApp')
|
||||
.directive('ngEnter', function () {
|
||||
return function (scope, element, attrs) {
|
||||
element.bind("keydown keypress", function (event) {
|
||||
if (event.which === 13) {
|
||||
scope.$apply(function () {
|
||||
scope.$eval(attrs.ngEnter);
|
||||
});
|
||||
|
||||
event.preventDefault();
|
||||
}
|
||||
});
|
||||
};
|
||||
});
|
||||
event.preventDefault();
|
||||
}
|
||||
});
|
||||
};
|
||||
});
|
||||
}());
|
|
@ -1,96 +1,104 @@
|
|||
'use strict';
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* @ngdoc directive
|
||||
* @name passmanApp.directive:passwordGen
|
||||
* @description
|
||||
* # passwordGen
|
||||
*/
|
||||
angular.module('passmanApp')
|
||||
.directive('otpGenerator', ['$compile', '$timeout',
|
||||
function ($compile, $timeout) {
|
||||
function dec2hex(s) { return (s < 15.5 ? '0' : '') + Math.round(s).toString(16); }
|
||||
function hex2dec(s) { return parseInt(s, 16); }
|
||||
|
||||
function base32tohex(base32) {
|
||||
if(!base32){
|
||||
return;
|
||||
}
|
||||
var base32chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
|
||||
var bits = "";
|
||||
var hex = "";
|
||||
|
||||
for (var i = 0; i < base32.length; i++) {
|
||||
var val = base32chars.indexOf(base32.charAt(i).toUpperCase());
|
||||
bits += leftpad(val.toString(2), 5, '0');
|
||||
/**
|
||||
* @ngdoc directive
|
||||
* @name passmanApp.directive:passwordGen
|
||||
* @description
|
||||
* # passwordGen
|
||||
*/
|
||||
angular.module('passmanApp')
|
||||
.directive('otpGenerator', ['$compile', '$timeout',
|
||||
function ($compile, $timeout) {
|
||||
function dec2hex (s) {
|
||||
return (s < 15.5 ? '0' : '') + Math.round(s).toString(16);
|
||||
}
|
||||
|
||||
for (var i = 0; i+4 <= bits.length; i+=4) {
|
||||
var chunk = bits.substr(i, 4);
|
||||
hex = hex + parseInt(chunk, 2).toString(16) ;
|
||||
function hex2dec (s) {
|
||||
return parseInt(s, 16);
|
||||
}
|
||||
return hex;
|
||||
|
||||
function base32tohex (base32) {
|
||||
if (!base32) {
|
||||
return;
|
||||
}
|
||||
var base32chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
|
||||
var bits = "";
|
||||
var hex = "";
|
||||
var i;
|
||||
for (i = 0; i < base32.length; i++) {
|
||||
var val = base32chars.indexOf(base32.charAt(i).toUpperCase());
|
||||
bits += leftpad(val.toString(2), 5, '0');
|
||||
}
|
||||
|
||||
for (i = 0; i + 4 <= bits.length; i += 4) {
|
||||
var chunk = bits.substr(i, 4);
|
||||
hex = hex + parseInt(chunk, 2).toString(16);
|
||||
}
|
||||
return hex;
|
||||
|
||||
}
|
||||
|
||||
function leftpad (str, len, pad) {
|
||||
if (len + 1 >= str.length) {
|
||||
str = Array(len + 1 - str.length).join(pad) + str;
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
return {
|
||||
restrict: 'A',
|
||||
template: '<span class="otp_generator"><span credential-field value="otp" secret="\'true\'"></span> <span ng-bind="timeleft"></span></span>',
|
||||
transclude: false,
|
||||
scope: {
|
||||
secret: '='
|
||||
},
|
||||
replace: true,
|
||||
link: function (scope, element) {
|
||||
scope.otp = null;
|
||||
scope.timeleft = null;
|
||||
scope.timer = null;
|
||||
var updateOtp = function () {
|
||||
if (!scope.secret) {
|
||||
return;
|
||||
}
|
||||
var key = base32tohex(scope.secret);
|
||||
var epoch = Math.round(new Date().getTime() / 1000.0);
|
||||
var time = leftpad(dec2hex(Math.floor(epoch / 30)), 16, '0');
|
||||
var hmacObj = new jsSHA(time, 'HEX');
|
||||
var hmac = hmacObj.getHMAC(key, 'HEX', 'SHA-1', "HEX");
|
||||
var offset = hex2dec(hmac.substring(hmac.length - 1));
|
||||
var otp = (hex2dec(hmac.substr(offset * 2, 8)) & hex2dec('7fffffff')) + '';
|
||||
otp = (otp).substr(otp.length - 6, 6);
|
||||
scope.otp = otp;
|
||||
|
||||
};
|
||||
|
||||
var timer = function () {
|
||||
var epoch = Math.round(new Date().getTime() / 1000.0);
|
||||
var countDown = 30 - (epoch % 30);
|
||||
if (epoch % 30 === 0) updateOtp();
|
||||
scope.timeleft = countDown;
|
||||
scope.timer = $timeout(timer, 1000);
|
||||
|
||||
};
|
||||
scope.$watch("secret", function (n) {
|
||||
if (n) {
|
||||
$timeout.cancel(scope.timer);
|
||||
updateOtp();
|
||||
timer();
|
||||
} else {
|
||||
$timeout.cancel(scope.timer);
|
||||
}
|
||||
}, true);
|
||||
scope.$on(
|
||||
"$destroy",
|
||||
function (event) {
|
||||
$timeout.cancel(scope.timer);
|
||||
}
|
||||
);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function leftpad(str, len, pad) {
|
||||
if (len + 1 >= str.length) {
|
||||
str = Array(len + 1 - str.length).join(pad) + str;
|
||||
}
|
||||
return str;
|
||||
}
|
||||
return {
|
||||
restrict: 'A',
|
||||
template: '<span class="otp_generator"><span credential-field value="otp" secret="\'true\'"></span> <span ng-bind="timeleft"></span></span>',
|
||||
transclude: false,
|
||||
scope: {
|
||||
secret: '='
|
||||
},
|
||||
replace: true,
|
||||
link: function (scope, element) {
|
||||
scope.otp = null;
|
||||
scope.timeleft = null;
|
||||
scope.timer = null;
|
||||
var updateOtp = function () {
|
||||
if (!scope.secret) {
|
||||
return;
|
||||
}
|
||||
var key = base32tohex(scope.secret);
|
||||
var epoch = Math.round(new Date().getTime() / 1000.0);
|
||||
var time = leftpad(dec2hex(Math.floor(epoch / 30)), 16, '0');
|
||||
var hmacObj = new jsSHA(time, 'HEX');
|
||||
var hmac = hmacObj.getHMAC(key, 'HEX', 'SHA-1', "HEX");
|
||||
var offset = hex2dec(hmac.substring(hmac.length - 1));
|
||||
var otp = (hex2dec(hmac.substr(offset * 2, 8)) & hex2dec('7fffffff')) + '';
|
||||
otp = (otp).substr(otp.length - 6, 6);
|
||||
scope.otp = otp;
|
||||
|
||||
};
|
||||
|
||||
var timer = function () {
|
||||
var epoch = Math.round(new Date().getTime() / 1000.0);
|
||||
var countDown = 30 - (epoch % 30);
|
||||
if (epoch % 30 == 0) updateOtp();
|
||||
scope.timeleft = countDown;
|
||||
scope.timer = $timeout(timer, 1000);
|
||||
|
||||
};
|
||||
scope.$watch("secret", function (n) {
|
||||
if (n) {
|
||||
$timeout.cancel(scope.timer);
|
||||
updateOtp();
|
||||
timer();
|
||||
} else {
|
||||
$timeout.cancel(scope.timer);
|
||||
}
|
||||
}, true);
|
||||
scope.$on(
|
||||
"$destroy",
|
||||
function (event) {
|
||||
$timeout.cancel(scope.timer);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
]);
|
||||
]);
|
||||
}());
|
|
@ -1,208 +1,225 @@
|
|||
'use strict';
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* @ngdoc directive
|
||||
* @name passmanApp.directive:passwordGen
|
||||
* @description
|
||||
* # passwordGen
|
||||
*/
|
||||
/**
|
||||
* @ngdoc directive
|
||||
* @name passmanApp.directive:passwordGen
|
||||
* @description
|
||||
* # passwordGen
|
||||
*/
|
||||
|
||||
angular.module('passmanApp')
|
||||
.directive('passwordGen', function ($timeout,$window) {
|
||||
function Arcfour () {
|
||||
this.j = this.i = 0, this.S = []
|
||||
}
|
||||
function ARC4init (r) {
|
||||
var t, n, e;
|
||||
for (t = 0; 256 > t; ++t)this.S[t] = t
|
||||
for (t = n = 0; 256 > t; ++t)n = n + this.S[t] + r[t % r.length] & 255, e = this.S[t], this.S[t] = this.S[n], this.S[n] = e
|
||||
this.j = this.i = 0
|
||||
}
|
||||
function ARC4next () {
|
||||
var r;
|
||||
return this.i = this.i + 1 & 255, this.j = this.j + this.S[this.i] & 255, r = this.S[this.i], this.S[this.i] = this.S[this.j], this.S[this.j] = r, this.S[r + this.S[this.i] & 255]
|
||||
}
|
||||
function prng_newstate () {
|
||||
return new Arcfour
|
||||
}
|
||||
function generatePassword (r, t, n, e, o, i, p, g) {
|
||||
var _, a, s, f, d, h, u, l, c, v, w, y, m;
|
||||
if (void 0 === r && (r = 8 + get_random(0, 1)), r > 256 && (r = 256, document.getElementById("length").value = 256), i > 256 && (i = 256), void 0 === t && (t = !0), void 0 === n && (n = !0), void 0 === e && (e = !0), void 0 === o && (o = !1), void 0 === i && (i = 0), void 0 === p && (p = !1), void 0 === g && (g = !0), _ = 0, a = 0, s = 0, g && (_ = a = s = 1), f = [], n && _ > 0)for (d = 0; _ > d; d++)f[f.length] = "L"
|
||||
if (t && a > 0)for (d = 0; a > d; d++)f[f.length] = "U"
|
||||
if (e && i > 0)for (d = 0; i > d; d++)f[f.length] = "D"
|
||||
if (o && s > 0)for (d = 0; s > d; d++)f[f.length] = "S"
|
||||
for (; f.length < r;)f[f.length] = "A"
|
||||
for (f.sort(function () {
|
||||
return 2 * get_random(0, 1) - 1
|
||||
}), h = "", u = "abcdefghjkmnpqrstuvwxyz", p || (u += "ilo"), n && (h += u), l = "ABCDEFGHJKMNPQRSTUVWXYZ", p || (l += "ILO"), t && (h += l), c = "23456789", p || (c += "10"), e && (h += c), v = "!@#$%^&*", o && (h += v), w = "", y = 0; r > y; y++) {
|
||||
switch (f[y]) {
|
||||
case"L":
|
||||
m = u;
|
||||
break;
|
||||
case"U":
|
||||
m = l;
|
||||
break;
|
||||
case"D":
|
||||
m = c;
|
||||
break;
|
||||
case"S":
|
||||
m = v;
|
||||
break;
|
||||
case"A":
|
||||
m = h
|
||||
}
|
||||
d = get_random(0, m.length - 1), w += m.charAt(d)
|
||||
angular.module('passmanApp')
|
||||
.directive('passwordGen', function ($timeout, $window) {
|
||||
/* jshint ignore:start */
|
||||
function Arcfour () {
|
||||
this.j = this.i = 0, this.S = []
|
||||
}
|
||||
return w
|
||||
}
|
||||
function rng_seed_int (r) {
|
||||
rng_pool[rng_pptr++] ^= 255 & r, rng_pool[rng_pptr++] ^= r >> 8 & 255, rng_pool[rng_pptr++] ^= r >> 16 & 255, rng_pool[rng_pptr++] ^= r >> 24 & 255, rng_pptr >= rng_psize && (rng_pptr -= rng_psize)
|
||||
}
|
||||
function rng_seed_time () {
|
||||
rng_seed_int((new Date).getTime())
|
||||
}
|
||||
function rng_get_byte () {
|
||||
if (null == rng_state) {
|
||||
for (rng_seed_time(), rng_state = prng_newstate(), rng_state.init(rng_pool), rng_pptr = 0; rng_pptr < rng_pool.length; ++rng_pptr)rng_pool[rng_pptr] = 0
|
||||
rng_pptr = 0
|
||||
|
||||
function ARC4init (r) {
|
||||
var t, n, e;
|
||||
for (t = 0; 256 > t; ++t)this.S[t] = t
|
||||
for (t = n = 0; 256 > t; ++t)n = n + this.S[t] + r[t % r.length] & 255, e = this.S[t], this.S[t] = this.S[n], this.S[n] = e
|
||||
this.j = this.i = 0
|
||||
}
|
||||
return rng_state.next()
|
||||
}
|
||||
function rng_get_bytes (r) {
|
||||
var t;
|
||||
for (t = 0; t < r.length; ++t)r[t] = rng_get_byte()
|
||||
}
|
||||
function SecureRandom () {
|
||||
}
|
||||
function get_random (r, t) {
|
||||
var n, e, o, i = t - r + 1
|
||||
for (rng_seed_time(), n = [], e = 0; 4 > e; e++)n[e] = 0
|
||||
for (rng_get_bytes(n), o = 0, e = 0; 4 > e; e++)o *= 256, o += n[e]
|
||||
return o %= i, o += r
|
||||
}
|
||||
function get_random_password (r, t) {
|
||||
var n;
|
||||
var pwlen, newpw;
|
||||
for ("number" != typeof r && (r = 12), "number" != typeof t && (t = 16), r > t && (n = r, r = t, t = n), pwlen = get_random(r, t), newpw = ""; newpw.length < pwlen;)newpw += String.fromCharCode(get_random(32, 127))
|
||||
return newpw
|
||||
}
|
||||
var rng_psize, rng_state, rng_pool, rng_pptr, t, z, crypt_obj, num, buf, i
|
||||
if (Arcfour.prototype.init = ARC4init, Arcfour.prototype.next = ARC4next, rng_psize = 256, null == rng_pool) {
|
||||
if (rng_pool = [], rng_pptr = 0, "undefined" != typeof navigator && "Netscape" == navigator.appName && navigator.appVersion < "5" && "undefined" != typeof window && window.crypto)for (z = window.crypto.random(32), t = 0; t < z.length; ++t)rng_pool[rng_pptr++] = 255 & z.charCodeAt(t)
|
||||
try {
|
||||
if (crypt_obj = null, "undefined" != typeof window && void 0 !== window.crypto ? crypt_obj = window.crypto : "undefined" != typeof window && void 0 !== window.msCrypto && (crypt_obj = window.msCrypto), void 0 !== crypt_obj && "function" == typeof crypt_obj.getRandomValues && rng_psize > rng_pptr)for (num = Math.floor((rng_psize - rng_pptr) / 2) + 1, buf = new Uint16Array(num), crypt_obj.getRandomValues(buf), i = 0; i < buf.length; i++)t = buf[i], rng_pool[rng_pptr++] = t >>> 8, rng_pool[rng_pptr++] = 255 & t
|
||||
} catch (e) {
|
||||
|
||||
function ARC4next () {
|
||||
var r;
|
||||
return this.i = this.i + 1 & 255, this.j = this.j + this.S[this.i] & 255, r = this.S[this.i], this.S[this.i] = this.S[this.j], this.S[this.j] = r, this.S[r + this.S[this.i] & 255]
|
||||
}
|
||||
for (; rng_psize > rng_pptr;)t = Math.floor(65536 * Math.random()), rng_pool[rng_pptr++] = t >>> 8, rng_pool[rng_pptr++] = 255 & t
|
||||
rng_pptr = 0, rng_seed_time()
|
||||
}
|
||||
SecureRandom.prototype.nextBytes = rng_get_bytes;
|
||||
|
||||
return {
|
||||
scope: {
|
||||
model : "=ngModel",
|
||||
length : "@",
|
||||
placeholder: "@",
|
||||
settings: '=settings',
|
||||
callback: '&callback'
|
||||
},
|
||||
function prng_newstate () {
|
||||
return new Arcfour
|
||||
}
|
||||
|
||||
restrict: "E",
|
||||
replace : "true",
|
||||
template: "" +
|
||||
"<div class=\" pw-gen \">" +
|
||||
"<div class=\"input-group \">" +
|
||||
"<input ng-show=\"!passwordVisible\" type=\"password\" ng-disabled=\"disabled\" class=\"form-control \" ng-model=\"password\" placeholder=\"{{placeholder}}\">" +
|
||||
"<input ng-show=\"passwordVisible\" type=\"text\" ng-disabled=\"disabled\" class=\"form-control \" ng-model=\"password\" placeholder=\"{{placeholder}}\">" +
|
||||
|
||||
'<span class="generate_pw">' +
|
||||
'<div class="cell" tooltip="\'Generate password\'" ng-click="generatePasswordStart()"><i class="fa fa-refresh"></i></div>' +
|
||||
'<div class="cell" tooltip="\'Toggle password visibility\'" ng-click="toggleVisibility()"><i class="fa" ng-class="{\'fa-eye\': passwordVisible, \'fa-eye-slash\': !passwordVisible }"></i></div>' +
|
||||
'<div class="cell" tooltip="\'Copy password to clipboard\'"><i class="fa fa-clipboard" ngclipboard-success="onSuccess(e);" ngclipboard-error="onError(e);" ngclipboard data-clipboard-text="{{password}}"></i></div>' +
|
||||
"</button>" +
|
||||
"</div>" +
|
||||
"</div>",
|
||||
link: function(scope, elem, attrs, modelCtrl) {
|
||||
scope.callback = scope.callback();
|
||||
scope.$watch("model", function () {
|
||||
scope.password = scope.model;
|
||||
});
|
||||
scope.passwordVisible = false;
|
||||
scope.toggleVisibility = function(){
|
||||
scope.passwordVisible = !scope.passwordVisible;
|
||||
};
|
||||
|
||||
scope.passwordNotNull = false;
|
||||
scope.$watch("settings", function () {
|
||||
if(scope.settings) {
|
||||
if (!scope.password && scope.settings.generateOnCreate) {
|
||||
scope.generatePasswordStart();
|
||||
}
|
||||
function generatePassword (r, t, n, e, o, i, p, g) {
|
||||
var _, a, s, f, d, h, u, l, c, v, w, y, m;
|
||||
if (void 0 === r && (r = 8 + get_random(0, 1)), r > 256 && (r = 256, document.getElementById("length").value = 256), i > 256 && (i = 256), void 0 === t && (t = !0), void 0 === n && (n = !0), void 0 === e && (e = !0), void 0 === o && (o = !1), void 0 === i && (i = 0), void 0 === p && (p = !1), void 0 === g && (g = !0), _ = 0, a = 0, s = 0, g && (_ = a = s = 1), f = [], n && _ > 0)for (d = 0; _ > d; d++)f[f.length] = "L"
|
||||
if (t && a > 0)for (d = 0; a > d; d++)f[f.length] = "U"
|
||||
if (e && i > 0)for (d = 0; i > d; d++)f[f.length] = "D"
|
||||
if (o && s > 0)for (d = 0; s > d; d++)f[f.length] = "S"
|
||||
for (; f.length < r;)f[f.length] = "A"
|
||||
for (f.sort(function () {
|
||||
return 2 * get_random(0, 1) - 1
|
||||
}), h = "", u = "abcdefghjkmnpqrstuvwxyz", p || (u += "ilo"), n && (h += u), l = "ABCDEFGHJKMNPQRSTUVWXYZ", p || (l += "ILO"), t && (h += l), c = "23456789", p || (c += "10"), e && (h += c), v = "!@#$%^&*", o && (h += v), w = "", y = 0; r > y; y++) {
|
||||
switch (f[y]) {
|
||||
case"L":
|
||||
m = u;
|
||||
break;
|
||||
case"U":
|
||||
m = l;
|
||||
break;
|
||||
case"D":
|
||||
m = c;
|
||||
break;
|
||||
case"S":
|
||||
m = v;
|
||||
break;
|
||||
case"A":
|
||||
m = h
|
||||
}
|
||||
});
|
||||
d = get_random(0, m.length - 1), w += m.charAt(d)
|
||||
}
|
||||
return w
|
||||
}
|
||||
|
||||
function rng_seed_int (r) {
|
||||
rng_pool[rng_pptr++] ^= 255 & r, rng_pool[rng_pptr++] ^= r >> 8 & 255, rng_pool[rng_pptr++] ^= r >> 16 & 255, rng_pool[rng_pptr++] ^= r >> 24 & 255, rng_pptr >= rng_psize && (rng_pptr -= rng_psize)
|
||||
}
|
||||
|
||||
scope.$watch("password", function () {
|
||||
scope.model = scope.password;
|
||||
scope.password_repeat = scope.model;
|
||||
});
|
||||
//
|
||||
scope.onSuccess = function(e) {
|
||||
//@TODO move OC.Notification to a service
|
||||
OC.Notification.showTemporary('Password copied to clipboard!');
|
||||
e.clearSelection();
|
||||
};
|
||||
function rng_seed_time () {
|
||||
rng_seed_int((new Date).getTime())
|
||||
}
|
||||
|
||||
scope.onError = function(e) {
|
||||
OC.Notification.showTemporary('Press Ctrl+C to copy!');
|
||||
};
|
||||
scope.progressDivShow = false;
|
||||
scope.generatePasswordStart = function() {
|
||||
scope.progressDivShow = true;
|
||||
scope.progressValue = 0;
|
||||
scope.progressWidth = {"width": scope.progressValue + "%"};
|
||||
scope.generatePasswordProgress();
|
||||
};
|
||||
scope.generatePasswordProgress = function() {
|
||||
$timeout(function() {
|
||||
if(scope.progressValue < 100) {
|
||||
scope.password = scope._generatePassword(scope.settings);
|
||||
scope.progressValue += 10;
|
||||
scope.progressWidth = {"width": scope.progressValue + "%"};
|
||||
scope.disabled = true;
|
||||
scope.generatePasswordProgress();
|
||||
} else {
|
||||
scope.disabled = false;
|
||||
if(scope.callback) {
|
||||
scope.callback(scope.password)
|
||||
function rng_get_byte () {
|
||||
if (null == rng_state) {
|
||||
for (rng_seed_time(), rng_state = prng_newstate(), rng_state.init(rng_pool), rng_pptr = 0; rng_pptr < rng_pool.length; ++rng_pptr)rng_pool[rng_pptr] = 0
|
||||
rng_pptr = 0
|
||||
}
|
||||
return rng_state.next()
|
||||
}
|
||||
|
||||
function rng_get_bytes (r) {
|
||||
var t;
|
||||
for (t = 0; t < r.length; ++t)r[t] = rng_get_byte()
|
||||
}
|
||||
|
||||
function SecureRandom () {
|
||||
}
|
||||
|
||||
function get_random (r, t) {
|
||||
var n, e, o, i = t - r + 1
|
||||
for (rng_seed_time(), n = [], e = 0; 4 > e; e++)n[e] = 0
|
||||
for (rng_get_bytes(n), o = 0, e = 0; 4 > e; e++)o *= 256, o += n[e]
|
||||
return o %= i, o += r
|
||||
}
|
||||
|
||||
function get_random_password (r, t) {
|
||||
var n;
|
||||
var pwlen, newpw;
|
||||
for ("number" != typeof r && (r = 12), "number" != typeof t && (t = 16), r > t && (n = r, r = t, t = n), pwlen = get_random(r, t), newpw = ""; newpw.length < pwlen;)newpw += String.fromCharCode(get_random(32, 127))
|
||||
return newpw
|
||||
}
|
||||
|
||||
var rng_psize, rng_state, rng_pool, rng_pptr, t, z, crypt_obj, num, buf, i
|
||||
if (Arcfour.prototype.init = ARC4init, Arcfour.prototype.next = ARC4next, rng_psize = 256, null == rng_pool) {
|
||||
if (rng_pool = [], rng_pptr = 0, "undefined" != typeof navigator && "Netscape" == navigator.appName && navigator.appVersion < "5" && "undefined" != typeof window && window.crypto)for (z = window.crypto.random(32), t = 0; t < z.length; ++t)rng_pool[rng_pptr++] = 255 & z.charCodeAt(t)
|
||||
try {
|
||||
if (crypt_obj = null, "undefined" != typeof window && void 0 !== window.crypto ? crypt_obj = window.crypto : "undefined" != typeof window && void 0 !== window.msCrypto && (crypt_obj = window.msCrypto), void 0 !== crypt_obj && "function" == typeof crypt_obj.getRandomValues && rng_psize > rng_pptr)for (num = Math.floor((rng_psize - rng_pptr) / 2) + 1, buf = new Uint16Array(num), crypt_obj.getRandomValues(buf), i = 0; i < buf.length; i++)t = buf[i], rng_pool[rng_pptr++] = t >>> 8, rng_pool[rng_pptr++] = 255 & t
|
||||
} catch (e) {
|
||||
}
|
||||
for (; rng_psize > rng_pptr;)t = Math.floor(65536 * Math.random()), rng_pool[rng_pptr++] = t >>> 8, rng_pool[rng_pptr++] = 255 & t
|
||||
rng_pptr = 0, rng_seed_time()
|
||||
}
|
||||
SecureRandom.prototype.nextBytes = rng_get_bytes;
|
||||
/* jshint ignore:end */
|
||||
return {
|
||||
scope: {
|
||||
model: "=ngModel",
|
||||
length: "@",
|
||||
placeholder: "@",
|
||||
settings: '=settings',
|
||||
callback: '&callback'
|
||||
},
|
||||
|
||||
restrict: "E",
|
||||
replace: "true",
|
||||
template: "" +
|
||||
"<div class=\" pw-gen \">" +
|
||||
"<div class=\"input-group \">" +
|
||||
"<input ng-show=\"!passwordVisible\" type=\"password\" ng-disabled=\"disabled\" class=\"form-control \" ng-model=\"password\" placeholder=\"{{placeholder}}\">" +
|
||||
"<input ng-show=\"passwordVisible\" type=\"text\" ng-disabled=\"disabled\" class=\"form-control \" ng-model=\"password\" placeholder=\"{{placeholder}}\">" +
|
||||
|
||||
'<span class="generate_pw">' +
|
||||
'<div class="cell" tooltip="\'Generate password\'" ng-click="generatePasswordStart()"><i class="fa fa-refresh"></i></div>' +
|
||||
'<div class="cell" tooltip="\'Toggle password visibility\'" ng-click="toggleVisibility()"><i class="fa" ng-class="{\'fa-eye\': passwordVisible, \'fa-eye-slash\': !passwordVisible }"></i></div>' +
|
||||
'<div class="cell" tooltip="\'Copy password to clipboard\'"><i class="fa fa-clipboard" ngclipboard-success="onSuccess(e);" ngclipboard-error="onError(e);" ngclipboard data-clipboard-text="{{password}}"></i></div>' +
|
||||
"</button>" +
|
||||
"</div>" +
|
||||
"</div>",
|
||||
link: function (scope, elem, attrs, modelCtrl) {
|
||||
scope.callback = scope.callback();
|
||||
scope.$watch("model", function () {
|
||||
scope.password = scope.model;
|
||||
});
|
||||
scope.passwordVisible = false;
|
||||
scope.toggleVisibility = function () {
|
||||
scope.passwordVisible = !scope.passwordVisible;
|
||||
};
|
||||
|
||||
scope.passwordNotNull = false;
|
||||
scope.$watch("settings", function () {
|
||||
if (scope.settings) {
|
||||
if (!scope.password && scope.settings.generateOnCreate) {
|
||||
scope.generatePasswordStart();
|
||||
}
|
||||
}
|
||||
}, 10);
|
||||
};
|
||||
});
|
||||
|
||||
|
||||
scope._generatePassword = function (settings) {
|
||||
var _settings = {
|
||||
'length': 12,
|
||||
'useUppercase': true,
|
||||
'useLowercase': true,
|
||||
'useDigits': true,
|
||||
'useSpecialChars': true,
|
||||
'minimumDigitCount': 3,
|
||||
'avoidAmbiguousCharacters': false,
|
||||
'requireEveryCharType': true
|
||||
scope.$watch("password", function () {
|
||||
scope.model = scope.password;
|
||||
scope.password_repeat = scope.model;
|
||||
});
|
||||
//
|
||||
scope.onSuccess = function (e) {
|
||||
//@TODO move OC.Notification to a service
|
||||
OC.Notification.showTemporary('Password copied to clipboard!');
|
||||
e.clearSelection();
|
||||
};
|
||||
settings = angular.merge(_settings, settings);
|
||||
var password = generatePassword(settings['length'],
|
||||
settings.useUppercase,
|
||||
settings.useLowercase,
|
||||
settings.useDigits,
|
||||
settings.useSpecialChars,
|
||||
settings.minimumDigitCount,
|
||||
settings.avoidAmbiguousCharacters,
|
||||
settings.requireEveryCharType);
|
||||
return password;
|
||||
};
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
scope.onError = function (e) {
|
||||
OC.Notification.showTemporary('Press Ctrl+C to copy!');
|
||||
};
|
||||
scope.progressDivShow = false;
|
||||
scope.generatePasswordStart = function () {
|
||||
scope.progressDivShow = true;
|
||||
scope.progressValue = 0;
|
||||
scope.progressWidth = {"width": scope.progressValue + "%"};
|
||||
scope.generatePasswordProgress();
|
||||
};
|
||||
scope.generatePasswordProgress = function () {
|
||||
$timeout(function () {
|
||||
if (scope.progressValue < 100) {
|
||||
scope.password = scope._generatePassword(scope.settings);
|
||||
scope.progressValue += 10;
|
||||
scope.progressWidth = {"width": scope.progressValue + "%"};
|
||||
scope.disabled = true;
|
||||
scope.generatePasswordProgress();
|
||||
} else {
|
||||
scope.disabled = false;
|
||||
if (scope.callback) {
|
||||
scope.callback(scope.password);
|
||||
}
|
||||
}
|
||||
}, 10);
|
||||
};
|
||||
|
||||
|
||||
scope._generatePassword = function (settings) {
|
||||
var _settings = {
|
||||
'length': 12,
|
||||
'useUppercase': true,
|
||||
'useLowercase': true,
|
||||
'useDigits': true,
|
||||
'useSpecialChars': true,
|
||||
'minimumDigitCount': 3,
|
||||
'avoidAmbiguousCharacters': false,
|
||||
'requireEveryCharType': true
|
||||
};
|
||||
settings = angular.merge(_settings, settings);
|
||||
/* jshint ignore:start */
|
||||
var password = generatePassword(settings['length'],
|
||||
settings.useUppercase,
|
||||
settings.useLowercase,
|
||||
settings.useDigits,
|
||||
settings.useSpecialChars,
|
||||
settings.minimumDigitCount,
|
||||
settings.avoidAmbiguousCharacters,
|
||||
settings.requireEveryCharType);
|
||||
/* jshint ignore:end */
|
||||
return password;
|
||||
};
|
||||
}
|
||||
};
|
||||
});
|
||||
}());
|
|
@ -1,31 +1,32 @@
|
|||
'use strict';
|
||||
|
||||
/**
|
||||
* @ngdoc directive
|
||||
* @name passmanApp.directive:passwordGen
|
||||
* @description
|
||||
* # passwordGen
|
||||
*/
|
||||
angular.module('passmanApp')
|
||||
.directive('progressBar', ['$window', function ($window) {
|
||||
return {
|
||||
restrict: 'A',
|
||||
template:''+
|
||||
'<div class="progress">'+
|
||||
'<div class="progress-bar" role="progressbar" aria-valuenow="{{progress}}"aria-valuemin="0" aria-valuemax="100" style="width:{{progress}}%;" use-theme>'+
|
||||
(function () {
|
||||
'use strict';
|
||||
/**
|
||||
* @ngdoc directive
|
||||
* @name passmanApp.directive:passwordGen
|
||||
* @description
|
||||
* # passwordGen
|
||||
*/
|
||||
angular.module('passmanApp')
|
||||
.directive('progressBar', ['$window', function ($window) {
|
||||
return {
|
||||
restrict: 'A',
|
||||
template: '' +
|
||||
'<div class="progress">' +
|
||||
'<div class="progress-bar" role="progressbar" aria-valuenow="{{progress}}"aria-valuemin="0" aria-valuemax="100" style="width:{{progress}}%;" use-theme>' +
|
||||
'<span class="sr-only">{{progress}}% Complete</span>' +
|
||||
'<span ng-if="index && total" class="progress-label" use-theme type="\'color\'" color="\'true\'">{{index}} / {{total}}</span>'+
|
||||
'<span ng-if="!index && !total" class="progress-label" use-theme type="\'color\'" color="\'true\'">{{progress}}%</span>'+
|
||||
'</div>'+
|
||||
'<span ng-if="index && total" class="progress-label" use-theme type="\'color\'" color="\'true\'">{{index}} / {{total}}</span>' +
|
||||
'<span ng-if="!index && !total" class="progress-label" use-theme type="\'color\'" color="\'true\'">{{progress}}%</span>' +
|
||||
'</div>' +
|
||||
'</div>',
|
||||
scope: {
|
||||
progress: '=progressBar',
|
||||
index: '=index',
|
||||
total: '=total'
|
||||
},
|
||||
scope: {
|
||||
progress: '=progressBar',
|
||||
index: '=index',
|
||||
total: '=total'
|
||||
},
|
||||
|
||||
link: function (scope, el, attr, ctrl) {
|
||||
link: function (scope, el, attr, ctrl) {
|
||||
|
||||
}
|
||||
};
|
||||
}]);
|
||||
}
|
||||
};
|
||||
}]);
|
||||
}());
|
|
@ -1,37 +1,44 @@
|
|||
'use strict';
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* @ngdoc directive
|
||||
* @name passmanApp.directive:passwordGen
|
||||
* @description
|
||||
* # passwordGen
|
||||
*/
|
||||
angular.module('passmanApp').directive("qrread", ['$parse','$compile',
|
||||
function($parse,$compile) {
|
||||
return {
|
||||
scope : true,
|
||||
link : function(scope, element, attributes) {
|
||||
var gCtx = null,gCanvas = null, c= 0, stype= 0, gUM=false, webkit=false, moz=false;
|
||||
var invoker = $parse(attributes.onRead);
|
||||
scope.imageData = null;
|
||||
/**
|
||||
* @ngdoc directive
|
||||
* @name passmanApp.directive:passwordGen
|
||||
* @description
|
||||
* # passwordGen
|
||||
*/
|
||||
angular.module('passmanApp').directive("qrread", ['$parse', '$compile',
|
||||
function ($parse, $compile) {
|
||||
return {
|
||||
scope: true,
|
||||
link: function (scope, element, attributes) {
|
||||
var gCtx = null, gCanvas = null, c = 0, stype = 0, gUM = false, webkit = false, moz = false;
|
||||
var invoker = $parse(attributes.onRead);
|
||||
scope.imageData = null;
|
||||
|
||||
qrcode.callback = function(result){
|
||||
//console.log('QR callback:',result);
|
||||
invoker(scope, {qrdata: {qrData: result, image: scope.imageData } });
|
||||
//element.val('');
|
||||
qrcode.callback = function (result) {
|
||||
//console.log('QR callback:',result);
|
||||
invoker(scope, {
|
||||
qrdata: {
|
||||
qrData: result,
|
||||
image: scope.imageData
|
||||
}
|
||||
});
|
||||
//element.val('');
|
||||
};
|
||||
element.bind("change", function (changeEvent) {
|
||||
var reader = new FileReader(), file = changeEvent.target.files[0];
|
||||
reader.readAsDataURL(file);
|
||||
reader.onload = (function (theFile) {
|
||||
return function (e) {
|
||||
//gCtx.clearRect(0, 0, gCanvas.width, gCanvas.height);
|
||||
scope.imageData = e.target.result;
|
||||
qrcode.decode(e.target.result);
|
||||
};
|
||||
})(file);
|
||||
});
|
||||
}
|
||||
element.bind("change", function(changeEvent) {
|
||||
var reader = new FileReader(),file = changeEvent.target.files[0];
|
||||
reader.readAsDataURL(file);
|
||||
reader.onload = (function(theFile) {
|
||||
return function(e) {
|
||||
//gCtx.clearRect(0, 0, gCanvas.width, gCanvas.height);
|
||||
scope.imageData = e.target.result;
|
||||
qrcode.decode(e.target.result);
|
||||
};
|
||||
})(file);
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
]);
|
||||
]);
|
||||
}());
|
|
@ -1,32 +1,33 @@
|
|||
'use strict';
|
||||
(function () {
|
||||
'use strict';
|
||||
/**
|
||||
* @ngdoc directive
|
||||
* @name passmanApp.directive:passwordGen
|
||||
* @description
|
||||
* # passwordGen
|
||||
*/
|
||||
angular.module('passmanApp')
|
||||
.directive('tooltip', ['$window', function ($window) {
|
||||
return {
|
||||
restrict: 'A',
|
||||
scope: {
|
||||
tooltip: '=tooltip'
|
||||
},
|
||||
|
||||
/**
|
||||
* @ngdoc directive
|
||||
* @name passmanApp.directive:passwordGen
|
||||
* @description
|
||||
* # passwordGen
|
||||
*/
|
||||
angular.module('passmanApp')
|
||||
.directive('tooltip', ['$window', function ($window) {
|
||||
return {
|
||||
restrict: 'A',
|
||||
scope: {
|
||||
tooltip: '=tooltip'
|
||||
},
|
||||
link: function (scope, el, attr, ctrl) {
|
||||
scope.$watch('tooltip', function (newVal, old) {
|
||||
if (scope.tooltip) {
|
||||
jQuery(el).attr('title', scope.tooltip);
|
||||
jQuery(el).tooltip();
|
||||
jQuery(el).attr('title', scope.tooltip).tooltip('fixTitle');
|
||||
jQuery('.tooltip-inner').text(scope.tooltip); // Dirty hack
|
||||
if (jQuery(el).is(':visible')) {
|
||||
//$(el).tooltip('show')
|
||||
}
|
||||
|
||||
link: function (scope, el, attr, ctrl) {
|
||||
scope.$watch('tooltip', function (newVal, old) {
|
||||
if (scope.tooltip) {
|
||||
$(el).attr('title', scope.tooltip);
|
||||
$(el).tooltip();
|
||||
$(el).attr('title', scope.tooltip).tooltip('fixTitle');
|
||||
$('.tooltip-inner').text(scope.tooltip); // Dirty hack
|
||||
if($(el).is(':visible')){
|
||||
//$(el).tooltip('show')
|
||||
}
|
||||
|
||||
}
|
||||
})
|
||||
}
|
||||
};
|
||||
}]);
|
||||
});
|
||||
}
|
||||
};
|
||||
}]);
|
||||
}());
|
|
@ -1,45 +1,47 @@
|
|||
'use strict';
|
||||
(function () {
|
||||
'use strict';
|
||||
/**
|
||||
* @ngdoc directive
|
||||
* @name passmanApp.directive:passwordGen
|
||||
* @description
|
||||
* # passwordGen
|
||||
*/
|
||||
angular.module('passmanApp')
|
||||
.directive('useTheme', ['$window', function ($window) {
|
||||
|
||||
/**
|
||||
* @ngdoc directive
|
||||
* @name passmanApp.directive:passwordGen
|
||||
* @description
|
||||
* # passwordGen
|
||||
*/
|
||||
angular.module('passmanApp')
|
||||
.directive('useTheme', ['$window', function ($window) {
|
||||
|
||||
function invertColor(hexTripletColor) {
|
||||
var color = hexTripletColor;
|
||||
color = color.substring(1); // remove #
|
||||
color = parseInt(color, 16); // convert to integer
|
||||
color = 0xFFFFFF ^ color; // invert three bytes
|
||||
color = color.toString(16); // convert to hex
|
||||
color = ("000000" + color).slice(-6); // pad with leading zeros
|
||||
color = "#" + color; // prepend #
|
||||
return color;
|
||||
}
|
||||
return {
|
||||
restrict: 'A',
|
||||
scope:{
|
||||
type: '=type',
|
||||
color: '=',
|
||||
negative: '='
|
||||
},
|
||||
link: function (scope, el, attr, ctrl) {
|
||||
var _color = $('#header').css('background-color');
|
||||
var _bg = _color;
|
||||
if(scope.negative){
|
||||
_bg = invertColor(_bg)
|
||||
}
|
||||
if(!scope.type) {
|
||||
$(el).css('background-color', _bg);
|
||||
} else {
|
||||
$(el).css(scope.type, _bg);
|
||||
}
|
||||
if(scope.color){
|
||||
$(el).css('color', invertColor(_color));
|
||||
}
|
||||
function invertColor (hexTripletColor) {
|
||||
var color = hexTripletColor;
|
||||
color = color.substring(1); // remove #
|
||||
color = parseInt(color, 16); // convert to integer
|
||||
color = 0xFFFFFF ^ color; // invert three bytes
|
||||
color = color.toString(16); // convert to hex
|
||||
color = ("000000" + color).slice(-6); // pad with leading zeros
|
||||
color = "#" + color; // prepend #
|
||||
return color;
|
||||
}
|
||||
};
|
||||
}]);
|
||||
|
||||
return {
|
||||
restrict: 'A',
|
||||
scope: {
|
||||
type: '=type',
|
||||
color: '=',
|
||||
negative: '='
|
||||
},
|
||||
link: function (scope, el, attr, ctrl) {
|
||||
var _color = jQuery('#header').css('background-color');
|
||||
var _bg = _color;
|
||||
if (scope.negative) {
|
||||
_bg = invertColor(_bg);
|
||||
}
|
||||
if (!scope.type) {
|
||||
jQuery(el).css('background-color', _bg);
|
||||
} else {
|
||||
jQuery(el).css(scope.type, _bg);
|
||||
}
|
||||
if (scope.color) {
|
||||
jQuery(el).css('color', invertColor(_color));
|
||||
}
|
||||
}
|
||||
};
|
||||
}]);
|
||||
}());
|
|
@ -1,52 +1,55 @@
|
|||
/**
|
||||
* Created by Marcos Zuriaga on 3/10/16.
|
||||
* This file is part of passman, licensed under AGPLv3
|
||||
*/
|
||||
(function () {
|
||||
'use strict';
|
||||
/**
|
||||
* Created by Marcos Zuriaga on 3/10/16.
|
||||
* This file is part of passman, licensed under AGPLv3
|
||||
*/
|
||||
|
||||
angular.module('passmanApp').factory('SharingACL', function(){
|
||||
function ACL(acl_permission){
|
||||
this.permission = acl_permission;
|
||||
}
|
||||
angular.module('passmanApp').factory('SharingACL', function () {
|
||||
function ACL (acl_permission) {
|
||||
this.permission = acl_permission;
|
||||
}
|
||||
|
||||
ACL.prototype.permissions = {
|
||||
READ: 0x01,
|
||||
WRITE: 0x02,
|
||||
FILES: 0x04,
|
||||
HISTORY: 0x08,
|
||||
OWNER: 0x80,
|
||||
};
|
||||
/**
|
||||
* Checks if a user has the given permission/s
|
||||
* @param permission
|
||||
* @returns {boolean}
|
||||
*/
|
||||
ACL.prototype.hasPermission = function(permission){
|
||||
return permission == (this.permission & permission);
|
||||
};
|
||||
ACL.prototype.permissions = {
|
||||
READ: 0x01,
|
||||
WRITE: 0x02,
|
||||
FILES: 0x04,
|
||||
HISTORY: 0x08,
|
||||
OWNER: 0x80,
|
||||
};
|
||||
/**
|
||||
* Checks if a user has the given permission/s
|
||||
* @param permission
|
||||
* @returns {boolean}
|
||||
*/
|
||||
ACL.prototype.hasPermission = function (permission) {
|
||||
return permission === (this.permission & permission);
|
||||
};
|
||||
|
||||
/**
|
||||
* Adds a permission to a user, leaving any other permissions intact
|
||||
* @param permission
|
||||
*/
|
||||
ACL.prototype.addPermission = function(permission){
|
||||
this.permission = this.permission | permission;
|
||||
};
|
||||
/**
|
||||
* Adds a permission to a user, leaving any other permissions intact
|
||||
* @param permission
|
||||
*/
|
||||
ACL.prototype.addPermission = function (permission) {
|
||||
this.permission = this.permission | permission;
|
||||
};
|
||||
|
||||
/**
|
||||
* Removes a given permission from the item, leaving any other intact
|
||||
* @param permission
|
||||
*/
|
||||
ACL.prototype.removePermission = function(permission){
|
||||
this.permission = this.permission & ~permission;
|
||||
};
|
||||
/**
|
||||
* Removes a given permission from the item, leaving any other intact
|
||||
* @param permission
|
||||
*/
|
||||
ACL.prototype.removePermission = function (permission) {
|
||||
this.permission = this.permission & ~permission;
|
||||
};
|
||||
|
||||
ACL.prototype.togglePermission = function(permission){
|
||||
this.permission ^= permission;
|
||||
}
|
||||
ACL.prototype.togglePermission = function (permission) {
|
||||
this.permission ^= permission;
|
||||
};
|
||||
|
||||
ACL.prototype.getAccessLevel = function() {
|
||||
return this.permission;
|
||||
};
|
||||
ACL.prototype.getAccessLevel = function () {
|
||||
return this.permission;
|
||||
};
|
||||
|
||||
return ACL;
|
||||
});
|
||||
return ACL;
|
||||
});
|
||||
}());
|
|
@ -1,16 +1,18 @@
|
|||
'use strict';
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* @ngdoc filter
|
||||
* @name passmanApp.filter:as
|
||||
* @function
|
||||
* @description
|
||||
* # as
|
||||
* Filter in the passmanApp.
|
||||
*/
|
||||
angular.module('passmanApp')
|
||||
.filter("as", function($parse) {
|
||||
return function(value, context, path) {
|
||||
return $parse(path).assign(context, value);
|
||||
};
|
||||
});
|
||||
/**
|
||||
* @ngdoc filter
|
||||
* @name passmanApp.filter:as
|
||||
* @function
|
||||
* @description
|
||||
* # as
|
||||
* Filter in the passmanApp.
|
||||
*/
|
||||
angular.module('passmanApp')
|
||||
.filter("as", function ($parse) {
|
||||
return function (value, context, path) {
|
||||
return $parse(path).assign(context, value);
|
||||
};
|
||||
});
|
||||
}());
|
|
@ -1,20 +1,21 @@
|
|||
'use strict';
|
||||
|
||||
/**
|
||||
* @ngdoc filter
|
||||
* @name passmanApp.filter:decrypt
|
||||
* @function
|
||||
* @description
|
||||
* # decrypt
|
||||
* Filter in the passmanApp.
|
||||
*/
|
||||
angular.module('passmanApp')
|
||||
.filter('bytes', function () {
|
||||
return function (bytes, precision) {
|
||||
if (isNaN(parseFloat(bytes)) || !isFinite(bytes)) return '-';
|
||||
if (typeof precision === 'undefined') precision = 1;
|
||||
var units = ['bytes', 'kB', 'MB', 'GB', 'TB', 'PB'],
|
||||
number = Math.floor(Math.log(bytes) / Math.log(1024));
|
||||
return (bytes / Math.pow(1024, Math.floor(number))).toFixed(precision) + ' ' + units[number];
|
||||
}
|
||||
});
|
||||
(function () {
|
||||
'use strict';
|
||||
/**
|
||||
* @ngdoc filter
|
||||
* @name passmanApp.filter:decrypt
|
||||
* @function
|
||||
* @description
|
||||
* # decrypt
|
||||
* Filter in the passmanApp.
|
||||
*/
|
||||
angular.module('passmanApp')
|
||||
.filter('bytes', function () {
|
||||
return function (bytes, precision) {
|
||||
if (isNaN(parseFloat(bytes)) || !isFinite(bytes)) return '-';
|
||||
if (typeof precision === 'undefined') precision = 1;
|
||||
var units = ['bytes', 'kB', 'MB', 'GB', 'TB', 'PB'],
|
||||
number = Math.floor(Math.log(bytes) / Math.log(1024));
|
||||
return (bytes / Math.pow(1024, Math.floor(number))).toFixed(precision) + ' ' + units[number];
|
||||
};
|
||||
});
|
||||
}());
|
|
@ -1,41 +1,42 @@
|
|||
'use strict';
|
||||
(function () {
|
||||
'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.trim() === "") {
|
||||
return credentials;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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].toLowerCase().indexOf(filter.filterText.toLowerCase()) >= 0){
|
||||
_credentials.push(c);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
var t = JSON.stringify(c[field]);
|
||||
if(t.indexOf(filter.filterText) >= 0){
|
||||
_credentials.push(c);
|
||||
break;
|
||||
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].toLowerCase().indexOf(filter.filterText.toLowerCase()) >= 0) {
|
||||
_credentials.push(c);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
var t = JSON.stringify(c[field]);
|
||||
if (t.indexOf(filter.filterText) >= 0) {
|
||||
_credentials.push(c);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return _credentials;
|
||||
}
|
||||
return _credentials;
|
||||
}
|
||||
};
|
||||
});
|
||||
};
|
||||
});
|
||||
}());
|
|
@ -1,42 +1,43 @@
|
|||
'use strict';
|
||||
(function () {
|
||||
'use strict';
|
||||
/**
|
||||
* @ngdoc filter
|
||||
* @name passmanApp.filter:propsFilter
|
||||
* @function
|
||||
* @description
|
||||
* # propsFilter
|
||||
* Filter in the passmanApp.
|
||||
*/
|
||||
angular.module('passmanApp')
|
||||
.filter('propsFilter', function () {
|
||||
return function (items, props) {
|
||||
var out = [];
|
||||
|
||||
/**
|
||||
* @ngdoc filter
|
||||
* @name passmanApp.filter:propsFilter
|
||||
* @function
|
||||
* @description
|
||||
* # propsFilter
|
||||
* Filter in the passmanApp.
|
||||
*/
|
||||
angular.module('passmanApp')
|
||||
.filter('propsFilter', function () {
|
||||
return function (items, props) {
|
||||
var out = [];
|
||||
if (angular.isArray(items)) {
|
||||
var keys = Object.keys(props);
|
||||
|
||||
if (angular.isArray(items)) {
|
||||
var keys = Object.keys(props);
|
||||
items.forEach(function (item) {
|
||||
var itemMatches = false;
|
||||
|
||||
items.forEach(function (item) {
|
||||
var itemMatches = false;
|
||||
|
||||
for (var i = 0; i < keys.length; i++) {
|
||||
var prop = keys[i];
|
||||
var text = props[prop].toLowerCase();
|
||||
if (item[prop].toString().toLowerCase().indexOf(text) !== -1) {
|
||||
itemMatches = true;
|
||||
break;
|
||||
for (var i = 0; i < keys.length; i++) {
|
||||
var prop = keys[i];
|
||||
var text = props[prop].toLowerCase();
|
||||
if (item[prop].toString().toLowerCase().indexOf(text) !== -1) {
|
||||
itemMatches = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (itemMatches) {
|
||||
out.push(item);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// Let the output be the input untouched
|
||||
out = items;
|
||||
}
|
||||
if (itemMatches) {
|
||||
out.push(item);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// Let the output be the input untouched
|
||||
out = items;
|
||||
}
|
||||
|
||||
return out;
|
||||
};
|
||||
});
|
||||
return out;
|
||||
};
|
||||
});
|
||||
}());
|
|
@ -1,19 +1,21 @@
|
|||
'use strict';
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* @ngdoc filter
|
||||
* @name passmanApp.filter:propsFilter
|
||||
* @function
|
||||
* @description
|
||||
* # propsFilter
|
||||
* Filter in the passmanApp.
|
||||
*/
|
||||
angular.module('passmanApp')
|
||||
.filter('range', function() {
|
||||
return function(val, range) {
|
||||
range = parseInt(range);
|
||||
for (var i=0; i<range; i++)
|
||||
val.push(i);
|
||||
return val;
|
||||
};
|
||||
});
|
||||
/**
|
||||
* @ngdoc filter
|
||||
* @name passmanApp.filter:propsFilter
|
||||
* @function
|
||||
* @description
|
||||
* # propsFilter
|
||||
* Filter in the passmanApp.
|
||||
*/
|
||||
angular.module('passmanApp')
|
||||
.filter('range', function () {
|
||||
return function (val, range) {
|
||||
range = parseInt(range);
|
||||
for (var i = 0; i < range; i++)
|
||||
val.push(i);
|
||||
return val;
|
||||
};
|
||||
});
|
||||
}());
|
|
@ -1,35 +1,37 @@
|
|||
'use strict';
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* @ngdoc filter
|
||||
* @name passmanApp.filter:selectedTags
|
||||
* @function
|
||||
* @description
|
||||
* # selectedTags
|
||||
* Filter in the passmanApp.
|
||||
*/
|
||||
angular.module('passmanApp')
|
||||
.filter('tagFilter', function() {
|
||||
return function(credentials, tags) {
|
||||
var _credentials = [];
|
||||
if(tags.length > 0) {
|
||||
for (var ci = 0; ci < credentials.length; ci++) {
|
||||
var c = credentials[ci];
|
||||
var matches = 0;
|
||||
for (var ct = 0; ct < c.tags_raw.length; ct++) {
|
||||
var t = c.tags_raw[ct];
|
||||
if(tags.indexOf(t.text) != -1){
|
||||
matches++;
|
||||
/**
|
||||
* @ngdoc filter
|
||||
* @name passmanApp.filter:selectedTags
|
||||
* @function
|
||||
* @description
|
||||
* # selectedTags
|
||||
* Filter in the passmanApp.
|
||||
*/
|
||||
angular.module('passmanApp')
|
||||
.filter('tagFilter', function () {
|
||||
return function (credentials, tags) {
|
||||
var _credentials = [];
|
||||
if (tags.length > 0) {
|
||||
for (var ci = 0; ci < credentials.length; ci++) {
|
||||
var c = credentials[ci];
|
||||
var matches = 0;
|
||||
for (var ct = 0; ct < c.tags_raw.length; ct++) {
|
||||
var t = c.tags_raw[ct];
|
||||
if (tags.indexOf(t.text) !== -1) {
|
||||
matches++;
|
||||
}
|
||||
}
|
||||
if (matches === tags.length) {
|
||||
_credentials.push(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(matches === tags.length){
|
||||
_credentials.push(c);
|
||||
if (tags.length === 0) {
|
||||
_credentials = credentials;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(tags.length == 0){
|
||||
_credentials = credentials;
|
||||
}
|
||||
return _credentials;
|
||||
};
|
||||
});
|
||||
return _credentials;
|
||||
};
|
||||
});
|
||||
}());
|
|
@ -1,5 +1,5 @@
|
|||
'use strict';
|
||||
|
||||
(function () {
|
||||
'use strict';
|
||||
/**
|
||||
* @ngdoc service
|
||||
* @name passmanApp.CacheService
|
||||
|
@ -17,5 +17,6 @@ angular.module('passmanApp')
|
|||
value = EncryptService.encryptString(value);
|
||||
localStorageService.set(key, value);
|
||||
}
|
||||
}
|
||||
};
|
||||
}]);
|
||||
}());
|
|
@ -1,313 +1,316 @@
|
|||
'use strict';
|
||||
|
||||
/**
|
||||
* @ngdoc service
|
||||
* @name passmanApp.CredentialService
|
||||
* @description
|
||||
* # CredentialService
|
||||
* Service in the passmanApp.
|
||||
*/
|
||||
angular.module('passmanApp')
|
||||
.service('CredentialService', ['$http', 'EncryptService', 'VaultService', 'FileService', function ($http, EncryptService, VaultService, FileService) {
|
||||
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
|
||||
};
|
||||
var _encryptedFields = ['description', 'username', 'password', 'files', 'custom_fields', 'otp', 'email', 'tags', 'url'];
|
||||
(function () {
|
||||
'use strict';
|
||||
/**
|
||||
* @ngdoc service
|
||||
* @name passmanApp.CredentialService
|
||||
* @description
|
||||
* # CredentialService
|
||||
* Service in the passmanApp.
|
||||
*/
|
||||
angular.module('passmanApp')
|
||||
.service('CredentialService', ['$http', 'EncryptService', 'VaultService', 'FileService', function ($http, EncryptService, VaultService, FileService) {
|
||||
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
|
||||
};
|
||||
var _encryptedFields = ['description', 'username', 'password', 'files', 'custom_fields', 'otp', 'email', 'tags', 'url'];
|
||||
|
||||
|
||||
return {
|
||||
newCredential: function () {
|
||||
return angular.copy(credential);
|
||||
},
|
||||
createCredential: function (credential) {
|
||||
var _credential = angular.copy(credential);
|
||||
for (var i = 0; i < _encryptedFields.length; i++) {
|
||||
var field = _encryptedFields[i];
|
||||
var fieldValue = angular.copy(credential[field]);
|
||||
_credential[field] = EncryptService.encryptString(JSON.stringify(fieldValue));
|
||||
}
|
||||
|
||||
_credential.expire_time = new Date( angular.copy(credential.expire_time) ).getTime() / 1000;
|
||||
|
||||
var queryUrl = OC.generateUrl('apps/passman/api/v2/credentials');
|
||||
return $http.post(queryUrl, _credential).then(function (response) {
|
||||
if (response.data) {
|
||||
return response.data;
|
||||
} else {
|
||||
return response;
|
||||
}
|
||||
});
|
||||
},
|
||||
getEncryptedFields: function () {
|
||||
return _encryptedFields;
|
||||
},
|
||||
updateCredential: function (credential, skipEncyption) {
|
||||
var _credential = angular.copy(credential);
|
||||
if(!skipEncyption){
|
||||
return {
|
||||
newCredential: function () {
|
||||
return angular.copy(credential);
|
||||
},
|
||||
createCredential: function (credential) {
|
||||
var _credential = angular.copy(credential);
|
||||
for (var i = 0; i < _encryptedFields.length; i++) {
|
||||
var field = _encryptedFields[i];
|
||||
var fieldValue = angular.copy(credential[field]);
|
||||
_credential[field] = EncryptService.encryptString(JSON.stringify(fieldValue));
|
||||
}
|
||||
}
|
||||
_credential.expire_time = new Date( angular.copy(credential.expire_time) ).getTime() / 1000;
|
||||
|
||||
var queryUrl = OC.generateUrl('apps/passman/api/v2/credentials/' + credential.guid);
|
||||
return $http.patch(queryUrl, _credential).then(function (response) {
|
||||
if (response.data) {
|
||||
return response.data;
|
||||
} else {
|
||||
return response;
|
||||
}
|
||||
});
|
||||
},
|
||||
getCredential: function(guid){
|
||||
var queryUrl = OC.generateUrl('apps/passman/api/v2/credentials/' + guid);
|
||||
return $http.get(queryUrl).then(function (response) {
|
||||
if (response.data) {
|
||||
return response.data;
|
||||
} else {
|
||||
return response;
|
||||
}
|
||||
});
|
||||
},
|
||||
destroyCredential: function(guid){
|
||||
var queryUrl = OC.generateUrl('apps/passman/api/v2/credentials/' + guid);
|
||||
return $http.delete(queryUrl).then(function (response) {
|
||||
if (response.data) {
|
||||
return response.data;
|
||||
} else {
|
||||
return response;
|
||||
}
|
||||
});
|
||||
},
|
||||
encryptCredential: function (credential, key) {
|
||||
for (var i = 0; i < _encryptedFields.length; i++) {
|
||||
var field = _encryptedFields[i];
|
||||
var fieldValue = angular.copy(credential[field]);
|
||||
credential[field] = EncryptService.encryptString(JSON.stringify(fieldValue), key);
|
||||
}
|
||||
return credential;
|
||||
},
|
||||
decryptCredential: function (credential, key) {
|
||||
for (var i = 0; i < _encryptedFields.length; i++) {
|
||||
var field = _encryptedFields[i];
|
||||
var fieldValue = angular.copy(credential[field]);
|
||||
_credential.expire_time = new Date(angular.copy(credential.expire_time)).getTime() / 1000;
|
||||
|
||||
try {
|
||||
var field_decrypted_value = EncryptService.decryptString(fieldValue, key)
|
||||
} catch (e){
|
||||
console.log(e)
|
||||
throw e
|
||||
}
|
||||
try{
|
||||
credential[field] = JSON.parse(field_decrypted_value);
|
||||
} catch (e){
|
||||
console.log('Field' + field + ' in '+ credential.label +' could not be parsed! Value:'+ fieldValue)
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
return credential;
|
||||
},
|
||||
getRevisions: function(guid){
|
||||
var queryUrl = OC.generateUrl('apps/passman/api/v2/credentials/' + guid + '/revision');
|
||||
return $http.get(queryUrl).then(function (response) {
|
||||
if (response.data) {
|
||||
return response.data;
|
||||
} else {
|
||||
return response;
|
||||
}
|
||||
});
|
||||
},
|
||||
updateRevision: function(revision){
|
||||
var _revision = angular.copy(revision);
|
||||
_revision.credential_data = window.btoa(JSON.stringify(_revision.credential_data));
|
||||
var queryUrl = OC.generateUrl('apps/passman/api/v2/credentials/' + revision.credential_data.guid + '/revision/' + revision.revision_id);
|
||||
return $http.patch(queryUrl, _revision).then(function (response) {
|
||||
if (response.data) {
|
||||
return response.data;
|
||||
} else {
|
||||
return response;
|
||||
}
|
||||
});
|
||||
},
|
||||
deleteRevision: function(credential_guid, revision_id){
|
||||
var queryUrl = OC.generateUrl('apps/passman/api/v2/credentials/' + credential_guid + '/revision/' + revision_id);
|
||||
return $http.delete(queryUrl).then(function (response) {
|
||||
if (response.data) {
|
||||
return response.data;
|
||||
} else {
|
||||
return response;
|
||||
}
|
||||
});
|
||||
},
|
||||
reencryptCredential: function(credential_guid, old_password, new_password){
|
||||
|
||||
var service = this;
|
||||
|
||||
var progress_datatype = function(current, total, process){
|
||||
this.process = process;
|
||||
this.current = current;
|
||||
this.total = total;
|
||||
this.calculated = current / total * 100;
|
||||
};
|
||||
|
||||
var promise_credential_update = function(){
|
||||
service.getCredential(credential_guid).then((function (credential) {
|
||||
this.parent.plain_credential = service.decryptCredential(credential, this.parent.old_password);
|
||||
var tmp = angular.copy(this.parent.plain_credential);
|
||||
this.parent.new_credential_cryptogram = service.encryptCredential(tmp, this.parent.new_password);
|
||||
|
||||
this.call_progress(new progress_datatype(1, 2, 'credential'));
|
||||
|
||||
// Save data
|
||||
this.parent.new_credential_cryptogram.skip_revision = true;
|
||||
service.updateCredential(this.parent.new_credential_cryptogram, true).then((function(data){
|
||||
this.call_progress(new progress_datatype(2, 2, 'credential'));
|
||||
this.call_then({
|
||||
plain_text: this.parent.plain_credential,
|
||||
cryptogram: this.parent.new_credential_cryptogram
|
||||
});
|
||||
}).bind(this));
|
||||
}).bind(this));
|
||||
};
|
||||
|
||||
var promise_files_update = function(){
|
||||
// Add the double of the files so we take encryption phase and upload to the server into the math
|
||||
this.total = this.parent.plain_credential.files.length * 2; // Binded on credential finish upload
|
||||
this.current = 0;
|
||||
|
||||
for (var i = 0; i < this.parent.plain_credential.files.length; i++){
|
||||
var _file = this.parent.plain_credential.files[i];
|
||||
FileService.getFile(_file).then((function (fileData) {
|
||||
//Decrypt with old key
|
||||
fileData.filename = EncryptService.decryptString(fileData.filename, this.parent.old_password);
|
||||
fileData.file_data = EncryptService.decryptString(fileData.file_data, this.parent.old_password);
|
||||
|
||||
this.current ++;
|
||||
|
||||
this.call_progress(new progress_datatype(this.current, this.total, 'files'));
|
||||
|
||||
FileService.updateFile(fileData, this.parent.new_password).then((function(data){
|
||||
this.current++;
|
||||
this.call_progress(new progress_datatype(this.current, this.total, 'files'));
|
||||
if (this.current == this.total) {
|
||||
this.call_then('All files has been updated');
|
||||
}
|
||||
}).bind(this));
|
||||
}).bind(this));
|
||||
}
|
||||
if (this.parent.plain_credential.files.length == 0){
|
||||
this.call_progress(new progress_datatype(0,0, 'files'));
|
||||
this.call_then("No files to update");
|
||||
}
|
||||
};
|
||||
|
||||
var promise_revisions_update = function(){
|
||||
service.getRevisions(this.parent.plain_credential.guid).then((function (revisions) {
|
||||
// Double, so we include the actual upload of the data back to the server
|
||||
this.total = revisions.length * 2;
|
||||
this.upload = 0;
|
||||
this.current = 0;
|
||||
this.revisions = revisions;
|
||||
|
||||
var revision_workload = function(){
|
||||
if (this.revisions.length == 0){
|
||||
this.call_progress(new progress_datatype(0,0, 'revisions'));
|
||||
this.call_then("No history to update");
|
||||
return;
|
||||
}
|
||||
var _revision = revisions[this.current];
|
||||
//Decrypt!
|
||||
_revision.credential_data = service.decryptCredential(_revision.credential_data, this.parent.old_password);
|
||||
_revision.credential_data = service.encryptCredential(_revision.credential_data, this.parent.new_password);
|
||||
this.current ++;
|
||||
|
||||
this.call_progress(new progress_datatype(this.current + this.upload, this.total, 'revisions'));
|
||||
|
||||
service.updateRevision(_revision).then((function(data){
|
||||
this.upload ++;
|
||||
this.call_progress(new progress_datatype(this.upload + this.current, this.total, 'revisions'));
|
||||
if (this.current + this.upload == this.total){
|
||||
this.call_then("History updated");
|
||||
}
|
||||
}).bind(this));
|
||||
|
||||
if (this.current != (this.total / 2)) {
|
||||
setTimeout(revision_workload.bind(this), 1);
|
||||
}
|
||||
};
|
||||
setTimeout(revision_workload.bind(this), 1);
|
||||
}).bind(this));
|
||||
};
|
||||
|
||||
var promise_workload = function(){
|
||||
this.old_password = angular.copy(old_password);
|
||||
this.new_password = angular.copy(new_password);
|
||||
this.promises = 0;
|
||||
|
||||
var master_promise = this;
|
||||
|
||||
var password_data = function(){
|
||||
this.old_password = master_promise.old_password;
|
||||
this.new_password = master_promise.new_password;
|
||||
this.plain_credential = master_promise.plain_credential;
|
||||
};
|
||||
this.credential_data = {};
|
||||
|
||||
(new C_Promise(promise_credential_update, new password_data())).progress(function(data){
|
||||
master_promise.call_progress(data);
|
||||
}).then(function(data){
|
||||
console.warn("End credential update");
|
||||
master_promise.plain_credential = data.plain_text;
|
||||
master_promise.promises ++;
|
||||
|
||||
master_promise.credential_data = data;
|
||||
|
||||
(new C_Promise(promise_files_update, new password_data())).progress(function(data){
|
||||
master_promise.call_progress(data);
|
||||
}).then(function(data){
|
||||
console.warn("End files update");
|
||||
master_promise.promises --;
|
||||
if (master_promise.promises == 0){
|
||||
master_promise.call_then(master_promise.credential_data);
|
||||
}
|
||||
});
|
||||
|
||||
master_promise.promises ++;
|
||||
(new C_Promise(promise_revisions_update, new password_data())).progress(function(data){
|
||||
master_promise.call_progress(data);
|
||||
}).then(function(data){
|
||||
console.warn("End revisions update");
|
||||
master_promise.promises --;
|
||||
if (master_promise.promises == 0){
|
||||
master_promise.call_then(master_promise.credential_data);
|
||||
}
|
||||
});
|
||||
var queryUrl = OC.generateUrl('apps/passman/api/v2/credentials');
|
||||
return $http.post(queryUrl, _credential).then(function (response) {
|
||||
if (response.data) {
|
||||
return response.data;
|
||||
} else {
|
||||
return response;
|
||||
}
|
||||
});
|
||||
};
|
||||
},
|
||||
getEncryptedFields: function () {
|
||||
return _encryptedFields;
|
||||
},
|
||||
updateCredential: function (credential, skipEncyption) {
|
||||
var _credential = angular.copy(credential);
|
||||
if (!skipEncyption) {
|
||||
for (var i = 0; i < _encryptedFields.length; i++) {
|
||||
var field = _encryptedFields[i];
|
||||
var fieldValue = angular.copy(credential[field]);
|
||||
_credential[field] = EncryptService.encryptString(JSON.stringify(fieldValue));
|
||||
}
|
||||
}
|
||||
_credential.expire_time = new Date(angular.copy(credential.expire_time)).getTime() / 1000;
|
||||
|
||||
return new C_Promise(promise_workload);
|
||||
}
|
||||
}
|
||||
}]);
|
||||
var queryUrl = OC.generateUrl('apps/passman/api/v2/credentials/' + credential.guid);
|
||||
return $http.patch(queryUrl, _credential).then(function (response) {
|
||||
if (response.data) {
|
||||
return response.data;
|
||||
} else {
|
||||
return response;
|
||||
}
|
||||
});
|
||||
},
|
||||
getCredential: function (guid) {
|
||||
var queryUrl = OC.generateUrl('apps/passman/api/v2/credentials/' + guid);
|
||||
return $http.get(queryUrl).then(function (response) {
|
||||
if (response.data) {
|
||||
return response.data;
|
||||
} else {
|
||||
return response;
|
||||
}
|
||||
});
|
||||
},
|
||||
destroyCredential: function (guid) {
|
||||
var queryUrl = OC.generateUrl('apps/passman/api/v2/credentials/' + guid);
|
||||
return $http.delete(queryUrl).then(function (response) {
|
||||
if (response.data) {
|
||||
return response.data;
|
||||
} else {
|
||||
return response;
|
||||
}
|
||||
});
|
||||
},
|
||||
encryptCredential: function (credential, key) {
|
||||
for (var i = 0; i < _encryptedFields.length; i++) {
|
||||
var field = _encryptedFields[i];
|
||||
var fieldValue = angular.copy(credential[field]);
|
||||
credential[field] = EncryptService.encryptString(JSON.stringify(fieldValue), key);
|
||||
}
|
||||
return credential;
|
||||
},
|
||||
decryptCredential: function (credential, key) {
|
||||
for (var i = 0; i < _encryptedFields.length; i++) {
|
||||
var field = _encryptedFields[i];
|
||||
var fieldValue = angular.copy(credential[field]);
|
||||
var field_decrypted_value;
|
||||
try {
|
||||
field_decrypted_value = EncryptService.decryptString(fieldValue, key);
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
throw e;
|
||||
}
|
||||
try {
|
||||
credential[field] = JSON.parse(field_decrypted_value);
|
||||
} catch (e) {
|
||||
console.log('Field' + field + ' in ' + credential.label + ' could not be parsed! Value:' + fieldValue);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
return credential;
|
||||
},
|
||||
getRevisions: function (guid) {
|
||||
var queryUrl = OC.generateUrl('apps/passman/api/v2/credentials/' + guid + '/revision');
|
||||
return $http.get(queryUrl).then(function (response) {
|
||||
if (response.data) {
|
||||
return response.data;
|
||||
} else {
|
||||
return response;
|
||||
}
|
||||
});
|
||||
},
|
||||
updateRevision: function (revision) {
|
||||
var _revision = angular.copy(revision);
|
||||
_revision.credential_data = window.btoa(JSON.stringify(_revision.credential_data));
|
||||
var queryUrl = OC.generateUrl('apps/passman/api/v2/credentials/' + revision.credential_data.guid + '/revision/' + revision.revision_id);
|
||||
return $http.patch(queryUrl, _revision).then(function (response) {
|
||||
if (response.data) {
|
||||
return response.data;
|
||||
} else {
|
||||
return response;
|
||||
}
|
||||
});
|
||||
},
|
||||
deleteRevision: function (credential_guid, revision_id) {
|
||||
var queryUrl = OC.generateUrl('apps/passman/api/v2/credentials/' + credential_guid + '/revision/' + revision_id);
|
||||
return $http.delete(queryUrl).then(function (response) {
|
||||
if (response.data) {
|
||||
return response.data;
|
||||
} else {
|
||||
return response;
|
||||
}
|
||||
});
|
||||
},
|
||||
reencryptCredential: function (credential_guid, old_password, new_password) {
|
||||
|
||||
var service = this;
|
||||
|
||||
var progress_datatype = function (current, total, process) {
|
||||
this.process = process;
|
||||
this.current = current;
|
||||
this.total = total;
|
||||
this.calculated = current / total * 100;
|
||||
};
|
||||
|
||||
var promise_credential_update = function () {
|
||||
service.getCredential(credential_guid).then((function (credential) {
|
||||
this.parent.plain_credential = service.decryptCredential(credential, this.parent.old_password);
|
||||
var tmp = angular.copy(this.parent.plain_credential);
|
||||
this.parent.new_credential_cryptogram = service.encryptCredential(tmp, this.parent.new_password);
|
||||
|
||||
this.call_progress(new progress_datatype(1, 2, 'credential'));
|
||||
|
||||
// Save data
|
||||
this.parent.new_credential_cryptogram.skip_revision = true;
|
||||
service.updateCredential(this.parent.new_credential_cryptogram, true).then((function (data) {
|
||||
this.call_progress(new progress_datatype(2, 2, 'credential'));
|
||||
this.call_then({
|
||||
plain_text: this.parent.plain_credential,
|
||||
cryptogram: this.parent.new_credential_cryptogram
|
||||
});
|
||||
}).bind(this));
|
||||
}).bind(this));
|
||||
};
|
||||
|
||||
var promise_files_update = function () {
|
||||
// Add the double of the files so we take encryption phase and upload to the server into the math
|
||||
this.total = this.parent.plain_credential.files.length * 2; // Binded on credential finish upload
|
||||
this.current = 0;
|
||||
|
||||
for (var i = 0; i < this.parent.plain_credential.files.length; i++) {
|
||||
var _file = this.parent.plain_credential.files[i];
|
||||
/* jshint ignore:start */
|
||||
FileService.getFile(_file).then((function (fileData) {
|
||||
//Decrypt with old key
|
||||
fileData.filename = EncryptService.decryptString(fileData.filename, this.parent.old_password);
|
||||
fileData.file_data = EncryptService.decryptString(fileData.file_data, this.parent.old_password);
|
||||
|
||||
this.current++;
|
||||
|
||||
this.call_progress(new progress_datatype(this.current, this.total, 'files'));
|
||||
|
||||
FileService.updateFile(fileData, this.parent.new_password).then((function (data) {
|
||||
this.current++;
|
||||
this.call_progress(new progress_datatype(this.current, this.total, 'files'));
|
||||
if (this.current === this.total) {
|
||||
this.call_then('All files has been updated');
|
||||
}
|
||||
}).bind(this));
|
||||
}).bind(this));
|
||||
/* jshint ignore:end */
|
||||
}
|
||||
if (this.parent.plain_credential.files.length === 0) {
|
||||
this.call_progress(new progress_datatype(0, 0, 'files'));
|
||||
this.call_then("No files to update");
|
||||
}
|
||||
};
|
||||
|
||||
var promise_revisions_update = function () {
|
||||
service.getRevisions(this.parent.plain_credential.guid).then((function (revisions) {
|
||||
// Double, so we include the actual upload of the data back to the server
|
||||
this.total = revisions.length * 2;
|
||||
this.upload = 0;
|
||||
this.current = 0;
|
||||
this.revisions = revisions;
|
||||
|
||||
var revision_workload = function () {
|
||||
if (this.revisions.length === 0) {
|
||||
this.call_progress(new progress_datatype(0, 0, 'revisions'));
|
||||
this.call_then("No history to update");
|
||||
return;
|
||||
}
|
||||
var _revision = revisions[this.current];
|
||||
//Decrypt!
|
||||
_revision.credential_data = service.decryptCredential(_revision.credential_data, this.parent.old_password);
|
||||
_revision.credential_data = service.encryptCredential(_revision.credential_data, this.parent.new_password);
|
||||
this.current++;
|
||||
|
||||
this.call_progress(new progress_datatype(this.current + this.upload, this.total, 'revisions'));
|
||||
|
||||
service.updateRevision(_revision).then((function (data) {
|
||||
this.upload++;
|
||||
this.call_progress(new progress_datatype(this.upload + this.current, this.total, 'revisions'));
|
||||
if (this.current + this.upload === this.total) {
|
||||
this.call_then("History updated");
|
||||
}
|
||||
}).bind(this));
|
||||
|
||||
if (this.current !== (this.total / 2)) {
|
||||
setTimeout(revision_workload.bind(this), 1);
|
||||
}
|
||||
};
|
||||
setTimeout(revision_workload.bind(this), 1);
|
||||
}).bind(this));
|
||||
};
|
||||
|
||||
var promise_workload = function () {
|
||||
this.old_password = angular.copy(old_password);
|
||||
this.new_password = angular.copy(new_password);
|
||||
this.promises = 0;
|
||||
|
||||
var master_promise = this;
|
||||
|
||||
var password_data = function () {
|
||||
this.old_password = master_promise.old_password;
|
||||
this.new_password = master_promise.new_password;
|
||||
this.plain_credential = master_promise.plain_credential;
|
||||
};
|
||||
this.credential_data = {};
|
||||
|
||||
(new C_Promise(promise_credential_update, new password_data())).progress(function (data) {
|
||||
master_promise.call_progress(data);
|
||||
}).then(function (data) {
|
||||
console.warn("End credential update");
|
||||
master_promise.plain_credential = data.plain_text;
|
||||
master_promise.promises++;
|
||||
|
||||
master_promise.credential_data = data;
|
||||
|
||||
(new C_Promise(promise_files_update, new password_data())).progress(function (data) {
|
||||
master_promise.call_progress(data);
|
||||
}).then(function (data) {
|
||||
console.warn("End files update");
|
||||
master_promise.promises--;
|
||||
if (master_promise.promises === 0) {
|
||||
master_promise.call_then(master_promise.credential_data);
|
||||
}
|
||||
});
|
||||
|
||||
master_promise.promises++;
|
||||
(new C_Promise(promise_revisions_update, new password_data())).progress(function (data) {
|
||||
master_promise.call_progress(data);
|
||||
}).then(function (data) {
|
||||
console.warn("End revisions update");
|
||||
master_promise.promises--;
|
||||
if (master_promise.promises === 0) {
|
||||
master_promise.call_then(master_promise.credential_data);
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
return new C_Promise(promise_workload);
|
||||
}
|
||||
};
|
||||
}]);
|
||||
}());
|
|
@ -1,44 +1,45 @@
|
|||
'use strict';
|
||||
(function () {
|
||||
'use strict';
|
||||
/**
|
||||
* @ngdoc service
|
||||
* @name passmanApp.EncryptService
|
||||
* @description
|
||||
* # EncryptService
|
||||
* Service in the passmanApp.
|
||||
*/
|
||||
angular.module('passmanApp')
|
||||
.service('EncryptService', ['VaultService', function (VaultService) {
|
||||
// AngularJS will instantiate a singleton by calling "new" on this function
|
||||
var encryption_config = {
|
||||
adata: "",
|
||||
iter: 1000,
|
||||
ks: 256,
|
||||
mode: 'ccm',
|
||||
ts: 64
|
||||
};
|
||||
|
||||
/**
|
||||
* @ngdoc service
|
||||
* @name passmanApp.EncryptService
|
||||
* @description
|
||||
* # EncryptService
|
||||
* Service in the passmanApp.
|
||||
*/
|
||||
angular.module('passmanApp')
|
||||
.service('EncryptService', ['VaultService', function (VaultService) {
|
||||
// AngularJS will instantiate a singleton by calling "new" on this function
|
||||
var encryption_config = {
|
||||
adata:"",
|
||||
iter: 1000,
|
||||
ks: 256,
|
||||
mode: 'ccm',
|
||||
ts:64
|
||||
};
|
||||
return {
|
||||
encryptString: function (string, _key) {
|
||||
if (!_key) {
|
||||
_key = VaultService.getActiveVault().vaultKey;
|
||||
}
|
||||
var rp = {};
|
||||
var ct = sjcl.encrypt(_key, string, encryption_config, rp);
|
||||
return window.btoa(ct);
|
||||
},
|
||||
decryptString: function (ciphertext, _key) {
|
||||
if (!_key) {
|
||||
_key = VaultService.getActiveVault().vaultKey;
|
||||
}
|
||||
ciphertext = window.atob(ciphertext);
|
||||
var rp = {};
|
||||
try {
|
||||
return sjcl.decrypt(_key, ciphertext, encryption_config, rp);
|
||||
} catch (e) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
encryptString: function(string, _key){
|
||||
if(!_key) {
|
||||
_key = VaultService.getActiveVault().vaultKey;
|
||||
}
|
||||
var rp = {};
|
||||
var ct = sjcl.encrypt(_key, string, encryption_config, rp);
|
||||
return window.btoa(ct);
|
||||
},
|
||||
decryptString: function(ciphertext, _key){
|
||||
if(!_key) {
|
||||
_key = VaultService.getActiveVault().vaultKey;
|
||||
}
|
||||
ciphertext = window.atob(ciphertext);
|
||||
var rp = {};
|
||||
try {
|
||||
return sjcl.decrypt(_key, ciphertext, encryption_config, rp)
|
||||
} catch(e) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}]);
|
||||
};
|
||||
}]);
|
||||
}());
|
|
@ -1,97 +1,99 @@
|
|||
'use strict';
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* @ngdoc service
|
||||
* @name passmanApp.FileService
|
||||
* @description
|
||||
* # FileService
|
||||
* Service in the passmanApp.
|
||||
*/
|
||||
angular.module('passmanApp')
|
||||
.service('FileService', ['$http', 'EncryptService', function ($http, EncryptService) {
|
||||
return {
|
||||
uploadFile: function (file, key) {
|
||||
var queryUrl = OC.generateUrl('apps/passman/api/v2/file');
|
||||
var _file = angular.copy(file);
|
||||
_file.filename = EncryptService.encryptString(_file.filename, key);
|
||||
var data = EncryptService.encryptString(angular.copy(file.data), key);
|
||||
_file.data = data;
|
||||
return $http.post(queryUrl, _file).then(function (response) {
|
||||
if (response.data) {
|
||||
return response.data;
|
||||
} else {
|
||||
return response;
|
||||
}
|
||||
});
|
||||
},
|
||||
deleteFile: function (file) {
|
||||
var queryUrl = OC.generateUrl('apps/passman/api/v2/file/' + file.file_id);
|
||||
var _file = angular.copy(file);
|
||||
return $http.delete(queryUrl, _file).then(function (response) {
|
||||
if (response.data) {
|
||||
return response.data;
|
||||
} else {
|
||||
return response;
|
||||
}
|
||||
});
|
||||
},
|
||||
getFile: function (file) {
|
||||
var queryUrl = OC.generateUrl('apps/passman/api/v2/file/' + file.file_id);
|
||||
var _file = angular.copy(file);
|
||||
return $http.get(queryUrl, _file).then(function (response) {
|
||||
if (response.data) {
|
||||
if (Object.prototype.toString.call(response.data) === '[object Array]') {
|
||||
return response.data.pop()
|
||||
} else {
|
||||
/**
|
||||
* @ngdoc service
|
||||
* @name passmanApp.FileService
|
||||
* @description
|
||||
* # FileService
|
||||
* Service in the passmanApp.
|
||||
*/
|
||||
angular.module('passmanApp')
|
||||
.service('FileService', ['$http', 'EncryptService', function ($http, EncryptService) {
|
||||
return {
|
||||
uploadFile: function (file, key) {
|
||||
var queryUrl = OC.generateUrl('apps/passman/api/v2/file');
|
||||
var _file = angular.copy(file);
|
||||
_file.filename = EncryptService.encryptString(_file.filename, key);
|
||||
var data = EncryptService.encryptString(angular.copy(file.data), key);
|
||||
_file.data = data;
|
||||
return $http.post(queryUrl, _file).then(function (response) {
|
||||
if (response.data) {
|
||||
return response.data;
|
||||
} else {
|
||||
return response;
|
||||
}
|
||||
} else {
|
||||
return response;
|
||||
}
|
||||
});
|
||||
},
|
||||
/**
|
||||
* Update a file and it's contents
|
||||
* @param file
|
||||
* @param key Optional encryption key to use
|
||||
* @returns {*}
|
||||
*/
|
||||
updateFile: function(file, key){
|
||||
var queryUrl = OC.generateUrl('apps/passman/api/v2/file/'+ file.file_id);
|
||||
var _file = angular.copy(file);
|
||||
_file.filename = EncryptService.encryptString(_file.filename, key);
|
||||
var data = EncryptService.encryptString(angular.copy(file.file_data), key);
|
||||
_file.file_data = data;
|
||||
return $http.patch(queryUrl, _file).then(function (response) {
|
||||
if (response.data) {
|
||||
return response.data;
|
||||
} else {
|
||||
return response;
|
||||
}
|
||||
});
|
||||
},
|
||||
dataURItoBlob: function (dataURI, ftype) {
|
||||
var byteString, mimeString, ab, ia, bb, i;
|
||||
// convert base64 to raw binary data held in a string
|
||||
// doesn't handle URLEncoded DataURIs - see SO answer #6850276 for code that does this
|
||||
byteString = atob(dataURI.split(',')[1]);
|
||||
});
|
||||
},
|
||||
deleteFile: function (file) {
|
||||
var queryUrl = OC.generateUrl('apps/passman/api/v2/file/' + file.file_id);
|
||||
var _file = angular.copy(file);
|
||||
return $http.delete(queryUrl, _file).then(function (response) {
|
||||
if (response.data) {
|
||||
return response.data;
|
||||
} else {
|
||||
return response;
|
||||
}
|
||||
});
|
||||
},
|
||||
getFile: function (file) {
|
||||
var queryUrl = OC.generateUrl('apps/passman/api/v2/file/' + file.file_id);
|
||||
var _file = angular.copy(file);
|
||||
return $http.get(queryUrl, _file).then(function (response) {
|
||||
if (response.data) {
|
||||
if (Object.prototype.toString.call(response.data) === '[object Array]') {
|
||||
return response.data.pop();
|
||||
} else {
|
||||
return response.data;
|
||||
}
|
||||
} else {
|
||||
return response;
|
||||
}
|
||||
});
|
||||
},
|
||||
/**
|
||||
* Update a file and it's contents
|
||||
* @param file
|
||||
* @param key Optional encryption key to use
|
||||
* @returns {*}
|
||||
*/
|
||||
updateFile: function (file, key) {
|
||||
var queryUrl = OC.generateUrl('apps/passman/api/v2/file/' + file.file_id);
|
||||
var _file = angular.copy(file);
|
||||
_file.filename = EncryptService.encryptString(_file.filename, key);
|
||||
var data = EncryptService.encryptString(angular.copy(file.file_data), key);
|
||||
_file.file_data = data;
|
||||
return $http.patch(queryUrl, _file).then(function (response) {
|
||||
if (response.data) {
|
||||
return response.data;
|
||||
} else {
|
||||
return response;
|
||||
}
|
||||
});
|
||||
},
|
||||
dataURItoBlob: function (dataURI, ftype) {
|
||||
var byteString, mimeString, ab, ia, bb, i;
|
||||
// convert base64 to raw binary data held in a string
|
||||
// doesn't handle URLEncoded DataURIs - see SO answer #6850276 for code that does this
|
||||
byteString = atob(dataURI.split(',')[1]);
|
||||
|
||||
// separate out the mime component
|
||||
mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];
|
||||
// separate out the mime component
|
||||
mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];
|
||||
|
||||
// write the bytes of the string to an ArrayBuffer
|
||||
ab = new ArrayBuffer(byteString.length);
|
||||
ia = new Uint8Array(ab);
|
||||
for (i = 0; i < byteString.length; i++) {
|
||||
ia[i] = byteString.charCodeAt(i);
|
||||
// write the bytes of the string to an ArrayBuffer
|
||||
ab = new ArrayBuffer(byteString.length);
|
||||
ia = new Uint8Array(ab);
|
||||
for (i = 0; i < byteString.length; i++) {
|
||||
ia[i] = byteString.charCodeAt(i);
|
||||
}
|
||||
|
||||
// write the ArrayBuffer to a blob, and you're done
|
||||
bb = new Blob([ab], {
|
||||
type: ftype
|
||||
});
|
||||
|
||||
return URL.createObjectURL(bb);
|
||||
}
|
||||
|
||||
// write the ArrayBuffer to a blob, and you're done
|
||||
bb = new Blob([ab], {
|
||||
type: ftype
|
||||
});
|
||||
|
||||
return URL.createObjectURL(bb);
|
||||
}
|
||||
}
|
||||
}]);
|
||||
};
|
||||
}]);
|
||||
}());
|
|
@ -1,5 +1,5 @@
|
|||
'use strict';
|
||||
|
||||
(function () {
|
||||
'use strict';
|
||||
/**
|
||||
* @ngdoc service
|
||||
* @name passmanApp.NotificationService
|
||||
|
@ -14,16 +14,17 @@ angular.module('passmanApp')
|
|||
showNotification: function (text, time, closeCallback) {
|
||||
var notification = OC.Notification.showHtml(text);
|
||||
to =$timeout(function () {
|
||||
OC.Notification.hide(notification, closeCallback)
|
||||
OC.Notification.hide(notification, closeCallback);
|
||||
}, time);
|
||||
return notification;
|
||||
},
|
||||
hideNotification: function (notification) {
|
||||
$timeout.cancel(to);
|
||||
OC.Notification.hide(notification)
|
||||
OC.Notification.hide(notification);
|
||||
},
|
||||
hideAll: function () {
|
||||
OC.Notification.hide();
|
||||
}
|
||||
}
|
||||
};
|
||||
}]);
|
||||
}());
|
||||
|
|
|
@ -1,32 +1,35 @@
|
|||
'use strict';
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* @ngdoc service
|
||||
* @name passmanApp.SettingsService
|
||||
* @description
|
||||
* # SettingsService
|
||||
* Service in the passmanApp.
|
||||
*/
|
||||
angular.module('passmanApp')
|
||||
.service('SettingsService', ['localStorageService', function (localStorageService) {
|
||||
var settings = {
|
||||
defaultVault: null,
|
||||
defaultVaultPass: null
|
||||
};
|
||||
var neverSend = ['defaultVault', 'defaultVaultPass'];
|
||||
|
||||
var cookie = localStorageService.get('settings');
|
||||
settings = angular.merge(settings, cookie);
|
||||
return {
|
||||
getSettings: function(){
|
||||
return settings
|
||||
},
|
||||
getSetting: function(name){
|
||||
return settings[name]
|
||||
},
|
||||
setSetting: function (name, value) {
|
||||
settings[name] = value;
|
||||
localStorageService.set('settings', settings);
|
||||
}
|
||||
}
|
||||
}]);
|
||||
/**
|
||||
* @ngdoc service
|
||||
* @name passmanApp.SettingsService
|
||||
* @description
|
||||
* # SettingsService
|
||||
* Service in the passmanApp.
|
||||
*/
|
||||
angular.module('passmanApp')
|
||||
.service('SettingsService', ['localStorageService', function (localStorageService) {
|
||||
var settings = {
|
||||
defaultVault: null,
|
||||
defaultVaultPass: null
|
||||
};
|
||||
var neverSend = ['defaultVault', 'defaultVaultPass'];
|
||||
|
||||
var cookie = localStorageService.get('settings');
|
||||
settings = angular.merge(settings, cookie);
|
||||
return {
|
||||
getSettings: function () {
|
||||
return settings;
|
||||
},
|
||||
getSetting: function (name) {
|
||||
return settings[name];
|
||||
},
|
||||
setSetting: function (name, value) {
|
||||
settings[name] = value;
|
||||
localStorageService.set('settings', settings);
|
||||
}
|
||||
};
|
||||
}]);
|
||||
}());
|
|
@ -1,272 +1,276 @@
|
|||
'use strict';
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* @ngdoc service
|
||||
* @name passmanApp.ShareService
|
||||
* @description
|
||||
* # ShareService
|
||||
* Service in the passmanApp.
|
||||
*/
|
||||
angular.module('passmanApp')
|
||||
.service('ShareService', ['$http', 'VaultService', 'EncryptService', 'CredentialService', function ($http, VaultService, EncryptService, CredentialService) {
|
||||
// Setup sjcl random engine to max paranoia level and start collecting data
|
||||
var paranoia_level = 10;
|
||||
sjcl.random.setDefaultParanoia(paranoia_level);
|
||||
sjcl.random.startCollectors();
|
||||
|
||||
return {
|
||||
search: function (string) {
|
||||
var queryUrl = OC.generateUrl('apps/passman/api/v2/sharing/search');
|
||||
return $http.post(queryUrl, {search: string}).then(function (response) {
|
||||
if (response.data) {
|
||||
return response.data;
|
||||
} else {
|
||||
return response;
|
||||
}
|
||||
});
|
||||
},
|
||||
shareWithUser: function (credential, target_user_data) {
|
||||
var queryUrl = OC.generateUrl('apps/passman/api/v2/sharing/share');
|
||||
return $http.post(queryUrl,
|
||||
{
|
||||
item_id: credential.credential_id,
|
||||
item_guid: credential.guid,
|
||||
permissions: target_user_data.accessLevel,
|
||||
vaults: target_user_data.vaults,
|
||||
}
|
||||
);
|
||||
},
|
||||
getVaultsByUser: function (userId) {
|
||||
var queryUrl = OC.generateUrl('apps/passman/api/v2/sharing/vaults/' + userId);
|
||||
return $http.get(queryUrl, {search: userId}).then(function (response) {
|
||||
if (response.data) {
|
||||
for (var i = 0; i < response.data.length; i++) {
|
||||
response.data[i].public_sharing_key = forge.pki.publicKeyFromPem(response.data[i].public_sharing_key);
|
||||
}
|
||||
return response.data;
|
||||
} else {
|
||||
return response;
|
||||
}
|
||||
});
|
||||
},
|
||||
getPendingRequests: function () {
|
||||
var queryUrl = OC.generateUrl('apps/passman/api/v2/sharing/pending');
|
||||
return $http.get(queryUrl).then(function (response) {
|
||||
if (response.data) {
|
||||
return response.data;
|
||||
}
|
||||
});
|
||||
},
|
||||
saveSharingRequest: function (request, crypted_shared_key) {
|
||||
var queryUrl = OC.generateUrl('apps/passman/api/v2/sharing/save');
|
||||
return $http.post(queryUrl, {
|
||||
item_guid: request.item_guid,
|
||||
target_vault_guid: request.target_vault_guid,
|
||||
final_shared_key: crypted_shared_key
|
||||
}).then(function (response) {
|
||||
return response.data;
|
||||
})
|
||||
},
|
||||
declineSharingRequest: function (request ) {
|
||||
var queryUrl = OC.generateUrl('apps/passman/api/v2/sharing/decline/'+ request.req_id);
|
||||
return $http.delete(queryUrl).then(function (response) {
|
||||
return response.data;
|
||||
})
|
||||
},
|
||||
unshareCredential: function (credential) {
|
||||
var queryUrl = OC.generateUrl('apps/passman/api/v2/sharing/credential/' + credential.guid);
|
||||
return $http.delete(queryUrl).then(function (response) {
|
||||
return response.data;
|
||||
})
|
||||
},
|
||||
/**
|
||||
* @ngdoc service
|
||||
* @name passmanApp.ShareService
|
||||
* @description
|
||||
* # ShareService
|
||||
* Service in the passmanApp.
|
||||
*/
|
||||
angular.module('passmanApp')
|
||||
.service('ShareService', ['$http', 'VaultService', 'EncryptService', 'CredentialService', function ($http, VaultService, EncryptService, CredentialService) {
|
||||
// Setup sjcl random engine to max paranoia level and start collecting data
|
||||
var paranoia_level = 10;
|
||||
sjcl.random.setDefaultParanoia(paranoia_level);
|
||||
sjcl.random.startCollectors();
|
||||
|
||||
unshareCredentialFromUser: function (credential, user_id) {
|
||||
var queryUrl = OC.generateUrl('apps/passman/api/v2/sharing/credential/' + credential.guid +'/'+ user_id);
|
||||
return $http.delete(queryUrl).then(function (response) {
|
||||
return response.data;
|
||||
})
|
||||
},
|
||||
|
||||
createPublicSharedCredential: function (shareObj) {
|
||||
var queryUrl = OC.generateUrl('apps/passman/api/v2/sharing/public');
|
||||
return $http.post(queryUrl, shareObj).then(function (response) {
|
||||
return response.data;
|
||||
})
|
||||
},
|
||||
getPublicSharedCredential: function (credential_guid) {
|
||||
var queryUrl = OC.generateUrl('apps/passman/api/v2/sharing/credential/' + credential_guid +'/public');
|
||||
return $http.get(queryUrl).then(function (response) {
|
||||
if (response.data) {
|
||||
return response;
|
||||
} else {
|
||||
return response;
|
||||
}
|
||||
},
|
||||
function (result) {
|
||||
return result;
|
||||
})
|
||||
},
|
||||
getSharedCredentialACL: function (credential) {
|
||||
var queryUrl = OC.generateUrl('apps/passman/api/v2/sharing/credential/' + credential.guid +'/acl');
|
||||
return $http.get(queryUrl).then(function (response) {
|
||||
return {
|
||||
search: function (string) {
|
||||
var queryUrl = OC.generateUrl('apps/passman/api/v2/sharing/search');
|
||||
return $http.post(queryUrl, {search: string}).then(function (response) {
|
||||
if (response.data) {
|
||||
return response.data;
|
||||
} else {
|
||||
return response;
|
||||
}
|
||||
},
|
||||
function (result) {
|
||||
return result;
|
||||
})
|
||||
},
|
||||
updateCredentialAcl: function(credential, acl){
|
||||
var queryUrl = OC.generateUrl('apps/passman/api/v2/sharing/credential/'+ credential.guid +'/acl');
|
||||
return $http.patch(queryUrl, acl).then(function (response) {
|
||||
return response.data;
|
||||
})
|
||||
},
|
||||
getCredendialsSharedWithUs: function (vault_guid) {
|
||||
var queryUrl = OC.generateUrl('apps/passman/api/v2/sharing/vault/' + vault_guid + '/get');
|
||||
return $http.get(queryUrl).then(function (response) {
|
||||
if (response.data) {
|
||||
return response.data;
|
||||
}
|
||||
});
|
||||
},
|
||||
downloadSharedFile: function (credential, file) {
|
||||
var queryUrl = OC.generateUrl('apps/passman/api/v2/sharing/credential/'+ credential.guid +'/file/'+ file.guid);
|
||||
return $http.get(queryUrl).then(function (response) {
|
||||
if (response.data) {
|
||||
return response.data;
|
||||
}
|
||||
});
|
||||
},
|
||||
encryptSharedCredential: function (credential, sharedKey) {
|
||||
var _credential = angular.copy(credential);
|
||||
_credential.shared_key = EncryptService.encryptString(sharedKey);
|
||||
var encrypted_fields = CredentialService.getEncryptedFields();
|
||||
for (var i = 0; i < encrypted_fields.length; i++) {
|
||||
var field = encrypted_fields[i];
|
||||
var fieldValue = angular.copy(credential[field]);
|
||||
_credential[field] = EncryptService.encryptString(JSON.stringify(fieldValue), sharedKey);
|
||||
}
|
||||
return _credential;
|
||||
},
|
||||
decryptSharedCredential: function (credential, sharedKey) {
|
||||
var _credential = angular.copy(credential);
|
||||
var encrypted_fields = CredentialService.getEncryptedFields();
|
||||
for (var i = 0; i < encrypted_fields.length; i++) {
|
||||
var field = encrypted_fields[i];
|
||||
var fieldValue = angular.copy(_credential[field]);
|
||||
if (_credential.hasOwnProperty(field)) {
|
||||
try {
|
||||
var field_decrypted_value = EncryptService.decryptString(fieldValue, sharedKey);
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
throw e
|
||||
}
|
||||
try {
|
||||
_credential[field] = JSON.parse(field_decrypted_value);
|
||||
} catch (e) {
|
||||
console.log('Field' + field + ' in ' + _credential.label + ' could not be parsed! Value:' + fieldValue)
|
||||
throw e
|
||||
}
|
||||
}
|
||||
}
|
||||
return _credential;
|
||||
},
|
||||
|
||||
generateRSAKeys: function (key_length, progress, callback) {
|
||||
var p = new C_Promise(function () {
|
||||
var state = forge.pki.rsa.createKeyPairGenerationState(key_length, 0x10001);
|
||||
var step = function () {
|
||||
// run for 100 ms
|
||||
if (!forge.pki.rsa.stepKeyPairGenerationState(state, 100)) {
|
||||
// console.log(state);
|
||||
if (state.p !== null) {
|
||||
// progress(50);
|
||||
this.call_progress(50);
|
||||
}
|
||||
else {
|
||||
// progress(0);
|
||||
this.call_progress(0);
|
||||
}
|
||||
setTimeout(step.bind(this), 1);
|
||||
}
|
||||
else {
|
||||
// callback(state.keys);
|
||||
this.call_then(state.keys);
|
||||
}
|
||||
};
|
||||
setTimeout(step.bind(this), 100);
|
||||
});
|
||||
return p;
|
||||
},
|
||||
generateSharedKey: function (size) {
|
||||
size = size || 20;
|
||||
return new C_Promise(function () {
|
||||
var t = this;
|
||||
CRYPTO.PASSWORD.generate(size,
|
||||
function (pass) {
|
||||
t.call_then(pass);
|
||||
},
|
||||
function (progress) {
|
||||
t.call_progress(progress);
|
||||
});
|
||||
},
|
||||
shareWithUser: function (credential, target_user_data) {
|
||||
var queryUrl = OC.generateUrl('apps/passman/api/v2/sharing/share');
|
||||
return $http.post(queryUrl,
|
||||
{
|
||||
item_id: credential.credential_id,
|
||||
item_guid: credential.guid,
|
||||
permissions: target_user_data.accessLevel,
|
||||
vaults: target_user_data.vaults,
|
||||
}
|
||||
);
|
||||
})
|
||||
},
|
||||
rsaKeyPairToPEM: function (keypair) {
|
||||
return {
|
||||
'publicKey': forge.pki.publicKeyToPem(keypair.publicKey),
|
||||
'privateKey': forge.pki.privateKeyToPem(keypair.privateKey)
|
||||
};
|
||||
},
|
||||
getSharingKeys: function () {
|
||||
var vault = VaultService.getActiveVault();
|
||||
return {
|
||||
'private_sharing_key': EncryptService.decryptString(angular.copy(vault.private_sharing_key)),
|
||||
'public_sharing_key': vault.public_sharing_key
|
||||
};
|
||||
},
|
||||
rsaPrivateKeyFromPEM: function (private_pem) {
|
||||
return forge.pki.privateKeyFromPem(private_pem);
|
||||
},
|
||||
rsaPublicKeyFromPEM: function (public_pem) {
|
||||
return forge.pki.publicKeyFromPem(public_pem);
|
||||
},
|
||||
/**
|
||||
* Cyphers an array of string in a non-blocking way
|
||||
* @param vaults[] An array of vaults with the processed public keys
|
||||
* @param string The string to cypher
|
||||
*/
|
||||
cypherRSAStringWithPublicKeyBulkAsync: function (vaults, string) {
|
||||
var workload = function () {
|
||||
if (this.current_index < this.vaults.length > 0 && this.vaults.length > 0) {
|
||||
var _vault = angular.copy(this.vaults[this.current_index]);
|
||||
_vault.key = forge.util.encode64(
|
||||
_vault.public_sharing_key.encrypt(this.string)
|
||||
);
|
||||
this.data.push(
|
||||
_vault
|
||||
);
|
||||
this.current_index++;
|
||||
},
|
||||
getVaultsByUser: function (userId) {
|
||||
var queryUrl = OC.generateUrl('apps/passman/api/v2/sharing/vaults/' + userId);
|
||||
return $http.get(queryUrl, {search: userId}).then(function (response) {
|
||||
if (response.data) {
|
||||
for (var i = 0; i < response.data.length; i++) {
|
||||
response.data[i].public_sharing_key = forge.pki.publicKeyFromPem(response.data[i].public_sharing_key);
|
||||
}
|
||||
return response.data;
|
||||
} else {
|
||||
return response;
|
||||
}
|
||||
});
|
||||
},
|
||||
getPendingRequests: function () {
|
||||
var queryUrl = OC.generateUrl('apps/passman/api/v2/sharing/pending');
|
||||
return $http.get(queryUrl).then(function (response) {
|
||||
if (response.data) {
|
||||
return response.data;
|
||||
}
|
||||
});
|
||||
},
|
||||
saveSharingRequest: function (request, crypted_shared_key) {
|
||||
var queryUrl = OC.generateUrl('apps/passman/api/v2/sharing/save');
|
||||
return $http.post(queryUrl, {
|
||||
item_guid: request.item_guid,
|
||||
target_vault_guid: request.target_vault_guid,
|
||||
final_shared_key: crypted_shared_key
|
||||
}).then(function (response) {
|
||||
return response.data;
|
||||
});
|
||||
},
|
||||
declineSharingRequest: function (request) {
|
||||
var queryUrl = OC.generateUrl('apps/passman/api/v2/sharing/decline/' + request.req_id);
|
||||
return $http.delete(queryUrl).then(function (response) {
|
||||
return response.data;
|
||||
});
|
||||
},
|
||||
unshareCredential: function (credential) {
|
||||
var queryUrl = OC.generateUrl('apps/passman/api/v2/sharing/credential/' + credential.guid);
|
||||
return $http.delete(queryUrl).then(function (response) {
|
||||
return response.data;
|
||||
});
|
||||
},
|
||||
|
||||
this.call_progress(this.current_index);
|
||||
setTimeout(workload.bind(this), 1);
|
||||
}
|
||||
else {
|
||||
this.call_then(this.data);
|
||||
}
|
||||
};
|
||||
return new C_Promise(function () {
|
||||
this.data = [];
|
||||
this.vaults = vaults;
|
||||
this.string = string;
|
||||
this.current_index = 0;
|
||||
unshareCredentialFromUser: function (credential, user_id) {
|
||||
var queryUrl = OC.generateUrl('apps/passman/api/v2/sharing/credential/' + credential.guid + '/' + user_id);
|
||||
return $http.delete(queryUrl).then(function (response) {
|
||||
return response.data;
|
||||
});
|
||||
},
|
||||
|
||||
setTimeout(workload.bind(this), 0);
|
||||
});
|
||||
}
|
||||
}
|
||||
}]);
|
||||
createPublicSharedCredential: function (shareObj) {
|
||||
var queryUrl = OC.generateUrl('apps/passman/api/v2/sharing/public');
|
||||
return $http.post(queryUrl, shareObj).then(function (response) {
|
||||
return response.data;
|
||||
});
|
||||
},
|
||||
getPublicSharedCredential: function (credential_guid) {
|
||||
var queryUrl = OC.generateUrl('apps/passman/api/v2/sharing/credential/' + credential_guid + '/public');
|
||||
return $http.get(queryUrl).then(function (response) {
|
||||
if (response.data) {
|
||||
return response;
|
||||
} else {
|
||||
return response;
|
||||
}
|
||||
},
|
||||
function (result) {
|
||||
return result;
|
||||
});
|
||||
},
|
||||
getSharedCredentialACL: function (credential) {
|
||||
var queryUrl = OC.generateUrl('apps/passman/api/v2/sharing/credential/' + credential.guid + '/acl');
|
||||
return $http.get(queryUrl).then(function (response) {
|
||||
if (response.data) {
|
||||
return response.data;
|
||||
} else {
|
||||
return response;
|
||||
}
|
||||
},
|
||||
function (result) {
|
||||
return result;
|
||||
});
|
||||
},
|
||||
updateCredentialAcl: function (credential, acl) {
|
||||
var queryUrl = OC.generateUrl('apps/passman/api/v2/sharing/credential/' + credential.guid + '/acl');
|
||||
return $http.patch(queryUrl, acl).then(function (response) {
|
||||
return response.data;
|
||||
});
|
||||
},
|
||||
getCredendialsSharedWithUs: function (vault_guid) {
|
||||
var queryUrl = OC.generateUrl('apps/passman/api/v2/sharing/vault/' + vault_guid + '/get');
|
||||
return $http.get(queryUrl).then(function (response) {
|
||||
if (response.data) {
|
||||
return response.data;
|
||||
}
|
||||
});
|
||||
},
|
||||
downloadSharedFile: function (credential, file) {
|
||||
var queryUrl = OC.generateUrl('apps/passman/api/v2/sharing/credential/' + credential.guid + '/file/' + file.guid);
|
||||
return $http.get(queryUrl).then(function (response) {
|
||||
if (response.data) {
|
||||
return response.data;
|
||||
}
|
||||
});
|
||||
},
|
||||
encryptSharedCredential: function (credential, sharedKey) {
|
||||
var _credential = angular.copy(credential);
|
||||
_credential.shared_key = EncryptService.encryptString(sharedKey);
|
||||
var encrypted_fields = CredentialService.getEncryptedFields();
|
||||
for (var i = 0; i < encrypted_fields.length; i++) {
|
||||
var field = encrypted_fields[i];
|
||||
var fieldValue = angular.copy(credential[field]);
|
||||
_credential[field] = EncryptService.encryptString(JSON.stringify(fieldValue), sharedKey);
|
||||
}
|
||||
return _credential;
|
||||
},
|
||||
decryptSharedCredential: function (credential, sharedKey) {
|
||||
var _credential = angular.copy(credential);
|
||||
var encrypted_fields = CredentialService.getEncryptedFields();
|
||||
for (var i = 0; i < encrypted_fields.length; i++) {
|
||||
var field = encrypted_fields[i];
|
||||
var fieldValue = angular.copy(_credential[field]);
|
||||
var field_decrypted_value;
|
||||
if (_credential.hasOwnProperty(field)) {
|
||||
try {
|
||||
field_decrypted_value = EncryptService.decryptString(fieldValue, sharedKey);
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
throw e;
|
||||
}
|
||||
try {
|
||||
_credential[field] = JSON.parse(field_decrypted_value);
|
||||
} catch (e) {
|
||||
console.log('Field' + field + ' in ' + _credential.label + ' could not be parsed! Value:' + fieldValue);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
return _credential;
|
||||
},
|
||||
|
||||
generateRSAKeys: function (key_length, progress, callback) {
|
||||
var p = new C_Promise(function () {
|
||||
var state = forge.pki.rsa.createKeyPairGenerationState(key_length, 0x10001);
|
||||
var step = function () {
|
||||
// run for 100 ms
|
||||
if (!forge.pki.rsa.stepKeyPairGenerationState(state, 100)) {
|
||||
// console.log(state);
|
||||
if (state.p !== null) {
|
||||
// progress(50);
|
||||
this.call_progress(50);
|
||||
}
|
||||
else {
|
||||
// progress(0);
|
||||
this.call_progress(0);
|
||||
}
|
||||
setTimeout(step.bind(this), 1);
|
||||
}
|
||||
else {
|
||||
// callback(state.keys);
|
||||
this.call_then(state.keys);
|
||||
}
|
||||
};
|
||||
setTimeout(step.bind(this), 100);
|
||||
});
|
||||
return p;
|
||||
},
|
||||
generateSharedKey: function (size) {
|
||||
size = size || 20;
|
||||
return new C_Promise(function () {
|
||||
var t = this;
|
||||
CRYPTO.PASSWORD.generate(size,
|
||||
function (pass) {
|
||||
t.call_then(pass);
|
||||
},
|
||||
function (progress) {
|
||||
t.call_progress(progress);
|
||||
}
|
||||
);
|
||||
});
|
||||
},
|
||||
rsaKeyPairToPEM: function (keypair) {
|
||||
return {
|
||||
'publicKey': forge.pki.publicKeyToPem(keypair.publicKey),
|
||||
'privateKey': forge.pki.privateKeyToPem(keypair.privateKey)
|
||||
};
|
||||
},
|
||||
getSharingKeys: function () {
|
||||
var vault = VaultService.getActiveVault();
|
||||
return {
|
||||
'private_sharing_key': EncryptService.decryptString(angular.copy(vault.private_sharing_key)),
|
||||
'public_sharing_key': vault.public_sharing_key
|
||||
};
|
||||
},
|
||||
rsaPrivateKeyFromPEM: function (private_pem) {
|
||||
return forge.pki.privateKeyFromPem(private_pem);
|
||||
},
|
||||
rsaPublicKeyFromPEM: function (public_pem) {
|
||||
return forge.pki.publicKeyFromPem(public_pem);
|
||||
},
|
||||
/**
|
||||
* Cyphers an array of string in a non-blocking way
|
||||
* @param vaults[] An array of vaults with the processed public keys
|
||||
* @param string The string to cypher
|
||||
*/
|
||||
cypherRSAStringWithPublicKeyBulkAsync: function (vaults, string) {
|
||||
var workload = function () {
|
||||
if (this.current_index < this.vaults.length > 0 && this.vaults.length > 0) {
|
||||
var _vault = angular.copy(this.vaults[this.current_index]);
|
||||
_vault.key = forge.util.encode64(
|
||||
_vault.public_sharing_key.encrypt(this.string)
|
||||
);
|
||||
this.data.push(
|
||||
_vault
|
||||
);
|
||||
this.current_index++;
|
||||
|
||||
this.call_progress(this.current_index);
|
||||
setTimeout(workload.bind(this), 1);
|
||||
}
|
||||
else {
|
||||
this.call_then(this.data);
|
||||
}
|
||||
};
|
||||
return new C_Promise(function () {
|
||||
this.data = [];
|
||||
this.vaults = vaults;
|
||||
this.string = string;
|
||||
this.current_index = 0;
|
||||
|
||||
setTimeout(workload.bind(this), 0);
|
||||
});
|
||||
}
|
||||
};
|
||||
}]);
|
||||
}());
|
|
@ -1,31 +1,32 @@
|
|||
'use strict';
|
||||
|
||||
/**
|
||||
* @ngdoc service
|
||||
* @name passmanApp.TagService
|
||||
* @description
|
||||
* # TagService
|
||||
* Service in the passmanApp.
|
||||
*/
|
||||
angular.module('passmanApp')
|
||||
.service('TagService', ['$filter', function ($filter) {
|
||||
var _tags = [];
|
||||
return {
|
||||
getTags: function () {
|
||||
return _tags;
|
||||
},
|
||||
searchTag: function(string){
|
||||
return $filter('filter')(_tags,{text: string });
|
||||
},
|
||||
addTags: function (tags) {
|
||||
for(var i =0; i < tags.length; i++){
|
||||
if( $filter('filter')(_tags,{text: tags[i].text }).length == 0){
|
||||
_tags.push(tags[i])
|
||||
(function () {
|
||||
'use strict';
|
||||
/**
|
||||
* @ngdoc service
|
||||
* @name passmanApp.TagService
|
||||
* @description
|
||||
* # TagService
|
||||
* Service in the passmanApp.
|
||||
*/
|
||||
angular.module('passmanApp')
|
||||
.service('TagService', ['$filter', function ($filter) {
|
||||
var _tags = [];
|
||||
return {
|
||||
getTags: function () {
|
||||
return _tags;
|
||||
},
|
||||
searchTag: function (string) {
|
||||
return $filter('filter')(_tags, {text: string});
|
||||
},
|
||||
addTags: function (tags) {
|
||||
for (var i = 0; i < tags.length; i++) {
|
||||
if ($filter('filter')(_tags, {text: tags[i].text}).length === 0) {
|
||||
_tags.push(tags[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
removeTag: function (tag) {
|
||||
},
|
||||
removeTag: function (tag) {
|
||||
|
||||
}
|
||||
}
|
||||
}]);
|
||||
}
|
||||
};
|
||||
}]);
|
||||
}());
|
|
@ -1,112 +1,115 @@
|
|||
'use strict';
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* @ngdoc service
|
||||
* @name passmanApp.VaultService
|
||||
* @description
|
||||
* # VaultService
|
||||
* Service in the passmanApp.
|
||||
*/
|
||||
angular.module('passmanApp')
|
||||
.service('VaultService', ['$http', function ($http) {
|
||||
// AngularJS will instantiate a singleton by calling "new" on this function
|
||||
var _this = this;
|
||||
var _activeVault;
|
||||
var service = {
|
||||
getVaults: function(){
|
||||
var queryUrl = OC.generateUrl('apps/passman/api/v2/vaults');
|
||||
return $http.get(queryUrl).then(function (response) {
|
||||
if(response.data){
|
||||
return response.data;
|
||||
} else {
|
||||
return response;
|
||||
}
|
||||
});
|
||||
},
|
||||
setActiveVault: function(vault){
|
||||
_activeVault = angular.copy(vault);
|
||||
},
|
||||
getActiveVault: function(){
|
||||
return _activeVault;
|
||||
},
|
||||
getVaultSetting: function(key, default_value){
|
||||
if(!_activeVault.vault_settings){
|
||||
return default_value;
|
||||
} else {
|
||||
return (_activeVault.vault_settings[key] !== undefined) ? _activeVault.vault_settings[key] : default_value;
|
||||
}
|
||||
|
||||
},
|
||||
setVaultSetting: function(key, value){
|
||||
if(!_activeVault.vault_settings){
|
||||
return false;
|
||||
} else {
|
||||
_activeVault.vault_settings[key] = value;
|
||||
_this.updateVault(_activeVault);
|
||||
}
|
||||
|
||||
},
|
||||
createVault: function (vaultName) {
|
||||
var queryUrl = OC.generateUrl('apps/passman/api/v2/vaults');
|
||||
return $http.post(queryUrl, { vault_name: vaultName }).then(function (response) {
|
||||
if(response.data){
|
||||
return response.data;
|
||||
} else {
|
||||
return response;
|
||||
}
|
||||
});
|
||||
},
|
||||
getVault: function (vault) {
|
||||
var queryUrl = OC.generateUrl('apps/passman/api/v2/vaults/' + vault.guid);
|
||||
return $http.get(queryUrl).then(function (response) {
|
||||
if(response.data){
|
||||
if(response.data.vault_settings){
|
||||
response.data.vault_settings = JSON.parse(window.atob(response.data.vault_settings));
|
||||
/**
|
||||
* @ngdoc service
|
||||
* @name passmanApp.VaultService
|
||||
* @description
|
||||
* # VaultService
|
||||
* Service in the passmanApp.
|
||||
*/
|
||||
angular.module('passmanApp')
|
||||
.service('VaultService', ['$http', function ($http) {
|
||||
// AngularJS will instantiate a singleton by calling "new" on this function
|
||||
var _this = this;
|
||||
var _activeVault;
|
||||
var service = {
|
||||
getVaults: function () {
|
||||
var queryUrl = OC.generateUrl('apps/passman/api/v2/vaults');
|
||||
return $http.get(queryUrl).then(function (response) {
|
||||
if (response.data) {
|
||||
return response.data;
|
||||
} else {
|
||||
response.data.vault_settings = {};
|
||||
return response;
|
||||
}
|
||||
return response.data;
|
||||
});
|
||||
},
|
||||
setActiveVault: function (vault) {
|
||||
_activeVault = angular.copy(vault);
|
||||
},
|
||||
getActiveVault: function () {
|
||||
return _activeVault;
|
||||
},
|
||||
getVaultSetting: function (key, default_value) {
|
||||
if (!_activeVault.vault_settings) {
|
||||
return default_value;
|
||||
} else {
|
||||
return response;
|
||||
return (_activeVault.vault_settings[key] !== undefined) ? _activeVault.vault_settings[key] : default_value;
|
||||
}
|
||||
});
|
||||
},
|
||||
updateVault: function (vault) {
|
||||
var _vault = angular.copy(vault);
|
||||
delete _vault.defaultVaultPass;
|
||||
delete _vault.defaultVault;
|
||||
delete _vault.vaultKey;
|
||||
_vault.vault_settings = window.btoa(JSON.stringify(_vault.vault_settings));
|
||||
var queryUrl = OC.generateUrl('apps/passman/api/v2/vaults/' + _vault.guid);
|
||||
return $http.patch(queryUrl, _vault).then(function (response) {
|
||||
if(response.data){
|
||||
return response.data;
|
||||
} else {
|
||||
return response;
|
||||
}
|
||||
});
|
||||
},
|
||||
updateSharingKeys: function (vault) {
|
||||
var queryUrl = OC.generateUrl('apps/passman/api/v2/vaults/' + vault.guid +'/sharing-keys');
|
||||
return $http.post(queryUrl, vault).then(function (response) {
|
||||
if(response.data){
|
||||
return response.data;
|
||||
} else {
|
||||
return response;
|
||||
}
|
||||
});
|
||||
},
|
||||
deleteVault: function (vault) {
|
||||
var queryUrl = OC.generateUrl('apps/passman/api/v2/vaults/' + vault.vault_id);
|
||||
return $http.delete(queryUrl).then(function (response) {
|
||||
if(response.data){
|
||||
return response.data;
|
||||
} else {
|
||||
return response;
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
return service;
|
||||
}]);
|
||||
},
|
||||
setVaultSetting: function (key, value) {
|
||||
if (!_activeVault.vault_settings) {
|
||||
return false;
|
||||
} else {
|
||||
_activeVault.vault_settings[key] = value;
|
||||
_this.updateVault(_activeVault);
|
||||
}
|
||||
|
||||
},
|
||||
createVault: function (vaultName) {
|
||||
var queryUrl = OC.generateUrl('apps/passman/api/v2/vaults');
|
||||
return $http.post(queryUrl, {vault_name: vaultName}).then(function (response) {
|
||||
if (response.data) {
|
||||
return response.data;
|
||||
} else {
|
||||
return response;
|
||||
}
|
||||
});
|
||||
},
|
||||
getVault: function (vault) {
|
||||
var queryUrl = OC.generateUrl('apps/passman/api/v2/vaults/' + vault.guid);
|
||||
return $http.get(queryUrl).then(function (response) {
|
||||
if (response.data) {
|
||||
if (response.data.vault_settings) {
|
||||
response.data.vault_settings = JSON.parse(window.atob(response.data.vault_settings));
|
||||
} else {
|
||||
response.data.vault_settings = {};
|
||||
}
|
||||
return response.data;
|
||||
} else {
|
||||
return response;
|
||||
}
|
||||
});
|
||||
},
|
||||
updateVault: function (vault) {
|
||||
var _vault = angular.copy(vault);
|
||||
delete _vault.defaultVaultPass;
|
||||
delete _vault.defaultVault;
|
||||
delete _vault.vaultKey;
|
||||
_vault.vault_settings = window.btoa(JSON.stringify(_vault.vault_settings));
|
||||
var queryUrl = OC.generateUrl('apps/passman/api/v2/vaults/' + _vault.guid);
|
||||
return $http.patch(queryUrl, _vault).then(function (response) {
|
||||
if (response.data) {
|
||||
return response.data;
|
||||
} else {
|
||||
return response;
|
||||
}
|
||||
});
|
||||
},
|
||||
updateSharingKeys: function (vault) {
|
||||
var queryUrl = OC.generateUrl('apps/passman/api/v2/vaults/' + vault.guid + '/sharing-keys');
|
||||
return $http.post(queryUrl, vault).then(function (response) {
|
||||
if (response.data) {
|
||||
return response.data;
|
||||
} else {
|
||||
return response;
|
||||
}
|
||||
});
|
||||
},
|
||||
deleteVault: function (vault) {
|
||||
var queryUrl = OC.generateUrl('apps/passman/api/v2/vaults/' + vault.vault_id);
|
||||
return $http.delete(queryUrl).then(function (response) {
|
||||
if (response.data) {
|
||||
return response.data;
|
||||
} else {
|
||||
return response;
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
return service;
|
||||
}]);
|
||||
}());
|
|
@ -7,6 +7,7 @@
|
|||
* @author Marcos Zuriaga <wolfi@wolfi.es>
|
||||
* @copyright Marcos Zuriarga 2015
|
||||
*/
|
||||
/*jshint curly: true */
|
||||
var CRYPTO = { // Global variables of the object:
|
||||
paranoia_level: null,
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
"version": "0.0.1",
|
||||
"devDependencies": {
|
||||
"grunt": "~0.4.5",
|
||||
"grunt-contrib-jshint": "~0.10.0",
|
||||
"grunt-contrib-jshint": "^0.12.0",
|
||||
"grunt-contrib-nodeunit": "~0.4.1",
|
||||
"grunt-contrib-sass": "^1.0.0",
|
||||
"grunt-contrib-uglify": "~0.5.0",
|
||||
|
|
Загрузка…
Ссылка в новой задаче