UNPKG

@toruslabs/customauth

Version:

CustomAuth login with torus to get user private key

118 lines (115 loc) 4.39 kB
import _objectWithoutProperties from '@babel/runtime/helpers/objectWithoutProperties'; import _objectSpread from '@babel/runtime/helpers/objectSpread2'; import _defineProperty from '@babel/runtime/helpers/defineProperty'; import base64url from 'base64url'; import { UX_MODE } from '../utils/enums.js'; import { randomId, getTimeout, broadcastChannelOptions } from '../utils/helpers.js'; import log from '../utils/loglevel.js'; import { PopupHandler } from '../utils/PopupHandler.js'; const _excluded = ["access_token", "id_token"]; class AbstractLoginHandler { // Not using object constructor because of this issue // https://github.com/microsoft/TypeScript/issues/5326 constructor(params) { _defineProperty(this, "nonce", randomId()); _defineProperty(this, "finalURL", void 0); _defineProperty(this, "params", void 0); this.params = params; } get state() { return encodeURIComponent(base64url.encode(JSON.stringify(_objectSpread(_objectSpread({}, this.params.customState || {}), {}, { instanceId: this.nonce, authConnectionId: this.params.authConnectionId, authConnection: this.params.authConnection, groupedAuthConnectionId: this.params.groupedAuthConnectionId, redirectToOpener: this.params.redirectToOpener || false })))); } async handleLoginWindow(params) { const authConnectionWindow = new PopupHandler({ url: this.finalURL, features: params.popupFeatures, timeout: getTimeout(this.params.authConnection) }); if (this.params.uxMode === UX_MODE.REDIRECT) { authConnectionWindow.redirect(params.locationReplaceOnRedirect); } else { const { RedundantAdaptiveBroadcastChannel: BroadcastChannel } = await import('@toruslabs/broadcast-channel'); return new Promise((resolve, reject) => { // eslint-disable-next-line @typescript-eslint/no-explicit-any let bc; const handleData = async ev => { try { const { error, data } = ev; const _ref = data || {}, { instanceParams, hashParams: { access_token: accessToken, id_token: idToken } } = _ref, rest = _objectWithoutProperties(_ref.hashParams, _excluded); if (error) { log.error(ev); reject(new Error(`Error: ${error}. Info: ${JSON.stringify(ev.data || {})}`)); return; } if (ev.data && instanceParams.authConnectionId === this.params.authConnectionId) { log.info(ev.data); if (!this.params.redirectToOpener && bc) await bc.postMessage({ success: true }); resolve(_objectSpread(_objectSpread({ accessToken, idToken: idToken || "" }, rest), {}, { // State has to be last here otherwise it will be overwritten state: instanceParams })); } } catch (error) { log.error(error); reject(error); } }; if (!this.params.redirectToOpener) { bc = new BroadcastChannel(`redirect_channel_${this.nonce}`, broadcastChannelOptions); bc.addEventListener("message", async ev => { await handleData(ev); bc.close(); authConnectionWindow.close(); }); } else { const postMessageEventHandler = async postMessageEvent => { if (!postMessageEvent.data) return; const ev = postMessageEvent.data; if (ev.channel !== `redirect_channel_${this.nonce}`) return; window.removeEventListener("message", postMessageEventHandler); handleData(ev); authConnectionWindow.close(); }; window.addEventListener("message", postMessageEventHandler); } try { authConnectionWindow.open(); } catch (error) { log.error(error); reject(error); return; } authConnectionWindow.once("close", () => { if (bc) bc.close(); reject(new Error("user closed popup")); }); }); } return null; } } export { AbstractLoginHandler as default };