UNPKG

hyperwallet-sdk

Version:

A library to manage users, transfer methods and payments through the Hyperwallet API

409 lines (354 loc) 16.7 kB
"use strict"; 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;