/** * Kushki Service. */ import { IDENTIFIERS as CORE, ILogger } from "@kushki/core"; import * as crypto from "crypto"; import { HmacSHA256, WordArray } from "crypto-js"; import { inject, injectable } from "inversify"; import { IKushkiService } from "repository/IKushkiService"; import { OptionsWithUri } from "request"; import * as rp from "request-promise"; import { Observable, of } from "rxjs"; import { switchMap } from "rxjs/operators"; import { TransactionFetch } from "types/transaction_fetch"; /** * Implementation */ @injectable() export class KushkiService implements IKushkiService { private readonly _logger: ILogger; constructor(@inject(CORE.ILogger) logger: ILogger) { this._logger = logger; } public generateToken(): string { const max_length: number = 32; const min_length: number = 0; return crypto .randomBytes(Math.ceil(max_length)) .toString("hex") .slice(min_length, max_length); } public generateTicketNumber(): string { const ticket_number_init: number = 2; const ticket_number_end: number = 14; const date: Date = new Date(); const components: number[] = [ date.getFullYear(), date.getMonth(), date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds(), date.getMilliseconds(), ]; return components.join("").substring(ticket_number_init, ticket_number_end); } public getTime(): number { const time: number = new Date().getTime(); const real_time_stamp: string = time.toString(); return Number(real_time_stamp); } public buildWebHookRequest( body: TransactionFetch, privateMid: string, url: string ): Observable { this._logger.info("Building queueWebhooks request."); const timestamp: number = new Date().getTime(); const signature: string = this._generateWebHookSign( privateMid, JSON.stringify(body), timestamp ); return this._sendWebHookRequest( url, body.publicMerchantId, signature, timestamp, body ); } private _generateWebHookSign( secretId: string, body: string, timestamp: number ): string { const payload: string = `${body}.${timestamp}`; const hash: WordArray = HmacSHA256(payload, secretId); this._logger.info(`Signature: ${hash.toString()}`); return hash.toString(); } private _sendWebHookRequest( url: string, clientId: string, signature: string, timestamp: number, body: TransactionFetch ): Observable { this._logger.info("Agent - webhookRequest", { url, clientId, signature, timestamp, body, }); const options: OptionsWithUri = { body, uri: url, headers: { "X-Kushki-Key": clientId, "X-Kushki-Signature": signature, "X-Kushki-Id": timestamp, }, json: true, }; this._logger.info("Options", options); return of(1).pipe(switchMap(() => rp.post(options))); } }