@front-finance/link
Advanced tools
Comparing version 1.0.8 to 1.1.1
@@ -38,166 +38,91 @@ "use strict"; | ||
}; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.createFrontConnection = void 0; | ||
var nonce_1 = require("./utils/nonce"); | ||
var localforage_1 = __importDefault(require("localforage")); | ||
var popup_1 = require("./utils/popup"); | ||
var authLinkHostKey = 'front-auth-link-host'; | ||
var hostRegex = /^https?:\/\/[^/]+/i; | ||
function saveAuthLinkHost(authLink) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var result; | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
result = hostRegex.exec(authLink); | ||
if (!(result && result.length > 0)) return [3 /*break*/, 2]; | ||
return [4 /*yield*/, localforage_1.default.setItem(authLinkHostKey, result[0])]; | ||
case 1: | ||
_a.sent(); | ||
_a.label = 2; | ||
case 2: return [2 /*return*/]; | ||
var event_types_1 = require("./utils/event-types"); | ||
var currentOptions; | ||
var iframeUrlObject; | ||
function eventsListener(event) { | ||
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k; | ||
switch (event.data.type) { | ||
case 'brokerageAccountAccessToken': { | ||
var payload = { | ||
accessToken: event.data.payload | ||
}; | ||
(_a = currentOptions === null || currentOptions === void 0 ? void 0 : currentOptions.onEvent) === null || _a === void 0 ? void 0 : _a.call(currentOptions, { | ||
type: 'integrationConnected', | ||
payload: payload | ||
}); | ||
(_b = currentOptions === null || currentOptions === void 0 ? void 0 : currentOptions.onBrokerConnected) === null || _b === void 0 ? void 0 : _b.call(currentOptions, payload); | ||
break; | ||
} | ||
case 'delayedAuthentication': { | ||
var payload = { | ||
delayedAuth: event.data.payload | ||
}; | ||
(_c = currentOptions === null || currentOptions === void 0 ? void 0 : currentOptions.onEvent) === null || _c === void 0 ? void 0 : _c.call(currentOptions, { | ||
type: 'integrationConnected', | ||
payload: payload | ||
}); | ||
(_d = currentOptions === null || currentOptions === void 0 ? void 0 : currentOptions.onBrokerConnected) === null || _d === void 0 ? void 0 : _d.call(currentOptions, payload); | ||
break; | ||
} | ||
case 'transferFinished': { | ||
var payload = event.data.payload; | ||
(_e = currentOptions === null || currentOptions === void 0 ? void 0 : currentOptions.onEvent) === null || _e === void 0 ? void 0 : _e.call(currentOptions, { | ||
type: 'transferCompleted', | ||
payload: payload | ||
}); | ||
(_f = currentOptions === null || currentOptions === void 0 ? void 0 : currentOptions.onTransferFinished) === null || _f === void 0 ? void 0 : _f.call(currentOptions, payload); | ||
break; | ||
} | ||
case 'close': | ||
case 'done': { | ||
(_g = currentOptions === null || currentOptions === void 0 ? void 0 : currentOptions.onExit) === null || _g === void 0 ? void 0 : _g.call(currentOptions, event.data.message); | ||
(0, popup_1.removePopup)(); | ||
break; | ||
} | ||
case 'oauthLinkOpen': { | ||
if (event.data.link) { | ||
var w = 700; | ||
var h = 800; | ||
var left = screen.width / 2 - w / 2; | ||
var top_1 = screen.height / 2 - h / 2; | ||
(_h = window | ||
.open(event.data.link, '_blank', "popup,noopener,noreferrer,resizable,scrollbars,width=".concat(w, ",height=").concat(h, ",top=").concat(top_1, ",left=").concat(left))) === null || _h === void 0 ? void 0 : _h.focus(); | ||
} | ||
}); | ||
}); | ||
} | ||
function getAuthLinkHost() { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var host; | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: return [4 /*yield*/, localforage_1.default.getItem(authLinkHostKey)]; | ||
case 1: | ||
host = _a.sent(); | ||
return [2 /*return*/, host || 'https://web.getfront.com']; | ||
break; | ||
} | ||
case 'loaded': { | ||
if (currentOptions === null || currentOptions === void 0 ? void 0 : currentOptions.accessTokens) { | ||
var iframeElement = document.getElementById(popup_1.iframeId); | ||
(_j = iframeElement.contentWindow) === null || _j === void 0 ? void 0 : _j.postMessage({ type: 'frontAccessTokens', payload: currentOptions.accessTokens }, (iframeUrlObject === null || iframeUrlObject === void 0 ? void 0 : iframeUrlObject.origin) || 'https://web.getfront.com'); | ||
} | ||
}); | ||
}); | ||
} | ||
var iframeId = 'front-link'; | ||
function deleteIframe() { | ||
var iframe = document.getElementById(iframeId); | ||
if (iframe) { | ||
setTimeout(function () { return iframe.remove(); }, 1000); | ||
} | ||
} | ||
function createListenerIframe(options, host) { | ||
var iframe = document.createElement('iframe'); | ||
iframe.id = iframeId; | ||
iframe.title = 'Front'; | ||
iframe.style.width = '0'; | ||
iframe.style.height = '0'; | ||
iframe.src = "".concat(host, "/b2b-iframe/").concat(options.clientId); | ||
document.body.appendChild(iframe); | ||
var messageListener = function (event) { | ||
switch (event.data.type) { | ||
case 'brokerageAccountAccessToken': { | ||
var payload = { | ||
accessToken: event.data.payload | ||
}; | ||
options.onBrokerConnected && options.onBrokerConnected(payload); | ||
break; | ||
break; | ||
} | ||
default: { | ||
if ((0, event_types_1.isFrontEventTypeKey)(event.data.type)) { | ||
(_k = currentOptions === null || currentOptions === void 0 ? void 0 : currentOptions.onEvent) === null || _k === void 0 ? void 0 : _k.call(currentOptions, event.data); | ||
} | ||
case 'delayedAuthentication': { | ||
var payload = { | ||
delayedAuth: event.data.payload | ||
}; | ||
options.onBrokerConnected && options.onBrokerConnected(payload); | ||
break; | ||
} | ||
case 'close': | ||
case 'done': { | ||
options.onExit && options.onExit(event.data.message); | ||
deleteIframe(); | ||
break; | ||
} | ||
break; | ||
} | ||
}; | ||
window.addEventListener('message', messageListener); | ||
} | ||
} | ||
function checkNonceAndCreateIframe(options) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var queryParams, isSuccessConnection, nonce, isNonceValid, host; | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
queryParams = new URLSearchParams(window.location.search); | ||
isSuccessConnection = queryParams.get('front-connection-success'); | ||
nonce = queryParams.get('front-connection-nonce'); | ||
if (isSuccessConnection !== 'true' || !nonce) { | ||
return [2 /*return*/]; | ||
} | ||
return [4 /*yield*/, (0, nonce_1.validateNonce)(nonce)]; | ||
case 1: | ||
isNonceValid = _a.sent(); | ||
if (!isNonceValid) return [3 /*break*/, 3]; | ||
return [4 /*yield*/, getAuthLinkHost()]; | ||
case 2: | ||
host = _a.sent(); | ||
createListenerIframe(options, host); | ||
_a.label = 3; | ||
case 3: return [2 /*return*/]; | ||
} | ||
}); | ||
}); | ||
} | ||
function addNonceToUrl(link) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var nonce, delimiter, url; | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: return [4 /*yield*/, saveAuthLinkHost(link)]; | ||
case 1: | ||
_a.sent(); | ||
return [4 /*yield*/, (0, nonce_1.generateAndSaveNonce)()]; | ||
case 2: | ||
nonce = _a.sent(); | ||
delimiter = link.indexOf('?') > 0 ? '&' : '?'; | ||
url = "".concat(link).concat(delimiter, "b2bNonce=").concat(nonce); | ||
return [2 /*return*/, url]; | ||
} | ||
}); | ||
}); | ||
} | ||
var createFrontConnection = function (options) { | ||
var openLink = function (link) { return __awaiter(void 0, void 0, void 0, function () { | ||
var url; | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
if (!link) { | ||
(options === null || options === void 0 ? void 0 : options.onExit) && options.onExit('Invalid link!'); | ||
return [2 /*return*/]; | ||
} | ||
return [4 /*yield*/, addNonceToUrl(link)]; | ||
case 1: | ||
url = _a.sent(); | ||
window.location.href = url; | ||
(0, popup_1.addPopup)(url, options); | ||
return [2 /*return*/]; | ||
} | ||
}); | ||
}); }; | ||
var openPopup = function (iframeUrl) { return __awaiter(void 0, void 0, void 0, function () { | ||
var url; | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
if (!iframeUrl) { | ||
(options === null || options === void 0 ? void 0 : options.onExit) && options.onExit('Invalid link!'); | ||
return [2 /*return*/]; | ||
} | ||
return [4 /*yield*/, addNonceToUrl(iframeUrl)]; | ||
case 1: | ||
url = _a.sent(); | ||
(0, popup_1.addPopup)(url, options); | ||
return [2 /*return*/]; | ||
var _a; | ||
return __generator(this, function (_b) { | ||
if (!iframeUrl) { | ||
(_a = options === null || options === void 0 ? void 0 : options.onExit) === null || _a === void 0 ? void 0 : _a.call(options, 'Invalid link!'); | ||
return [2 /*return*/]; | ||
} | ||
currentOptions = options; | ||
iframeUrlObject = new URL(iframeUrl); | ||
window.removeEventListener('message', eventsListener); | ||
(0, popup_1.addPopup)(iframeUrl); | ||
window.addEventListener('message', eventsListener); | ||
return [2 /*return*/]; | ||
}); | ||
}); }; | ||
checkNonceAndCreateIframe(options); | ||
return { | ||
openLink: openLink, | ||
openPopup: openPopup, | ||
@@ -207,2 +132,3 @@ closePopup: function () { | ||
(0, popup_1.removePopup)(); | ||
window.removeEventListener('message', eventsListener); | ||
(_a = options.onExit) === null || _a === void 0 ? void 0 : _a.call(options); | ||
@@ -209,0 +135,0 @@ } |
@@ -1,3 +0,3 @@ | ||
export * from './utils/nonce'; | ||
export * from './utils/types'; | ||
export * from './utils/event-types'; | ||
export { createFrontConnection } from './FrontConnection'; |
@@ -18,5 +18,5 @@ "use strict"; | ||
exports.createFrontConnection = void 0; | ||
__exportStar(require("./utils/nonce"), exports); | ||
__exportStar(require("./utils/types"), exports); | ||
__exportStar(require("./utils/event-types"), exports); | ||
var FrontConnection_1 = require("./FrontConnection"); | ||
Object.defineProperty(exports, "createFrontConnection", { enumerable: true, get: function () { return FrontConnection_1.createFrontConnection; } }); |
@@ -1,3 +0,3 @@ | ||
import { FrontOptions } from './types'; | ||
export declare const iframeId = "front-link-popup__iframe"; | ||
export declare function removePopup(): void; | ||
export declare function addPopup(iframeLink: string, options: FrontOptions): void; | ||
export declare function addPopup(iframeLink: string): void; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.addPopup = exports.removePopup = void 0; | ||
exports.addPopup = exports.removePopup = exports.iframeId = void 0; | ||
var popupId = 'front-link-popup'; | ||
@@ -8,46 +8,5 @@ var backdropId = 'front-link-popup__backdrop'; | ||
var stylesId = 'front-link-popup__styles'; | ||
var getPopupHtml = function (link) { return "\n<div id=\"".concat(popupId, "\">\n <div id=\"").concat(backdropId, "\"></div>\n <div id=\"").concat(popupContentId, "\">\n <iframe src=\"").concat(link, "\" allow=\"clipboard-read *; clipboard-write *\" />\n </div>\n</div>\n"); }; | ||
exports.iframeId = 'front-link-popup__iframe'; | ||
var getPopupHtml = function (link) { return "\n<div id=\"".concat(popupId, "\">\n <div id=\"").concat(backdropId, "\"></div>\n <div id=\"").concat(popupContentId, "\">\n <iframe id=\"").concat(exports.iframeId, "\" src=\"").concat(link, "\" allow=\"clipboard-read *; clipboard-write *\" />\n </div>\n</div>\n"); }; | ||
var styles = "\n<style id=\"".concat(stylesId, "\">\n body {\n position: fixed;\n left: 0;\n top: 0;\n bottom: 0;\n right: 0;\n overflow: hidden;\n }\n\n #").concat(popupId, " {\n all: unset;\n position: fixed;\n left: 0;\n top: 0;\n bottom: 0;\n right: 0;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n z-index: 10000;\n }\n\n #").concat(backdropId, " {\n position: absolute;\n left: 0;\n top: 0;\n bottom: 0;\n right: 0;\n z-index: 10000;\n background: black;\n opacity: 0.6;\n }\n\n #").concat(popupContentId, " {\n position: absolute;\n height: 80%;\n max-height: 710px;\n min-height: 685px;\n margin: auto;\n z-index: 10001;\n width: 30%;\n max-width: 430px;\n min-width: 380px;\n display: flex;\n flex-direction: column;\n border-radius: 24px;\n background: white;\n flex-grow: 1;\n }\n\n #").concat(popupContentId, " iframe {\n border: none;\n width: 100%;\n flex-grow: 1;\n border-radius: 24px;\n }\n\n @media only screen and (max-width: 768px) {\n #").concat(popupContentId, " {\n height: 100vh;\n width: 100vw;\n max-width: 100%;\n min-width: 100%;\n max-height: 100%;\n min-height: 100%;\n border-radius: 0px;\n }\n\n #").concat(popupContentId, " iframe {\n border-radius: 0px;\n }\n }\n</style>\n"); | ||
var currentOptions; | ||
function eventsListener(event) { | ||
var _a, _b, _c, _d, _e; | ||
switch (event.data.type) { | ||
case 'brokerageAccountAccessToken': { | ||
var payload = { | ||
accessToken: event.data.payload | ||
}; | ||
(_a = currentOptions === null || currentOptions === void 0 ? void 0 : currentOptions.onBrokerConnected) === null || _a === void 0 ? void 0 : _a.call(currentOptions, payload); | ||
break; | ||
} | ||
case 'delayedAuthentication': { | ||
var payload = { | ||
delayedAuth: event.data.payload | ||
}; | ||
(_b = currentOptions === null || currentOptions === void 0 ? void 0 : currentOptions.onBrokerConnected) === null || _b === void 0 ? void 0 : _b.call(currentOptions, payload); | ||
break; | ||
} | ||
case 'transferFinished': { | ||
var payload = event.data.payload; | ||
(_c = currentOptions === null || currentOptions === void 0 ? void 0 : currentOptions.onTransferFinished) === null || _c === void 0 ? void 0 : _c.call(currentOptions, payload); | ||
break; | ||
} | ||
case 'close': | ||
case 'done': { | ||
(_d = currentOptions === null || currentOptions === void 0 ? void 0 : currentOptions.onExit) === null || _d === void 0 ? void 0 : _d.call(currentOptions, event.data.message); | ||
removePopup(); | ||
break; | ||
} | ||
case 'oauthLinkOpen': { | ||
if (event.data.link) { | ||
var w = 700; | ||
var h = 800; | ||
var left = screen.width / 2 - w / 2; | ||
var top_1 = screen.height / 2 - h / 2; | ||
(_e = window | ||
.open(event.data.link, '_blank', "popup,noopener,noreferrer,resizable,scrollbars,width=".concat(w, ",height=").concat(h, ",top=").concat(top_1, ",left=").concat(left))) === null || _e === void 0 ? void 0 : _e.focus(); | ||
} | ||
break; | ||
} | ||
} | ||
} | ||
function removePopup() { | ||
@@ -64,12 +23,9 @@ var existingPopup = window.document.getElementById(popupId); | ||
} | ||
window.removeEventListener('message', eventsListener); | ||
} | ||
exports.removePopup = removePopup; | ||
function addPopup(iframeLink, options) { | ||
function addPopup(iframeLink) { | ||
removePopup(); | ||
currentOptions = options; | ||
var popup = getPopupHtml(iframeLink); | ||
window.document.head.appendChild(htmlToElement(styles)); | ||
window.document.body.appendChild(htmlToElement(popup)); | ||
window.addEventListener('message', eventsListener); | ||
} | ||
@@ -76,0 +32,0 @@ exports.addPopup = addPopup; |
import type { BrokerType } from '@front-finance/api'; | ||
import { FrontEventType } from './event-types'; | ||
export type EventType = 'brokerageAccountAccessToken' | 'delayedAuthentication' | 'close' | 'done' | 'loaded' | 'oauthLinkOpen' | 'transferFinished'; | ||
export interface FrontConnection { | ||
openLink: (authLink: string) => Promise<void>; | ||
openPopup: (iframeLink: string) => Promise<void>; | ||
closePopup: () => void; | ||
} | ||
export interface SetTitleEvent { | ||
type: 'setTitle'; | ||
title: string; | ||
hideTitle?: boolean; | ||
} | ||
export interface BrokerAccountToken { | ||
@@ -62,7 +57,38 @@ account: BrokerAccount; | ||
export type TransferFinishedPayload = TransferFinishedSuccessPayload | TransferFinishedErrorPayload; | ||
export interface IntegrationAccessToken { | ||
accountId: string; | ||
accountName: string; | ||
accessToken: string; | ||
brokerType: BrokerType; | ||
brokerName: string; | ||
} | ||
export interface FrontOptions { | ||
/** | ||
* Client ID that can be obtained at https://dashboard.getfront.com/company/keys | ||
*/ | ||
clientId: string; | ||
/** | ||
* A callback function that is called when an integration is succesfully connected. | ||
* It receives a payload of type `FrontPayload`. | ||
*/ | ||
onBrokerConnected: (payload: FrontPayload) => void; | ||
/** | ||
* (Optional) A callback function that is called when the Front iframe is closed. | ||
*/ | ||
onExit?: (error?: string) => void; | ||
/** | ||
* (Optional) A callback function that is called when a transfer is finished. | ||
* It receives a payload of type `TransferFinishedPayload`. | ||
*/ | ||
onTransferFinished?: (payload: TransferFinishedPayload) => void; | ||
/** | ||
* (Optional) A callback function that is called when various events occur within the Front iframe. | ||
* It receives an object with type `FrontEventTypeKeys` indicating the event, and an optional 'payload' containing additional data. | ||
*/ | ||
onEvent?: (event: FrontEventType) => void; | ||
/** | ||
* (Optional) An array of integration access tokens. | ||
* These access tokens are used to initialize crypto transfers flow at 'Select asset step' | ||
*/ | ||
accessTokens?: IntegrationAccessToken[]; | ||
} |
@@ -37,161 +37,89 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
}; | ||
import { generateAndSaveNonce, validateNonce } from './utils/nonce'; | ||
import localforage from 'localforage'; | ||
import { addPopup, removePopup } from './utils/popup'; | ||
var authLinkHostKey = 'front-auth-link-host'; | ||
var hostRegex = /^https?:\/\/[^/]+/i; | ||
function saveAuthLinkHost(authLink) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var result; | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
result = hostRegex.exec(authLink); | ||
if (!(result && result.length > 0)) return [3 /*break*/, 2]; | ||
return [4 /*yield*/, localforage.setItem(authLinkHostKey, result[0])]; | ||
case 1: | ||
_a.sent(); | ||
_a.label = 2; | ||
case 2: return [2 /*return*/]; | ||
import { addPopup, iframeId, removePopup } from './utils/popup'; | ||
import { isFrontEventTypeKey } from './utils/event-types'; | ||
var currentOptions; | ||
var iframeUrlObject; | ||
function eventsListener(event) { | ||
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k; | ||
switch (event.data.type) { | ||
case 'brokerageAccountAccessToken': { | ||
var payload = { | ||
accessToken: event.data.payload | ||
}; | ||
(_a = currentOptions === null || currentOptions === void 0 ? void 0 : currentOptions.onEvent) === null || _a === void 0 ? void 0 : _a.call(currentOptions, { | ||
type: 'integrationConnected', | ||
payload: payload | ||
}); | ||
(_b = currentOptions === null || currentOptions === void 0 ? void 0 : currentOptions.onBrokerConnected) === null || _b === void 0 ? void 0 : _b.call(currentOptions, payload); | ||
break; | ||
} | ||
case 'delayedAuthentication': { | ||
var payload = { | ||
delayedAuth: event.data.payload | ||
}; | ||
(_c = currentOptions === null || currentOptions === void 0 ? void 0 : currentOptions.onEvent) === null || _c === void 0 ? void 0 : _c.call(currentOptions, { | ||
type: 'integrationConnected', | ||
payload: payload | ||
}); | ||
(_d = currentOptions === null || currentOptions === void 0 ? void 0 : currentOptions.onBrokerConnected) === null || _d === void 0 ? void 0 : _d.call(currentOptions, payload); | ||
break; | ||
} | ||
case 'transferFinished': { | ||
var payload = event.data.payload; | ||
(_e = currentOptions === null || currentOptions === void 0 ? void 0 : currentOptions.onEvent) === null || _e === void 0 ? void 0 : _e.call(currentOptions, { | ||
type: 'transferCompleted', | ||
payload: payload | ||
}); | ||
(_f = currentOptions === null || currentOptions === void 0 ? void 0 : currentOptions.onTransferFinished) === null || _f === void 0 ? void 0 : _f.call(currentOptions, payload); | ||
break; | ||
} | ||
case 'close': | ||
case 'done': { | ||
(_g = currentOptions === null || currentOptions === void 0 ? void 0 : currentOptions.onExit) === null || _g === void 0 ? void 0 : _g.call(currentOptions, event.data.message); | ||
removePopup(); | ||
break; | ||
} | ||
case 'oauthLinkOpen': { | ||
if (event.data.link) { | ||
var w = 700; | ||
var h = 800; | ||
var left = screen.width / 2 - w / 2; | ||
var top_1 = screen.height / 2 - h / 2; | ||
(_h = window | ||
.open(event.data.link, '_blank', "popup,noopener,noreferrer,resizable,scrollbars,width=".concat(w, ",height=").concat(h, ",top=").concat(top_1, ",left=").concat(left))) === null || _h === void 0 ? void 0 : _h.focus(); | ||
} | ||
}); | ||
}); | ||
} | ||
function getAuthLinkHost() { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var host; | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: return [4 /*yield*/, localforage.getItem(authLinkHostKey)]; | ||
case 1: | ||
host = _a.sent(); | ||
return [2 /*return*/, host || 'https://web.getfront.com']; | ||
break; | ||
} | ||
case 'loaded': { | ||
if (currentOptions === null || currentOptions === void 0 ? void 0 : currentOptions.accessTokens) { | ||
var iframeElement = document.getElementById(iframeId); | ||
(_j = iframeElement.contentWindow) === null || _j === void 0 ? void 0 : _j.postMessage({ type: 'frontAccessTokens', payload: currentOptions.accessTokens }, (iframeUrlObject === null || iframeUrlObject === void 0 ? void 0 : iframeUrlObject.origin) || 'https://web.getfront.com'); | ||
} | ||
}); | ||
}); | ||
} | ||
var iframeId = 'front-link'; | ||
function deleteIframe() { | ||
var iframe = document.getElementById(iframeId); | ||
if (iframe) { | ||
setTimeout(function () { return iframe.remove(); }, 1000); | ||
} | ||
} | ||
function createListenerIframe(options, host) { | ||
var iframe = document.createElement('iframe'); | ||
iframe.id = iframeId; | ||
iframe.title = 'Front'; | ||
iframe.style.width = '0'; | ||
iframe.style.height = '0'; | ||
iframe.src = "".concat(host, "/b2b-iframe/").concat(options.clientId); | ||
document.body.appendChild(iframe); | ||
var messageListener = function (event) { | ||
switch (event.data.type) { | ||
case 'brokerageAccountAccessToken': { | ||
var payload = { | ||
accessToken: event.data.payload | ||
}; | ||
options.onBrokerConnected && options.onBrokerConnected(payload); | ||
break; | ||
break; | ||
} | ||
default: { | ||
if (isFrontEventTypeKey(event.data.type)) { | ||
(_k = currentOptions === null || currentOptions === void 0 ? void 0 : currentOptions.onEvent) === null || _k === void 0 ? void 0 : _k.call(currentOptions, event.data); | ||
} | ||
case 'delayedAuthentication': { | ||
var payload = { | ||
delayedAuth: event.data.payload | ||
}; | ||
options.onBrokerConnected && options.onBrokerConnected(payload); | ||
break; | ||
} | ||
case 'close': | ||
case 'done': { | ||
options.onExit && options.onExit(event.data.message); | ||
deleteIframe(); | ||
break; | ||
} | ||
break; | ||
} | ||
}; | ||
window.addEventListener('message', messageListener); | ||
} | ||
} | ||
function checkNonceAndCreateIframe(options) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var queryParams, isSuccessConnection, nonce, isNonceValid, host; | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
queryParams = new URLSearchParams(window.location.search); | ||
isSuccessConnection = queryParams.get('front-connection-success'); | ||
nonce = queryParams.get('front-connection-nonce'); | ||
if (isSuccessConnection !== 'true' || !nonce) { | ||
return [2 /*return*/]; | ||
} | ||
return [4 /*yield*/, validateNonce(nonce)]; | ||
case 1: | ||
isNonceValid = _a.sent(); | ||
if (!isNonceValid) return [3 /*break*/, 3]; | ||
return [4 /*yield*/, getAuthLinkHost()]; | ||
case 2: | ||
host = _a.sent(); | ||
createListenerIframe(options, host); | ||
_a.label = 3; | ||
case 3: return [2 /*return*/]; | ||
} | ||
}); | ||
}); | ||
} | ||
function addNonceToUrl(link) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var nonce, delimiter, url; | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: return [4 /*yield*/, saveAuthLinkHost(link)]; | ||
case 1: | ||
_a.sent(); | ||
return [4 /*yield*/, generateAndSaveNonce()]; | ||
case 2: | ||
nonce = _a.sent(); | ||
delimiter = link.indexOf('?') > 0 ? '&' : '?'; | ||
url = "".concat(link).concat(delimiter, "b2bNonce=").concat(nonce); | ||
return [2 /*return*/, url]; | ||
} | ||
}); | ||
}); | ||
} | ||
export var createFrontConnection = function (options) { | ||
var openLink = function (link) { return __awaiter(void 0, void 0, void 0, function () { | ||
var url; | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
if (!link) { | ||
(options === null || options === void 0 ? void 0 : options.onExit) && options.onExit('Invalid link!'); | ||
return [2 /*return*/]; | ||
} | ||
return [4 /*yield*/, addNonceToUrl(link)]; | ||
case 1: | ||
url = _a.sent(); | ||
window.location.href = url; | ||
addPopup(url, options); | ||
return [2 /*return*/]; | ||
} | ||
}); | ||
}); }; | ||
var openPopup = function (iframeUrl) { return __awaiter(void 0, void 0, void 0, function () { | ||
var url; | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
if (!iframeUrl) { | ||
(options === null || options === void 0 ? void 0 : options.onExit) && options.onExit('Invalid link!'); | ||
return [2 /*return*/]; | ||
} | ||
return [4 /*yield*/, addNonceToUrl(iframeUrl)]; | ||
case 1: | ||
url = _a.sent(); | ||
addPopup(url, options); | ||
return [2 /*return*/]; | ||
var _a; | ||
return __generator(this, function (_b) { | ||
if (!iframeUrl) { | ||
(_a = options === null || options === void 0 ? void 0 : options.onExit) === null || _a === void 0 ? void 0 : _a.call(options, 'Invalid link!'); | ||
return [2 /*return*/]; | ||
} | ||
currentOptions = options; | ||
iframeUrlObject = new URL(iframeUrl); | ||
window.removeEventListener('message', eventsListener); | ||
addPopup(iframeUrl); | ||
window.addEventListener('message', eventsListener); | ||
return [2 /*return*/]; | ||
}); | ||
}); }; | ||
checkNonceAndCreateIframe(options); | ||
return { | ||
openLink: openLink, | ||
openPopup: openPopup, | ||
@@ -201,2 +129,3 @@ closePopup: function () { | ||
removePopup(); | ||
window.removeEventListener('message', eventsListener); | ||
(_a = options.onExit) === null || _a === void 0 ? void 0 : _a.call(options); | ||
@@ -203,0 +132,0 @@ } |
@@ -1,3 +0,3 @@ | ||
export * from './utils/nonce'; | ||
export * from './utils/types'; | ||
export * from './utils/event-types'; | ||
export { createFrontConnection } from './FrontConnection'; |
@@ -1,3 +0,3 @@ | ||
export * from './utils/nonce'; | ||
export * from './utils/types'; | ||
export * from './utils/event-types'; | ||
export { createFrontConnection } from './FrontConnection'; |
{ | ||
"name": "@front-finance/link", | ||
"version": "1.0.8", | ||
"version": "1.1.1", | ||
"description": "Front Finance accounts connection client lib", | ||
@@ -18,5 +18,3 @@ "license": "MIT", | ||
}, | ||
"dependencies": { | ||
"localforage": "^1.10.0" | ||
}, | ||
"dependencies": {}, | ||
"main": "cjs/index.js", | ||
@@ -23,0 +21,0 @@ "module": "index.js", |
@@ -34,3 +34,3 @@ # @front-finance/link | ||
You can use `iFrameUrl` from this response to open the popup window with `openPopup` method. `url` field is used to open link in the same tab by `openLink` method. | ||
You can use `iFrameUrl` from this response to open the popup window with `openPopup` method. | ||
@@ -106,16 +106,17 @@ ### Generating connection method | ||
| key | type | description | | ||
| -------------------- | ------------------------------------------------------ | ---------------------------------------------------------- | | ||
| `clientId` | `string` | Keys from https://dashboard.getfront.com/company/keys page | | ||
| `onBrokerConnected` | `(payload: FrontPayload) => void` | Callback called when users connects their accounts | | ||
| `onExit` | `((error?: string \| undefined) => void) \| undefined` | Called if connection not happened | | ||
| `onTransferFinished` | `(payload: TransferFinishedPayload) => void` | Callback called when a crypto transfer is executed | | ||
| key | type | description | | ||
| -------------------- | ------------------------------------------------------ | ------------------------------------------------------------------------------------ | | ||
| `clientId` | `string` | Keys from https://dashboard.getfront.com/company/keys page | | ||
| `onBrokerConnected` | `(payload: FrontPayload) => void` | Callback called when users connects their accounts | | ||
| `onExit` | `((error?: string \| undefined) => void) \| undefined` | Called if connection not happened | | ||
| `onTransferFinished` | `(payload: TransferFinishedPayload) => void` | Callback called when a crypto transfer is executed | | ||
| `onEvent` | `(payload: FrontEventType) => void` | A callback function that is called when various events occur within the Front iframe | | ||
| `accessTokens` | `IntegrationAccessToken[]` | An array of integration access tokens | | ||
#### `createFrontConnection` return value | ||
| key | type | description | | ||
| ------------ | -------------------------------------- | ---------------------- | | ||
| `openLink` | `(link: string) => Promise<void>` | Opens url in same tab. | | ||
| `openPopup` | `(iframeUrl: string) => Promise<void>` | Opens url in popup | | ||
| `closePopup` | `() => Promise<void>` | Closes popup window | | ||
| key | type | description | | ||
| ------------ | -------------------------------------- | ------------------- | | ||
| `openPopup` | `(iframeUrl: string) => Promise<void>` | Opens url in popup | | ||
| `closePopup` | `() => Promise<void>` | Closes popup window | | ||
@@ -122,0 +123,0 @@ ### Using tokens |
@@ -1,3 +0,3 @@ | ||
import { FrontOptions } from './types'; | ||
export declare const iframeId = "front-link-popup__iframe"; | ||
export declare function removePopup(): void; | ||
export declare function addPopup(iframeLink: string, options: FrontOptions): void; | ||
export declare function addPopup(iframeLink: string): void; |
@@ -5,46 +5,5 @@ var popupId = 'front-link-popup'; | ||
var stylesId = 'front-link-popup__styles'; | ||
var getPopupHtml = function (link) { return "\n<div id=\"".concat(popupId, "\">\n <div id=\"").concat(backdropId, "\"></div>\n <div id=\"").concat(popupContentId, "\">\n <iframe src=\"").concat(link, "\" allow=\"clipboard-read *; clipboard-write *\" />\n </div>\n</div>\n"); }; | ||
export var iframeId = 'front-link-popup__iframe'; | ||
var getPopupHtml = function (link) { return "\n<div id=\"".concat(popupId, "\">\n <div id=\"").concat(backdropId, "\"></div>\n <div id=\"").concat(popupContentId, "\">\n <iframe id=\"").concat(iframeId, "\" src=\"").concat(link, "\" allow=\"clipboard-read *; clipboard-write *\" />\n </div>\n</div>\n"); }; | ||
var styles = "\n<style id=\"".concat(stylesId, "\">\n body {\n position: fixed;\n left: 0;\n top: 0;\n bottom: 0;\n right: 0;\n overflow: hidden;\n }\n\n #").concat(popupId, " {\n all: unset;\n position: fixed;\n left: 0;\n top: 0;\n bottom: 0;\n right: 0;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n z-index: 10000;\n }\n\n #").concat(backdropId, " {\n position: absolute;\n left: 0;\n top: 0;\n bottom: 0;\n right: 0;\n z-index: 10000;\n background: black;\n opacity: 0.6;\n }\n\n #").concat(popupContentId, " {\n position: absolute;\n height: 80%;\n max-height: 710px;\n min-height: 685px;\n margin: auto;\n z-index: 10001;\n width: 30%;\n max-width: 430px;\n min-width: 380px;\n display: flex;\n flex-direction: column;\n border-radius: 24px;\n background: white;\n flex-grow: 1;\n }\n\n #").concat(popupContentId, " iframe {\n border: none;\n width: 100%;\n flex-grow: 1;\n border-radius: 24px;\n }\n\n @media only screen and (max-width: 768px) {\n #").concat(popupContentId, " {\n height: 100vh;\n width: 100vw;\n max-width: 100%;\n min-width: 100%;\n max-height: 100%;\n min-height: 100%;\n border-radius: 0px;\n }\n\n #").concat(popupContentId, " iframe {\n border-radius: 0px;\n }\n }\n</style>\n"); | ||
var currentOptions; | ||
function eventsListener(event) { | ||
var _a, _b, _c, _d, _e; | ||
switch (event.data.type) { | ||
case 'brokerageAccountAccessToken': { | ||
var payload = { | ||
accessToken: event.data.payload | ||
}; | ||
(_a = currentOptions === null || currentOptions === void 0 ? void 0 : currentOptions.onBrokerConnected) === null || _a === void 0 ? void 0 : _a.call(currentOptions, payload); | ||
break; | ||
} | ||
case 'delayedAuthentication': { | ||
var payload = { | ||
delayedAuth: event.data.payload | ||
}; | ||
(_b = currentOptions === null || currentOptions === void 0 ? void 0 : currentOptions.onBrokerConnected) === null || _b === void 0 ? void 0 : _b.call(currentOptions, payload); | ||
break; | ||
} | ||
case 'transferFinished': { | ||
var payload = event.data.payload; | ||
(_c = currentOptions === null || currentOptions === void 0 ? void 0 : currentOptions.onTransferFinished) === null || _c === void 0 ? void 0 : _c.call(currentOptions, payload); | ||
break; | ||
} | ||
case 'close': | ||
case 'done': { | ||
(_d = currentOptions === null || currentOptions === void 0 ? void 0 : currentOptions.onExit) === null || _d === void 0 ? void 0 : _d.call(currentOptions, event.data.message); | ||
removePopup(); | ||
break; | ||
} | ||
case 'oauthLinkOpen': { | ||
if (event.data.link) { | ||
var w = 700; | ||
var h = 800; | ||
var left = screen.width / 2 - w / 2; | ||
var top_1 = screen.height / 2 - h / 2; | ||
(_e = window | ||
.open(event.data.link, '_blank', "popup,noopener,noreferrer,resizable,scrollbars,width=".concat(w, ",height=").concat(h, ",top=").concat(top_1, ",left=").concat(left))) === null || _e === void 0 ? void 0 : _e.focus(); | ||
} | ||
break; | ||
} | ||
} | ||
} | ||
export function removePopup() { | ||
@@ -61,11 +20,8 @@ var existingPopup = window.document.getElementById(popupId); | ||
} | ||
window.removeEventListener('message', eventsListener); | ||
} | ||
export function addPopup(iframeLink, options) { | ||
export function addPopup(iframeLink) { | ||
removePopup(); | ||
currentOptions = options; | ||
var popup = getPopupHtml(iframeLink); | ||
window.document.head.appendChild(htmlToElement(styles)); | ||
window.document.body.appendChild(htmlToElement(popup)); | ||
window.addEventListener('message', eventsListener); | ||
} | ||
@@ -72,0 +28,0 @@ function htmlToElement(html) { |
import type { BrokerType } from '@front-finance/api'; | ||
import { FrontEventType } from './event-types'; | ||
export type EventType = 'brokerageAccountAccessToken' | 'delayedAuthentication' | 'close' | 'done' | 'loaded' | 'oauthLinkOpen' | 'transferFinished'; | ||
export interface FrontConnection { | ||
openLink: (authLink: string) => Promise<void>; | ||
openPopup: (iframeLink: string) => Promise<void>; | ||
closePopup: () => void; | ||
} | ||
export interface SetTitleEvent { | ||
type: 'setTitle'; | ||
title: string; | ||
hideTitle?: boolean; | ||
} | ||
export interface BrokerAccountToken { | ||
@@ -62,7 +57,38 @@ account: BrokerAccount; | ||
export type TransferFinishedPayload = TransferFinishedSuccessPayload | TransferFinishedErrorPayload; | ||
export interface IntegrationAccessToken { | ||
accountId: string; | ||
accountName: string; | ||
accessToken: string; | ||
brokerType: BrokerType; | ||
brokerName: string; | ||
} | ||
export interface FrontOptions { | ||
/** | ||
* Client ID that can be obtained at https://dashboard.getfront.com/company/keys | ||
*/ | ||
clientId: string; | ||
/** | ||
* A callback function that is called when an integration is succesfully connected. | ||
* It receives a payload of type `FrontPayload`. | ||
*/ | ||
onBrokerConnected: (payload: FrontPayload) => void; | ||
/** | ||
* (Optional) A callback function that is called when the Front iframe is closed. | ||
*/ | ||
onExit?: (error?: string) => void; | ||
/** | ||
* (Optional) A callback function that is called when a transfer is finished. | ||
* It receives a payload of type `TransferFinishedPayload`. | ||
*/ | ||
onTransferFinished?: (payload: TransferFinishedPayload) => void; | ||
/** | ||
* (Optional) A callback function that is called when various events occur within the Front iframe. | ||
* It receives an object with type `FrontEventTypeKeys` indicating the event, and an optional 'payload' containing additional data. | ||
*/ | ||
onEvent?: (event: FrontEventType) => void; | ||
/** | ||
* (Optional) An array of integration access tokens. | ||
* These access tokens are used to initialize crypto transfers flow at 'Select asset step' | ||
*/ | ||
accessTokens?: IntegrationAccessToken[]; | ||
} |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
0
128
39949
736
1
- Removedlocalforage@^1.10.0
- Removedimmediate@3.0.6(transitive)
- Removedlie@3.1.1(transitive)
- Removedlocalforage@1.10.0(transitive)