Browse Source

return more info on missing parameters

activeAddress
Ivan Socolsky 9 years ago
parent
commit
036abf001c
No known key found for this signature in database GPG Key ID: FAECE6A05FAA4F56
  1. 12
      lib/common/utils.js
  2. 64
      lib/server.js
  3. 2
      test/integration/server.js
  4. 22
      test/utils.js

12
lib/common/utils.js

@ -7,13 +7,13 @@ var encoding = Bitcore.encoding;
var Utils = {};
Utils.checkRequired = function(obj, args) {
Utils.getMissingFields = function(obj, args) {
args = [].concat(args);
if (!_.isObject(obj)) return false;
for (var i = 0; i < args.length; i++) {
if (!obj.hasOwnProperty(args[i])) return false;
}
return true;
if (!_.isObject(obj)) return args;
var missing = _.filter(args, function(arg) {
return !obj.hasOwnProperty(arg);
});
return missing;
};
/**

64
lib/server.js

@ -59,6 +59,12 @@ function WalletService() {
this.notifyTicker = 0;
};
function checkRequired(obj, args, cb) {
var missing = Utils.getMissingFields(obj, args);
if (_.isEmpty(missing)) return true;
cb(new ClientError('Required argument ' + _.first(missing) + ' missing.'));
return false;
};
/**
* Gets the current version of BWS
@ -177,8 +183,7 @@ WalletService.getInstance = function(opts) {
* @param {string} opts.clientVersion - A string that identifies the client issuing the request
*/
WalletService.getInstanceWithAuth = function(opts, cb) {
if (!Utils.checkRequired(opts, ['copayerId', 'message', 'signature']))
return cb(new ClientError('Required argument missing'));
if (!checkRequired(opts, ['copayerId', 'message', 'signature'], cb)) return;
var server = new WalletService();
server.storage.fetchCopayerLookup(opts.copayerId, function(err, copayer) {
@ -217,8 +222,7 @@ WalletService.prototype.createWallet = function(opts, cb) {
var self = this,
pubKey;
if (!Utils.checkRequired(opts, ['name', 'm', 'n', 'pubKey']))
return cb(new ClientError('Required argument missing'));
if (!checkRequired(opts, ['name', 'm', 'n', 'pubKey'], cb)) return;
if (_.isEmpty(opts.name)) return cb(new ClientError('Invalid wallet name'));
if (!Wallet.verifyCopayerLimits(opts.m, opts.n))
@ -512,8 +516,7 @@ WalletService.prototype._addKeyToCopayer = function(wallet, copayer, opts, cb) {
WalletService.prototype.addAccess = function(opts, cb) {
var self = this;
if (!Utils.checkRequired(opts, ['copayerId', 'requestPubKey', 'signature']))
return cb(new ClientError('Required argument missing'));
if (!checkRequired(opts, ['copayerId', 'requestPubKey', 'signature'], cb)) return;
self.storage.fetchCopayerLookup(opts.copayerId, function(err, copayer) {
if (err) return cb(err);
@ -612,8 +615,7 @@ WalletService._getCopayerHash = function(name, xPubKey, requestPubKey) {
WalletService.prototype.joinWallet = function(opts, cb) {
var self = this;
if (!Utils.checkRequired(opts, ['walletId', 'name', 'xPubKey', 'requestPubKey', 'copayerSignature']))
return cb(new ClientError('Required argument missing'));
if (!checkRequired(opts, ['walletId', 'name', 'xPubKey', 'requestPubKey', 'copayerSignature'], cb)) return;
if (_.isEmpty(opts.name))
return cb(new ClientError('Invalid copayer name'));
@ -841,8 +843,7 @@ WalletService.prototype.getMainAddresses = function(opts, cb) {
WalletService.prototype.verifyMessageSignature = function(opts, cb) {
var self = this;
if (!Utils.checkRequired(opts, ['message', 'signature']))
return cb(new ClientError('Required argument missing'));
if (!checkRequired(opts, ['message', 'signature'], cb)) return;
self.getWallet({}, function(err, wallet) {
if (err) return cb(err);
@ -1164,8 +1165,7 @@ WalletService.prototype.getSendMaxInfo = function(opts, cb) {
opts = opts || {};
if (!Utils.checkRequired(opts, ['feePerKb']))
return cb(new ClientError('Required argument missing'));
if (!checkRequired(opts, ['feePerKb'], cb)) return;
self.getWallet({}, function(err, wallet) {
if (err) return cb(err);
@ -1633,14 +1633,12 @@ WalletService.prototype._canCreateTx = function(cb) {
});
};
WalletService.prototype._validateOutputs = function(opts, wallet) {
WalletService.prototype._validateOutputs = function(opts, wallet, cb) {
for (var i = 0; i < opts.outputs.length; i++) {
var output = opts.outputs[i];
output.valid = false;
if (!Utils.checkRequired(output, ['toAddress', 'amount'])) {
return new ClientError('Required outputs argument missing');
}
if (!checkRequired(output, ['toAddress', 'amount'], cb)) return;
var toAddress = {};
try {
@ -1700,8 +1698,7 @@ WalletService.prototype.createTxLegacy = function(opts, cb) {
}
opts.outputs = [].concat(opts.outputs);
if (!Utils.checkRequired(opts, ['outputs', 'proposalSignature']))
return cb(new ClientError('Required argument missing'));
if (!checkRequired(opts, ['outputs', 'proposalSignature'], cb)) return;
var type = opts.type || Model.TxProposalLegacy.Types.SIMPLE;
if (!Model.TxProposalLegacy.isTypeSupported(type))
@ -1747,7 +1744,7 @@ WalletService.prototype.createTxLegacy = function(opts, cb) {
if (!canCreate) return cb(Errors.TX_CANNOT_CREATE);
if (type != Model.TxProposalLegacy.Types.EXTERNAL) {
var validationError = self._validateOutputs(opts, wallet);
var validationError = self._validateOutputs(opts, wallet, cb);
if (validationError) {
return cb(validationError);
}
@ -1816,8 +1813,7 @@ WalletService.prototype._validateAndSanitizeTxOpts = function(wallet, opts, cb)
async.series([
function(next) {
if (!Utils.checkRequired(opts, ['outputs']))
return next(new ClientError('Required argument missing'));
if (!checkRequired(opts, ['outputs'], next)) return;
next();
},
function(next) {
@ -1854,7 +1850,7 @@ WalletService.prototype._validateAndSanitizeTxOpts = function(wallet, opts, cb)
},
function(next) {
if (opts.validateOutputs === false) return next();
var validationError = self._validateOutputs(opts, wallet);
var validationError = self._validateOutputs(opts, wallet, next);
if (validationError) {
return next(validationError);
}
@ -1970,8 +1966,7 @@ WalletService.prototype.publishTx = function(opts, cb) {
return utxo.txid + '|' + utxo.vout
};
if (!Utils.checkRequired(opts, ['txProposalId', 'proposalSignature']))
return cb(new ClientError('Required argument missing'));
if (!checkRequired(opts, ['txProposalId', 'proposalSignature'], cb)) return;
self._runLocked(cb, function(cb) {
self.getWallet({}, function(err, wallet) {
@ -2087,8 +2082,7 @@ WalletService.prototype.getRemainingDeleteLockTime = function(txp) {
WalletService.prototype.removePendingTx = function(opts, cb) {
var self = this;
if (!Utils.checkRequired(opts, ['txProposalId']))
return cb(new ClientError('Required argument missing'));
if (!checkRequired(opts, ['txProposalId'], cb)) return;
self._runLocked(cb, function(cb) {
@ -2126,8 +2120,7 @@ WalletService.prototype._broadcastRawTx = function(network, raw, cb) {
WalletService.prototype.broadcastRawTx = function(opts, cb) {
var self = this;
if (!Utils.checkRequired(opts, ['network', 'rawTx']))
return cb(new ClientError('Required argument missing'));
if (!checkRequired(opts, ['network', 'rawTx'], cb)) return;
var network = opts.network || 'livenet';
if (network != 'livenet' && network != 'testnet')
@ -2155,8 +2148,7 @@ WalletService.prototype._checkTxInBlockchain = function(txp, cb) {
WalletService.prototype.signTx = function(opts, cb) {
var self = this;
if (!Utils.checkRequired(opts, ['txProposalId', 'signatures']))
return cb(new ClientError('Required argument missing'));
if (!checkRequired(opts, ['txProposalId', 'signatures'], cb)) return;
self.getWallet({}, function(err, wallet) {
if (err) return cb(err);
@ -2254,8 +2246,7 @@ WalletService.prototype._processBroadcast = function(txp, opts, cb) {
WalletService.prototype.broadcastTx = function(opts, cb) {
var self = this;
if (!Utils.checkRequired(opts, ['txProposalId']))
return cb(new ClientError('Required argument missing'));
if (!checkRequired(opts, ['txProposalId'], cb)) return;
self.getWallet({}, function(err, wallet) {
if (err) return cb(err);
@ -2308,8 +2299,7 @@ WalletService.prototype.broadcastTx = function(opts, cb) {
WalletService.prototype.rejectTx = function(opts, cb) {
var self = this;
if (!Utils.checkRequired(opts, ['txProposalId']))
return cb(new ClientError('Required argument missing'));
if (!checkRequired(opts, ['txProposalId'], cb)) return;
self.getTx({
txProposalId: opts.txProposalId
@ -2790,8 +2780,7 @@ WalletService.prototype.startScan = function(opts, cb) {
WalletService.prototype.getFiatRate = function(opts, cb) {
var self = this;
if (!Utils.checkRequired(opts, ['code']))
return cb(new ClientError('Required argument missing'));
if (!checkRequired(opts, ['code'], cb)) return;
self.fiatRateService.getRate(opts, function(err, rate) {
if (err) return cb(err);
@ -2800,8 +2789,7 @@ WalletService.prototype.getFiatRate = function(opts, cb) {
};
WalletService.prototype.pushNotificationsSubscribe = function(opts, cb) {
if (!Utils.checkRequired(opts, ['token']))
return cb(new ClientError('Required argument missing'));
if (!checkRequired(opts, ['token'], cb)) return;
var self = this;

2
test/integration/server.js

@ -509,7 +509,7 @@ describe('Wallet service', function() {
};
server.joinWallet(copayerOpts, function(err) {
should.exist(err);
err.message.should.contain('argument missing');
err.message.should.contain('argument copayerSignature missing');
done();
});
});

22
test/utils.js

@ -7,7 +7,7 @@ var should = chai.should();
var Utils = require('../lib/common/utils');
describe('Utils', function() {
describe('#checkRequired', function() {
describe('#getMissingFields', function() {
it('should check required fields', function() {
var obj = {
id: 'id',
@ -16,36 +16,36 @@ describe('Utils', function() {
};
var fixtures = [{
args: 'id',
check: true
check: [],
}, {
args: ['id'],
check: true
check: []
}, {
args: ['id, name'],
check: false
check: ['id, name'],
}, {
args: ['id', 'name'],
check: true
check: []
}, {
args: 'array',
check: true
check: []
}, {
args: 'dummy',
check: false
check: ['dummy']
}, {
args: ['dummy1', 'dummy2'],
check: false
check: ['dummy1', 'dummy2']
}, {
args: ['id', 'dummy'],
check: false
check: ['dummy']
}, ];
_.each(fixtures, function(f) {
Utils.checkRequired(obj, f.args).should.equal(f.check);
Utils.getMissingFields(obj, f.args).should.deep.equal(f.check);
});
});
it('should fail to check required fields on non-object', function() {
var obj = 'dummy';
Utils.checkRequired(obj, 'name').should.be.false;
Utils.getMissingFields(obj, 'name').should.deep.equal(['name']);
});
});

Loading…
Cancel
Save