@transferwise/approve-api-action-helpers
Version:
An http client that handles SCA protected requests gracefully
83 lines (71 loc) • 2.58 kB
JavaScript
/* 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);
}