expresscheckout-nodejs
Version:
Juspay's official expresscheckout-nodejs sdk
329 lines • 15.1 kB
JavaScript
"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