mirror of
https://github.com/nextcloud/passman.git
synced 2025-11-10 22:22:38 +08:00
Added promise class
Refactored crypto services to use promises Fixed issues with the sharing settings page
This commit is contained in:
parent
0201f049fb
commit
966efcf4a5
5 changed files with 214 additions and 28 deletions
|
|
@ -4,33 +4,30 @@
|
||||||
angular.module('passmanApp')
|
angular.module('passmanApp')
|
||||||
.controller('SharingSettingsCtrl', ['$scope', 'VaultService', 'CredentialService', 'SettingsService', '$location', '$routeParams', 'ShareService', 'EncryptService',
|
.controller('SharingSettingsCtrl', ['$scope', 'VaultService', 'CredentialService', 'SettingsService', '$location', '$routeParams', 'ShareService', 'EncryptService',
|
||||||
function ($scope, VaultService, CredentialService, SettingsService, $location, $routeParams, ShareService, EncryptService) {
|
function ($scope, VaultService, CredentialService, SettingsService, $location, $routeParams, ShareService, EncryptService) {
|
||||||
$scope.active_vault = VaultService.getActiveVault();
|
$scope.vault = VaultService.getActiveVault();
|
||||||
|
$scope.sharing_keys = ShareService.getSharingKeys();
|
||||||
|
|
||||||
$scope.progress = 1;
|
$scope.progress = 1;
|
||||||
$scope.generating = false;
|
$scope.generating = false;
|
||||||
|
|
||||||
$scope.sharing_keys = ShareService.getSharingKeys();
|
|
||||||
|
|
||||||
$scope.generateKeys = function (length) {
|
$scope.generateKeys = function (length) {
|
||||||
$scope.progress = 1;
|
$scope.progress = 1;
|
||||||
$scope.generating = true;
|
$scope.generating = true;
|
||||||
|
|
||||||
ShareService.generateRSAKeys(length, function(progress){
|
ShareService.generateRSAKeys(length).progress(function(progress){
|
||||||
$scope.progress = progress > 0 ? 2:1;
|
$scope.progress = progress > 0 ? 2:1;
|
||||||
$scope.$apply();
|
$scope.$apply();
|
||||||
console.log($scope.progress);
|
}).then(function(kp){
|
||||||
}, function(kp){
|
console.log('stuff done');
|
||||||
$scope.generating = false;
|
$scope.generating = false;
|
||||||
|
|
||||||
var pem = ShareService.rsaKeyPairToPEM(kp)
|
var pem = ShareService.rsaKeyPairToPEM(kp)
|
||||||
|
|
||||||
$scope.active_vault.private_sharing_key = pem.privateKey;
|
$scope.vault.private_sharing_key = EncryptService.encryptString(pem.privateKey);
|
||||||
$scope.active_vault.public_sharing_key = pem.publicKey;
|
$scope.vault.public_sharing_key = pem.publicKey;
|
||||||
|
|
||||||
|
VaultService.updateSharingKeys($scope.vault).then(function (result) {
|
||||||
var _vault = angular.copy($scope.active_vault);
|
$scope.sharing_keys = ShareService.getSharingKeys();
|
||||||
_vault.private_sharing_key = EncryptService.encryptString(_vault.private_sharing_key);
|
|
||||||
VaultService.updateSharingKeys(_vault).then(function (result) {
|
|
||||||
console.log('done')
|
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,11 @@
|
||||||
*/
|
*/
|
||||||
angular.module('passmanApp')
|
angular.module('passmanApp')
|
||||||
.service('ShareService', ['$http', 'VaultService', 'EncryptService', function ($http, VaultService, EncryptService) {
|
.service('ShareService', ['$http', 'VaultService', 'EncryptService', function ($http, VaultService, EncryptService) {
|
||||||
|
// 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 {
|
return {
|
||||||
search: function (string) {
|
search: function (string) {
|
||||||
var queryUrl = OC.generateUrl('apps/passman/api/v2/sharing/search');
|
var queryUrl = OC.generateUrl('apps/passman/api/v2/sharing/search');
|
||||||
|
|
@ -21,24 +26,43 @@ angular.module('passmanApp')
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
generateRSAKeys: function(key_length, progress, callback){
|
generateRSAKeys: function(key_length, progress, callback){
|
||||||
var state = forge.pki.rsa.createKeyPairGenerationState(key_length, 0x10001);
|
var p = new C_Promise(function(promise){
|
||||||
var step = function() {
|
var state = forge.pki.rsa.createKeyPairGenerationState(key_length, 0x10001);
|
||||||
// run for 100 ms
|
var step = function() {
|
||||||
if(!forge.pki.rsa.stepKeyPairGenerationState(state, 100)) {
|
// run for 100 ms
|
||||||
// console.log(state);
|
if(!forge.pki.rsa.stepKeyPairGenerationState(state, 100)) {
|
||||||
if (state.p !== null) {
|
// console.log(state);
|
||||||
progress(50);
|
if (state.p !== null) {
|
||||||
|
// progress(50);
|
||||||
|
promise.call_progress(50);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// progress(0);
|
||||||
|
promise.call_progress(50);
|
||||||
|
}
|
||||||
|
setTimeout(step, 1);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
progress(0);
|
// callback(state.keys);
|
||||||
|
promise.call_then(state.keys);
|
||||||
}
|
}
|
||||||
setTimeout(step, 1);
|
};
|
||||||
}
|
setTimeout(step, 100);
|
||||||
else {
|
});
|
||||||
callback(state.keys);
|
return p;
|
||||||
}
|
},
|
||||||
};
|
generateSharedKey: function(size){
|
||||||
setTimeout(step, 100);
|
size = size || 20;
|
||||||
|
return new C_Promise(function(promise){ /** prmise C_Promise **/
|
||||||
|
CRYPTO.PASSWORD.generate(size,
|
||||||
|
function(pass) {
|
||||||
|
promise.call_then(pass);
|
||||||
|
},
|
||||||
|
function(progress) {
|
||||||
|
promise.call_progress(progress);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
})
|
||||||
},
|
},
|
||||||
rsaKeyPairToPEM: function(keypair){
|
rsaKeyPairToPEM: function(keypair){
|
||||||
return {
|
return {
|
||||||
|
|
|
||||||
129
js/lib/crypto_wrap.js
Normal file
129
js/lib/crypto_wrap.js
Normal file
|
|
@ -0,0 +1,129 @@
|
||||||
|
/**
|
||||||
|
* ownCloud/NextCloud - passman
|
||||||
|
*
|
||||||
|
* This file is licensed under the Affero General Public License version 3 or
|
||||||
|
* later. See the COPYING file.
|
||||||
|
*
|
||||||
|
* @author Marcos Zuriaga <wolfi@wolfi.es>
|
||||||
|
* @copyright Marcos Zuriarga 2015
|
||||||
|
*/
|
||||||
|
var CRYPTO = { // Global variables of the object:
|
||||||
|
paranoia_level: null,
|
||||||
|
|
||||||
|
PASSWORD : {
|
||||||
|
/**
|
||||||
|
* Callback will be called once the password its generated, it should accept one parameter, and the parameter will be the key (
|
||||||
|
* CRYPTO.PASSWORD.generate(100, function(password){
|
||||||
|
* console.log("The generated password is: " + password);
|
||||||
|
* // Do more stuff here
|
||||||
|
* }, function (current_percentage){
|
||||||
|
* console.log("The current password generation progress it's: " + current_percentage + "%");
|
||||||
|
* // Do real stuff here, update a progressbar, etc.
|
||||||
|
* }
|
||||||
|
* );
|
||||||
|
* )
|
||||||
|
* @param length The minium length of the generated password (it generates in packs of 4 characters,
|
||||||
|
* so it can end up being up to 3 characters longer)
|
||||||
|
* @param callback The function to be called after the password generation its done
|
||||||
|
* @param progress The process of the generation, optional, called each 4 characters generated.
|
||||||
|
*/
|
||||||
|
generate : function (length, callback, progress, start_string) {
|
||||||
|
if (!sjcl.random.isReady(paranoia_level)) {
|
||||||
|
setTimeout(this.generate(length, callback, progress, start_string), 500);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (start_string == null) start_string = "";
|
||||||
|
if (start_string.length < length) {
|
||||||
|
start_string += CRYPTO.RANDOM.getRandomASCII();
|
||||||
|
if (progress != null) progress(start_string.length / length * 100);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
callback(start_string);
|
||||||
|
if (progress != null) progress(100);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
setTimeout(this.generate(length, callback, progress, start_string), 100);
|
||||||
|
},
|
||||||
|
|
||||||
|
logRepeatedCharCount: function (str) {
|
||||||
|
var chars = [];
|
||||||
|
|
||||||
|
for (i = 0; i < str.length; i++) {
|
||||||
|
chars[str.charAt(i)] = (chars[str.charAt(i)] == null) ? 0 : chars[str.charAt(i)] + 1;
|
||||||
|
}
|
||||||
|
return chars;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
RANDOM: {
|
||||||
|
/**
|
||||||
|
* Returns a random string of 4 characters length
|
||||||
|
*/
|
||||||
|
getRandomASCII : function () {
|
||||||
|
// console.warn(paranoia_level);
|
||||||
|
|
||||||
|
var ret = "";
|
||||||
|
while (ret.length < 4) {
|
||||||
|
var int = sjcl.random.randomWords(1, paranoia_level);
|
||||||
|
int = int[0];
|
||||||
|
|
||||||
|
var tmp = this._isASCII((int & 0xFF000000) >> 24);
|
||||||
|
if (tmp) ret += tmp;
|
||||||
|
|
||||||
|
tmp = this._isASCII((int & 0x00FF0000) >> 16);
|
||||||
|
if (tmp) ret += tmp;
|
||||||
|
|
||||||
|
tmp = this._isASCII((int & 0x0000FF00) >> 8);
|
||||||
|
if (tmp) ret += tmp;
|
||||||
|
|
||||||
|
tmp = this._isASCII(int & 0x000000FF);
|
||||||
|
if (tmp) ret += tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether the given data it's an ascii character, returning the corresponding character; returns false otherwise
|
||||||
|
*
|
||||||
|
* @param data
|
||||||
|
* @returns {string}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
_isASCII : function (data) {
|
||||||
|
return (data > 31 && data < 127) ? String.fromCharCode(data) : false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the random and other cryptographic engines needed for this library to work
|
||||||
|
* The default paranoia, in case no paranoia level it's provided, it's 10 (1024).
|
||||||
|
* The higher paranoia level allowed by sjcl.
|
||||||
|
*
|
||||||
|
* PARANOIA_LEVELS:
|
||||||
|
* 0 = 0
|
||||||
|
* 1 = 48
|
||||||
|
* 2 = 64
|
||||||
|
* 3 = 96
|
||||||
|
* 4 = 128
|
||||||
|
* 5 = 192
|
||||||
|
* 6 = 256
|
||||||
|
* 7 = 384
|
||||||
|
* 8 = 512
|
||||||
|
* 9 = 768
|
||||||
|
* 10 = 1024
|
||||||
|
*
|
||||||
|
* @param default_paranoia (0-10 integer)
|
||||||
|
*/
|
||||||
|
initEngines : function (default_paranoia) {
|
||||||
|
paranoia_level = default_paranoia || 10;
|
||||||
|
|
||||||
|
sjcl.random.setDefaultParanoia(this.paranoia_level);
|
||||||
|
sjcl.random.startCollectors();
|
||||||
|
|
||||||
|
console.warn('Crypto stuff initialized');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
CRYPTO.initEngines();
|
||||||
34
js/lib/promise.js
Normal file
34
js/lib/promise.js
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
/**
|
||||||
|
* ownCloud/NextCloud - passman
|
||||||
|
*
|
||||||
|
* This file is licensed under the Affero General Public License version 3 or
|
||||||
|
* later. See the COPYING file.
|
||||||
|
*
|
||||||
|
* @author Marcos Zuriaga <wolfi@wolfi.es>
|
||||||
|
* @copyright Marcos Zuriarga 2016
|
||||||
|
*/
|
||||||
|
|
||||||
|
function C_Promise(workload){
|
||||||
|
this.then = function(callback){
|
||||||
|
this.finally = callback;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
this.progress = function(callback){
|
||||||
|
this.update = callback;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
this.error = function (callback){
|
||||||
|
this.error_function = callback;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
this.call_then = function(data){
|
||||||
|
if (this.finally !== undefined) this.finally(data);
|
||||||
|
}
|
||||||
|
this.call_progress = function(data){
|
||||||
|
if (this.progress !== undefined) this.progress(data);
|
||||||
|
}
|
||||||
|
this.call_error = function(data){
|
||||||
|
if(this.error_function !== undefined) this.error_function(data);
|
||||||
|
}
|
||||||
|
setTimeout(workload(this), 100);
|
||||||
|
}
|
||||||
|
|
@ -22,6 +22,8 @@ script('passman', 'vendor/angular-xeditable/xeditable.min');
|
||||||
script('passman', 'vendor/sha/sha');
|
script('passman', 'vendor/sha/sha');
|
||||||
script('passman', 'vendor/llqrcode/llqrcode');
|
script('passman', 'vendor/llqrcode/llqrcode');
|
||||||
script('passman', 'vendor/forge.0.6.9.min');
|
script('passman', 'vendor/forge.0.6.9.min');
|
||||||
|
script('passman', 'lib/promise');
|
||||||
|
script('passman', 'lib/crypto_wrap');
|
||||||
|
|
||||||
|
|
||||||
script('passman', 'app/app');
|
script('passman', 'app/app');
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue