252 lines
6.5 KiB
JavaScript
252 lines
6.5 KiB
JavaScript
'use strict';
|
|
|
|
var assert = require('assert');
|
|
|
|
var bitcore = require('bitcore-lib');
|
|
var _ = require('lodash');
|
|
var utils = require('./utils');
|
|
|
|
var MAX_INT = 0xffffffff; // Math.pow(2, 32) - 1
|
|
|
|
exports.sanitizeRangeOptions = function(options) {
|
|
if (!options) {
|
|
options = {};
|
|
}
|
|
options.height = options.height || 0;
|
|
options.index = options.index || 0;
|
|
|
|
if (!options.limit) {
|
|
options.limit = 10;
|
|
} else if (options.limit > 500) {
|
|
throw new Error('Limit exceeds maximum');
|
|
}
|
|
|
|
assert(bitcore.util.js.isNaturalNumber(options.height), '"height" is expected to be a natural number');
|
|
assert(bitcore.util.js.isNaturalNumber(options.index), '"index" is expected to be a natural number');
|
|
assert(bitcore.util.js.isNaturalNumber(options.limit), '"limit" is expected to be a natural number');
|
|
|
|
assert(options.limit <= 500, '"limit" exceeds maximum');
|
|
|
|
if (options.end) {
|
|
assert(bitcore.util.js.isNaturalNumber(options.end.height), '"end height" is expected to be a natural number');
|
|
}
|
|
return options;
|
|
};
|
|
|
|
exports.checkRangeParams = function(req, res, next) {
|
|
assert(req.bitcoinHeight, '"bitcoinHeight" is expected to be set on the request');
|
|
|
|
var range = {
|
|
height: parseInt(req.query.height),
|
|
index: parseInt(req.query.index),
|
|
limit: parseInt(req.query.limit),
|
|
end: {
|
|
height: req.bitcoinHeight,
|
|
index: MAX_INT
|
|
}
|
|
};
|
|
|
|
if (req.query.end) {
|
|
range.end.height = parseInt(req.query.end) || req.bitcoinHeight;
|
|
}
|
|
|
|
try {
|
|
range = exports.sanitizeRangeOptions(range);
|
|
} catch(e) {
|
|
return utils.sendError({
|
|
message: 'Invalid params: ' + e.message,
|
|
statusCode: 400
|
|
}, res);
|
|
}
|
|
|
|
assert(range.height <= range.end.height, '\'Height\' param required to be less than \'End\' param.');
|
|
req.range = range;
|
|
next();
|
|
};
|
|
|
|
exports.checkAddress = function(req, res, next) {
|
|
var address;
|
|
var addressStr;
|
|
|
|
if (req.body.address) {
|
|
addressStr = req.body.address;
|
|
} else {
|
|
addressStr = req.params.address;
|
|
}
|
|
|
|
if(!addressStr) {
|
|
return utils.sendError({
|
|
message: 'Address param is expected',
|
|
statusCode: 400
|
|
}, res);
|
|
}
|
|
|
|
assert(req.network, '"network" is expected to be set on the request');
|
|
|
|
try {
|
|
address = new bitcore.Address(addressStr, req.network);
|
|
} catch(e) {
|
|
return utils.sendError({
|
|
message: 'Invalid address: ' + e.message,
|
|
statusCode: 400
|
|
}, res);
|
|
}
|
|
|
|
req.address = address;
|
|
next();
|
|
};
|
|
|
|
//exports.checkAddresses = function(req, res, next) {
|
|
// var addresses = [];
|
|
//
|
|
// if (!req.body.addresses || !req.body.addresses.length || !Array.isArray(req.body.addresses)) {
|
|
// return utils.sendError({
|
|
// message: 'Addresses param is expected',
|
|
// statusCode: 400
|
|
// }, res);
|
|
// }
|
|
//
|
|
// assert(req.network, '"network" is expected to be set on the request');
|
|
//
|
|
// for (var i = 0; i < req.body.addresses.length; i++) {
|
|
// var address;
|
|
// try {
|
|
// address = new bitcore.Address(req.body.addresses[i], req.network);
|
|
// } catch(e) {
|
|
// return utils.sendError({
|
|
// message: 'Invalid address: ' + e.message,
|
|
// statusCode: 400
|
|
// }, res);
|
|
// }
|
|
// addresses.push(address);
|
|
// }
|
|
//
|
|
// req.addresses = addresses;
|
|
// next();
|
|
//};
|
|
|
|
exports.checkWalletId = function(req, res, next) {
|
|
|
|
if (!req.params.walletId) {
|
|
return utils.sendError({
|
|
message: 'Wallet id is expected',
|
|
statusCode: 400
|
|
}, res);
|
|
}
|
|
|
|
if (req.params.walletId.length !== 64 || !bitcore.util.js.isHexa(req.params.walletId)) {
|
|
return utils.sendError({
|
|
message: 'Wallet id is expected to be a hexadecimal string with length of 64',
|
|
statusCode: 400
|
|
}, res);
|
|
}
|
|
|
|
req.walletId = new Buffer(req.params.walletId, 'hex');
|
|
next();
|
|
|
|
};
|
|
|
|
exports.checkAddresses = function(req, res, next) {
|
|
|
|
if (!req.file && req.body) {
|
|
req.addresses = req.body;
|
|
return next();
|
|
}
|
|
|
|
if (!req.file || !req.file.buffer) {
|
|
generateError(406, 'Content-Type must be set to multipart/form' +
|
|
' and addresses key and value must be given.');
|
|
return;
|
|
}
|
|
var buf = req.file.buffer;
|
|
var bufString = buf.toString();
|
|
req.addresses = parse(bufString);
|
|
if (!req.addresses) {
|
|
generateError(415, 'Could not parse addresses buffer into something meaningful.');
|
|
return;
|
|
}
|
|
next();
|
|
|
|
function generateError(status, msg) {
|
|
res.status(status).jsonp({
|
|
error: msg
|
|
});
|
|
}
|
|
|
|
//we are able to deal with json/jsonl, possibly others
|
|
function parse(string) {
|
|
var ret = false;
|
|
var delims = [null, '\n', ' '];
|
|
for(var i = 0; i < delims.length; i++) {
|
|
ret = utils.delimitedStringParse(delims[i], string);
|
|
if (_.isArray(ret)) {
|
|
return ret;
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
};
|
|
|
|
exports.checkAuthHeaders = function(req, res) {
|
|
var identity = req.header('x-identity');
|
|
var signature = req.header('x-signature');
|
|
var nonce = req.header('x-nonce');
|
|
if (identity && (identity.length > 130 || !bitcore.util.js.isHexa(identity))) {
|
|
utils.sendError({
|
|
message: 'x-identity is expected to be a hexadecimal string with length of less than 131',
|
|
statusCode: 400
|
|
}, res);
|
|
return false;
|
|
}
|
|
if (signature && (signature.length > 142 || !bitcore.util.js.isHexa(signature))) {
|
|
utils.sendError({
|
|
message: 'x-signature is expected to be a hexadecimal string with length of less than 143',
|
|
statusCode: 400
|
|
}, res);
|
|
return false;
|
|
}
|
|
if (nonce && (nonce.length > 128 || nonce.length % 2 !== 0 || !bitcore.util.js.isHexa(nonce))) {
|
|
utils.sendError({
|
|
message: 'x-nonce is expected to be a hexadecimal string with length of less than 129',
|
|
statusCode: 400
|
|
}, res);
|
|
return false;
|
|
}
|
|
return true;
|
|
};
|
|
|
|
exports.checkDate = function(dateStrings) {
|
|
var errors = [];
|
|
if (!Array.isArray(dateStrings)) {
|
|
dateStrings = [dateStrings];
|
|
}
|
|
for(var i = 0; i < dateStrings.length; i++) {
|
|
internalDateCheck(dateStrings[i]);
|
|
}
|
|
|
|
function internalDateCheck(dateString) {
|
|
var date = new Date(utils.toIntIfNumberLike(dateString));
|
|
if (date.toString() === 'Invalid Date') {
|
|
errors.push('The date supplied: \'' + dateString +
|
|
'\' is not a valid date string. A valid date could be: \'2016-09-01\'.');
|
|
}
|
|
}
|
|
return errors;
|
|
};
|
|
|
|
exports.checkDateFunction = function(callback) {
|
|
var self = this;
|
|
return function() {
|
|
var args = Array.prototype.slice.call(arguments);
|
|
var errors = self.checkDate([args[1], args[2]]);
|
|
if (errors.length > 0) {
|
|
args.unshift(errors);
|
|
} else {
|
|
args.unshift(null);
|
|
}
|
|
callback.apply(null, args);
|
|
};
|
|
};
|
|
|
|
module.exports = exports;
|