UNPKG

@trilo/hippopotamus

Version:

Make requests to the Trilo ecosystem

450 lines (449 loc) 22.1 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __generator = (this && this.__generator) || function (thisArg, body) { var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); while (_) try { if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; case 5: _.label++; y = op[1]; op = [0]; continue; case 7: op = _.ops.pop(); _.trys.pop(); continue; default: if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } if (t[2]) _.ops.pop(); _.trys.pop(); continue; } op = body.call(thisArg, _); } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } }; Object.defineProperty(exports, "__esModule", { value: true }); exports.Trilo = void 0; var node_fetch_1 = require("node-fetch"); // import { AgreementUndertaking } from "../../../baobab/src/API"; // import { // TAgreement, // TSendingBank, // TSendingBankAccount, // } from "../../../baobab/types"; var constants_1 = require("./constants"); var getStagePrefix_1 = require("./getStagePrefix"); var setupCredentials_1 = require("./setupCredentials"); var urls_1 = require("./urls"); var sanitisation_1 = require("./sanitisation"); var Trilo = /** @class */ (function () { function Trilo(_a) { var _this = this; var credentials = _a.credentials, stage = _a.stage, debug = _a.debug, redirectUri = _a.redirectUri; this.key = ""; this.secret = ""; this.expireAt = 0; this.stagePrefix = ""; this.debug = false; this.redirectUri = ""; this.logger = function () { var what = []; for (var _i = 0; _i < arguments.length; _i++) { what[_i] = arguments[_i]; } if (_this.debug) { console.log.apply(console, what); } }; this.init = function () { return __awaiter(_this, void 0, void 0, function () { var _a, canEnterAgreement, allowedRedirectUris; var _b; return __generator(this, function (_c) { switch (_c.label) { case 0: if (!(this.key && this.secret)) return [3 /*break*/, 3]; return [4 /*yield*/, setupCredentials_1.default({ stagePrefix: this.stagePrefix, key: this.key, secret: this.secret, })]; case 1: (_b = _c.sent(), this.accessToken = _b.accessToken, // basicString: this.basicString, this.expireAt = _b.expireAt); this.logger("Obtained credentials, expiring at " + this.expireAt); return [4 /*yield*/, this.setupConfig()]; case 2: _a = _c.sent(), canEnterAgreement = _a.canEnterAgreement, allowedRedirectUris = _a.allowedRedirectUris; if (!canEnterAgreement) { this.logger("Merchant is unable to entire an agreemnt"); } if (allowedRedirectUris && allowedRedirectUris.length === 1) { // only have 1 so just use it if (!this.redirectUri) { // haven't already set in init config this.redirectUri = allowedRedirectUris[0]; } } _c.label = 3; case 3: return [2 /*return*/]; } }); }); }; this.setupConfig = function () { return __awaiter(_this, void 0, void 0, function () { return __generator(this, function (_a) { return [2 /*return*/, this.baobabFetcher({ content: {}, path: constants_1.EPATH.GET_CONFIG, })]; }); }); }; /** * Obtain a trilo id to submit with a new Agreement to identify your consumer */ this.getTriloId = function (_a) { var userAttribute = _a.userAttribute, email = _a.email, phone = _a.phone; return __awaiter(_this, void 0, void 0, function () { var response; return __generator(this, function (_b) { switch (_b.label) { case 0: this.logger("getTriloId", { userAttribute: userAttribute, email: email, phone: phone, }); return [4 /*yield*/, this.baobabFetcher({ content: { userAttribute: userAttribute, email: email, phone: phone }, path: constants_1.EPATH.GET_TRILOID, })]; case 1: response = _b.sent(); this.logger(response); return [2 /*return*/, response]; } }); }); }; /** * use the key and secret to get an access token from the OAuth server Cognito */ this.newAgreement = function (_a) { var amount = _a.amount, _b = _a.currency, currency = _b === void 0 ? "gbp" : _b, _c = _a.triloId, triloId = _c === void 0 ? undefined : _c; return __awaiter(_this, void 0, void 0, function () { var response, agreementId, status_1, authenticationUri, sendingBankAccounts, sendingBanks, agreement, version, error_1; var _d, _e, _f; return __generator(this, function (_g) { switch (_g.label) { case 0: _g.trys.push([0, 9, , 10]); amount = sanitisation_1.checkAmount(amount); return [4 /*yield*/, this.makeAgreementId({ amount: amount, currency: currency, redirectUri: this.redirectUri, })]; case 1: response = _g.sent(); agreementId = response.agreementId; status_1 = constants_1.SESSION_STATE.PERFORM_AUTH; authenticationUri = undefined; sendingBankAccounts = []; sendingBanks = []; if (!triloId) return [3 /*break*/, 7]; return [4 /*yield*/, this.camelFetcher({ path: constants_1.EPATH.COLLECT_AGREEMENT, content: { triloId: triloId, agreementId: agreementId, }, })]; case 2: agreement = (_g.sent()).agreement; return [4 /*yield*/, this.listBanks({ triloId: triloId })]; case 3: // get the user's preferred banks (_d = _g.sent(), _e = _d.sendingBankAccounts, sendingBankAccounts = _e === void 0 ? [] : _e, _f = _d.sendingBanks, sendingBanks = _f === void 0 ? [] : _f); if (!sendingBankAccounts.length) return [3 /*break*/, 5]; version = agreement.version; return [4 /*yield*/, this.camelFetcher({ path: constants_1.EPATH.ACCEPT_AGREEMENT, content: { triloId: triloId, agreementId: agreementId, version: version, accepted: true, sendingBankAccountId: sendingBankAccounts[0].id, }, })]; case 4: // have at least one, use index 0 to collect agreement (authenticationUri = (_g.sent()).authUrl); return [3 /*break*/, 6]; case 5: status_1 = constants_1.SESSION_STATE.SELECT_BANK; _g.label = 6; case 6: return [3 /*break*/, 8]; case 7: // generic agreement so return generic getway url authenticationUri = urls_1.makePayUrl({ stagePrefix: this.stagePrefix, agreementId: agreementId, }); _g.label = 8; case 8: return [2 /*return*/, { status: status_1, sendingBankAccounts: sendingBankAccounts, sendingBanks: sendingBanks, agreementId: agreementId, authenticationUri: authenticationUri, success: true, }]; case 9: error_1 = _g.sent(); return [2 /*return*/, { error: error_1, success: false, }]; case 10: return [2 /*return*/]; } }); }); }; this.listBanks = function (_a) { var triloId = _a.triloId; return _this.camelFetcher({ path: constants_1.EPATH.FIND_BANKS, content: { triloId: triloId, undertaking: "SingleImmediate", }, }); }; this.makeAgreementId = function (_a) { var redirectUri = _a.redirectUri, amount = _a.amount, _b = _a.currency, currency = _b === void 0 ? "gbp" : _b; return __awaiter(_this, void 0, void 0, function () { var response; return __generator(this, function (_c) { switch (_c.label) { case 0: return [4 /*yield*/, this.baobabFetcher({ path: constants_1.EPATH.INITIATE, content: { amount: amount, currency: currency, redirectUri: redirectUri, }, })]; case 1: response = _c.sent(); if (response.success) { return [2 /*return*/, { agreementId: response.agreementId }]; } throw JSON.stringify(response); } }); }); }; this.cancelAgreement = function (_a) { var agreementId = _a.id; return _this.baobabFetcher({ content: { agreementId: agreementId, cancel: true, }, path: constants_1.EPATH.CANCEL, }); }; this.baobabFetcher = function (_a) { var content = _a.content, path = _a.path, _b = _a.headers, headers = _b === void 0 ? {} : _b; return __awaiter(_this, void 0, void 0, function () { return __generator(this, function (_c) { return [2 /*return*/, this.fetcher({ url: urls_1.baobabUrl({ path: path, stagePrefix: this.stagePrefix }), content: content, headers: headers, })]; }); }); }; this.camelFetcher = function (_a) { var content = _a.content, path = _a.path, _b = _a.headers, headers = _b === void 0 ? {} : _b; return __awaiter(_this, void 0, void 0, function () { return __generator(this, function (_c) { return [2 /*return*/, this.fetcher({ url: urls_1.camelApiUrl({ path: path, stagePrefix: this.stagePrefix }), content: content, headers: headers, })]; }); }); }; this.fetcher = function (_a) { var content = _a.content, url = _a.url, _b = _a.headers, extraHeaders = _b === void 0 ? {} : _b; return __awaiter(_this, void 0, void 0, function () { var headers, req; var _this = this; return __generator(this, function (_c) { switch (_c.label) { case 0: return [4 /*yield*/, this.getAuthHeaders()]; case 1: headers = _c.sent(); Object.entries(extraHeaders).forEach(function (_a) { var key = _a[0], value = _a[1]; return headers.set(key, value); }); req = new node_fetch_1.Request(url, { method: "POST", headers: headers, body: JSON.stringify(content), }); return [2 /*return*/, node_fetch_1.default(req).then(function (response) { return __awaiter(_this, void 0, void 0, function () { var json; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, response.json()]; case 1: json = _a.sent(); this.logger(json); return [2 /*return*/, json]; } }); }); })]; } }); }); }; this.getAuthHeaders = function () { return __awaiter(_this, void 0, void 0, function () { var headers; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this.isReady()]; case 1: _a.sent(); headers = new node_fetch_1.Headers(); headers.set("Authorization", "Bearer " + this.accessToken); headers.set("Content-Type", "application/json"); return [2 /*return*/, headers]; } }); }); }; this.signup = function (_a) { var email = _a.email, password = _a.password; return __awaiter(_this, void 0, void 0, function () { var triloId, UserSub; return __generator(this, function (_b) { switch (_b.label) { case 0: return [4 /*yield*/, this.camelFetcher({ path: constants_1.EPATH.GET_CREDENTIALS, content: {}, })]; case 1: triloId = (_b.sent()).identityId; return [4 /*yield*/, this.camelFetcher({ path: constants_1.EPATH.SIGNUP, content: { email: email, password: password, triloId: triloId, }, })]; case 2: UserSub = (_b.sent()).UserSub; return [2 /*return*/, { triloId: triloId, }]; } }); }); }; this.login = function (_a) { var email = _a.email, password = _a.password; return __awaiter(_this, void 0, void 0, function () { var triloId; return __generator(this, function (_b) { switch (_b.label) { case 0: return [4 /*yield*/, this.camelFetcher({ path: constants_1.EPATH.SIGNUP, content: { username: email, password: password, }, })]; case 1: triloId = (_b.sent()).identityId; return [2 /*return*/, { triloId: triloId, }]; } }); }); }; this.checkIdentity = function (_a) { var triloId = _a.triloId; return __awaiter(_this, void 0, void 0, function () { var identityId; return __generator(this, function (_b) { switch (_b.label) { case 0: return [4 /*yield*/, this.camelFetcher({ path: constants_1.EPATH.GET_CREDENTIALS, content: { triloId: triloId, }, })]; case 1: identityId = (_b.sent()).identityId; return [2 /*return*/, { loggedIn: identityId === triloId, }]; } }); }); }; this.isReady = function () { return new Promise(function (res, rej) { if (_this.accessToken) { res(); } else { var failureTime_1 = 2000; var readyInterval_1 = setInterval(function () { failureTime_1--; if (_this.accessToken) { clearInterval(readyInterval_1); res(); } else if (failureTime_1 < 0) { clearInterval(readyInterval_1); rej("No Access Token recieved within 2s"); } }, 1); } }); }; if (debug) { this.debug = debug; } if (redirectUri) { this.redirectUri = redirectUri; } (this.stagePrefix = getStagePrefix_1.default(stage, this.logger).stagePrefix); this.key = credentials === null || credentials === void 0 ? void 0 : credentials.key; this.secret = credentials === null || credentials === void 0 ? void 0 : credentials.secret; this.init(); } return Trilo; }()); exports.Trilo = Trilo;