From bbf9a9c4d5bd0042835d48485b4de3c719f4ee91 Mon Sep 17 00:00:00 2001 From: Mario Colque Date: Mon, 28 Apr 2014 16:22:59 -0300 Subject: [PATCH 01/21] added PasswordController --- index.html | 37 +++++++++++++++++++++++++++++++++++++ js/app.js | 4 +++- js/controllers/password.js | 11 +++++++++++ js/routes.js | 4 ++++ 4 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 js/controllers/password.js diff --git a/index.html b/index.html index 6ccfdd6fa..fc947f2a3 100644 --- a/index.html +++ b/index.html @@ -254,6 +254,42 @@ + + + + + diff --git a/js/app.js b/js/app.js index aa9cdfde1..d146ce544 100644 --- a/js/app.js +++ b/js/app.js @@ -20,7 +20,8 @@ var copayApp = window.copayApp = angular.module('copay',[ 'copay.setup', 'copay.directives', 'copay.video', - 'copay.import' + 'copay.import', + 'copay.password', ]); angular.module('copay.header', []); @@ -37,4 +38,5 @@ angular.module('copay.socket', []); angular.module('copay.directives', []); angular.module('copay.video', []); angular.module('copay.import', []); +angular.module('copay.password', []); diff --git a/js/controllers/password.js b/js/controllers/password.js new file mode 100644 index 000000000..00e3d9909 --- /dev/null +++ b/js/controllers/password.js @@ -0,0 +1,11 @@ +'use strict'; + +angular.module('copay.password').controller('PasswordController', + function($scope, $rootScope) { + $scope.title = 'Password'; + + $scope.getPassphrase = function() { + console.log('######### Password', $scope.password); + }; + + }); diff --git a/js/routes.js b/js/routes.js index 36ed4654b..154d1c614 100644 --- a/js/routes.js +++ b/js/routes.js @@ -22,6 +22,10 @@ angular templateUrl: 'setup.html', validate: false }) + .when('/password', { + templateUrl: 'password.html', + validate: false + }) .when('/addresses', { templateUrl: 'addresses.html', validate: true From 973e65f375b6a03f8d69c2bcda627257438f18c9 Mon Sep 17 00:00:00 2001 From: Mario Colque Date: Mon, 28 Apr 2014 17:23:15 -0300 Subject: [PATCH 02/21] added crypto-js libs --- index.html | 2 ++ 1 file changed, 2 insertions(+) diff --git a/index.html b/index.html index fc947f2a3..83e6fec3d 100644 --- a/index.html +++ b/index.html @@ -573,6 +573,8 @@ + + From 62b95ac12287445843e6be98cc7ecef19c87e99a Mon Sep 17 00:00:00 2001 From: Mario Colque Date: Wed, 30 Apr 2014 10:52:39 -0300 Subject: [PATCH 03/21] added Passphrase model --- copay.js | 2 ++ index.html | 1 + js/app.js | 2 ++ util/build.js | 4 +++- 4 files changed, 8 insertions(+), 1 deletion(-) diff --git a/copay.js b/copay.js index d68d1cfb1..35a492730 100644 --- a/copay.js +++ b/copay.js @@ -3,6 +3,8 @@ module.exports.PublicKeyRing = require('./js/models/core/PublicKeyRing'); module.exports.TxProposals = require('./js/models/core/TxProposals'); module.exports.PrivateKey = require('./js/models/core/PrivateKey'); +module.exports.Passphrase = require('./js/models/core/Passphrase'); + // components var WebRTC = module.exports.WebRTC = require('./js/models/network/WebRTC'); diff --git a/index.html b/index.html index 83e6fec3d..867ae98db 100644 --- a/index.html +++ b/index.html @@ -589,6 +589,7 @@ + diff --git a/js/app.js b/js/app.js index d146ce544..060a2103c 100644 --- a/js/app.js +++ b/js/app.js @@ -22,6 +22,7 @@ var copayApp = window.copayApp = angular.module('copay',[ 'copay.video', 'copay.import', 'copay.password', + 'copay.passphrase' ]); angular.module('copay.header', []); @@ -39,4 +40,5 @@ angular.module('copay.directives', []); angular.module('copay.video', []); angular.module('copay.import', []); angular.module('copay.password', []); +angular.module('copay.passphrase', []); diff --git a/util/build.js b/util/build.js index 5cd7a3d7a..fd587da26 100755 --- a/util/build.js +++ b/util/build.js @@ -68,7 +68,9 @@ var createBundle = function(opts) { b.require('./js/models/core/PublicKeyRing', { expose: '../js/models/core/PublicKeyRing' }); - + b.require('./js/models/core/Passphrase', { + expose: '../js/models/core/Passphrase' + }); if (!opts.dontminify) { b.transform({ From 06b25db3646d1dd4eba8468b24eadb78b33d096a Mon Sep 17 00:00:00 2001 From: Mario Colque Date: Wed, 30 Apr 2014 16:30:25 -0300 Subject: [PATCH 04/21] added Passphrase model and service --- js/models/core/Passphrase.js | 24 ++++++++++++++++++++++++ js/services/passphrase.js | 7 +++++++ 2 files changed, 31 insertions(+) create mode 100644 js/models/core/Passphrase.js create mode 100644 js/services/passphrase.js diff --git a/js/models/core/Passphrase.js b/js/models/core/Passphrase.js new file mode 100644 index 000000000..5a0569df3 --- /dev/null +++ b/js/models/core/Passphrase.js @@ -0,0 +1,24 @@ +'use strict'; + +function Passphrase(config) { + config = config || {}; + this.salt = config.storageSalt; + this.iterations = config.iterations || 1000; +}; + +Passphrase.prototype.get = function(password) { + var hash = CryptoJS.SHA256(CryptoJS.SHA256(password)); + var salt = CryptoJS.enc.Hex.parse(this.salt); + var key512 = CryptoJS.PBKDF2(hash, salt, { keySize: 512/32, iterations: this.iterations }); + + return key512; +}; + +Passphrase.prototype.getBase64 = function(password) { + var key512 = this.get(password); + var keyBase64 = key512.toString(CryptoJS.enc.Base64); + + return keyBase64; +}; + +module.exports = Passphrase; diff --git a/js/services/passphrase.js b/js/services/passphrase.js new file mode 100644 index 000000000..2ea188869 --- /dev/null +++ b/js/services/passphrase.js @@ -0,0 +1,7 @@ +'use strict'; + +var passphrase; +angular.module('copay.passphrase').factory('Passphrase', function($rootScope) { + passphrase = passphrase || new copay.Passphrase(config); + return passphrase; +}); From 9eec30a729c1835b2e499e8789e37aead14d12c1 Mon Sep 17 00:00:00 2001 From: Mario Colque Date: Wed, 30 Apr 2014 16:32:39 -0300 Subject: [PATCH 05/21] using StorageLocalEncrypted instead LocalPlain module --- copay.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/copay.js b/copay.js index 35a492730..f35ba8732 100644 --- a/copay.js +++ b/copay.js @@ -15,7 +15,7 @@ var StorageLocalEncrypted = module.exports.StorageLocalEncrypted = require('./js var WalletFactory = require('soop').load('./js/models/core/WalletFactory',{ Network: WebRTC, Blockchain: Insight, - Storage: StorageLocalPlain, + Storage: StorageLocalEncrypted, }); module.exports.WalletFactory = WalletFactory; From ecd979493a6837f0e3bae910d9bf9a7f3f9f9152 Mon Sep 17 00:00:00 2001 From: Mario Colque Date: Wed, 30 Apr 2014 16:36:20 -0300 Subject: [PATCH 06/21] using Base64 instead Hex for storageSalt --- js/models/core/Passphrase.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/models/core/Passphrase.js b/js/models/core/Passphrase.js index 5a0569df3..57f765cd1 100644 --- a/js/models/core/Passphrase.js +++ b/js/models/core/Passphrase.js @@ -8,7 +8,7 @@ function Passphrase(config) { Passphrase.prototype.get = function(password) { var hash = CryptoJS.SHA256(CryptoJS.SHA256(password)); - var salt = CryptoJS.enc.Hex.parse(this.salt); + var salt = CryptoJS.enc.Base64.parse(this.salt); var key512 = CryptoJS.PBKDF2(hash, salt, { keySize: 512/32, iterations: this.iterations }); return key512; From cd4db8a097b5d005e24f628179ec97cc421c2869 Mon Sep 17 00:00:00 2001 From: Mario Colque Date: Wed, 30 Apr 2014 16:36:44 -0300 Subject: [PATCH 07/21] added encryption configs --- config.template.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/config.template.js b/config.template.js index 793c7d940..b3ebac205 100644 --- a/config.template.js +++ b/config.template.js @@ -43,6 +43,8 @@ var config = { }, verbose: 1, themes: ['default'] + iterations: 1000, + storageSalt: 'mjuBtGybi/4=', // choose your own salt (base64) }; var log = function () { From 9d27a0b85d9a61fa417f0ae12448796ea9317d3d Mon Sep 17 00:00:00 2001 From: Mario Colque Date: Thu, 1 May 2014 09:59:43 -0300 Subject: [PATCH 08/21] added password support to UI/Controllers --- index.html | 14 +++++++++----- js/controllers/password.js | 10 +++++++--- js/controllers/setup.js | 6 ++++-- js/controllers/signin.js | 7 ++++--- 4 files changed, 24 insertions(+), 13 deletions(-) diff --git a/index.html b/index.html index 867ae98db..f7b2727f6 100644 --- a/index.html +++ b/index.html @@ -218,7 +218,6 @@ ng-options="requiredCopayers as requiredCopayers for requiredCopayers in RCValues"> -
@@ -230,6 +229,12 @@
+
+
+
Wallet Password
+ +
+
Wallet name (optional)
@@ -240,7 +245,6 @@
-
+ +
@@ -328,7 +332,7 @@ - + @@ -185,7 +186,6 @@ - - - diff --git a/js/app.js b/js/app.js index 060a2103c..db15e356c 100644 --- a/js/app.js +++ b/js/app.js @@ -21,7 +21,6 @@ var copayApp = window.copayApp = angular.module('copay',[ 'copay.directives', 'copay.video', 'copay.import', - 'copay.password', 'copay.passphrase' ]); @@ -39,6 +38,5 @@ angular.module('copay.socket', []); angular.module('copay.directives', []); angular.module('copay.video', []); angular.module('copay.import', []); -angular.module('copay.password', []); angular.module('copay.passphrase', []); diff --git a/js/routes.js b/js/routes.js index 154d1c614..36ed4654b 100644 --- a/js/routes.js +++ b/js/routes.js @@ -22,10 +22,6 @@ angular templateUrl: 'setup.html', validate: false }) - .when('/password', { - templateUrl: 'password.html', - validate: false - }) .when('/addresses', { templateUrl: 'addresses.html', validate: true From 32f27b6c0a28a5c2abb54a2f7f666a35057d3171 Mon Sep 17 00:00:00 2001 From: Mario Colque Date: Thu, 1 May 2014 14:21:55 -0300 Subject: [PATCH 16/21] added copayer password support --- js/controllers/setup.js | 12 +++++++----- js/controllers/signin.js | 30 +++++++++++++++++++----------- 2 files changed, 26 insertions(+), 16 deletions(-) diff --git a/js/controllers/setup.js b/js/controllers/setup.js index dfa543095..1da4404e4 100644 --- a/js/controllers/setup.js +++ b/js/controllers/setup.js @@ -4,6 +4,7 @@ angular.module('copay.setup').controller('SetupController', function($scope, $rootScope, $location, walletFactory, controllerUtils, Passphrase) { $scope.loading = false; + $scope.walletPassword = $rootScope.walletPassword; // ng-repeat defined number of times instead of repeating over array? $scope.getNumber = function(num) { @@ -31,15 +32,16 @@ angular.module('copay.setup').controller('SetupController', updateRCSelect(tc); }); - $scope.create = function(totalCopayers, requiredCopayers, walletName, myNickname) { + $scope.create = function() { $scope.loading = true; + var passphrase = Passphrase.getBase64($scope.walletPassword); var opts = { - requiredCopayers: requiredCopayers, - totalCopayers: totalCopayers, - name: walletName, - nickname: myNickname, + requiredCopayers: $scope.requiredCopayers, + totalCopayers: $scope.totalCopayers, + name: $scope.walletName, + nickname: $scope.myNickname, passphrase: passphrase, }; var w = walletFactory.create(opts); diff --git a/js/controllers/signin.js b/js/controllers/signin.js index 9c543a34c..af3406ecc 100644 --- a/js/controllers/signin.js +++ b/js/controllers/signin.js @@ -1,31 +1,37 @@ 'use strict'; angular.module('copay.signin').controller('SigninController', - function($scope, $rootScope, $location, walletFactory, controllerUtils) { + function($scope, $rootScope, $location, walletFactory, controllerUtils, Passphrase) { $scope.loading = false; $scope.wallets = walletFactory.getWallets(); $scope.selectedWalletId = $scope.wallets.length ? $scope.wallets[0].id : null; + $scope.openPassword = ''; - $scope.create = function(walletName) { + $scope.create = function() { $scope.loading = true; - $rootScope.walletName = walletName; + + $rootScope.walletName = $scope.walletName; + $rootScope.walletPassword = $scope.createPassword; $location.path('setup'); }; - $scope.open = function(walletId) { - $scope.loading = true; - $rootScope.openedWalletId = walletId; + $scope.open = function() { + if ($scope.openPassword != '') { + $scope.loading = true; - $location.path('password'); + var passphrase = Passphrase.getBase64($scope.openPassword); + var w = walletFactory.open($scope.selectedWalletId, { passphrase: passphrase}); + controllerUtils.startNetwork(w); + } }; - $scope.join = function(secret, nickname ) { + $scope.join = function() { $scope.loading = true; walletFactory.network.on('badSecret', function() { }); - walletFactory.joinCreateSession(secret, nickname, function(err,w) { + walletFactory.joinCreateSession($scope.connectionId, $scope.nickname, function(err,w) { $scope.loading = false; if (err || !w) { @@ -36,9 +42,11 @@ angular.module('copay.signin').controller('SigninController', else $rootScope.flashMessage = { message: 'Unknown error', type: 'error'}; controllerUtils.onErrorDigest(); - } - else + } else { + var passphrase = Passphrase.getBase64($scope.joinPassword); + w.storage._setPassphrase(passphrase); controllerUtils.startNetwork(w); + } }); }; }); From a825929456086f8dd871137e1466e224adeee7d2 Mon Sep 17 00:00:00 2001 From: Mario Colque Date: Thu, 1 May 2014 14:32:09 -0300 Subject: [PATCH 17/21] fixed ui --- index.html | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/index.html b/index.html index 794b6d70b..183bc9171 100644 --- a/index.html +++ b/index.html @@ -200,15 +200,16 @@
-
-
Select total number of copayers
- -
-
-
Select required number of signatures
- +
+
Select total number of copayers
+ +
+
+
Select required number of signatures
+ +
From a9416ce1cdba64b4e892e0f138f4c01888113f7e Mon Sep 17 00:00:00 2001 From: Mario Colque Date: Thu, 1 May 2014 15:12:38 -0300 Subject: [PATCH 18/21] fixed tests --- test/mocks/FakeStorage.js | 4 ++++ test/test.Walletfactory.js | 1 + 2 files changed, 5 insertions(+) diff --git a/test/mocks/FakeStorage.js b/test/mocks/FakeStorage.js index 4e12e25fb..77fe38213 100644 --- a/test/mocks/FakeStorage.js +++ b/test/mocks/FakeStorage.js @@ -3,6 +3,10 @@ var FakeStorage = function(){ this.storage = {}; }; +FakeStorage.prototype._setPassphrase = function (password) { + this.storage.passphrase = password; +}; + FakeStorage.prototype.setGlobal = function (id, payload) { this.storage[id] = payload; }; diff --git a/test/test.Walletfactory.js b/test/test.Walletfactory.js index 4aa5398dd..a3feeba50 100644 --- a/test/test.Walletfactory.js +++ b/test/test.Walletfactory.js @@ -32,6 +32,7 @@ describe('WalletFactory model', function() { port: 80 }, networkName: 'testnet', + passphrase: 'test', }; it('should create the factory', function() { From 4617a24bbe912962d5eb7918fc3d8a0a237aef74 Mon Sep 17 00:00:00 2001 From: Mario Colque Date: Thu, 1 May 2014 16:21:53 -0300 Subject: [PATCH 19/21] fixed passphrase setting when a existent wallet is opened --- js/models/core/WalletFactory.js | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/js/models/core/WalletFactory.js b/js/models/core/WalletFactory.js index 5e6708c38..a76446372 100644 --- a/js/models/core/WalletFactory.js +++ b/js/models/core/WalletFactory.js @@ -68,13 +68,12 @@ WalletFactory.prototype.fromObj = function(obj) { return w; }; -WalletFactory.prototype.read = function(walletId, passphrase) { +WalletFactory.prototype.read = function(walletId) { if (! this._checkRead(walletId)) return false; var obj = {}; var s = this.storage; - s._setPassphrase(passphrase); obj.id = walletId; obj.opts = s.get(walletId, 'opts'); @@ -128,12 +127,15 @@ WalletFactory.prototype.create = function(opts) { }; WalletFactory.prototype.open = function(walletId, opts) { - this.log('Opening walletId:' + walletId); opts = opts || {}; opts.id = walletId; opts.verbose = this.verbose; - var w = this.read(walletId, opts.passphrase) || this.create(opts); + + this.storage._setPassphrase(opts.passphrase); + + var w = this.read(walletId) || this.create(opts); w.store(); + return w; }; From 4f4fa56db4d3b1daaa9afc72c853776a15f1d157 Mon Sep 17 00:00:00 2001 From: Mario Colque Date: Thu, 1 May 2014 16:28:07 -0300 Subject: [PATCH 20/21] added password exists validation to join form --- js/controllers/signin.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/js/controllers/signin.js b/js/controllers/signin.js index af3406ecc..06584f8f6 100644 --- a/js/controllers/signin.js +++ b/js/controllers/signin.js @@ -34,11 +34,13 @@ angular.module('copay.signin').controller('SigninController', walletFactory.joinCreateSession($scope.connectionId, $scope.nickname, function(err,w) { $scope.loading = false; - if (err || !w) { + if (err || !w || !$scope.joinPassword) { if (err === 'joinError') $rootScope.flashMessage = { message: 'Can not find peer'}; else if (err === 'badSecret') $rootScope.flashMessage = { message: 'Bad secret secret string', type: 'error'}; + else if (!$scope.joinPassword) + $rootScope.flashMessage = { message: 'Enter your wallet password', type: 'error' }; else $rootScope.flashMessage = { message: 'Unknown error', type: 'error'}; controllerUtils.onErrorDigest(); From 2d114923296fe09b41e9fc9e50df1aad6ed704b9 Mon Sep 17 00:00:00 2001 From: Mario Colque Date: Thu, 1 May 2014 17:07:11 -0300 Subject: [PATCH 21/21] removed unnecessary peer.html template --- index.html | 26 -------------------------- 1 file changed, 26 deletions(-) diff --git a/index.html b/index.html index 183bc9171..972943ea6 100644 --- a/index.html +++ b/index.html @@ -246,32 +246,6 @@
- -