- 1 :
- 2 :
(function(root, factory) {
- 3 :
if (typeof define === 'function' && define.amd) {
- 4 :
// AMD. Register as an anonymous module.
- 5 :
define(['superagent', 'querystring'], factory);
- 6 :
} else if (typeof module === 'object' && module.exports) {
- 7 :
// CommonJS-like environments that support module.exports, like Node.
- 8 :
module.exports = factory(require('logtown').getLogger('orbipay-paymentsapi-client/src/ApiClient'), require('superagent'), require('querystring'), require('./CommonUtil'), require('crypto'));
- 9 :
} else {
- 10 :
// Browser globals (root is window)
- 11 :
if (!root.OrbipayPaymentsapiClient) {
- 12 :
root.OrbipayPaymentsapiClient = {};
- 13 :
}
- 14 :
root.OrbipayPaymentsapiClient.ApiClient = factory(root.superagent, root.querystring);
- 15 :
}
- 16 :
}(this, function(logger, superagent, querystring, CommonUtil, crypto) {
- 17 :
'use strict';
- 18 :
- 19 :
/**
- 20 :
* @module ApiClient
- 21 :
*/
- 22 :
- 23 :
/**
- 24 :
* <h3 style="color:red"> This class subject to change without prior notice, Please dont use this class directly. </h3>
- 25 :
- 26 :
* Manages low level client-server communications, parameter marshalling, etc. There should not be any need for an
- 27 :
* application to use this class directly - the *Api and model classes provide the public API for the service. The
- 28 :
* contents of this file should be regarded as internal but are documented for completeness.
- 29 :
* @alias module:ApiClient
- 30 :
* @class
- 31 :
*/
- 32 :
var exports = function(clientSignatureKey, basePath, clientApiKey, authScheme) {
- 33 :
/**
- 34 :
* The base URL against which to resolve every API call's (relative) path.
- 35 :
* @type {String}
- 36 :
* @default https://api.orbipay.com/payments/v1
- 37 :
*/
- 38 :
this.basePath = basePath;
- 39 :
- 40 :
/**
- 41 :
* The authentication methods to be included for all API calls.
- 42 :
* @type {Array.<String>}
- 43 :
*/
- 44 :
this.authentications = {
- 45 :
};
- 46 :
/**
- 47 :
* The default HTTP headers to be included for all API calls.
- 48 :
* @type {Array.<String>}
- 49 :
* @default {}
- 50 :
*/
- 51 :
this.defaultHeaders = {};
- 52 :
- 53 :
/**
- 54 :
* The default HTTP timeout for all API calls.
- 55 :
* @type {Number}
- 56 :
* @default 60
- 57 :
*/
- 58 :
this.timeout = 60;
- 59 :
- 60 :
/**
- 61 :
* If set to false an additional timestamp parameter is added to all API GET calls to
- 62 :
* prevent browser caching
- 63 :
* @type {Boolean}
- 64 :
* @default true
- 65 :
*/
- 66 :
this.cache = true;
- 67 :
- 68 :
/**
- 69 :
* If set to true, the client will save the cookies from each server
- 70 :
* response, and return them in the next request.
- 71 :
* @default false
- 72 :
*/
- 73 :
this.enableCookies = false;
- 74 :
- 75 :
/*
- 76 :
* Used to save and return cookies in a node.js (non-browser) setting,
- 77 :
* if this.enableCookies is set to true.
- 78 :
*/
- 79 :
if (typeof window === 'undefined') {
- 80 :
this.agent = new superagent.agent();
- 81 :
}
- 82 :
- 83 :
/*
- 84 :
* Allow user to override superagent agent
- 85 :
*/
- 86 :
this.requestAgent = null;
- 87 :
- 88 :
this.clientSignatureKey = clientSignatureKey;
- 89 :
this.clientApiKey = clientApiKey;
- 90 :
this.authScheme = authScheme;
- 91 :
- 92 :
};
- 93 :
- 94 :
/**
- 95 :
* Returns a string representation for an actual parameter.
- 96 :
* @param param The actual parameter.
- 97 :
* @returns {String} The string representation of <code>param</code>.
- 98 :
*/
- 99 :
exports.prototype.paramToString = function(param) {
- 100 :
if (param === undefined || param === null) {
- 101 :
return '';
- 102 :
}
- 103 :
if (param instanceof Date) {
- 104 :
return param.toJSON();
- 105 :
}
- 106 :
return param.toString();
- 107 :
};
- 108 :
- 109 :
/**
- 110 :
* Builds full URL by appending the given path to the base URL and replacing path parameter place-holders with parameter values.
- 111 :
* NOTE: query parameters are not handled here.
- 112 :
* @param {String} path The path to append to the base URL.
- 113 :
* @param {Object} pathParams The parameter values to append.
- 114 :
* @returns {String} The encoded path with parameter values substituted.
- 115 :
*/
- 116 :
exports.prototype.buildUrl = function(path, pathParams) {
- 117 :
if (!path.match(/^\//)) {
- 118 :
path = '/' + path;
- 119 :
}
- 120 :
var url = this.basePath + path;
- 121 :
var _this = this;
- 122 :
url = url.replace(/\{([\w-]+)\}/g, function(fullMatch, key) {
- 123 :
var value;
- 124 :
if (pathParams.hasOwnProperty(key)) {
- 125 :
value = _this.paramToString(pathParams[key]);
- 126 :
if(exports.isEmptyString(value)){
- 127 :
logger.error('Missing the required parameter ' + key);
- 128 :
throw new Error('Missing the required parameter ' + key);
- 129 :
}
- 130 :
} else {
- 131 :
value = fullMatch;
- 132 :
}
- 133 :
return encodeURIComponent(value);
- 134 :
});
- 135 :
return url;
- 136 :
};
- 137 :
- 138 :
/**
- 139 :
* Checks whether the given content type represents JSON.<br>
- 140 :
* JSON content type examples:<br>
- 141 :
* <ul>
- 142 :
* <li>application/json</li>
- 143 :
* <li>application/json; charset=UTF8</li>
- 144 :
* <li>APPLICATION/JSON</li>
- 145 :
* </ul>
- 146 :
* @param {String} contentType The MIME content type to check.
- 147 :
* @returns {Boolean} <code>true</code> if <code>contentType</code> represents JSON, otherwise <code>false</code>.
- 148 :
*/
- 149 :
exports.prototype.isJsonMime = function(contentType) {
- 150 :
return Boolean(contentType != null && contentType.match(/^application\/json(;.*)?$/i));
- 151 :
};
- 152 :
- 153 :
/**
- 154 :
* Chooses a content type from the given array, with JSON preferred; i.e. return JSON if included, otherwise return the first.
- 155 :
* @param {Array.<String>} contentTypes
- 156 :
* @returns {String} The chosen content type, preferring JSON.
- 157 :
*/
- 158 :
exports.prototype.jsonPreferredMime = function(contentTypes) {
- 159 :
for (var i = 0; i < contentTypes.length; i++) {
- 160 :
if (this.isJsonMime(contentTypes[i])) {
- 161 :
return contentTypes[i];
- 162 :
}
- 163 :
}
- 164 :
return contentTypes[0];
- 165 :
};
- 166 :
- 167 :
/**
- 168 :
* Checks whether the given parameter value represents file-like content.
- 169 :
* @param param The parameter to check.
- 170 :
* @returns {Boolean} <code>true</code> if <code>param</code> represents a file.
- 171 :
*/
- 172 :
exports.prototype.isFileParam = function(param) {
- 173 :
// fs.ReadStream in Node.js and Electron (but not in runtime like browserify)
- 174 :
if (typeof require === 'function') {
- 175 :
var fs;
- 176 :
try {
- 177 :
fs = require('fs');
- 178 :
} catch (err) {}
- 179 :
if (fs && fs.ReadStream && param instanceof fs.ReadStream) {
- 180 :
return true;
- 181 :
}
- 182 :
}
- 183 :
// Buffer in Node.js
- 184 :
if (typeof Buffer === 'function' && param instanceof Buffer) {
- 185 :
return true;
- 186 :
}
- 187 :
// Blob in browser
- 188 :
if (typeof Blob === 'function' && param instanceof Blob) {
- 189 :
return true;
- 190 :
}
- 191 :
// File in browser (it seems File object is also instance of Blob, but keep this for safe)
- 192 :
if (typeof File === 'function' && param instanceof File) {
- 193 :
return true;
- 194 :
}
- 195 :
return false;
- 196 :
};
- 197 :
- 198 :
/**
- 199 :
* Normalizes parameter values:
- 200 :
* <ul>
- 201 :
* <li>remove nils</li>
- 202 :
* <li>keep files and arrays</li>
- 203 :
* <li>format to string with `paramToString` for other cases</li>
- 204 :
* </ul>
- 205 :
* @param {Object.<String, Object>} params The parameters as object properties.
- 206 :
* @returns {Object.<String, Object>} normalized parameters.
- 207 :
*/
- 208 :
exports.prototype.normalizeParams = function(params) {
- 209 :
var newParams = {};
- 210 :
for (var key in params) {
- 211 :
if (params.hasOwnProperty(key) && params[key] != undefined && params[key] != null) {
- 212 :
var value = params[key];
- 213 :
if (this.isFileParam(value) || Array.isArray(value)) {
- 214 :
newParams[key] = value;
- 215 :
} else {
- 216 :
newParams[key] = this.paramToString(value);
- 217 :
}
- 218 :
}
- 219 :
}
- 220 :
return newParams;
- 221 :
};
- 222 :
- 223 :
/**
- 224 :
* Enumeration of collection format separator strategies.
- 225 :
* @enum {String}
- 226 :
* @readonly
- 227 :
*/
- 228 :
exports.CollectionFormatEnum = {
- 229 :
/**
- 230 :
* Comma-separated values. Value: <code>csv</code>
- 231 :
* @const
- 232 :
*/
- 233 :
CSV: ',',
- 234 :
/**
- 235 :
* Space-separated values. Value: <code>ssv</code>
- 236 :
* @const
- 237 :
*/
- 238 :
SSV: ' ',
- 239 :
/**
- 240 :
* Tab-separated values. Value: <code>tsv</code>
- 241 :
* @const
- 242 :
*/
- 243 :
TSV: '\t',
- 244 :
/**
- 245 :
* Pipe(|)-separated values. Value: <code>pipes</code>
- 246 :
* @const
- 247 :
*/
- 248 :
PIPES: '|',
- 249 :
/**
- 250 :
* Native array. Value: <code>multi</code>
- 251 :
* @const
- 252 :
*/
- 253 :
MULTI: 'multi'
- 254 :
};
- 255 :
- 256 :
/**
- 257 :
* Builds a string representation of an array-type actual parameter, according to the given collection format.
- 258 :
* @param {Array} param An array parameter.
- 259 :
* @param {module:ApiClient.CollectionFormatEnum} collectionFormat The array element separator strategy.
- 260 :
* @returns {String|Array} A string representation of the supplied collection, using the specified delimiter. Returns
- 261 :
* <code>param</code> as is if <code>collectionFormat</code> is <code>multi</code>.
- 262 :
*/
- 263 :
exports.prototype.buildCollectionParam = function buildCollectionParam(param, collectionFormat) {
- 264 :
if (param == null) {
- 265 :
return null;
- 266 :
}
- 267 :
switch (collectionFormat) {
- 268 :
case 'csv':
- 269 :
return param.map(this.paramToString).join(',');
- 270 :
case 'ssv':
- 271 :
return param.map(this.paramToString).join(' ');
- 272 :
case 'tsv':
- 273 :
return param.map(this.paramToString).join('\t');
- 274 :
case 'pipes':
- 275 :
return param.map(this.paramToString).join('|');
- 276 :
case 'multi':
- 277 :
// return the array directly as SuperAgent will handle it as expected
- 278 :
return param.map(this.paramToString);
- 279 :
default:
- 280 :
throw new Error('Unknown collection format: ' + collectionFormat);
- 281 :
}
- 282 :
};
- 283 :
- 284 :
/**
- 285 :
* Applies authentication headers to the request.
- 286 :
* @param {Object} request The request object created by a <code>superagent()</code> call.
- 287 :
* @param {Array.<String>} authNames An array of authentication method names.
- 288 :
*/
- 289 :
exports.prototype.applyAuthToRequest = function(request, authNames) {
- 290 :
var _this = this;
- 291 :
authNames.forEach(function(authName) {
- 292 :
var auth = _this.authentications[authName];
- 293 :
switch (auth.type) {
- 294 :
case 'basic':
- 295 :
if (auth.username || auth.password) {
- 296 :
request.auth(auth.username || '', auth.password || '');
- 297 :
}
- 298 :
break;
- 299 :
case 'apiKey':
- 300 :
if (auth.apiKey) {
- 301 :
var data = {};
- 302 :
if (auth.apiKeyPrefix) {
- 303 :
data[auth.name] = auth.apiKeyPrefix + ' ' + auth.apiKey;
- 304 :
} else {
- 305 :
data[auth.name] = auth.apiKey;
- 306 :
}
- 307 :
if (auth['in'] === 'header') {
- 308 :
request.set(data);
- 309 :
} else {
- 310 :
request.query(data);
- 311 :
}
- 312 :
}
- 313 :
break;
- 314 :
case 'oauth2':
- 315 :
if (auth.accessToken) {
- 316 :
request.set({'Authorization': 'Bearer ' + auth.accessToken});
- 317 :
}
- 318 :
break;
- 319 :
default:
- 320 :
throw new Error('Unknown authentication type: ' + auth.type);
- 321 :
}
- 322 :
});
- 323 :
};
- 324 :
- 325 :
/**
- 326 :
* Deserializes an HTTP response body into a value of the specified type.
- 327 :
* @param {Object} response A SuperAgent response object.
- 328 :
* @param {(String|Array.<String>|Object.<String, Object>|Function)} returnType The type to return. Pass a string for simple types
- 329 :
* or the constructor function for a complex type. Pass an array containing the type name to return an array of that type. To
- 330 :
* return an object, pass an object with one property whose name is the key type and whose value is the corresponding value type:
- 331 :
* all properties on <code>data<code> will be converted to this type.
- 332 :
* @returns A value of the specified type.
- 333 :
*/
- 334 :
exports.prototype.deserialize = function deserialize(response, returnType) {
- 335 :
if (response == null || returnType == null || response.status == 204) {
- 336 :
return null;
- 337 :
}
- 338 :
// Rely on SuperAgent for parsing response body.
- 339 :
// See http://visionmedia.github.io/superagent/#parsing-response-bodies
- 340 :
var data = response.body;
- 341 :
if (data == null || (typeof data === 'object' && typeof data.length === 'undefined' && !Object.keys(data).length)) {
- 342 :
// SuperAgent does not always produce a body; use the unparsed response as a fallback
- 343 :
data = response.text;
- 344 :
}
- 345 :
return exports.convertToType(data, returnType);
- 346 :
};
- 347 :
- 348 :
/**
- 349 :
* Callback function to receive the result of the operation.
- 350 :
* @callback module:ApiClient~callApiCallback
- 351 :
* @param {String} error Error message, if any.
- 352 :
* @param data The data returned by the service call.
- 353 :
* @param {String} response The complete HTTP response.
- 354 :
*/
- 355 :
- 356 :
/**
- 357 :
* Invokes the REST service using the supplied settings and parameters.
- 358 :
* @param {String} path The base URL to invoke.
- 359 :
* @param {String} httpMethod The HTTP method to use.
- 360 :
* @param {Object.<String, String>} pathParams A map of path parameters and their values.
- 361 :
* @param {Object.<String, Object>} queryParams A map of query parameters and their values.
- 362 :
* @param {Object.<String, Object>} collectionQueryParams A map of collection query parameters and their values.
- 363 :
* @param {Object.<String, Object>} headerParams A map of header parameters and their values.
- 364 :
* @param {Object.<String, Object>} formParams A map of form parameters and their values.
- 365 :
* @param {Object} bodyParam The value to pass as the request body.
- 366 :
* @param {Array.<String>} authNames An array of authentication type names.
- 367 :
* @param {Array.<String>} contentTypes An array of request MIME types.
- 368 :
* @param {Array.<String>} accepts An array of acceptable response MIME types.
- 369 :
* @param {(String|Array|ObjectFunction)} returnType The required type to return; can be a string for simple types or the
- 370 :
* constructor for a complex type.
- 371 :
* @param {module:ApiClient~callApiCallback} callback The callback function.
- 372 :
* @returns {Object} The SuperAgent request object.
- 373 :
*/
- 374 :
exports.prototype.callApi = function callApi(path, httpMethod, pathParams,
- 375 :
queryParams, headerParams, formParams, bodyParam, authNames, contentTypes, accepts,
- 376 :
returnType, callback) {
- 377 :
- 378 :
var _this = this;
- 379 :
var url = this.buildUrl(path, pathParams);
- 380 :
logger.debug('HTTP URL: ' + url);
- 381 :
logger.debug('HTTP Method: ' + httpMethod);
- 382 :
- 383 :
// added by us
- 384 :
- 385 :
var resourcePath = this.resourcePath(path, pathParams);
- 386 :
- 387 :
if(this.clientApiKey == null || this.clientApiKey == ''){
- 388 :
this.clientApiKey = headerParams['client_key'];
- 389 :
}
- 390 :
- 391 :
if(this.authScheme == null || this.authScheme == '' || this.authScheme == 'OPAY1-HMAC-SHA256'){
- 392 :
var authorizationData = exports.computeOPAY1HMACSHA256Hash(resourcePath, httpMethod, queryParams, headerParams, formParams, bodyParam, this.clientSignatureKey);
- 393 :
var clientHash = authorizationData['hash'];
- 394 :
headerParams['Authorization'] = 'OPAY1-HMAC-SHA256 Credential=' + this.clientApiKey + ',Signature=' + clientHash.trim() + '';
- 395 :
}else if(this.authScheme == 'OPAY2-HMAC-SHA256'){
- 396 :
var authorizationData = exports.computeOPAY2HMACSHA256Hash(headerParams['client_key'], this.clientApiKey,this.clientSignatureKey, headerParams['timestamp']);
- 397 :
var clientHash = authorizationData['hash'];
- 398 :
headerParams['Authorization'] = 'OPAY2-HMAC-SHA256 Credential=' + this.clientApiKey + ',Signature=' + clientHash.trim() + '';
- 399 :
}else if(this.authScheme == 'OPAY3-HMAC-SHA256'){
- 400 :
headerParams['Authorization'] = 'OPAY3-HMAC-SHA256 Credential=' + this.clientApiKey;
- 401 :
}else{
- 402 :
logger.debug('invalid auth_scheme received');
- 403 :
throw new Error('invalid auth_scheme received');
- 404 :
}
- 405 :
headerParams['User-Agent'] = 'orbipay-paymentsapi-client/1.14.0/Node';
- 406 :
- 407 :
var request = superagent(httpMethod, url);
- 408 :
// apply authentications
- 409 :
this.applyAuthToRequest(request, authNames);
- 410 :
- 411 :
// set query parameters
- 412 :
if (httpMethod.toUpperCase() === 'GET' && this.cache === false) {
- 413 :
queryParams['_'] = new Date().getTime();
- 414 :
}
- 415 :
request.query(this.normalizeParams(queryParams));
- 416 :
logger.debug('Query Params: ', JSON.stringify(queryParams));
- 417 :
// set header parameters
- 418 :
request.set(this.defaultHeaders).set(this.normalizeParams(headerParams));
- 419 :
logger.debug('Request Headers: ', JSON.stringify(headerParams));
- 420 :
- 421 :
logger.debug('Request Body: ', JSON.stringify(bodyParam, CommonUtil.maskSensitiveInfo));
- 422 :
- 423 :
// set requestAgent if it is set by user
- 424 :
if (this.requestAgent) {
- 425 :
request.agent(this.requestAgent);
- 426 :
}
- 427 :
- 428 :
if (process.env['ORBIPAY_PAYMENTS_API_TIMEOUT_SECONDS']) {
- 429 :
this.timeout = process.env['ORBIPAY_PAYMENTS_API_TIMEOUT_SECONDS'];
- 430 :
logger.debug('HTTP TIMEOUT in seconds : ' + this.timeout);
- 431 :
}
- 432 :
else{
- 433 :
logger.warn('Timeout environment variable, ORBIPAY_PAYMENTS_API_TIMEOUT_SECONDS is not found setting default value in seconds: ', this.timeout);
- 434 :
}
- 435 :
- 436 :
request.timeout(this.timeout*1000);
- 437 :
- 438 :
var contentType = this.jsonPreferredMime(contentTypes);
- 439 :
if (contentType) {
- 440 :
// Issue with superagent and multipart/form-data (https://github.com/visionmedia/superagent/issues/746)
- 441 :
if(contentType !== 'multipart/form-data') {
- 442 :
request.type(contentType);
- 443 :
}
- 444 :
} else if (!request.header['Content-Type']) {
- 445 :
request.type('application/json');
- 446 :
}
- 447 :
- 448 :
if (contentType === 'application/x-www-form-urlencoded') {
- 449 :
request.send(querystring.stringify(this.normalizeParams(formParams)));
- 450 :
} else if (contentType === 'multipart/form-data') {
- 451 :
var _formParams = this.normalizeParams(formParams);
- 452 :
for (var formParamKey in _formParams) {
- 453 :
if (_formParams.hasOwnProperty(formParamKey)) {
- 454 :
if (this.isFileParam(_formParams[formParamKey])) {
- 455 :
// file field
- 456 :
request.attach(formParamKey, _formParams[formParamKey]);
- 457 :
} else {
- 458 :
request.field(formParamKey, _formParams[formParamKey]);
- 459 :
}
- 460 :
}
- 461 :
}
- 462 :
} else if (bodyParam) {
- 463 :
request.send(bodyParam);
- 464 :
}
- 465 :
- 466 :
var accept = this.jsonPreferredMime(accepts);
- 467 :
if (accept) {
- 468 :
request.accept(accept);
- 469 :
}
- 470 :
- 471 :
if (returnType === 'Blob') {
- 472 :
request.responseType('blob');
- 473 :
} else if (returnType === 'String') {
- 474 :
request.responseType('string');
- 475 :
}
- 476 :
- 477 :
// Attach previously saved cookies, if enabled
- 478 :
if (this.enableCookies){
- 479 :
if (typeof window === 'undefined') {
- 480 :
this.agent.attachCookies(request);
- 481 :
}
- 482 :
else {
- 483 :
request.withCredentials();
- 484 :
}
- 485 :
}
- 486 :
- 487 :
- 488 :
if (callback) {
- 489 :
logger.info('Sending Request to Service');
- 490 :
request.end(function (error, response) {
- 491 :
var data = null;
- 492 :
if (!error) {
- 493 :
try {
- 494 :
data = _this.deserialize(response, returnType);
- 495 :
logger.info('Receive Response from Service : HTTP Status Code :', response.status);
- 496 :
logger.debug('HTTP Response Body :', JSON.stringify(data, CommonUtil.maskSensitiveInfo));
- 497 :
if (_this.enableCookies && typeof window === 'undefined') {
- 498 :
_this.agent.saveCookies(response);
- 499 :
}
- 500 :
} catch (err) {
- 501 :
error = err;
- 502 :
}
- 503 :
}
- 504 :
- 505 :
if (error) {
- 506 :
logger.info('Receive Response from Service : HTTP Status Code :', error.status);
- 507 :
logger.error('HTTP Error code :', error.code);
- 508 :
logger.error('HTTP Error errno :', error.errno);
- 509 :
logger.error('HTTP Error message :', error.message);
- 510 :
if(response && response.text) {
- 511 :
logger.debug('HTTP Response Body :', response.text);
- 512 :
}
- 513 :
else{
- 514 :
logger.warn('HTTP Body is not received ');
- 515 :
}
- 516 :
}
- 517 :
response = response || {};
- 518 :
logger.debug('Response Headers :', JSON.stringify(response['header']));
- 519 :
if(response['header']) {
- 520 :
logger.info('request_uuid :', response['header']['request_uuid']);
- 521 :
}
- 522 :
callback(error, data, response);
- 523 :
});
- 524 :
}
- 525 :
- 526 :
return request;
- 527 :
};
- 528 :
- 529 :
/**
- 530 :
* Parses an ISO-8601 string representation of a date value.
- 531 :
* @param {String} str The date value as a string.
- 532 :
* @returns {Date} The parsed date object.
- 533 :
*/
- 534 :
exports.parseDate = function(str) {
- 535 :
return new Date(str.replace(/T/i, ' '));
- 536 :
};
- 537 :
- 538 :
/**
- 539 :
* Converts a value to the specified type.
- 540 :
* @param {(String|Object)} data The data to convert, as a string or object.
- 541 :
* @param {(String|Array.<String>|Object.<String, Object>|Function)} type The type to return. Pass a string for simple types
- 542 :
* or the constructor function for a complex type. Pass an array containing the type name to return an array of that type. To
- 543 :
* return an object, pass an object with one property whose name is the key type and whose value is the corresponding value type:
- 544 :
* all properties on <code>data<code> will be converted to this type.
- 545 :
* @returns An instance of the specified type or null or undefined if data is null or undefined.
- 546 :
*/
- 547 :
exports.convertToType = function(data, type) {
- 548 :
if (data === null || data === undefined)
- 549 :
return data;
- 550 :
- 551 :
switch (type) {
- 552 :
case 'Boolean':
- 553 :
return Boolean(data);
- 554 :
case 'Integer':
- 555 :
return parseInt(data, 10);
- 556 :
case 'Number':
- 557 :
return parseFloat(data);
- 558 :
case 'String':
- 559 :
if(typeof data === 'string'){
- 560 :
return String(data);
- 561 :
}
- 562 :
else{
- 563 :
return data;
- 564 :
}
- 565 :
case 'Date':
- 566 :
return this.parseDate(String(data));
- 567 :
case 'Blob':
- 568 :
return data;
- 569 :
default:
- 570 :
if (type === Object) {
- 571 :
// generic object, return directly
- 572 :
return data;
- 573 :
} else if (typeof type === 'function') {
- 574 :
// for model type like: User
- 575 :
return type.constructFromObject(data);
- 576 :
} else if (Array.isArray(type)) {
- 577 :
// for array type like: ['String']
- 578 :
var itemType = type[0];
- 579 :
return data.map(function(item) {
- 580 :
return exports.convertToType(item, itemType);
- 581 :
});
- 582 :
} else if (typeof type === 'object') {
- 583 :
// for plain object type like: {'String': 'Integer'}
- 584 :
var keyType, valueType;
- 585 :
for (var j in type) {
- 586 :
if (type.hasOwnProperty(j)) {
- 587 :
keyType = j;
- 588 :
valueType = type[j];
- 589 :
break;
- 590 :
}
- 591 :
}
- 592 :
var result = {};
- 593 :
for (var k in data) {
- 594 :
if (data.hasOwnProperty(k)) {
- 595 :
var key = exports.convertToType(k, keyType);
- 596 :
var value = exports.convertToType(data[k], valueType);
- 597 :
result[key] = value;
- 598 :
}
- 599 :
}
- 600 :
return result;
- 601 :
} else {
- 602 :
// for unknown type, return the data directly
- 603 :
return data;
- 604 :
}
- 605 :
}
- 606 :
};
- 607 :
- 608 :
/**
- 609 :
* Constructs a new map or array model from REST data.
- 610 :
* @param data {Object|Array} The REST data.
- 611 :
* @param obj {Object|Array} The target object or array.
- 612 :
*/
- 613 :
exports.constructFromObject = function(data, obj, itemType) {
- 614 :
if (Array.isArray(data)) {
- 615 :
for (var i = 0; i < data.length; i++) {
- 616 :
if (data.hasOwnProperty(i))
- 617 :
obj[i] = exports.convertToType(data[i], itemType);
- 618 :
}
- 619 :
} else {
- 620 :
for (var k in data) {
- 621 :
if (data.hasOwnProperty(k))
- 622 :
obj[k] = exports.convertToType(data[k], itemType);
- 623 :
}
- 624 :
}
- 625 :
};
- 626 :
- 627 :
exports.prototype.resourcePath = function (path, pathParams) {
- 628 :
if (!path.match(/^\//)) {
- 629 :
path = '/' + path;
- 630 :
}
- 631 :
var url = path;
- 632 :
var _this = this;
- 633 :
url = url.replace(/{([\w-]+)}/g, function (fullMatch, key) {
- 634 :
var value;
- 635 :
if (pathParams.hasOwnProperty(key)) {
- 636 :
value = _this.paramToString(pathParams[key]);
- 637 :
} else {
- 638 :
value = fullMatch;
- 639 :
}
- 640 :
return encodeURIComponent(value);
- 641 :
});
- 642 :
return url;
- 643 :
};
- 644 :
- 645 :
exports.getFormString = function (params) {
- 646 :
var key;
- 647 :
var response = {};
- 648 :
var paramString = '';
- 649 :
var logArray = [];
- 650 :
- 651 :
for (key in params) {
- 652 :
if (params.hasOwnProperty(key)) {
- 653 :
var value = params[key];
- 654 :
if (Array.isArray(value)) {
- 655 :
for (var k in value) {
- 656 :
if (value.hasOwnProperty(k)) {
- 657 :
var v = value[k];
- 658 :
if (!exports.isNullOrUndefined(v)) {
- 659 :
paramString = paramString + (key.trim() + '=' + v) + '&';
- 660 :
logArray.push({
- 661 :
'key': key,
- 662 :
'value': v
- 663 :
});
- 664 :
}
- 665 :
}
- 666 :
}
- 667 :
} else {
- 668 :
if (!exports.isNullOrUndefined(value)) {
- 669 :
paramString = paramString + (key + '=' + value) + '&';
- 670 :
logArray.push({
- 671 :
'key': key,
- 672 :
'value': value
- 673 :
});
- 674 :
}
- 675 :
}
- 676 :
}
- 677 :
}
- 678 :
response['paramString'] = paramString.substring(0, paramString.length - 1);
- 679 :
response['logArray'] = logArray;
- 680 :
- 681 :
return response;
- 682 :
};
- 683 :
- 684 :
- 685 :
exports.isNullOrUndefined = function (data) {
- 686 :
return (typeof(data) === 'undefined' || data === null);
- 687 :
};
- 688 :
- 689 :
- 690 :
exports.isEmptyString = function (string) {
- 691 :
return (string === undefined || string === null || string === '');
- 692 :
};
- 693 :
- 694 :
exports.getQueryString = function (inparams) {
- 695 :
var key;
- 696 :
var trimmedValue;
- 697 :
var paramString = '';
- 698 :
var filteredKeys = [];
- 699 :
var params = {};
- 700 :
- 701 :
for (key in inparams) {
- 702 :
if (inparams.hasOwnProperty(key) && !exports.isEmptyString(key) && !exports.isEmptyString(key.trim()) && inparams[key] !== undefined && inparams[key] !== null) {
- 703 :
params[key.trim()] = inparams[key];
- 704 :
filteredKeys.push(key.trim());
- 705 :
}
- 706 :
}
- 707 :
- 708 :
//sorting Keys
- 709 :
filteredKeys.sort();
- 710 :
- 711 :
for (var i = 0; i < filteredKeys.length; i++) {
- 712 :
key = filteredKeys[i];
- 713 :
var value = params[key];
- 714 :
if (Array.isArray(value)) {
- 715 :
- 716 :
value = value.map(Function.prototype.call, String.prototype.trim);
- 717 :
- 718 :
//sorting values
- 719 :
value.sort();
- 720 :
- 721 :
for (var k in value) {
- 722 :
if (value.hasOwnProperty(k)) {
- 723 :
var v = value[k];
- 724 :
if (!exports.isEmptyString(v)) {
- 725 :
trimmedValue = v.trim();
- 726 :
if (!exports.isEmptyString(trimmedValue)) {
- 727 :
paramString = paramString + (key.trim() + '=' + trimmedValue) + '&';
- 728 :
}
- 729 :
}
- 730 :
}
- 731 :
}
- 732 :
- 733 :
} else {
- 734 :
if (!exports.isEmptyString(value)) {
- 735 :
trimmedValue = value.trim();
- 736 :
if (!exports.isEmptyString(trimmedValue)) {
- 737 :
paramString = paramString + (key.trim() + '=' + trimmedValue) + '&';
- 738 :
}
- 739 :
}
- 740 :
}
- 741 :
}
- 742 :
return paramString.substring(0, paramString.length - 1);
- 743 :
};
- 744 :
- 745 :
exports.getHeaderString = function (inparams) {
- 746 :
var key;
- 747 :
var trimmedValue;
- 748 :
var paramString = '';
- 749 :
var filteredKeys = [];
- 750 :
var params = {};
- 751 :
- 752 :
for (key in inparams) {
- 753 :
if (inparams.hasOwnProperty(key) && !exports.isEmptyString(key) && !exports.isEmptyString(key.trim()) && exports.isValidHeaderParam(key.trim()) && inparams[key] !== undefined && inparams[key] !== null) {
- 754 :
params[key.trim()] = inparams[key];
- 755 :
filteredKeys.push(key.trim());
- 756 :
}
- 757 :
}
- 758 :
- 759 :
//sorting Keys
- 760 :
filteredKeys.sort();
- 761 :
- 762 :
for (var i = 0; i < filteredKeys.length; i++) {
- 763 :
key = filteredKeys[i];
- 764 :
var value = params[key];
- 765 :
if (!exports.isEmptyString(value)) {
- 766 :
trimmedValue = value.trim();
- 767 :
if (!exports.isEmptyString(trimmedValue)) {
- 768 :
paramString = paramString + (key.trim() + '=' + trimmedValue) + '&';
- 769 :
}
- 770 :
}
- 771 :
}
- 772 :
return paramString.substring(0, paramString.length - 1);
- 773 :
};
- 774 :
- 775 :
exports.computeOPAY1HMACSHA256Hash = function (resourcePath, method, queryParams, headerParams, formParams, body, signatureKey) {
- 776 :
if(signatureKey == null || signatureKey == '' ){
- 777 :
throw new Error('Invalid value for secret');
- 778 :
}
- 779 :
var textToHash = '';
- 780 :
textToHash = textToHash + method.toUpperCase() + ':';
- 781 :
textToHash = textToHash + '/payments/v1' + decodeURIComponent(resourcePath) + ':';
- 782 :
textToHash = textToHash + exports.getQueryString(queryParams) + ':';
- 783 :
textToHash = textToHash + exports.getHeaderString(headerParams) + ':';
- 784 :
- 785 :
if (exports.isNonEmptyObject(body)) {
- 786 :
textToHash = textToHash + JSON.stringify(body);
- 787 :
logger.debug('HTTP Request Body :', JSON.stringify(body, CommonUtil.maskSensitiveInfo));
- 788 :
} else {
- 789 :
var formData = exports.getFormString(formParams);
- 790 :
textToHash = textToHash + formData['paramString'];
- 791 :
logger.debug('Form Params :', CommonUtil.maskSensitiveFormParams(formData['logArray']));
- 792 :
}
- 793 :
- 794 :
var hash = exports.generateHmacHash(signatureKey, textToHash).trim();
- 795 :
- 796 :
var response = {};
- 797 :
- 798 :
response['hash'] = hash;
- 799 :
return response;
- 800 :
};
- 801 :
- 802 :
exports.computeOPAY2HMACSHA256Hash = function (clientKey, apiKey, secretKey, timestamp) {
- 803 :
- 804 :
if(secretKey == null || secretKey == '' ){
- 805 :
throw new Error('Invalid value for secret');
- 806 :
}
- 807 :
- 808 :
var textToHash = '';
- 809 :
textToHash = textToHash + clientKey + ':';
- 810 :
textToHash = textToHash + apiKey + ':';
- 811 :
textToHash = textToHash + secretKey + ':';
- 812 :
textToHash = textToHash + timestamp;
- 813 :
- 814 :
var hash = exports.generateHmacHash(secretKey, textToHash).trim();
- 815 :
- 816 :
var response = {};
- 817 :
- 818 :
response['hash'] = hash;
- 819 :
return response;
- 820 :
};
- 821 :
- 822 :
- 823 :
exports.isNonEmptyObject = function (obj) {
- 824 :
return (obj !== null && typeof obj === 'object' && Object.keys(obj).length > 0);
- 825 :
};
- 826 :
- 827 :
exports.generateHmacHash = function (key, text) {
- 828 :
return crypto.createHmac('sha256', new Buffer(key, 'utf-8')).update(new Buffer(text, 'utf-8')).digest('base64');
- 829 :
};
- 830 :
- 831 :
- 832 :
exports.isValidHeaderParam = function (headerParam) {
- 833 :
return ['product' , 'trace_id' , 'idempotent_request_key' , 'channel' , 'requestor' , 'client_key' , 'X-OPAY-Headers' , 'requestor_type' , 'timestamp'].indexOf(headerParam) !== -1;
- 834 :
};
- 835 :
- 836 :
/**
- 837 :
* The default API client implementation.
- 838 :
* @type {module:ApiClient}
- 839 :
*/
- 840 :
exports.instance = new exports();
- 841 :
- 842 :
return exports;
- 843 :
}));