supports multiple pubkeys per copayer
This commit is contained in:
parent
3122e9ba7c
commit
edc3bc6713
|
@ -151,16 +151,6 @@ ExpressApp.prototype.start = function(opts, cb) {
|
|||
});
|
||||
|
||||
|
||||
router.put('/v1/copayers', function(req, res) {
|
||||
getServerWithAuth(req, res, function(server) {
|
||||
server.replaceTemporaryRequestKey(req.body, function(err, result) {
|
||||
if (err) return returnError(err, res, req);
|
||||
res.json(result);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
router.get('/v1/wallets/', function(req, res) {
|
||||
getServerWithAuth(req, res, function(server) {
|
||||
var result = {};
|
||||
|
|
|
@ -17,11 +17,10 @@ function Copayer() {
|
|||
};
|
||||
|
||||
|
||||
// requestPubKey could be one or an array of keys
|
||||
Copayer.create = function(opts) {
|
||||
opts = opts || {};
|
||||
$.checkArgument(opts.xPubKey, 'Missing copayer extended public key');
|
||||
$.checkArgument(opts.requestPubKey, 'Missing copayer request public key');
|
||||
$.checkArgument(opts.requestPubKey || opts.requestPubKeys, 'Missing copayer request public key');
|
||||
|
||||
opts.copayerIndex = opts.copayerIndex || 0;
|
||||
|
||||
|
@ -32,12 +31,16 @@ Copayer.create = function(opts) {
|
|||
|
||||
x.id = WalletUtils.xPubToCopayerId(x.xPubKey);
|
||||
x.name = opts.name;
|
||||
x.signature = opts.signature; // So third parties can check independently
|
||||
x.requestPubKey = opts.requestPubKey;
|
||||
|
||||
if (!x.requestPubKeys) {
|
||||
x.requestPubKeys = [{
|
||||
key: opts.requestPubKey,
|
||||
signature: opts.signature,
|
||||
}];
|
||||
}
|
||||
x.addressManager = AddressManager.create({
|
||||
copayerIndex: opts.copayerIndex
|
||||
});
|
||||
x.isTemporaryRequestKey = opts.isTemporaryRequestKey || false;
|
||||
|
||||
return x;
|
||||
};
|
||||
|
@ -49,12 +52,15 @@ Copayer.fromObj = function(obj) {
|
|||
x.id = obj.id;
|
||||
x.name = obj.name;
|
||||
x.xPubKey = obj.xPubKey;
|
||||
x.requestPubKey = obj.requestPubKey;
|
||||
x.signature = obj.signature;
|
||||
x.isTemporaryRequestKey = obj.isTemporaryRequestKey;
|
||||
|
||||
if (!obj.requestPubKeys) {
|
||||
x.requestPubKeys = [{
|
||||
key: obj.requestPubKey,
|
||||
signature: obj.signature,
|
||||
}];
|
||||
} else {
|
||||
x.requestPubKeys = obj.requestPubKeys;
|
||||
}
|
||||
x.addressManager = AddressManager.fromObj(obj.addressManager);
|
||||
|
||||
return x;
|
||||
};
|
||||
|
||||
|
|
|
@ -115,15 +115,12 @@ Wallet.prototype.addCopayerRequestKey = function(copayerId, requestPubKey, signa
|
|||
});
|
||||
$.checkState(c);
|
||||
|
||||
if (_.isArray(c.requestPubKey)) {
|
||||
$.checkState(_.isArray(c.signature));
|
||||
//new ones go first
|
||||
c.requestPubKeys.unshift({
|
||||
key: requestPubKey,
|
||||
signature: signature,
|
||||
});
|
||||
|
||||
c.requestPubKey.push(requestPubKey);
|
||||
c.signature.push(signature);
|
||||
} else {
|
||||
c.requestPubKey = requestPubKey;
|
||||
c.signature = signature;
|
||||
}
|
||||
//this._updatePublicKeyRing();
|
||||
};
|
||||
|
||||
|
|
|
@ -165,7 +165,7 @@ WalletService.getInstance = function(opts) {
|
|||
* @param {Object} opts
|
||||
* @param {string} opts.copayerId - The copayer id making the request.
|
||||
* @param {string} opts.message - The contents of the request to be signed.
|
||||
* @param {string} opts.signature - Signature of message to be verified using the copayer's requestPubKey
|
||||
* @param {string} opts.signature - Signature of message to be verified using one of the copayer's requestPubKeys
|
||||
* @param {string} opts.clientVersion - A string that identifies the client issuing the request
|
||||
*/
|
||||
WalletService.getInstanceWithAuth = function(opts, cb) {
|
||||
|
@ -177,7 +177,7 @@ WalletService.getInstanceWithAuth = function(opts, cb) {
|
|||
if (err) return cb(err);
|
||||
if (!copayer) return cb(new ClientError(Errors.codes.NOT_AUTHORIZED, 'Copayer not found'));
|
||||
|
||||
var isValid = server._verifySignature(opts.message, opts.signature, copayer.requestPubKey);
|
||||
var isValid = server._verifySignatureAgainstArray(opts.message, opts.signature, copayer.requestPubKeys);
|
||||
if (!isValid)
|
||||
return cb(new ClientError(Errors.codes.NOT_AUTHORIZED, 'Invalid signature'));
|
||||
|
||||
|
@ -276,10 +276,24 @@ WalletService.prototype.getWallet = function(opts, cb) {
|
|||
* Verifies a signature
|
||||
* @param text
|
||||
* @param signature
|
||||
* @param pubKey
|
||||
* @param pubKeys
|
||||
*/
|
||||
WalletService.prototype._verifySignature = function(text, signature, pubKey) {
|
||||
return WalletUtils.verifyMessage(text, signature, pubKey);
|
||||
WalletService.prototype._verifySignature = function(text, signature, pubkey) {
|
||||
return WalletUtils.verifyMessage(text, signature, pubkey);
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Verifies signature againt a collection of pubkeys
|
||||
* @param text
|
||||
* @param signature
|
||||
* @param pubKeys
|
||||
*/
|
||||
WalletService.prototype._verifySignatureAgainstArray = function(text, signature, pubKeys) {
|
||||
var self = this;
|
||||
return _.any(pubKeys, function(item) {
|
||||
return self._verifySignature(text, signature, item.key);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -545,7 +559,7 @@ WalletService.prototype.verifyMessageSignature = function(opts, cb) {
|
|||
|
||||
var copayer = wallet.getCopayer(self.copayerId);
|
||||
|
||||
var isValid = self._verifySignature(opts.message, opts.signature, copayer.requestPubKey);
|
||||
var isValid = self._verifySignatureAgainstArray(opts.message, opts.signature, copayer.requestPubKeys);
|
||||
return cb(null, isValid);
|
||||
});
|
||||
};
|
||||
|
@ -966,7 +980,7 @@ WalletService.prototype.createTx = function(opts, cb) {
|
|||
hash = WalletUtils.getProposalHash(header)
|
||||
}
|
||||
|
||||
if (!self._verifySignature(hash, opts.proposalSignature, copayer.requestPubKey))
|
||||
if (!self._verifySignatureAgainstArray(hash, opts.proposalSignature, copayer.requestPubKeys))
|
||||
return cb(new ClientError('Invalid proposal signature'));
|
||||
|
||||
self._canCreateTx(self.copayerId, function(err, canCreate) {
|
||||
|
|
|
@ -110,10 +110,11 @@ Storage.prototype.storeWalletAndUpdateCopayersLookup = function(wallet, cb) {
|
|||
var self = this;
|
||||
|
||||
var copayerLookups = _.map(wallet.copayers, function(copayer) {
|
||||
$.checkState(copayer.requestPubKeys);
|
||||
return {
|
||||
copayerId: copayer.id,
|
||||
walletId: wallet.id,
|
||||
requestPubKey: copayer.requestPubKey,
|
||||
requestPubKeys: copayer.requestPubKeys,
|
||||
};
|
||||
});
|
||||
|
||||
|
@ -133,11 +134,20 @@ Storage.prototype.storeWalletAndUpdateCopayersLookup = function(wallet, cb) {
|
|||
};
|
||||
|
||||
Storage.prototype.fetchCopayerLookup = function(copayerId, cb) {
|
||||
|
||||
this.db.collection(collections.COPAYERS_LOOKUP).findOne({
|
||||
copayerId: copayerId
|
||||
}, function(err, result) {
|
||||
if (err) return cb(err);
|
||||
if (!result) return cb();
|
||||
|
||||
if (!result.requestPubKeys) {
|
||||
result.requestPubKeys = [{
|
||||
key: result.requestPubKey,
|
||||
signature: result.signature,
|
||||
}];
|
||||
}
|
||||
|
||||
return cb(null, result);
|
||||
});
|
||||
};
|
||||
|
|
|
@ -1405,7 +1405,7 @@ describe('Wallet service', function() {
|
|||
});
|
||||
|
||||
|
||||
describe.only('Multiple request Pub Keys', function() {
|
||||
describe.skip('Multiple request Pub Keys', function() {
|
||||
var server, wallet;
|
||||
beforeEach(function(done) {
|
||||
helpers.createAndJoinWallet(2, 2, function(s, w) {
|
||||
|
|
|
@ -90,6 +90,7 @@ describe('Storage', function() {
|
|||
name: 'copayer ' + i,
|
||||
xPubKey: 'xPubKey ' + i,
|
||||
requestPubKey: 'requestPubKey ' + i,
|
||||
signature: 'xxx',
|
||||
});
|
||||
wallet.addCopayer(copayer);
|
||||
});
|
||||
|
@ -101,7 +102,8 @@ describe('Storage', function() {
|
|||
should.not.exist(err);
|
||||
should.exist(lookup);
|
||||
lookup.walletId.should.equal('123');
|
||||
lookup.requestPubKey.should.equal('requestPubKey 1');
|
||||
lookup.requestPubKeys[0].key.should.equal('requestPubKey 1');
|
||||
lookup.requestPubKeys[0].signature.should.equal('xxx');
|
||||
done();
|
||||
})
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue