UNPKG

expresscheckout-nodejs

Version:

Juspay's official expresscheckout-nodejs sdk

329 lines 15.1 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); /* eslint-disable @typescript-eslint/no-explicit-any */ const http = __importStar(require("http")); const https = __importStar(require("https")); const url_1 = require("url"); const Juspay_js_1 = __importDefault(require("./Juspay.js")); const utils_js_1 = require("./utils.js"); const JuspayError_js_1 = require("./JuspayError.js"); const index_js_1 = __importDefault(require("./security/index.js")); const JuspayLogger_js_1 = require("./JuspayLogger.js"); class JuspayResource { constructor(juspayEnv) { this.logger = JuspayLogger_js_1.DefaultJuspayLogger.getLoggerInstance(JuspayResource.name); this.juspayEnvironment = juspayEnv; } makeServiceCall({ method, path = '/', headers = {}, body, timeout, query, juspayOverrideConfig, auth = ['BASIC'], opts = { authPriority: 'default', }, }) { return new Promise(async (resolve, reject) => { try { const juspayEnvironment = this.juspayEnvironment.override(juspayOverrideConfig); const authMethod = this.authDecider(juspayEnvironment, auth, opts); headers = Object.assign(Object.assign({ 'Content-Type': 'application/x-www-form-urlencoded', 'User-Agent': `NODEJS_SDK/${Juspay_js_1.default.pkg.version}`, version: juspayEnvironment.getVersion(), 'x-merchantid': juspayEnvironment.getMerchantId() }, headers), juspayEnvironment.getHeaders()); switch (authMethod) { case 'BASIC': const apiKey = juspayEnvironment.getApiKey(), merchantId = juspayEnvironment.getMerchantId(); if (apiKey == undefined || merchantId == undefined) { throw new TypeError(`Using BASIC auth, please set merchant id and api key to use this resource ${path}.`); } headers = Object.assign(Object.assign({}, headers), { Authorization: 'Basic ' + (0, utils_js_1.base64Encode)(apiKey) }); break; case 'JWE': const jweAuthConfig = juspayEnvironment.getJweEncryption(); if (jweAuthConfig == undefined) { throw new TypeError('Using JWE auth, please set jweAuth field in config'); } headers = Object.assign(Object.assign({}, headers), { 'Content-Type': 'application/json' }); if (opts.jwePath == undefined) { path = `/v4${path}`; } else { path = opts.jwePath; } let dataToEncrypt; if (method == 'GET') { method = 'POST'; dataToEncrypt = JSON.stringify(query); } else { dataToEncrypt = JSON.stringify(body); } body = index_js_1.default.JWT.jwtEncrypt(dataToEncrypt, jweAuthConfig.keyId, jweAuthConfig.publicKey, jweAuthConfig.privateKey); break; case 'SIGNATURE': default: throw new TypeError('Auth method not implemented'); } let data = ''; if (method != 'GET') { if (headers['Content-Type'] == 'application/x-www-form-urlencoded') { data = (0, utils_js_1.prepareData)(body); } else { data = JSON.stringify(body); } } this.logger.info({ value: body, message: 'Request parameters', }); let pathWithQueryParams = path; if (authMethod != 'JWE') { pathWithQueryParams = path + (0, utils_js_1.prepareQueryParams)(query); } const fullPath = new url_1.URL(pathWithQueryParams, juspayEnvironment.getBaseUrl()), isInsecureConnection = fullPath.protocol === 'http'; let agent = opts.agent; if (!agent) { agent = isInsecureConnection ? new http.Agent({ keepAlive: true }) : new https.Agent({ keepAlive: true }); } this.logger.info({ message: 'Executing request', value: fullPath.pathname + fullPath.search, }); const httpOptions = { host: fullPath.host, port: fullPath.port, path: fullPath.pathname + fullPath.search, method, agent, // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore headers, }; const req = (isInsecureConnection ? http : https).request(httpOptions); req.setTimeout(timeout || juspayEnvironment.getTimeout(), () => { req.destroy(new JuspayError_js_1.TimeoutError('Socket Timeout during request execution')); }); req.on('response', async (res) => { this.logger.info({ message: 'Received HTTP Response Code', value: res.statusCode, }); const httpResponse = new HttpResponseHandler(res, authMethod, juspayEnvironment.getJweEncryption()); try { resolve(await httpResponse.parseResponse()); } catch (error) { this.logger.error(error); reject(error); } }); req.on('error', (error) => { this.logger.error({ message: 'Please check your internet connection/Failed to establish connection', value: error, }); reject(error); }); req.once('socket', (socket) => { if (socket.connecting) { socket.once(isInsecureConnection ? 'connect' : 'secureConnect', () => { req.write(data); req.end(); }); } else { req.write(data); req.end(); } }); } catch (error) { this.logger.error(error); return reject(error); } }); } authDecider(juspayEnvironment, auth, opts) { const defaultPriority = [ 'JWE', 'SIGNATURE', 'BASIC', ]; let priority = []; if (opts.authPriority == 'default' || opts.authPriority == undefined) { for (let i = 0; i < defaultPriority.length; i++) { const authMethod = defaultPriority[i]; if (auth.includes(authMethod)) { priority.push(authMethod); } } } else { priority = auth; } for (let i = 0; i < priority.length; i++) { const authMethod = priority[i]; switch (authMethod) { case 'BASIC': if (juspayEnvironment.getApiKey() && juspayEnvironment.getMerchantId()) { return 'BASIC'; } break; case 'JWE': if (juspayEnvironment.getJweEncryption()) { return 'JWE'; } break; case 'SIGNATURE': default: throw new TypeError(authMethod + ' auth is not implemented'); } } if (juspayEnvironment.getApiKey() && juspayEnvironment.getMerchantId() && opts.authPriority != 'ordered') { return 'BASIC'; } if (priority.includes('BASIC') == false) { priority.push('BASIC'); } const errorMessage = `No authentication config found in Juspay instance. Please setup the config to support this auth ${priority}. For JWE encryption. Setup using new Juspay(jweAuth: {keyId:string, publicKey:string, privateKey: string}, merchantId:string). You can get these configs from dashboard under security>JWT section. For BASIC authentication. Setup using new Juspay({apiKey:string, merchantId:string}), you can get apiKey from dashboard under security?API KEYS. Please ensure merchantId has been set. `; throw new TypeError(errorMessage); } } class HttpResponseHandler { constructor(res, authMethod, jweAuthConfig) { this.logger = JuspayLogger_js_1.DefaultJuspayLogger.getLoggerInstance(HttpResponseHandler.name); // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore this.__status_code = res.statusCode; // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore this.__headers = res.headers || {}; this.__res = res; this.__jwe_auth_config = jweAuthConfig; this.__auth_method = authMethod; } getRawResponse() { return this.__res; } getStatusCode() { return this.__status_code; } getHeaders() { return this.__headers; } toStream(streamCompleteCallback) { this.__res.once('end', () => streamCompleteCallback()); return this.__res; } parseResponse() { return new Promise((resolve, reject) => { if (this.__response != undefined) { return resolve(this.__response); } let response = ''; this.__res.setEncoding('utf8'); this.__res.on('data', (chunk) => { response += chunk; }); this.__res.once('end', async () => { this.__response = response; const http = { headers: this.getHeaders(), statusCode: this.getStatusCode(), url: this.__res.url, method: this.__res.method, httpVersion: this.__res.httpVersion, httpVersionMajor: this.__res.httpVersionMajor, httpVersionMinor: this.__res.httpVersionMinor, headersDistinct: this.__res.headersDistinct, rawHeaders: this.__res.rawHeaders, statusMessage: this.__res.statusMessage, }; let resJson; try { resJson = JSON.parse(response); this.__response = resJson; this.logger.info({ message: 'Received response', value: resJson, }); } catch (e) { this.logger.info({ message: 'Received response', value: response, }); reject(new JuspayError_js_1.InternalServerError(this.__response)); } let finalResponse = Object.assign(Object.assign({}, resJson), { http }); try { if (this.__status_code >= 200 && this.__status_code < 300) { switch (this.__auth_method) { case 'JWE': const decryptedResponse = this.jweDecryptRequest(resJson); finalResponse = Object.assign(Object.assign({}, decryptedResponse), { http }); break; case 'BASIC': case 'SIGNATURE': default: finalResponse = Object.assign(Object.assign({}, resJson), { http }); } return resolve(finalResponse); } else { const statusCode = this.__res.statusCode; if (statusCode == 400 || statusCode == 404) return reject(new JuspayError_js_1.InvalidRequestError(this.__response)); else if (statusCode == 401) return reject(new JuspayError_js_1.AuthenticationError(this.__response)); else if (statusCode == 403) return reject(new JuspayError_js_1.AuthorizationError(this.__response)); else return reject(new JuspayError_js_1.APIError(this.__response)); } } catch (err) { reject(new JuspayError_js_1.JuspayError(err)); } }); }); } jweDecryptRequest(body) { const jweAuthConfig = this.__jwe_auth_config; if (jweAuthConfig == undefined) { throw new TypeError('Please setup jwe encryption keys to use jwe + jws auth.'); } const res = index_js_1.default.JWT.jwtDecrypt(body, jweAuthConfig.keyId, jweAuthConfig.publicKey, jweAuthConfig.privateKey); return JSON.parse(res); } } exports.default = JuspayResource; //# sourceMappingURL=JuspayResource.js.map