From 313fcd4808a599e931aabd998200115c3cb1c576 Mon Sep 17 00:00:00 2001 From: Gustavo Cortez Date: Mon, 7 Jul 2014 01:33:39 -0300 Subject: [PATCH 1/9] Added creator's signature to address book entry. Re-factory somethings and improve the merge of them --- index.html | 9 ++- js/controllers/send.js | 34 ++++----- js/models/core/Wallet.js | 56 +++++++++++---- test/test.Wallet.js | 152 ++++++++++++++++++++++++++------------- 4 files changed, 169 insertions(+), 82 deletions(-) diff --git a/index.html b/index.html index 339e7e7ce..6455f73b7 100644 --- a/index.html +++ b/index.html @@ -753,16 +753,19 @@ Address Creator Date -   + Signature + Hidden - + {{info.label}} {{addr}} {{$root.wallet.publicKeyRing.nicknameForCopayer(info.copayerId)}} - + {{signAddressBook[addr]}} + {{info.hidden}} diff --git a/js/controllers/send.js b/js/controllers/send.js index 5d94e90fd..a09e76010 100644 --- a/js/controllers/send.js +++ b/js/controllers/send.js @@ -186,23 +186,23 @@ angular.module('copayApp.controllers').controller('SendController', }, 500); }; - $scope.deleteAddressBook = function(addressBook) { - var w = $rootScope.wallet; - $timeout(function() { - var errorMsg; - try { - w.deleteAddressBook(addressBook); - } catch (e) { - errorMsg = e.message; - } + $scope.signAddressBook = {}; - if (errorMsg) { - notification.error('Error', errorMsg); - } else { - notification.success('Success', 'Entry removed successfully'); - } - $rootScope.$digest(); - }, 500); + $scope.checkSignAddressBook = function(key) { + if (key) { + $timeout(function() { + var w = $rootScope.wallet; + var sign = w.verifySignAddressBook(key); + $scope.signAddressBook[key] = sign; + }, 10); + } + }; + + $scope.toggleAddressBookEntry = function(key) { + if (key) { + var w = $rootScope.wallet; + w.toggleAddressBookEntry(key); + } }; $scope.copyAddress = function(address) { @@ -250,11 +250,11 @@ angular.module('copayApp.controllers').controller('SendController', if (errorMsg) { notification.error('Error', errorMsg); } else { + $scope.checkSignAddressBook(entry.address); notification.success('Success', 'New entry has been created'); } $rootScope.$digest(); }, 500); - $anchorScroll(); // reset fields $scope.newaddress = $scope.newlabel = null; }); diff --git a/js/models/core/Wallet.js b/js/models/core/Wallet.js index fec67735b..ece26ad2a 100644 --- a/js/models/core/Wallet.js +++ b/js/models/core/Wallet.js @@ -146,11 +146,6 @@ Wallet.prototype._handleAddressBook = function(senderId, data, isInbound) { if (!this.addressBook[key]) { this.addressBook[key] = rcv[key]; hasChange = true; - } else { - if (rcv[key].createdTs > this.addressBook[key].createdTs) { - this.addressBook[key] = rcv[key]; - hasChange = true; - } } } if (hasChange) { @@ -244,7 +239,6 @@ Wallet.prototype.getMyCopayerIdPriv = function() { return this.privateKey.getIdPriv(); //copayer idpriv is hex of a private key }; - Wallet.prototype.getSecret = function() { var pubkeybuf = new Buffer(this.getMyCopayerId(), 'hex'); var str = Base58Check.encode(pubkeybuf); @@ -838,21 +832,42 @@ Wallet.prototype._checkAddressBook = function(key) { Wallet.prototype.setAddressBook = function(key, label) { this._checkAddressBook(key); + var copayerId = this.getMyCopayerId(); + var ts = Date.now(); + var payload = { + address: key, + label: label, + copayerId: copayerId, + createdTs: ts + }; var addressbook = { - createdTs: Date.now(), - copayerId: this.getMyCopayerId(), - label: label + hidden: false, + createdTs: ts, + copayerId: copayerId, + label: label, + signature: this.signObject(payload) }; this.addressBook[key] = addressbook; this.sendAddressBook(); this.store(); }; -Wallet.prototype.deleteAddressBook = function(key) { +Wallet.prototype.verifySignAddressBook = function(key) { if (key) { - this.addressBook[key].copayerId = -1; - this.addressBook[key].createdTs = Date.now(); - this.sendAddressBook(); + var signature = this.addressBook[key].signature; + var payload = { + address: key, + label: this.addressBook[key].label, + copayerId: this.addressBook[key].copayerId, + createdTs: this.addressBook[key].createdTs + }; + return this.verifySignedObject(payload, signature); + } +} + +Wallet.prototype.toggleAddressBookEntry = function(key) { + if (key) { + this.addressBook[key].hidden = !this.addressBook[key].hidden; this.store(); } }; @@ -867,4 +882,19 @@ Wallet.prototype.offerBackup = function() { this.store(); }; +Wallet.prototype.signObject = function(payload) { + var key = new bitcore.Key(); + key.private = new Buffer(this.getMyCopayerIdPriv(), 'hex'); + key.regenerateSync(); + var sign = bitcore.Message.sign(JSON.stringify(payload), key); + return sign.toString('hex'); +} + +Wallet.prototype.verifySignedObject = function(payload, signature) { + var pubkey = new Buffer(this.getMyCopayerId(), 'hex'); + var sign = new Buffer(signature, 'hex'); + var v = bitcore.Message.verifyWithPubKey(pubkey, JSON.stringify(payload), sign); + return v; +} + module.exports = require('soop')(Wallet); diff --git a/test/test.Wallet.js b/test/test.Wallet.js index 20dd4b6ba..c172a1e93 100644 --- a/test/test.Wallet.js +++ b/test/test.Wallet.js @@ -78,11 +78,13 @@ describe('Wallet model', function() { label: 'John', copayerId: '026a55261b7c898fff760ebe14fd22a71892295f3b49e0ca66727bc0a0d7f94d03', createdTs: 1403102115, + hidden: false }, '2MtP8WyiwG7ZdVWM96CVsk2M1N8zyfiVQsY': { label: 'Jennifer', copayerId: '032991f836543a492bd6d0bb112552bfc7c5f3b7d5388fcbcbf2fbb893b44770d7', createdTs: 1403103115, + hidden: false } }; @@ -760,61 +762,113 @@ describe('Wallet model', function() { done(); }); - var contacts = [{ - label: 'Charles', - address: '2N8pJWpXCAxmNLHKVEhz3TtTcYCtHd43xWU ', - }, { - label: 'Linda', - address: '2N4Zq92goYGrf5J4F4SZZq7jnPYbCiyRYT2 ', - }]; + describe('#AddressBook', function() { + var contacts = [{ + label: 'Charles', + address: '2N8pJWpXCAxmNLHKVEhz3TtTcYCtHd43xWU ', + }, { + label: 'Linda', + address: '2N4Zq92goYGrf5J4F4SZZq7jnPYbCiyRYT2 ', + }]; - it('should create new entry for address book', function() { - var w = createW(); - contacts.forEach(function(c) { - w.setAddressBook(c.address, c.label); + it('should create new entry for address book', function() { + var w = createW(); + contacts.forEach(function(c) { + w.setAddressBook(c.address, c.label); + }); + Object.keys(w.addressBook).length.should.equal(4); }); - Object.keys(w.addressBook).length.should.equal(4); - }); - it('should fail if create a duplicate address', function() { - var w = createW(); - w.setAddressBook(contacts[0].address, contacts[0].label); - (function() { + it('should fail if create a duplicate address', function() { + var w = createW(); w.setAddressBook(contacts[0].address, contacts[0].label); - }).should. - throw(); - }); - - it('should delete an entry for address book', function() { - var w = createW(); - contacts.forEach(function(c) { - w.setAddressBook(c.address, c.label); + (function() { + w.setAddressBook(contacts[0].address, contacts[0].label); + }).should. + throw(); + }); + + it('should show/hide everywhere', function() { + var w = createW(); + var key = '2NFR2kzH9NUdp8vsXTB4wWQtTtzhpKxsyoJ'; + w.toggleAddressBookEntry(key); + w.addressBook[key].hidden.should.equal(true); + w.toggleAddressBookEntry(key); + w.addressBook[key].hidden.should.equal(false); + }); + + it('handle network addressBook correctly', function() { + var w = createW(); + var data = { + walletId: w.id, + addressBook: { + 'msj42CCGruhRsFrGATiUuh25dtxYtnpbTx': { + label: 'Faucet', + copayerId: '026a55261b7c898fff760ebe14fd22a71892295f3b49e0ca66727bc0a0d7f94d03', + createdTs: 1403102115, + } + }, + type: 'addressbook' + }; + Object.keys(w.addressBook).length.should.equal(2); + // New address + w._handleAddressBook('senderID', data, true); + Object.keys(w.addressBook).length.should.equal(3); + // Existent address + w._handleAddressBook('senderID', data, true); + Object.keys(w.addressBook).length.should.equal(3); + }); + + it('should return signed object', function() { + var w = createW(); + var payload = { + address: 'msj42CCGruhRsFrGATiUuh25dtxYtnpbTx', + label: 'Faucet', + copayerId: '026a55261b7c898fff760ebe14fd22a71892295f3b49e0ca66727bc0a0d7f94d03', + createdTs: 1403102115 + }; + should.exist(w.signObject(payload)); + }); + + it('should verify signed object', function() { + var w = createW(); + var data = { + address: 'msj42CCGruhRsFrGATiUuh25dtxYtnpbTx', + label: 'Faucet', + copayerId: '026a55261b7c898fff760ebe14fd22a71892295f3b49e0ca66727bc0a0d7f94d03', + createdTs: 1403102115, + }; + var signature = w.signObject(data); + + w.verifySignedObject(data, signature).should.equal(true); + data.label = 'Another'; + w.verifySignedObject(data, signature).should.equal(false); + }); + + it('should verify signed addressbook entry', function() { + var w = createW(); + var key = 'msj42CCGruhRsFrGATiUuh25dtxYtnpbTx'; + var payload = { + address: key, + label: 'Faucet', + copayerId: '026a55261b7c898fff760ebe14fd22a71892295f3b49e0ca66727bc0a0d7f94d03', + createdTs: 1403102115, + }; + + var addressbook = { + hidden: false, + createdTs: payload.createdTs, + copayerId: payload.copayerId, + label: payload.label, + signature: w.signObject(payload) + }; + w.addressBook[key] = addressbook; + + w.verifySignAddressBook(key).should.equal(true); + w.addressBook[key].label = 'Another'; + w.verifySignAddressBook(key).should.equal(false); }); - Object.keys(w.addressBook).length.should.equal(4); - var key = contacts[0].address; - w.deleteAddressBook(key); - w.addressBook[key].copayerId.should.equal(-1); - }); - it('handle network addressBook correctly', function() { - var w = createW(); - var data = { - walletId: w.id, - addressBook: { - 'msj42CCGruhRsFrGATiUuh25dtxYtnpbTx': { - label: 'Faucet', - copayerId: '026a55261b7c898fff760ebe14fd22a71892295f3b49e0ca66727bc0a0d7f94d03', - createdTs: 1403102115, - } - }, - type: 'addressbook' - }; - Object.keys(w.addressBook).length.should.equal(2); - w._handleAddressBook('senderID', data, true); - Object.keys(w.addressBook).length.should.equal(3); - data.addressBook['msj42CCGruhRsFrGATiUuh25dtxYtnpbTx'].createdTs = 1403102215; - w._handleAddressBook('senderID', data, true); - Object.keys(w.addressBook).length.should.equal(3); }); it('#getNetworkName', function() { From c83e0c73da06abfb29eb6be473e39b603b658ce4 Mon Sep 17 00:00:00 2001 From: Gustavo Cortez Date: Mon, 7 Jul 2014 01:57:25 -0300 Subject: [PATCH 2/9] Delete entry with a wrong signature --- js/controllers/send.js | 3 +++ js/models/core/Wallet.js | 8 +++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/js/controllers/send.js b/js/controllers/send.js index a09e76010..ed679e6b1 100644 --- a/js/controllers/send.js +++ b/js/controllers/send.js @@ -194,6 +194,9 @@ angular.module('copayApp.controllers').controller('SendController', var w = $rootScope.wallet; var sign = w.verifySignAddressBook(key); $scope.signAddressBook[key] = sign; + if (!sign) { + notification.error('Wrong signature', 'Entry of Addressbooks was deleted'); + } }, 10); } }; diff --git a/js/models/core/Wallet.js b/js/models/core/Wallet.js index ece26ad2a..486a9ad2c 100644 --- a/js/models/core/Wallet.js +++ b/js/models/core/Wallet.js @@ -861,7 +861,13 @@ Wallet.prototype.verifySignAddressBook = function(key) { copayerId: this.addressBook[key].copayerId, createdTs: this.addressBook[key].createdTs }; - return this.verifySignedObject(payload, signature); + var sign = this.verifySignedObject(payload, signature); + if (!sign) { + // remove wrong signed entry + delete this.addressBook[key]; + this.store(); + } + return sign; } } From 2ad4aee2d627c12064973e368ef744e6561c77dd Mon Sep 17 00:00:00 2001 From: Gustavo Cortez Date: Mon, 7 Jul 2014 02:21:29 -0300 Subject: [PATCH 3/9] Show only entry I want. Hidden anywhere. --- css/main.css | 7 +++++++ index.html | 10 +++++----- js/directives.js | 2 +- 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/css/main.css b/css/main.css index 2aeac8172..ef96e3dc6 100644 --- a/css/main.css +++ b/css/main.css @@ -640,4 +640,11 @@ ul.pagination li.current a:hover, ul.pagination li.current a:focus { display: block; margin-bottom: 1rem; } +.addressbook-disabled td { + color: #ccc; + text-decoration: line-through; +} +.addressbook-disabled a { + color: #7A9FB6; +} diff --git a/index.html b/index.html index 6455f73b7..8d0085f87 100644 --- a/index.html +++ b/index.html @@ -742,7 +742,7 @@ -
+

