hyperwallet-sdk
Version:
A library to manage users, transfer methods and payments through the Hyperwallet API
409 lines (354 loc) • 16.7 kB
JavaScript
Object.defineProperty(exports, "__esModule", {
value: true
});
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _superagent = require("superagent");
var _superagent2 = _interopRequireDefault(_superagent);
var _uuid = require("uuid");
var _package = require("../../package.json");
var _package2 = _interopRequireDefault(_package);
var _Encryption = require("./Encryption");
var _Encryption2 = _interopRequireDefault(_Encryption);
var _HyperwalletVerificationDocument = require("../models/HyperwalletVerificationDocument");
var _HyperwalletVerificationDocument2 = _interopRequireDefault(_HyperwalletVerificationDocument);
var _HyperwalletVerificationDocumentReason = require("../models/HyperwalletVerificationDocumentReason");
var _HyperwalletVerificationDocumentReason2 = _interopRequireDefault(_HyperwalletVerificationDocumentReason);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
/**
* The callback interface for api calls
*
* @typedef {function} api-callback
* @param {Object[]} [errors] - In case of an error an array with error objects otherwise undefined
* @param {string} [errors[].fieldName] - The field name (if error is caused by a particular field)
* @param {string} errors[].message - The error message
* @param {string} errors[].code - The error code
* @param {Object} data - The rest response body
* @param {Object} res - The raw superagent response object
*/
/**
* The Hyperwallet API Client
*/
var ApiClient = function () {
/**
* Create a instance of the API client
*
* @param {string} username - The API username
* @param {string} password - The API password
* @param {string} server - The API server to connect to
* @param {string} encryptionData - The API encryption data
*/
function ApiClient(username, password, server, encryptionData) {
_classCallCheck(this, ApiClient);
/**
* The API username
*
* @type {string}
* @protected
*/
this.username = username;
/**
* The API password
*
* @type {string}
* @protected
*/
this.password = password;
/**
* The API server to connect to
* @type {string}
* @protected
*/
this.server = server;
/**
* The Node SDK Version number
*
* @type {string}
* @protected
*/
this.version = _package2.default.version;
/**
* The flag shows if encryption is enabled
*
* @type {boolean}
* @protected
*/
this.isEncrypted = false;
this.contextId = (0, _uuid.v4)();
if (encryptionData && encryptionData.clientPrivateKeySetPath && encryptionData.hyperwalletKeySetPath) {
this.isEncrypted = true;
this.clientPrivateKeySetPath = encryptionData.clientPrivateKeySetPath;
this.hyperwalletKeySetPath = encryptionData.hyperwalletKeySetPath;
this.encryption = new _Encryption2.default(this.clientPrivateKeySetPath, this.hyperwalletKeySetPath);
}
}
/**
* Format response to documents model before passing to callback
*
* @param {Object} res - Response object
*
*/
_createClass(ApiClient, [{
key: "doPost",
/**
* Do a POST call to the Hyperwallet API server
*
* @param {string} partialUrl - The api endpoint to call (gets prefixed by `server` and `/rest/v4/`)
* @param {Object} data - The data to send to the server
* @param {Object} params - Query parameters to send in this call
* @param {api-callback} callback - The callback for this call
*/
value: function doPost(partialUrl, data, params, callback) {
var _this = this;
var contentType = "application/json";
var accept = "application/json";
var requestDataPromise = new Promise(function (resolve) {
return resolve(data);
});
if (this.isEncrypted) {
contentType = "application/jose+json";
accept = "application/jose+json";
ApiClient.createJoseJsonParser();
requestDataPromise = this.encryption.encrypt(data);
}
requestDataPromise.then(function (requestData) {
_superagent2.default.post(_this.server + "/rest/v4/" + partialUrl).auth(_this.username, _this.password).set("User-Agent", "Hyperwallet Node SDK v" + _this.version).set("x-sdk-version", _this.version).set("x-sdk-type", "NodeJS").set("x-sdk-contextId", _this.contextId).type(contentType).accept(accept).query(params).send(requestData).end(_this.wrapCallback("POST", callback));
}).catch(function () {
return callback([{ message: "Failed to encrypt body for POST request" }], undefined, undefined);
});
}
/**
* Do a PUT call to the Hyperwallet API server to upload documents
*
* @param {string} partialUrl - The api endpoint to call (gets prefixed by `server` and `/rest/v4/`)
* @param {Object} data - The data to send to the server
* @param {api-callback} callback - The callback for this call
*/
}, {
key: "doPutMultipart",
value: function doPutMultipart(partialUrl, data, callback) {
var _this2 = this;
var contentType = "multipart/form-data";
var accept = "application/json";
/* eslint-disable no-unused-vars */
var keys = Object.keys(data);
/* eslint-enable no-unused-vars */
var requestDataPromise = new Promise(function (resolve) {
return resolve(data);
});
if (this.isEncrypted) {
contentType = "multipart/form-data";
accept = "application/jose+json";
ApiClient.createJoseJsonParser();
requestDataPromise = this.encryption.encrypt(data);
}
requestDataPromise.then(function () {
var req = _superagent2.default.put(_this2.server + "/rest/v4/" + partialUrl).auth(_this2.username, _this2.password).set("User-Agent", "Hyperwallet Node SDK v" + _this2.version).set("x-sdk-version", _this2.version).set("x-sdk-type", "NodeJS").set("x-sdk-contextId", _this2.contextId).type(contentType).accept(accept);
keys.forEach(function (key) {
if (key === "data") {
req.field(key, JSON.stringify(data[key]));
} else {
req.attach(key, data[key]);
}
});
req.end(_this2.wrapCallback("PUT", callback));
}).catch(function (err) {
return callback(err, undefined, undefined);
});
}
/**
* Do a PUT call to the Hyperwallet API server
*
* @param {string} partialUrl - The api endpoint to call (gets prefixed by server and /rest/v4/)
* @param {Object} data - The data to send to the server
* @param {Object} params - Query parameters to send in this call
* @param {api-callback} callback - The callback for this call
*/
}, {
key: "doPut",
value: function doPut(partialUrl, data, params, callback) {
var _this3 = this;
var contentType = "application/json";
var accept = "application/json";
var requestDataPromise = new Promise(function (resolve) {
return resolve(data);
});
if (this.isEncrypted) {
contentType = "application/jose+json";
accept = "application/jose+json";
ApiClient.createJoseJsonParser();
requestDataPromise = this.encryption.encrypt(data);
}
requestDataPromise.then(function (requestData) {
_superagent2.default.put(_this3.server + "/rest/v4/" + partialUrl).auth(_this3.username, _this3.password).set("User-Agent", "Hyperwallet Node SDK v" + _this3.version).set("x-sdk-version", _this3.version).set("x-sdk-type", "NodeJS").set("x-sdk-contextId", _this3.contextId).type(contentType).accept(accept).query(params).send(requestData).end(_this3.wrapCallback("PUT", callback));
}).catch(function () {
return callback([{ message: "Failed to encrypt body for PUT request" }], undefined, undefined);
});
}
/**
* Do a GET call to the Hyperwallet API server
*
* @param {string} partialUrl - The api endpoint to call (gets prefixed by `server` and `/rest/v4/`)
* @param {Object} params - Query parameters to send in this call
* @param {api-callback} callback - The callback for this call
*/
}, {
key: "doGet",
value: function doGet(partialUrl, params, callback) {
var contentType = "application/json";
var accept = "application/json";
if (this.isEncrypted) {
contentType = "application/jose+json";
accept = "application/jose+json";
ApiClient.createJoseJsonParser();
}
_superagent2.default.get(this.server + "/rest/v4/" + partialUrl).auth(this.username, this.password).set("User-Agent", "Hyperwallet Node SDK v" + this.version).set("x-sdk-version", this.version).set("x-sdk-type", "NodeJS").set("x-sdk-contextId", this.contextId).type(contentType).accept(accept).query(params).end(this.wrapCallback("GET", callback));
}
/**
* Wrap a callback to process possible API and network errors
*
* @param {string} httpMethod - The http method that is currently processing
* @param {api-callback} callback - The final callback
* @returns {function(err: Object, res: Object)} - The super agent callback
*
* @private
*/
}, {
key: "wrapCallback",
value: function wrapCallback(httpMethod) {
var _this4 = this;
var callback = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : function () {
return null;
};
return function (err, res) {
var contentTypeHeader = res && res.header ? res.header["content-type"] : undefined;
if (!err) {
var expectedContentType = _this4.isEncrypted ? "application/jose+json" : "application/json";
if (res && res.status !== 204 && contentTypeHeader && !contentTypeHeader.includes(expectedContentType)) {
callback([{
message: "Invalid Content-Type specified in Response Header"
}], res ? res.body : undefined, res);
return;
}
}
if (_this4.isEncrypted && contentTypeHeader && contentTypeHeader.includes("application/jose+json") && res.body && !ApiClient.isEmptyResponseBody(res.body)) {
_this4.processEncryptedResponse(httpMethod, err, res.body, callback);
} else {
_this4.processNonEncryptedResponse(err, res, callback);
}
};
}
/**
* Process non encrypted response from server
*
* @param {Object} err - Error object
* @param {Object} res - Response object
* @param {api-callback} callback - The final callback
*
* @private
*/
}, {
key: "processNonEncryptedResponse",
value: function processNonEncryptedResponse(err, res, callback) {
if (!err) {
var formattedRes = ApiClient.formatResForCallback(res);
callback(undefined, formattedRes.body, formattedRes);
return;
}
var errors = [{
message: err.status ? err.message : "Could not communicate with " + this.server,
code: err.status ? err.status.toString() : "COMMUNICATION_ERROR"
}];
if (res && res.body && res.body.errors) {
// eslint-disable-next-line prefer-destructuring
errors = res.body.errors;
}
callback(errors, res ? res.body : undefined, res);
}
/**
* Process encrypted response from server
*
* @param {string} httpMethod - The http method that is currently processing
* @param {Object} err - Error object
* @param {Object} res - Response object
* @param {api-callback} callback - The final callback
*
* @private
*/
}, {
key: "processEncryptedResponse",
value: function processEncryptedResponse(httpMethod, err, res, callback) {
var _this5 = this;
this.encryption.decrypt(res).then(function (decryptedData) {
var responseBody = JSON.parse(decryptedData.payload.toString());
if (responseBody.errors) {
var responseWithErrors = {};
responseWithErrors.body = responseBody;
_this5.processNonEncryptedResponse(responseBody, responseWithErrors, callback);
} else {
var formattedRes = ApiClient.formatResForCallback({ body: responseBody });
callback(undefined, formattedRes.body, decryptedData);
}
}).catch(function () {
return callback([{ message: "Failed to decrypt response for " + httpMethod + " request" }], res, res);
});
}
/**
* Creates response body parser for application/jose+json content-type
*
* @private
*/
}], [{
key: "formatResForCallback",
value: function formatResForCallback(res) {
var retRes = res;
if (res && res.body) {
var retBody = res.body;
var documents = retBody.documents;
if (documents && documents.length > 0) {
var documentsArr = [];
documents.forEach(function (dVal) {
var doc = dVal;
if (dVal.reasons && dVal.reasons.length > 0) {
var reasonsArr = [];
dVal.reasons.forEach(function (rVal) {
reasonsArr.push(new _HyperwalletVerificationDocumentReason2.default(rVal));
});
doc.reasons = reasonsArr;
}
documentsArr.push(new _HyperwalletVerificationDocument2.default(doc));
});
retBody.documents = documentsArr;
retRes.body = retBody;
}
}
return retRes;
}
}, {
key: "createJoseJsonParser",
value: function createJoseJsonParser() {
_superagent2.default.parse["application/jose+json"] = function (res, callback) {
var data = "";
res.on("data", function (chunk) {
data += chunk;
});
res.on("end", function () {
callback(null, data);
});
};
}
/**
* Helper function to check if the response body is an empty object
*
* @private
*/
}, {
key: "isEmptyResponseBody",
value: function isEmptyResponseBody(body) {
return Object.keys(body).length === 0 && Object.getPrototypeOf(body) === Object.prototype;
}
}]);
return ApiClient;
}();
exports.default = ApiClient;
;