@toruslabs/customauth
Version:
CustomAuth login with torus to get user private key
120 lines (116 loc) • 4.44 kB
JavaScript
;
var _objectWithoutProperties = require('@babel/runtime/helpers/objectWithoutProperties');
var _objectSpread = require('@babel/runtime/helpers/objectSpread2');
var _defineProperty = require('@babel/runtime/helpers/defineProperty');
var base64url = require('base64url');
var enums = require('../utils/enums.js');
var helpers = require('../utils/helpers.js');
var loglevel = require('../utils/loglevel.js');
var PopupHandler = require('../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", helpers.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.PopupHandler({
url: this.finalURL,
features: params.popupFeatures,
timeout: helpers.getTimeout(this.params.authConnection)
});
if (this.params.uxMode === enums.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) {
loglevel.error(ev);
reject(new Error(`Error: ${error}. Info: ${JSON.stringify(ev.data || {})}`));
return;
}
if (ev.data && instanceParams.authConnectionId === this.params.authConnectionId) {
loglevel.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) {
loglevel.error(error);
reject(error);
}
};
if (!this.params.redirectToOpener) {
bc = new BroadcastChannel(`redirect_channel_${this.nonce}`, helpers.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) {
loglevel.error(error);
reject(error);
return;
}
authConnectionWindow.once("close", () => {
if (bc) bc.close();
reject(new Error("user closed popup"));
});
});
}
return null;
}
}
module.exports = AbstractLoginHandler;