UNPKG

@transferwise/approve-api-action-helpers

Version:

An http client that handles SCA protected requests gracefully

83 lines (71 loc) 2.58 kB
/* eslint-disable fp/no-mutation */ import { MESSAGE_SUCCESS, MESSAGE_FAILED, MESSAGE_CLOSED } from './config'; import { createForm } from './createForm'; const WIDTH = 580; const HEIGHT = 600; // based on https://stackoverflow.com/a/16861050 const getPopupPosition = () => { const dualScreenLeft = window.screenLeft !== undefined ? window.screenLeft : window.screenX; const dualScreenTop = window.screenTop !== undefined ? window.screenTop : window.screenY; // eslint-disable-next-line no-nested-ternary const width = window.innerWidth ? window.innerWidth : document.documentElement.clientWidth ? document.documentElement.clientWidth : screen.width; // eslint-disable-line no-restricted-globals // eslint-disable-next-line no-nested-ternary const height = window.innerHeight ? window.innerHeight : document.documentElement.clientHeight ? document.documentElement.clientHeight : screen.height; // eslint-disable-line no-restricted-globals const systemZoom = width / window.screen.availWidth; const left = (width - WIDTH) / 2 / systemZoom + dualScreenLeft; const top = (height - HEIGHT) / 2 / systemZoom + dualScreenTop; return { width: WIDTH / systemZoom, height: HEIGHT / systemZoom, top, left, }; }; export function popupFlow({ token, approvalPageUrl, resolve, reject }) { // 1. creates a new form, but doesn't submit it yet const name = 'tw-approve-api-action'; const form = createForm({ target: name, token, approvalPageUrl, flow: 'popup' }); // eslint-disable-next-line unicorn/prefer-dom-node-append document.body.appendChild(form); // 2. opens the approval page in popup window const { width, height, top, left } = getPopupPosition(); const approvalPage = window.open( approvalPageUrl, name, `resizable,scrollbars,status,location,width=${width},height=${height},top=${top},left=${left}`, ); // 3. submit the form (will POST to this popup window) form.submit(); // not fully sure if this is needed if (approvalPage.focus) { approvalPage.focus(); } const handleEvents = (event) => { // eslint-disable-next-line default-case switch (event.data) { case MESSAGE_SUCCESS: closePopup(); resolve(); return; case MESSAGE_FAILED: closePopup(); reject(); return; case MESSAGE_CLOSED: closePopup(); } }; const closePopup = () => { approvalPage.close(); window.removeEventListener('message', handleEvents); }; window.addEventListener('message', handleEvents); }