Address Book

Empty. Create an alias for your addresses

@@ -753,18 +753,18 @@ Address Creator Date - Signature Hidden - + {{info.label}} {{addr}} {{$root.wallet.publicKeyRing.nicknameForCopayer(info.copayerId)}} - {{signAddressBook[addr]}} {{info.hidden}} diff --git a/js/directives.js b/js/directives.js index 6ee8e901b..62a8d0387 100644 --- a/js/directives.js +++ b/js/directives.js @@ -129,7 +129,7 @@ angular.module('copayApp.directives') var address = attrs.address; var contact = scope.wallet.addressBook[address]; - if (contact) { + if (contact && !contact.hidden) { element.append(contact.label); attrs['tooltip'] = attrs.address; } else { From 7cdf559fd7aae425eaea17a905ee493525800e82 Mon Sep 17 00:00:00 2001 From: Gustavo Cortez Date: Mon, 7 Jul 2014 10:58:43 -0300 Subject: [PATCH 4/9] Fixes typos: Matias's suggestions. Added more tests --- js/controllers/send.js | 12 ++++++------ js/models/core/Wallet.js | 22 ++++++++++++++-------- test/test.Wallet.js | 16 +++++++++++----- 3 files changed, 31 insertions(+), 19 deletions(-) diff --git a/js/controllers/send.js b/js/controllers/send.js index ed679e6b1..dc9518351 100644 --- a/js/controllers/send.js +++ b/js/controllers/send.js @@ -186,15 +186,15 @@ angular.module('copayApp.controllers').controller('SendController', }, 500); }; - $scope.signAddressBook = {}; + $scope.addressbook = {}; - $scope.checkSignAddressBook = function(key) { + $scope.verifyAddressbookSignature = function(key) { if (key) { $timeout(function() { var w = $rootScope.wallet; - var sign = w.verifySignAddressBook(key); - $scope.signAddressBook[key] = sign; - if (!sign) { + var signature = w.verfifyAddressbookSignature(key); + $scope.addressbook[key] = signature; + if (!signature) { notification.error('Wrong signature', 'Entry of Addressbooks was deleted'); } }, 10); @@ -253,7 +253,7 @@ angular.module('copayApp.controllers').controller('SendController', if (errorMsg) { notification.error('Error', errorMsg); } else { - $scope.checkSignAddressBook(entry.address); + $scope.verifyAddressbookSignature(entry.address); notification.success('Success', 'New entry has been created'); } $rootScope.$digest(); diff --git a/js/models/core/Wallet.js b/js/models/core/Wallet.js index 486a9ad2c..7bd375377 100644 --- a/js/models/core/Wallet.js +++ b/js/models/core/Wallet.js @@ -840,19 +840,19 @@ Wallet.prototype.setAddressBook = function(key, label) { copayerId: copayerId, createdTs: ts }; - var addressbook = { + var newEntry = { hidden: false, createdTs: ts, copayerId: copayerId, label: label, - signature: this.signObject(payload) + signature: this.signJson(payload) }; - this.addressBook[key] = addressbook; + this.addressBook[key] = newEntry; this.sendAddressBook(); this.store(); }; -Wallet.prototype.verifySignAddressBook = function(key) { +Wallet.prototype.verfifyAddressbookSignature = function(key) { if (key) { var signature = this.addressBook[key].signature; var payload = { @@ -861,13 +861,16 @@ Wallet.prototype.verifySignAddressBook = function(key) { copayerId: this.addressBook[key].copayerId, createdTs: this.addressBook[key].createdTs }; - var sign = this.verifySignedObject(payload, signature); - if (!sign) { + var isVerified = this.verifySignedObject(payload, signature); + if (!isVerified) { // remove wrong signed entry delete this.addressBook[key]; this.store(); } - return sign; + return isVerified; + } + else { + throw new Error('Key is required'); } } @@ -876,6 +879,9 @@ Wallet.prototype.toggleAddressBookEntry = function(key) { this.addressBook[key].hidden = !this.addressBook[key].hidden; this.store(); } + else { + throw new Error('Key is required'); + } }; Wallet.prototype.isReady = function() { @@ -888,7 +894,7 @@ Wallet.prototype.offerBackup = function() { this.store(); }; -Wallet.prototype.signObject = function(payload) { +Wallet.prototype.signJson = function(payload) { var key = new bitcore.Key(); key.private = new Buffer(this.getMyCopayerIdPriv(), 'hex'); key.regenerateSync(); diff --git a/test/test.Wallet.js b/test/test.Wallet.js index c172a1e93..d42aa6707 100644 --- a/test/test.Wallet.js +++ b/test/test.Wallet.js @@ -795,6 +795,9 @@ describe('Wallet model', function() { w.addressBook[key].hidden.should.equal(true); w.toggleAddressBookEntry(key); w.addressBook[key].hidden.should.equal(false); + (function() { + w.toggleAddressBookEntry(); + }).should.throw(); }); it('handle network addressBook correctly', function() { @@ -827,7 +830,7 @@ describe('Wallet model', function() { copayerId: '026a55261b7c898fff760ebe14fd22a71892295f3b49e0ca66727bc0a0d7f94d03', createdTs: 1403102115 }; - should.exist(w.signObject(payload)); + should.exist(w.signJson(payload)); }); it('should verify signed object', function() { @@ -838,7 +841,7 @@ describe('Wallet model', function() { copayerId: '026a55261b7c898fff760ebe14fd22a71892295f3b49e0ca66727bc0a0d7f94d03', createdTs: 1403102115, }; - var signature = w.signObject(data); + var signature = w.signJson(data); w.verifySignedObject(data, signature).should.equal(true); data.label = 'Another'; @@ -860,13 +863,16 @@ describe('Wallet model', function() { createdTs: payload.createdTs, copayerId: payload.copayerId, label: payload.label, - signature: w.signObject(payload) + signature: w.signJson(payload) }; w.addressBook[key] = addressbook; - w.verifySignAddressBook(key).should.equal(true); + w.verfifyAddressbookSignature(key).should.equal(true); w.addressBook[key].label = 'Another'; - w.verifySignAddressBook(key).should.equal(false); + w.verfifyAddressbookSignature(key).should.equal(false); + (function() { + w.verfifyAddressbookSignature(); + }).should.throw(); }); }); From ac2eda367055bb0e290d75ec3a0ff2bf040c6953 Mon Sep 17 00:00:00 2001 From: Gustavo Cortez Date: Mon, 7 Jul 2014 14:53:34 -0300 Subject: [PATCH 5/9] Fixes typos and re-factory throw errors --- js/controllers/send.js | 25 +++++++++--------------- js/models/core/Wallet.js | 42 ++++++++++++++++------------------------ 2 files changed, 26 insertions(+), 41 deletions(-) diff --git a/js/controllers/send.js b/js/controllers/send.js index dc9518351..914e6e54e 100644 --- a/js/controllers/send.js +++ b/js/controllers/send.js @@ -186,26 +186,19 @@ angular.module('copayApp.controllers').controller('SendController', }, 500); }; - $scope.addressbook = {}; - $scope.verifyAddressbookSignature = function(key) { - if (key) { - $timeout(function() { - var w = $rootScope.wallet; - var signature = w.verfifyAddressbookSignature(key); - $scope.addressbook[key] = signature; - if (!signature) { - notification.error('Wrong signature', 'Entry of Addressbooks was deleted'); - } - }, 10); - } + $timeout(function() { + var w = $rootScope.wallet; + var isValid = w.verfifyAddressbookSignature(key); + if (!isValid) { + notification.error('Wrong signature', 'Entry of Addressbooks was deleted'); + } + }, 10); }; $scope.toggleAddressBookEntry = function(key) { - if (key) { - var w = $rootScope.wallet; - w.toggleAddressBookEntry(key); - } + var w = $rootScope.wallet; + w.toggleAddressBookEntry(key); }; $scope.copyAddress = function(address) { diff --git a/js/models/core/Wallet.js b/js/models/core/Wallet.js index 7bd375377..910b7d5ad 100644 --- a/js/models/core/Wallet.js +++ b/js/models/core/Wallet.js @@ -853,35 +853,27 @@ Wallet.prototype.setAddressBook = function(key, label) { }; Wallet.prototype.verfifyAddressbookSignature = function(key) { - if (key) { - var signature = this.addressBook[key].signature; - var payload = { - address: key, - label: this.addressBook[key].label, - copayerId: this.addressBook[key].copayerId, - createdTs: this.addressBook[key].createdTs - }; - var isVerified = this.verifySignedObject(payload, signature); - if (!isVerified) { - // remove wrong signed entry - delete this.addressBook[key]; - this.store(); - } - return isVerified; - } - else { - throw new Error('Key is required'); + if (!key) throw new Error('Key is required'); + var signature = this.addressBook[key].signature; + var payload = { + address: key, + label: this.addressBook[key].label, + copayerId: this.addressBook[key].copayerId, + createdTs: this.addressBook[key].createdTs + }; + var isVerified = this.verifySignedObject(payload, signature); + if (!isVerified) { + // remove wrong signed entry + delete this.addressBook[key]; + this.store(); } + return isVerified; } Wallet.prototype.toggleAddressBookEntry = function(key) { - if (key) { - this.addressBook[key].hidden = !this.addressBook[key].hidden; - this.store(); - } - else { - throw new Error('Key is required'); - } + if (!key) throw new Error('Key is required'); + this.addressBook[key].hidden = !this.addressBook[key].hidden; + this.store(); }; Wallet.prototype.isReady = function() { From 0931024e23fec40573165c367640669441c0505e Mon Sep 17 00:00:00 2001 From: Gustavo Cortez Date: Mon, 7 Jul 2014 17:38:17 -0300 Subject: [PATCH 6/9] Fixes: verify addressbook method --- index.html | 3 +-- js/controllers/send.js | 13 +------------ js/models/core/Wallet.js | 11 ++++++----- test/test.Wallet.js | 35 +++++++++++++++++++++++++---------- 4 files changed, 33 insertions(+), 29 deletions(-) diff --git a/index.html b/index.html index 8d0085f87..40bb5f18c 100644 --- a/index.html +++ b/index.html @@ -758,8 +758,7 @@ {{info.label}} {{addr}} diff --git a/js/controllers/send.js b/js/controllers/send.js index 914e6e54e..e068ef0b4 100644 --- a/js/controllers/send.js +++ b/js/controllers/send.js @@ -14,7 +14,7 @@ angular.module('copayApp.controllers').controller('SendController', var flag; if (w) { for (var k in w.addressBook) { - if (w.addressBook[k].copayerId != -1) { + if (w.addressBook[k]) { flag = true; break; } @@ -186,16 +186,6 @@ angular.module('copayApp.controllers').controller('SendController', }, 500); }; - $scope.verifyAddressbookSignature = function(key) { - $timeout(function() { - var w = $rootScope.wallet; - var isValid = w.verfifyAddressbookSignature(key); - if (!isValid) { - notification.error('Wrong signature', 'Entry of Addressbooks was deleted'); - } - }, 10); - }; - $scope.toggleAddressBookEntry = function(key) { var w = $rootScope.wallet; w.toggleAddressBookEntry(key); @@ -246,7 +236,6 @@ angular.module('copayApp.controllers').controller('SendController', if (errorMsg) { notification.error('Error', errorMsg); } else { - $scope.verifyAddressbookSignature(entry.address); notification.success('Success', 'New entry has been created'); } $rootScope.$digest(); diff --git a/js/models/core/Wallet.js b/js/models/core/Wallet.js index 910b7d5ad..4265b785d 100644 --- a/js/models/core/Wallet.js +++ b/js/models/core/Wallet.js @@ -145,6 +145,7 @@ Wallet.prototype._handleAddressBook = function(senderId, data, isInbound) { for (var key in rcv) { if (!this.addressBook[key]) { this.addressBook[key] = rcv[key]; + var isVerified = this.verifyAddressbookSignature(senderId, key); hasChange = true; } } @@ -852,8 +853,8 @@ Wallet.prototype.setAddressBook = function(key, label) { this.store(); }; -Wallet.prototype.verfifyAddressbookSignature = function(key) { - if (!key) throw new Error('Key is required'); +Wallet.prototype.verifyAddressbookSignature = function(senderId, key) { + if (!key) throw new Error('Keys are required'); var signature = this.addressBook[key].signature; var payload = { address: key, @@ -861,7 +862,7 @@ Wallet.prototype.verfifyAddressbookSignature = function(key) { copayerId: this.addressBook[key].copayerId, createdTs: this.addressBook[key].createdTs }; - var isVerified = this.verifySignedObject(payload, signature); + var isVerified = this.verifySignedJson(senderId, payload, signature); if (!isVerified) { // remove wrong signed entry delete this.addressBook[key]; @@ -894,8 +895,8 @@ Wallet.prototype.signJson = function(payload) { return sign.toString('hex'); } -Wallet.prototype.verifySignedObject = function(payload, signature) { - var pubkey = new Buffer(this.getMyCopayerId(), 'hex'); +Wallet.prototype.verifySignedJson = function(senderId, payload, signature) { + var pubkey = new Buffer(senderId, 'hex'); var sign = new Buffer(signature, 'hex'); var v = bitcore.Message.verifyWithPubKey(pubkey, JSON.stringify(payload), sign); return v; diff --git a/test/test.Wallet.js b/test/test.Wallet.js index d42aa6707..cb3f0c280 100644 --- a/test/test.Wallet.js +++ b/test/test.Wallet.js @@ -802,23 +802,36 @@ describe('Wallet model', function() { it('handle network addressBook correctly', function() { var w = createW(); + var pk = '026a55261b7c898fff760ebe14fd22a71892295f3b49e0ca66727bc0a0d7f94d03'; var data = { walletId: w.id, addressBook: { 'msj42CCGruhRsFrGATiUuh25dtxYtnpbTx': { label: 'Faucet', - copayerId: '026a55261b7c898fff760ebe14fd22a71892295f3b49e0ca66727bc0a0d7f94d03', + copayerId: pk, createdTs: 1403102115, } }, type: 'addressbook' }; + var payload = { + address: 'msj42CCGruhRsFrGATiUuh25dtxYtnpbTx', + label: 'Faucet', + copayerId: pk, + createdTs: 1403102115, + }; + data.addressBook['msj42CCGruhRsFrGATiUuh25dtxYtnpbTx'].signature = w.signJson(payload); + Object.keys(w.addressBook).length.should.equal(2); // New address - w._handleAddressBook('senderID', data, true); + w._handleAddressBook(pk, data, true); Object.keys(w.addressBook).length.should.equal(3); // Existent address - w._handleAddressBook('senderID', data, true); + w._handleAddressBook(pk, data, true); + Object.keys(w.addressBook).length.should.equal(3); + // Address with wrong signature (do nothing) + data.addressBook['msj42CCGruhRsFrGATiUuh25dtxYtnpbTx'].label = 'Bad' + w._handleAddressBook(pk, data, true); Object.keys(w.addressBook).length.should.equal(3); }); @@ -835,26 +848,28 @@ describe('Wallet model', function() { it('should verify signed object', function() { var w = createW(); + var pk = '026a55261b7c898fff760ebe14fd22a71892295f3b49e0ca66727bc0a0d7f94d03'; var data = { address: 'msj42CCGruhRsFrGATiUuh25dtxYtnpbTx', label: 'Faucet', - copayerId: '026a55261b7c898fff760ebe14fd22a71892295f3b49e0ca66727bc0a0d7f94d03', + copayerId: pk, createdTs: 1403102115, }; var signature = w.signJson(data); - w.verifySignedObject(data, signature).should.equal(true); + w.verifySignedJson(pk, data, signature).should.equal(true); data.label = 'Another'; - w.verifySignedObject(data, signature).should.equal(false); + w.verifySignedJson(pk, data, signature).should.equal(false); }); it('should verify signed addressbook entry', function() { var w = createW(); var key = 'msj42CCGruhRsFrGATiUuh25dtxYtnpbTx'; + var pk = '026a55261b7c898fff760ebe14fd22a71892295f3b49e0ca66727bc0a0d7f94d03'; var payload = { address: key, label: 'Faucet', - copayerId: '026a55261b7c898fff760ebe14fd22a71892295f3b49e0ca66727bc0a0d7f94d03', + copayerId: pk, createdTs: 1403102115, }; @@ -867,11 +882,11 @@ describe('Wallet model', function() { }; w.addressBook[key] = addressbook; - w.verfifyAddressbookSignature(key).should.equal(true); + w.verifyAddressbookSignature(pk, key).should.equal(true); w.addressBook[key].label = 'Another'; - w.verfifyAddressbookSignature(key).should.equal(false); + w.verifyAddressbookSignature(pk, key).should.equal(false); (function() { - w.verfifyAddressbookSignature(); + w.verifyAddressbookSignature(); }).should.throw(); }); From c00deb25f93d8d6a77bf96049caad43925069568 Mon Sep 17 00:00:00 2001 From: Gustavo Cortez Date: Mon, 7 Jul 2014 19:12:34 -0300 Subject: [PATCH 7/9] Fix tests --- index.html | 2 +- test/test.Wallet.js | 91 +++++++++++++++++++-------------------------- 2 files changed, 39 insertions(+), 54 deletions(-) diff --git a/index.html b/index.html index c98c59fb6..c81c687e0 100644 --- a/index.html +++ b/index.html @@ -779,7 +779,7 @@ {{info.label}} {{addr}} diff --git a/test/test.Wallet.js b/test/test.Wallet.js index bc4946e70..fdd7355b7 100644 --- a/test/test.Wallet.js +++ b/test/test.Wallet.js @@ -826,36 +826,26 @@ describe('Wallet model', function() { it('handle network addressBook correctly', function() { var w = createW(); - var pk = '026a55261b7c898fff760ebe14fd22a71892295f3b49e0ca66727bc0a0d7f94d03'; + var data = { - walletId: w.id, + type: "addressbook", addressBook: { - 'msj42CCGruhRsFrGATiUuh25dtxYtnpbTx': { - label: 'Faucet', - copayerId: pk, - createdTs: 1403102115, + "3Ae1ieAYNXznm7NkowoFTu5MkzgrTfDz8Z" : { + copayerId: "03baa45498fee1045fa8f91a2913f638dc3979b455498924d3cf1a11303c679cdb", + createdTs: 1404769393509, + hidden: false, + label: "adsf", + signature: "3046022100d4cdefef66ab8cea26031d5df03a38fc9ec9b09b0fb31d3a26b6e204918e9e78022100ecdbbd889ec99ea1bfd471253487af07a7fa7c0ac6012ca56e10e66f335e4586" } - }, - type: 'addressbook' + }, + walletId: "11d23e638ed84c06", + isBroadcast: 1 }; - var payload = { - address: 'msj42CCGruhRsFrGATiUuh25dtxYtnpbTx', - label: 'Faucet', - copayerId: pk, - createdTs: 1403102115, - }; - data.addressBook['msj42CCGruhRsFrGATiUuh25dtxYtnpbTx'].signature = w.signJson(payload); - + + var senderId = "03baa45498fee1045fa8f91a2913f638dc3979b455498924d3cf1a11303c679cdb"; + Object.keys(w.addressBook).length.should.equal(2); - // New address - w._handleAddressBook(pk, data, true); - Object.keys(w.addressBook).length.should.equal(3); - // Existent address - w._handleAddressBook(pk, data, true); - Object.keys(w.addressBook).length.should.equal(3); - // Address with wrong signature (do nothing) - data.addressBook['msj42CCGruhRsFrGATiUuh25dtxYtnpbTx'].label = 'Bad' - w._handleAddressBook(pk, data, true); + w._handleAddressBook(senderId, data, true); Object.keys(w.addressBook).length.should.equal(3); }); @@ -872,43 +862,38 @@ describe('Wallet model', function() { it('should verify signed object', function() { var w = createW(); - var pk = '026a55261b7c898fff760ebe14fd22a71892295f3b49e0ca66727bc0a0d7f94d03'; - var data = { - address: 'msj42CCGruhRsFrGATiUuh25dtxYtnpbTx', - label: 'Faucet', - copayerId: pk, - createdTs: 1403102115, - }; - var signature = w.signJson(data); - w.verifySignedJson(pk, data, signature).should.equal(true); - data.label = 'Another'; - w.verifySignedJson(pk, data, signature).should.equal(false); + var payload = { + address: "3Ae1ieAYNXznm7NkowoFTu5MkzgrTfDz8Z", + label: "adsf", + copayerId: "03baa45498fee1045fa8f91a2913f638dc3979b455498924d3cf1a11303c679cdb", + createdTs: 1404769393509 + } + + var signature = "3046022100d4cdefef66ab8cea26031d5df03a38fc9ec9b09b0fb31d3a26b6e204918e9e78022100ecdbbd889ec99ea1bfd471253487af07a7fa7c0ac6012ca56e10e66f335e4586"; + + var pubKey = "03baa45498fee1045fa8f91a2913f638dc3979b455498924d3cf1a11303c679cdb"; + + w.verifySignedJson(pubKey, payload, signature).should.equal(true); + payload.label = 'Another'; + w.verifySignedJson(pubKey, payload, signature).should.equal(false); }); it('should verify signed addressbook entry', function() { var w = createW(); - var key = 'msj42CCGruhRsFrGATiUuh25dtxYtnpbTx'; - var pk = '026a55261b7c898fff760ebe14fd22a71892295f3b49e0ca66727bc0a0d7f94d03'; - var payload = { - address: key, - label: 'Faucet', - copayerId: pk, - createdTs: 1403102115, - }; - - var addressbook = { + var key = "3Ae1ieAYNXznm7NkowoFTu5MkzgrTfDz8Z"; + var pubKey = "03baa45498fee1045fa8f91a2913f638dc3979b455498924d3cf1a11303c679cdb"; + w.addressBook[key] = { + copayerId: pubKey, + createdTs: 1404769393509, hidden: false, - createdTs: payload.createdTs, - copayerId: payload.copayerId, - label: payload.label, - signature: w.signJson(payload) + label: "adsf", + signature: "3046022100d4cdefef66ab8cea26031d5df03a38fc9ec9b09b0fb31d3a26b6e204918e9e78022100ecdbbd889ec99ea1bfd471253487af07a7fa7c0ac6012ca56e10e66f335e4586" }; - w.addressBook[key] = addressbook; - w.verifyAddressbookSignature(pk, key).should.equal(true); + w.verifyAddressbookSignature(pubKey, key).should.equal(true); w.addressBook[key].label = 'Another'; - w.verifyAddressbookSignature(pk, key).should.equal(false); + w.verifyAddressbookSignature(pubKey, key).should.equal(false); (function() { w.verifyAddressbookSignature(); }).should.throw(); From 14cea0362f3efd4cd5806e529f03d808fbba3622 Mon Sep 17 00:00:00 2001 From: Gustavo Cortez Date: Mon, 7 Jul 2014 20:01:50 -0300 Subject: [PATCH 8/9] Fixes and re-factory --- js/models/core/Wallet.js | 26 +++++++++++--------------- test/test.Wallet.js | 6 +++--- 2 files changed, 14 insertions(+), 18 deletions(-) diff --git a/js/models/core/Wallet.js b/js/models/core/Wallet.js index dd6d312e6..7e892dd42 100644 --- a/js/models/core/Wallet.js +++ b/js/models/core/Wallet.js @@ -140,9 +140,11 @@ Wallet.prototype._handleAddressBook = function(senderId, data, isInbound) { var hasChange; for (var key in rcv) { if (!this.addressBook[key]) { - this.addressBook[key] = rcv[key]; - var isVerified = this.verifyAddressbookSignature(senderId, key); - hasChange = true; + var isVerified = this.verifyAddressbookEntry(rcv[key], senderId, key); + if (isVerified) { + this.addressBook[key] = rcv[key]; + hasChange = true; + } } } if (hasChange) { @@ -854,22 +856,16 @@ Wallet.prototype.setAddressBook = function(key, label) { this.store(); }; -Wallet.prototype.verifyAddressbookSignature = function(senderId, key) { +Wallet.prototype.verifyAddressbookEntry = function(rcvEntry, senderId, key) { if (!key) throw new Error('Keys are required'); - var signature = this.addressBook[key].signature; + var signature = rcvEntry.signature; var payload = { address: key, - label: this.addressBook[key].label, - copayerId: this.addressBook[key].copayerId, - createdTs: this.addressBook[key].createdTs + label: rcvEntry.label, + copayerId: rcvEntry.copayerId, + createdTs: rcvEntry.createdTs }; - var isVerified = this.verifySignedJson(senderId, payload, signature); - if (!isVerified) { - // remove wrong signed entry - delete this.addressBook[key]; - this.store(); - } - return isVerified; + return this.verifySignedJson(senderId, payload, signature); } Wallet.prototype.toggleAddressBookEntry = function(key) { diff --git a/test/test.Wallet.js b/test/test.Wallet.js index fdd7355b7..42991ed57 100644 --- a/test/test.Wallet.js +++ b/test/test.Wallet.js @@ -891,11 +891,11 @@ describe('Wallet model', function() { signature: "3046022100d4cdefef66ab8cea26031d5df03a38fc9ec9b09b0fb31d3a26b6e204918e9e78022100ecdbbd889ec99ea1bfd471253487af07a7fa7c0ac6012ca56e10e66f335e4586" }; - w.verifyAddressbookSignature(pubKey, key).should.equal(true); + w.verifyAddressbookEntry(w.addressBook[key], pubKey, key).should.equal(true); w.addressBook[key].label = 'Another'; - w.verifyAddressbookSignature(pubKey, key).should.equal(false); + w.verifyAddressbookEntry(w.addressBook[key], pubKey, key).should.equal(false); (function() { - w.verifyAddressbookSignature(); + w.verifyAddressbookEntry(); }).should.throw(); }); From b25a781add18800fc1eee4bb6149d048110c0676 Mon Sep 17 00:00:00 2001 From: Gustavo Cortez Date: Mon, 7 Jul 2014 20:25:25 -0300 Subject: [PATCH 9/9] . --- css/main.css | 3 +-- index.html | 5 +++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/css/main.css b/css/main.css index c1bf699b6..e3e9db981 100644 --- a/css/main.css +++ b/css/main.css @@ -647,9 +647,8 @@ ul.pagination li.current a:hover, ul.pagination li.current a:focus { } .addressbook-disabled td { color: #ccc; - text-decoration: line-through; } -.addressbook-disabled a { +.addressbook-disabled td a { color: #7A9FB6; } diff --git a/index.html b/index.html index c81c687e0..44bb9a939 100644 --- a/index.html +++ b/index.html @@ -774,7 +774,7 @@ Address Creator Date - Hidden + @@ -785,7 +785,8 @@ {{addr}} {{$root.wallet.publicKeyRing.nicknameForCopayer(info.copayerId)}} - {{info.hidden}} + {{info.hidden ? + 'Enable' : 'Disable'}}