@toruslabs/customauth
Version:
CustomAuth login with torus to get user private key
118 lines (115 loc) • 4.39 kB
JavaScript
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 };