Add JSHint, solve all problems

This commit is contained in:
brantje 2016-10-07 19:56:29 +02:00
Родитель e818e40f2f
Коммит 15b32b7e5e
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 5FF1D117F918687F
47 изменённых файлов: 3987 добавлений и 3869 удалений

10
.jshintrc Normal file
Просмотреть файл

@ -0,0 +1,10 @@
{
"maxerr" : 50,
"jquery" : true, // jQuery
"globals" : {
"angular": true,
"PassmanImporter": true,
"OC": true,
"window": true
} // additional predefined global variables
}

Просмотреть файл

@ -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']);
};

Просмотреть файл

@ -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",