From 6bf2a10fd21d2e31decabf10084ffad08c8b40ae Mon Sep 17 00:00:00 2001 From: Ivan Socolsky Date: Sun, 22 Feb 2015 01:35:25 -0300 Subject: [PATCH] base58 walletId in secret --- lib/client/api.js | 6 ++++- lib/model/notification.js | 3 ++- lib/model/txproposal.js | 2 +- lib/walletutils.js | 47 +++++++++++++++++++++++++---------- test/integration/clientApi.js | 16 ++++++++++-- 5 files changed, 56 insertions(+), 18 deletions(-) diff --git a/lib/client/api.js b/lib/client/api.js index 1caa8a8..c73448b 100644 --- a/lib/client/api.js +++ b/lib/client/api.js @@ -307,7 +307,11 @@ API.prototype.joinWallet = function(secret, copayerName, cb) { if (data) return cb('Storage already contains a wallet'); - var secretData = WalletUtils.fromSecret(secret); + try { + var secretData = WalletUtils.fromSecret(secret); + } catch (ex) { + return cb(ex); + } var data = self._initData(secretData.network, secretData.walletPrivKey); self._doJoinWallet(secretData.walletId, secretData.walletPrivKey, data.publicKeyRing[0], copayerName, function(err, wallet) { diff --git a/lib/model/notification.js b/lib/model/notification.js index 07b621f..18f94ec 100644 --- a/lib/model/notification.js +++ b/lib/model/notification.js @@ -1,3 +1,4 @@ +var _ = require('lodash'); var Uuid = require('uuid'); /* @@ -33,7 +34,7 @@ Notification.create = function(opts) { var now = Date.now(); x.createdOn = Math.floor(now / 1000); - x.id = ('00000000000000' + now).slice(-14) + ('0000' + opts.ticker || 0).slice(-4); + x.id = _.padLeft(now, 14, '0') + _.padLeft(opts.ticker || 0, 4, '0'); x.type = opts.type || 'general'; x.data = opts.data; diff --git a/lib/model/txproposal.js b/lib/model/txproposal.js index 3742b6a..e1a1b23 100644 --- a/lib/model/txproposal.js +++ b/lib/model/txproposal.js @@ -18,7 +18,7 @@ TxProposal.create = function(opts) { var now = Date.now(); x.createdOn = Math.floor(now / 1000); - x.id = ('00000000000000' + now).slice(-14) + Uuid.v4(); + x.id = _.padLeft(now, 14, '0') + Uuid.v4(); x.creatorId = opts.creatorId; x.toAddress = opts.toAddress; x.amount = opts.amount; diff --git a/lib/walletutils.js b/lib/walletutils.js index a5d151c..092e3ec 100644 --- a/lib/walletutils.js +++ b/lib/walletutils.js @@ -7,6 +7,7 @@ var Address = Bitcore.Address; var PrivateKey = Bitcore.PrivateKey; var PublicKey = Bitcore.PublicKey; var crypto = Bitcore.crypto; +var encoding = Bitcore.encoding; var HDPath = require('./hdpath'); var Utils = require('./utils'); @@ -32,10 +33,10 @@ WalletUtils.signMessage = function(text, privKey) { WalletUtils.accessFromData = function(data) { - if (data.xPrivKey) + if (data.xPrivKey) return 'full'; - - if (data.rwPrivKey) + + if (data.rwPrivKey) return 'readwrite'; return 'readonly'; @@ -84,22 +85,42 @@ WalletUtils.xPubToCopayerId = function(xpub) { }; WalletUtils.toSecret = function(walletId, walletPrivKey, network) { - return walletId + ':' + walletPrivKey.toWIF() + ':' + (network == 'testnet' ? 'T' : 'L'); + var widHex = new Buffer(walletId.replace(/-/g, ''), 'hex'); + widBase58 = new encoding.Base58(widHex).toString(); + return widBase58 + walletPrivKey.toWIF() + (network == 'testnet' ? 'T' : 'L'); }; WalletUtils.fromSecret = function(secret) { $.checkArgument(secret); - var secretSplit = secret.split(':'); - var walletId = secretSplit[0]; - var walletPrivKey = Bitcore.PrivateKey.fromString(secretSplit[1]); - var networkChar = secretSplit[2]; - - return { - walletId: walletId, - walletPrivKey: walletPrivKey, - network: networkChar == 'T' ? 'testnet' : 'livenet', + function split(str, indexes) { + var parts = []; + indexes.push(str.length); + var i = 0; + while (i < indexes.length) { + parts.push(str.substring(i == 0 ? 0 : indexes[i - 1], indexes[i])); + i++; + }; + return parts; }; + + try { + var secretSplit = split(secret, [22, 74]); + var widBase58 = secretSplit[0]; + var widHex = encoding.Base58.decode(widBase58).toString('hex'); + var walletId = split(widHex, [8, 12, 16, 20]).join('-'); + + var walletPrivKey = Bitcore.PrivateKey.fromString(secretSplit[1]); + var networkChar = secretSplit[2]; + + return { + walletId: walletId, + walletPrivKey: walletPrivKey, + network: networkChar == 'T' ? 'testnet' : 'livenet', + }; + } catch (ex) { + throw new Error('Invalid secret'); + } }; diff --git a/test/integration/clientApi.js b/test/integration/clientApi.js index 8d8c486..8782b3f 100644 --- a/test/integration/clientApi.js +++ b/test/integration/clientApi.js @@ -193,8 +193,20 @@ describe('client API ', function() { }); }); }); - it('should fail with a unknown secret', function(done) { - var oldSecret = '3f8e5acb-ceeb-4aae-134f-692d934e3b1c:L2gohj8s2fLKqVU5cQutAVGciutUxczFxLxxXHFsjzLh71ZjkFQQ:T'; + it('should fail with an invalid secret', function(done) { + // Invalid length + clients[0].joinWallet('dummy', 'copayer', function(err, result) { + err.message.should.contain('Invalid secret'); + // Right length, invalid char for base 58 + clients[0].joinWallet('lPU9zqUiQFRnt3sWBQ1pnPKx9xC3KD83jxhYVJbLABxn1qhdBfQ7dYtzQqNKpSrDWDqF261S1zT', 'copayer', function(err, result) { + err.message.should.contain('Invalid secret'); + done(); + }); + }); + }); + it('should fail with an unknown secret', function(done) { + // Unknown walletId + var oldSecret = 'VPU9zqUiQFRnt3sWBQ1pnPKx9xC3KD83jxhYVJbLABxn1qhdBfQ7dYtzQqNKpSrDWDqF261S1zT'; clients[0].joinWallet(oldSecret, 'copayer', function(err, result) { err.code.should.contain('BADREQUEST'); done();