UNPKG

@oraichain/customauth

Version:

CustomAuth login with torus to get user private key

1,409 lines (1,329 loc) 63.5 kB
/******/ (() => { // webpackBootstrap /******/ "use strict"; /******/ // The require scope /******/ var __webpack_require__ = {}; /******/ /************************************************************************/ /******/ /* webpack/runtime/compat get default export */ /******/ (() => { /******/ // getDefaultExport function for compatibility with non-harmony modules /******/ __webpack_require__.n = (module) => { /******/ var getter = module && module.__esModule ? /******/ () => (module['default']) : /******/ () => (module); /******/ __webpack_require__.d(getter, { a: getter }); /******/ return getter; /******/ }; /******/ })(); /******/ /******/ /* webpack/runtime/define property getters */ /******/ (() => { /******/ // define getter functions for harmony exports /******/ __webpack_require__.d = (exports, definition) => { /******/ for(var key in definition) { /******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) { /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] }); /******/ } /******/ } /******/ }; /******/ })(); /******/ /******/ /* webpack/runtime/hasOwnProperty shorthand */ /******/ (() => { /******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) /******/ })(); /******/ /******/ /* webpack/runtime/make namespace object */ /******/ (() => { /******/ // define __esModule on exports /******/ __webpack_require__.r = (exports) => { /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); /******/ } /******/ Object.defineProperty(exports, '__esModule', { value: true }); /******/ }; /******/ })(); /******/ /************************************************************************/ var __webpack_exports__ = {}; // ESM COMPAT FLAG __webpack_require__.r(__webpack_exports__); // EXPORTS __webpack_require__.d(__webpack_exports__, { AGGREGATE_VERIFIER: () => (/* reexport */ AGGREGATE_VERIFIER), LOGIN: () => (/* reexport */ LOGIN), Network: () => (/* reexport */ Network), NetworkConfig: () => (/* reexport */ NetworkConfig), REDIRECT_PARAMS_STORAGE_METHOD: () => (/* reexport */ REDIRECT_PARAMS_STORAGE_METHOD), TORUS_METHOD: () => (/* reexport */ TORUS_METHOD), UX_MODE: () => (/* reexport */ UX_MODE), are3PCSupported: () => (/* reexport */ are3PCSupported), broadcastChannelOptions: () => (/* reexport */ broadcastChannelOptions), constructURL: () => (/* reexport */ constructURL), createHandler: () => (/* reexport */ HandlerFactory), "default": () => (/* reexport */ login), eventToPromise: () => (/* reexport */ eventToPromise), getPopupFeatures: () => (/* reexport */ getPopupFeatures), getVerifierId: () => (/* reexport */ getVerifierId), handleRedirectParameters: () => (/* reexport */ handleRedirectParameters), isFirefox: () => (/* reexport */ isFirefox), loginToConnectionMap: () => (/* reexport */ loginToConnectionMap), metadataUrl: () => (/* reexport */ metadataUrl), padUrlString: () => (/* reexport */ padUrlString), query: () => (/* reexport */ query), randomId: () => (/* reexport */ randomId), storageAvailable: () => (/* reexport */ storageAvailable), stringtifyError: () => (/* reexport */ stringtifyError), validateAndConstructUrl: () => (/* reexport */ validateAndConstructUrl), wait: () => (/* reexport */ wait) }); ;// CONCATENATED MODULE: ./src/utils/enums.ts const LOGIN = { GOOGLE: "google", FACEBOOK: "facebook", REDDIT: "reddit", DISCORD: "discord", TWITCH: "twitch", APPLE: "apple", GITHUB: "github", LINKEDIN: "linkedin", TWITTER: "twitter", WEIBO: "weibo", LINE: "line", EMAIL_PASSWORD: "email_password", PASSWORDLESS: "passwordless", JWT: "jwt", WEBAUTHN: "webauthn" }; const AGGREGATE_VERIFIER = { SINGLE_VERIFIER_ID: "single_id_verifier" // AND_AGGREGATE_VERIFIER : "and_aggregate_verifier", // OR_AGGREGATE_VERIFIER : "or_aggregate_verifier", }; const UX_MODE = { POPUP: "popup" }; const REDIRECT_PARAMS_STORAGE_METHOD = { LOCAL_STORAGE: "localStorage", SESSION_STORAGE: "sessionStorage", SERVER: "server" }; const TORUS_METHOD = { TRIGGER_LOGIN: "triggerLogin" }; ;// CONCATENATED MODULE: external "@babel/runtime/helpers/defineProperty" const defineProperty_namespaceObject = require("@babel/runtime/helpers/defineProperty"); var defineProperty_default = /*#__PURE__*/__webpack_require__.n(defineProperty_namespaceObject); ;// CONCATENATED MODULE: external "@toruslabs/http-helpers" const http_helpers_namespaceObject = require("@toruslabs/http-helpers"); ;// CONCATENATED MODULE: external "lodash.merge" const external_lodash_merge_namespaceObject = require("lodash.merge"); var external_lodash_merge_default = /*#__PURE__*/__webpack_require__.n(external_lodash_merge_namespaceObject); ;// CONCATENATED MODULE: external "@babel/runtime/helpers/objectWithoutProperties" const objectWithoutProperties_namespaceObject = require("@babel/runtime/helpers/objectWithoutProperties"); var objectWithoutProperties_default = /*#__PURE__*/__webpack_require__.n(objectWithoutProperties_namespaceObject); ;// CONCATENATED MODULE: external "@toruslabs/broadcast-channel" const broadcast_channel_namespaceObject = require("@toruslabs/broadcast-channel"); ;// CONCATENATED MODULE: external "bowser" const external_bowser_namespaceObject = require("bowser"); var external_bowser_default = /*#__PURE__*/__webpack_require__.n(external_bowser_namespaceObject); ;// CONCATENATED MODULE: external "serialize-error" const external_serialize_error_namespaceObject = require("serialize-error"); ;// CONCATENATED MODULE: external "loglevel" const external_loglevel_namespaceObject = require("loglevel"); var external_loglevel_default = /*#__PURE__*/__webpack_require__.n(external_loglevel_namespaceObject); ;// CONCATENATED MODULE: ./src/utils/loglevel.ts /* harmony default export */ const loglevel = (external_loglevel_default().getLogger("customauth")); ;// CONCATENATED MODULE: ./src/utils/helpers.ts function eventToPromise(emitter) { return new Promise((resolve, reject) => { const handler = ev => { const { error = "", data } = ev; emitter.removeEventListener("message", handler); if (error) return reject(new Error(error)); return resolve(data); }; emitter.addEventListener("message", handler); }); } // These are the connection names used by auth0 const loginToConnectionMap = { [LOGIN.APPLE]: "apple", [LOGIN.GITHUB]: "github", [LOGIN.LINKEDIN]: "linkedin", [LOGIN.TWITTER]: "twitter", [LOGIN.WEIBO]: "weibo", [LOGIN.LINE]: "line", [LOGIN.EMAIL_PASSWORD]: "Username-Password-Authentication", [LOGIN.PASSWORDLESS]: "email" }; const padUrlString = url => url.href.endsWith("/") ? url.href : `${url.href}/`; /** * Returns a random number. Don't use for cryptographic purposes. * @returns a random number */ const randomId = () => Math.random().toString(36).slice(2); const broadcastChannelOptions = { // type: 'localstorage', // (optional) enforce a type, oneOf['native', 'idb', 'localstorage', 'node'] webWorkerSupport: false // (optional) set this to false if you know that your channel will never be used in a WebWorker (increases performance) }; function caseSensitiveField(field, isCaseSensitive) { return isCaseSensitive ? field : field.toLowerCase(); } const getVerifierId = function (userInfo, typeOfLogin, verifierIdField) { let isVerifierIdCaseSensitive = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : true; const { name, email } = userInfo; if (verifierIdField) return caseSensitiveField(userInfo[verifierIdField], isVerifierIdCaseSensitive); switch (typeOfLogin) { case LOGIN.PASSWORDLESS: case LOGIN.EMAIL_PASSWORD: return caseSensitiveField(name, isVerifierIdCaseSensitive); case LOGIN.WEIBO: case LOGIN.GITHUB: case LOGIN.TWITTER: case LOGIN.APPLE: case LOGIN.LINKEDIN: case LOGIN.LINE: case LOGIN.JWT: return caseSensitiveField(email, isVerifierIdCaseSensitive); default: throw new Error("Invalid login type"); } }; const handleRedirectParameters = (hash, queryParameters) => { const hashParameters = hash.split("&").reduce((result, item) => { const [part0, part1] = item.split("="); result[part0] = part1; return result; }, {}); loglevel.info(hashParameters, queryParameters); let instanceParameters = {}; let error = ""; if (Object.keys(hashParameters).length > 0 && hashParameters.state) { instanceParameters = JSON.parse(atob(decodeURIComponent(decodeURIComponent(hashParameters.state)))) || {}; error = hashParameters.error_description || hashParameters.error || error; } else if (Object.keys(queryParameters).length > 0 && queryParameters.state) { instanceParameters = JSON.parse(atob(decodeURIComponent(decodeURIComponent(queryParameters.state)))) || {}; if (queryParameters.error) error = queryParameters.error; } return { error, instanceParameters, hashParameters }; }; function storageAvailable(type) { let storage; try { storage = window[type]; const x = "__storage_test__"; storage.setItem(x, x); storage.removeItem(x); return true; } catch (e) { return e && ( // everything except Firefox e.code === 22 || // Firefox e.code === 1014 || // test name field too, because code might not be present // everything except Firefox e.name === "QuotaExceededError" || // Firefox e.name === "NS_ERROR_DOM_QUOTA_REACHED") && // acknowledge QuotaExceededError only if there's something already stored storage && storage.length !== 0; } } function getPopupFeatures() { // Fixes dual-screen position Most browsers Firefox const dualScreenLeft = window.screenLeft !== undefined ? window.screenLeft : window.screenX; const dualScreenTop = window.screenTop !== undefined ? window.screenTop : window.screenY; const w = 1200; const h = 700; const width = window.innerWidth ? window.innerWidth : document.documentElement.clientWidth ? document.documentElement.clientWidth : window.screen.width; const height = window.innerHeight ? window.innerHeight : document.documentElement.clientHeight ? document.documentElement.clientHeight : window.screen.height; const systemZoom = 1; // No reliable estimate const left = Math.abs((width - w) / 2 / systemZoom + dualScreenLeft); const top = Math.abs((height - h) / 2 / systemZoom + dualScreenTop); const features = `titlebar=0,toolbar=0,status=0,location=0,menubar=0,height=${h / systemZoom},width=${w / systemZoom},top=${top},left=${left}`; return features; } const isFirefox = () => { var _window; return ((_window = window) === null || _window === void 0 || (_window = _window.navigator) === null || _window === void 0 ? void 0 : _window.userAgent.toLowerCase().indexOf("firefox")) > -1 || false; }; function constructURL(params) { const { baseURL, query, hash } = params; const url = new URL(baseURL); if (query) { Object.keys(query).forEach(key => { url.searchParams.append(key, query[key]); }); } if (hash) { const h = new URL(constructURL({ baseURL, query: hash })).searchParams.toString(); url.hash = h; } return url.toString(); } function are3PCSupported() { var _navigator; const browserInfo = external_bowser_default().parse(navigator.userAgent); loglevel.info(JSON.stringify(browserInfo), "current browser info"); let thirdPartyCookieSupport = true; // brave if ((_navigator = navigator) !== null && _navigator !== void 0 && _navigator.brave) { thirdPartyCookieSupport = false; } // All webkit & gecko engine instances use itp (intelligent tracking prevention - // https://webkit.org/tracking-prevention/#intelligent-tracking-prevention-itp) if (browserInfo.engine.name === (external_bowser_default()).ENGINE_MAP.WebKit || browserInfo.engine.name === (external_bowser_default()).ENGINE_MAP.Gecko) { thirdPartyCookieSupport = false; } return thirdPartyCookieSupport; } const validateAndConstructUrl = domain => { try { const url = new URL(decodeURIComponent(domain)); return url; } catch (error) { throw new Error(`${(error === null || error === void 0 ? void 0 : error.message) || ""}, Note: Your jwt domain: (i.e ${domain}) must have http:// or https:// prefix`); } }; const wait = s => new Promise(resolve => { setTimeout(resolve, s * 1000); }); function stringtifyError(error) { return JSON.stringify((0,external_serialize_error_namespaceObject.serializeError)(error)); } ;// CONCATENATED MODULE: external "events" const external_events_namespaceObject = require("events"); ;// CONCATENATED MODULE: ./src/utils/PopupHandler.ts class PopupHandler extends external_events_namespaceObject.EventEmitter { constructor(_ref) { let { url, target, features } = _ref; super(); this.url = url; this.target = target || "_blank"; this.features = features || getPopupFeatures(); this.window = undefined; this.windowTimer = undefined; this.iClosedWindow = false; this._setupTimer(); } _setupTimer() { this.windowTimer = Number(setInterval(() => { if (this.window && this.window.closed) { clearInterval(this.windowTimer); if (!this.iClosedWindow) { this.emit("close"); } this.iClosedWindow = false; this.window = undefined; } if (this.window === undefined) clearInterval(this.windowTimer); }, 500)); } open() { var _this$window; this.window = window.open(this.url.href, this.target, this.features); if ((_this$window = this.window) !== null && _this$window !== void 0 && _this$window.focus) this.window.focus(); return Promise.resolve(); } close() { this.iClosedWindow = true; if (this.window) this.window.close(); } redirect(locationReplaceOnRedirect) { if (locationReplaceOnRedirect) { window.location.replace(this.url.href); } else { window.location.href = this.url.href; } } } /* harmony default export */ const utils_PopupHandler = (PopupHandler); ;// CONCATENATED MODULE: ./src/handlers/AbstractLoginHandler.ts const _excluded = ["access_token", "id_token"]; function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { defineProperty_default()(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } class AbstractLoginHandler { // Not using object constructor because of this issue // https://github.com/microsoft/TypeScript/issues/5326 constructor(clientId, redirect_uri, typeOfLogin, uxMode, redirectToOpener, jwtParams, customState) { defineProperty_default()(this, "nonce", randomId()); this.clientId = clientId; this.redirect_uri = redirect_uri; this.typeOfLogin = typeOfLogin; this.uxMode = uxMode; this.redirectToOpener = redirectToOpener; this.jwtParams = jwtParams; this.customState = customState; } get state() { return encodeURIComponent(window.btoa(JSON.stringify(_objectSpread(_objectSpread({}, this.customState || {}), {}, { instanceId: this.nonce, typeOfLogin: this.typeOfLogin, redirectToOpener: this.redirectToOpener || false })))); } handleLoginWindow(params) { const verifierWindow = new utils_PopupHandler({ url: this.finalURL, features: params.popupFeatures }); return new Promise((resolve, reject) => { 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_default()(_ref.hashParams, _excluded); if (error) { loglevel.error(ev); reject(new Error(`Error: ${error}. Info: ${JSON.stringify(ev.data || {})}`)); return; } if (ev.data) { if (!this.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.redirectToOpener) { bc = new broadcast_channel_namespaceObject.BroadcastChannel(`redirect_channel_${this.nonce}`, broadcastChannelOptions); bc.addEventListener("message", async ev => { await handleData(ev); bc.close(); verifierWindow.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); verifierWindow.close(); }; window.addEventListener("message", postMessageEventHandler); } verifierWindow.open(); verifierWindow.once("close", () => { if (bc) bc.close(); reject(new Error("user closed popup")); }); }); } } /* harmony default export */ const handlers_AbstractLoginHandler = (AbstractLoginHandler); ;// CONCATENATED MODULE: ./src/handlers/DiscordHandler.ts class DiscordHandler extends handlers_AbstractLoginHandler { constructor(clientId, redirect_uri, typeOfLogin, uxMode, redirectToOpener, jwtParams, customState) { super(clientId, redirect_uri, typeOfLogin, uxMode, redirectToOpener, jwtParams, customState); defineProperty_default()(this, "RESPONSE_TYPE", "token"); defineProperty_default()(this, "SCOPE", "identify email"); this.clientId = clientId; this.redirect_uri = redirect_uri; this.typeOfLogin = typeOfLogin; this.uxMode = uxMode; this.redirectToOpener = redirectToOpener; this.jwtParams = jwtParams; this.customState = customState; this.setFinalUrl(); } setFinalUrl() { const finalUrl = new URL("https://discord.com/api/oauth2/authorize"); const clonedParams = JSON.parse(JSON.stringify(this.jwtParams || {})); const finalJwtParams = external_lodash_merge_default()({ state: this.state, response_type: this.RESPONSE_TYPE, client_id: this.clientId, redirect_uri: this.redirect_uri, scope: this.SCOPE }, clonedParams); Object.keys(finalJwtParams).forEach(key => { if (finalJwtParams[key]) finalUrl.searchParams.append(key, finalJwtParams[key]); }); this.finalURL = finalUrl; } async getUserInfo(params) { const { accessToken } = params; const userInfo = await (0,http_helpers_namespaceObject.get)("https://discord.com/api/users/@me", { headers: { Authorization: `Bearer ${accessToken}` } }); const { id, avatar, email = "", username: name = "", discriminator = "" } = userInfo; const profileImage = avatar === null ? `https://cdn.discord.com/embed/avatars/${Number(discriminator) % 5}.png` : `https://cdn.discord.com/avatars/${id}/${avatar}.png?size=2048`; return { profileImage, name: `${name}#${discriminator}`, email, verifierId: id, typeOfLogin: this.typeOfLogin }; } } ;// CONCATENATED MODULE: ./src/handlers/FacebookHandler.ts class FacebookHandler extends handlers_AbstractLoginHandler { constructor(clientId, redirect_uri, typeOfLogin, uxMode, redirectToOpener, jwtParams, customState) { super(clientId, redirect_uri, typeOfLogin, uxMode, redirectToOpener, jwtParams, customState); defineProperty_default()(this, "RESPONSE_TYPE", "token"); defineProperty_default()(this, "SCOPE", "public_profile email"); this.clientId = clientId; this.redirect_uri = redirect_uri; this.typeOfLogin = typeOfLogin; this.uxMode = uxMode; this.redirectToOpener = redirectToOpener; this.jwtParams = jwtParams; this.customState = customState; this.setFinalUrl(); } setFinalUrl() { const finalUrl = new URL("https://www.facebook.com/v15.0/dialog/oauth"); const clonedParams = JSON.parse(JSON.stringify(this.jwtParams || {})); const finalJwtParams = external_lodash_merge_default()({ state: this.state, response_type: this.RESPONSE_TYPE, client_id: this.clientId, redirect_uri: this.redirect_uri, scope: this.SCOPE }, clonedParams); Object.keys(finalJwtParams).forEach(key => { if (finalJwtParams[key]) finalUrl.searchParams.append(key, finalJwtParams[key]); }); this.finalURL = finalUrl; } async getUserInfo(params) { const { accessToken } = params; const userInfo = await (0,http_helpers_namespaceObject.get)("https://graph.facebook.com/me?fields=name,email,picture.type(large)", { headers: { Authorization: `Bearer ${accessToken}` } }); const { name = "", id, picture, email = "" } = userInfo; return { email, name, profileImage: picture.data.url || "", verifierId: id, typeOfLogin: this.typeOfLogin }; } } ;// CONCATENATED MODULE: ./src/handlers/GoogleHandler.ts class GoogleHandler extends handlers_AbstractLoginHandler { constructor(clientId, redirect_uri, typeOfLogin, uxMode, redirectToOpener, jwtParams, customState) { super(clientId, redirect_uri, typeOfLogin, uxMode, redirectToOpener, jwtParams, customState); defineProperty_default()(this, "RESPONSE_TYPE", "token id_token"); defineProperty_default()(this, "SCOPE", "profile email openid"); defineProperty_default()(this, "PROMPT", "consent select_account"); this.clientId = clientId; this.redirect_uri = redirect_uri; this.typeOfLogin = typeOfLogin; this.uxMode = uxMode; this.redirectToOpener = redirectToOpener; this.jwtParams = jwtParams; this.customState = customState; this.setFinalUrl(); } setFinalUrl() { const finalUrl = new URL("https://accounts.google.com/o/oauth2/v2/auth"); const clonedParams = JSON.parse(JSON.stringify(this.jwtParams || {})); const finalJwtParams = external_lodash_merge_default()({ state: this.state, response_type: this.RESPONSE_TYPE, client_id: this.clientId, prompt: this.PROMPT, redirect_uri: this.redirect_uri, scope: this.SCOPE, nonce: this.nonce }, clonedParams); Object.keys(finalJwtParams).forEach(key => { if (finalJwtParams[key]) finalUrl.searchParams.append(key, finalJwtParams[key]); }); this.finalURL = finalUrl; } async getUserInfo(params) { const { accessToken } = params; const userInfo = await (0,http_helpers_namespaceObject.get)("https://www.googleapis.com/userinfo/v2/me", { headers: { Authorization: `Bearer ${accessToken}` } }); const { picture: profileImage = "", email = "", name = "" } = userInfo; return { email, name, profileImage, verifierId: email.toLowerCase(), typeOfLogin: this.typeOfLogin }; } } ;// CONCATENATED MODULE: external "jwt-decode" const external_jwt_decode_namespaceObject = require("jwt-decode"); var external_jwt_decode_default = /*#__PURE__*/__webpack_require__.n(external_jwt_decode_namespaceObject); ;// CONCATENATED MODULE: ./src/handlers/JwtHandler.ts class JwtHandler extends handlers_AbstractLoginHandler { constructor(clientId, redirect_uri, typeOfLogin, uxMode, redirectToOpener, jwtParams, customState) { super(clientId, redirect_uri, typeOfLogin, uxMode, redirectToOpener, jwtParams, customState); defineProperty_default()(this, "SCOPE", "openid profile email"); defineProperty_default()(this, "RESPONSE_TYPE", "token id_token"); defineProperty_default()(this, "PROMPT", "login"); this.clientId = clientId; this.redirect_uri = redirect_uri; this.typeOfLogin = typeOfLogin; this.uxMode = uxMode; this.redirectToOpener = redirectToOpener; this.jwtParams = jwtParams; this.customState = customState; this.setFinalUrl(); } setFinalUrl() { const { domain } = this.jwtParams; const finalUrl = validateAndConstructUrl(domain); finalUrl.pathname += finalUrl.pathname.endsWith("/") ? "authorize" : "/authorize"; const clonedParams = JSON.parse(JSON.stringify(this.jwtParams)); delete clonedParams.domain; const finalJwtParams = external_lodash_merge_default()({ state: this.state, response_type: this.RESPONSE_TYPE, client_id: this.clientId, prompt: this.PROMPT, redirect_uri: this.redirect_uri, scope: this.SCOPE, connection: loginToConnectionMap[this.typeOfLogin], nonce: this.nonce }, clonedParams); Object.keys(finalJwtParams).forEach(key => { if (finalJwtParams[key]) finalUrl.searchParams.append(key, finalJwtParams[key]); }); this.finalURL = finalUrl; } async getUserInfo(params) { const { idToken, accessToken } = params; const { domain, verifierIdField, isVerifierIdCaseSensitive, user_info_route = "userinfo" } = this.jwtParams; if (accessToken) { try { const domainUrl = new URL(domain); const userInfo = await (0,http_helpers_namespaceObject.get)(`${padUrlString(domainUrl)}${user_info_route}`, { headers: { Authorization: `Bearer ${accessToken}` } }); const { picture, name, email } = userInfo; return { email, name, profileImage: picture, verifierId: getVerifierId(userInfo, this.typeOfLogin, verifierIdField, isVerifierIdCaseSensitive), typeOfLogin: this.typeOfLogin }; } catch (error) { // ignore external_loglevel_default().warn(error, "Unable to get userinfo from endpoint"); } } if (idToken) { const decodedToken = external_jwt_decode_default()(idToken); const { name, email, picture } = decodedToken; return { profileImage: picture, name, email, verifierId: email, typeOfLogin: this.typeOfLogin }; } throw new Error("Access/id token not available"); } } ;// CONCATENATED MODULE: ./src/handlers/PasswordlessHandler.ts const PasswordlessHandler_excluded = ["access_token", "id_token"]; function PasswordlessHandler_ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } function PasswordlessHandler_objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? PasswordlessHandler_ownKeys(Object(t), !0).forEach(function (r) { defineProperty_default()(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : PasswordlessHandler_ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } class PasswordlessHandler_JwtHandler extends handlers_AbstractLoginHandler { constructor(clientId, redirect_uri, typeOfLogin, uxMode, redirectToOpener, jwtParams, customState) { super(clientId, redirect_uri, typeOfLogin, uxMode, redirectToOpener, jwtParams, customState); defineProperty_default()(this, "SCOPE", "openid profile email"); defineProperty_default()(this, "RESPONSE_TYPE", "token id_token"); defineProperty_default()(this, "PROMPT", "login"); this.clientId = clientId; this.redirect_uri = redirect_uri; this.typeOfLogin = typeOfLogin; this.uxMode = uxMode; this.redirectToOpener = redirectToOpener; this.jwtParams = jwtParams; this.customState = customState; this.setFinalUrl(); } setFinalUrl() { const { domain } = this.jwtParams; const domainUrl = validateAndConstructUrl(domain); domainUrl.pathname = "/passwordless/start"; this.finalURL = domainUrl; } async getUserInfo(params) { const { idToken, accessToken } = params; const { domain, verifierIdField, isVerifierIdCaseSensitive } = this.jwtParams; try { const domainUrl = new URL(domain); const userInfo = await (0,http_helpers_namespaceObject.get)(`${padUrlString(domainUrl)}userinfo`, { headers: { Authorization: `Bearer ${accessToken}` } }); const { picture, name, email } = userInfo; return { email, name, profileImage: picture, verifierId: getVerifierId(userInfo, this.typeOfLogin, verifierIdField, isVerifierIdCaseSensitive), typeOfLogin: this.typeOfLogin }; } catch (error) { loglevel.error(error); const decodedToken = external_jwt_decode_default()(idToken); const { name, email, picture } = decodedToken; return { profileImage: picture, name, email, verifierId: getVerifierId(decodedToken, this.typeOfLogin, verifierIdField, isVerifierIdCaseSensitive), typeOfLogin: this.typeOfLogin }; } } handleLoginWindow() { return new Promise((resolve, reject) => { if (this.redirectToOpener) { reject(new Error("Cannot use redirect to opener for passwordless")); return; } const handleData = ev => { try { const { error, data } = ev; const _ref = data || {}, { instanceParams, hashParams: { access_token: accessToken, id_token: idToken } } = _ref, rest = objectWithoutProperties_default()(_ref.hashParams, PasswordlessHandler_excluded); if (error) { loglevel.error(ev.error); reject(new Error(error)); return; } if (ev.data) { loglevel.info(ev.data); resolve(PasswordlessHandler_objectSpread(PasswordlessHandler_objectSpread({ accessToken, idToken: idToken || "" }, rest), {}, { state: instanceParams })); } } catch (error) { loglevel.error(error); reject(error); } }; const bc = new broadcast_channel_namespaceObject.BroadcastChannel(`redirect_channel_${this.nonce}`, broadcastChannelOptions); bc.addEventListener("message", async ev => { handleData(ev); bc.close(); }); try { const { connection = "email", login_hint } = this.jwtParams; const finalJwtParams = external_lodash_merge_default()({ client_id: this.clientId, connection, email: connection === "email" ? login_hint : undefined, phone_number: connection === "sms" ? login_hint : undefined, send: "link", authParams: { scope: this.SCOPE, state: this.state, response_type: this.RESPONSE_TYPE, redirect_uri: this.redirect_uri, nonce: this.nonce, prompt: this.PROMPT } }, { authParams: this.jwtParams }); // using stringify and parse to remove undefined params // This method is only resolved when the user clicks the email link (0,http_helpers_namespaceObject.post)(this.finalURL.href, JSON.parse(JSON.stringify(finalJwtParams))).then(response => { loglevel.info("posted", response); return undefined; }).catch(error => { loglevel.error(error); reject(error); }); } catch (error) { loglevel.error(error); reject(error); } }); } } ;// CONCATENATED MODULE: ./src/handlers/RedditHandler.ts class RedditHandler extends handlers_AbstractLoginHandler { constructor(clientId, redirect_uri, typeOfLogin, uxMode, redirectToOpener, jwtParams, customState) { super(clientId, redirect_uri, typeOfLogin, uxMode, redirectToOpener, jwtParams, customState); defineProperty_default()(this, "RESPONSE_TYPE", "token"); defineProperty_default()(this, "SCOPE", "identity"); this.clientId = clientId; this.redirect_uri = redirect_uri; this.typeOfLogin = typeOfLogin; this.uxMode = uxMode; this.redirectToOpener = redirectToOpener; this.jwtParams = jwtParams; this.customState = customState; this.setFinalUrl(); } setFinalUrl() { const finalUrl = new URL(`https://www.reddit.com/api/v1/authorize${window.innerWidth < 600 ? ".compact" : ""}`); const clonedParams = JSON.parse(JSON.stringify(this.jwtParams || {})); const finalJwtParams = external_lodash_merge_default()({ state: this.state, response_type: this.RESPONSE_TYPE, client_id: this.clientId, redirect_uri: this.redirect_uri, scope: this.SCOPE }, clonedParams); Object.keys(finalJwtParams).forEach(key => { if (finalJwtParams[key]) finalUrl.searchParams.append(key, finalJwtParams[key]); }); this.finalURL = finalUrl; } async getUserInfo(params) { const { accessToken } = params; const userInfo = await (0,http_helpers_namespaceObject.get)("https://oauth.reddit.com/api/v1/me", { headers: { Authorization: `Bearer ${accessToken}` } }); const { icon_img: profileImage = "", name = "" } = userInfo; return { email: "", name, profileImage: profileImage.split("?").length > 0 ? profileImage.split("?")[0] : profileImage, verifierId: name.toLowerCase(), typeOfLogin: this.typeOfLogin }; } } ;// CONCATENATED MODULE: ./src/handlers/TwitchHandler.ts class TwitchHandler extends handlers_AbstractLoginHandler { constructor(clientId, redirect_uri, typeOfLogin, uxMode, redirectToOpener, jwtParams, customState) { super(clientId, redirect_uri, typeOfLogin, uxMode, redirectToOpener, jwtParams, customState); defineProperty_default()(this, "RESPONSE_TYPE", "token"); defineProperty_default()(this, "SCOPE", "user:read:email"); this.clientId = clientId; this.redirect_uri = redirect_uri; this.typeOfLogin = typeOfLogin; this.uxMode = uxMode; this.redirectToOpener = redirectToOpener; this.jwtParams = jwtParams; this.customState = customState; this.setFinalUrl(); } setFinalUrl() { const finalUrl = new URL("https://id.twitch.tv/oauth2/authorize"); const clonedParams = JSON.parse(JSON.stringify(this.jwtParams || {})); const finalJwtParams = external_lodash_merge_default()({ state: this.state, response_type: this.RESPONSE_TYPE, client_id: this.clientId, redirect_uri: this.redirect_uri, scope: this.SCOPE, force_verify: true }, clonedParams); Object.keys(finalJwtParams).forEach(key => { if (finalJwtParams[key]) finalUrl.searchParams.append(key, finalJwtParams[key]); }); this.finalURL = finalUrl; } async getUserInfo(params) { const { accessToken } = params; const userInfo = await (0,http_helpers_namespaceObject.get)("https://api.twitch.tv/helix/users", { headers: { Authorization: `Bearer ${accessToken}`, "Client-ID": this.clientId } }); const [{ profile_image_url: profileImage = "", display_name: name = "", email = "", id: verifierId }] = userInfo.data || []; return { profileImage, name, email, verifierId, typeOfLogin: this.typeOfLogin }; } } ;// CONCATENATED MODULE: ./src/handlers/HandlerFactory.ts const createHandler = _ref => { let { clientId, redirect_uri, typeOfLogin, jwtParams, redirectToOpener, uxMode, customState } = _ref; if (!typeOfLogin || !clientId) { throw new Error("Invalid params"); } const { domain, login_hint } = jwtParams || {}; switch (typeOfLogin) { case LOGIN.GOOGLE: return new GoogleHandler(clientId, redirect_uri, typeOfLogin, uxMode, redirectToOpener, jwtParams, customState); case LOGIN.FACEBOOK: return new FacebookHandler(clientId, redirect_uri, typeOfLogin, uxMode, redirectToOpener, jwtParams, customState); case LOGIN.TWITCH: return new TwitchHandler(clientId, redirect_uri, typeOfLogin, uxMode, redirectToOpener, jwtParams, customState); case LOGIN.REDDIT: return new RedditHandler(clientId, redirect_uri, typeOfLogin, uxMode, redirectToOpener, jwtParams, customState); case LOGIN.DISCORD: return new DiscordHandler(clientId, redirect_uri, typeOfLogin, uxMode, redirectToOpener, jwtParams, customState); case LOGIN.PASSWORDLESS: if (!domain || !login_hint) throw new Error("Invalid params"); return new PasswordlessHandler_JwtHandler(clientId, redirect_uri, typeOfLogin, uxMode, redirectToOpener, jwtParams, customState); case LOGIN.APPLE: case LOGIN.GITHUB: case LOGIN.LINKEDIN: case LOGIN.TWITTER: case LOGIN.WEIBO: case LOGIN.LINE: case LOGIN.EMAIL_PASSWORD: case LOGIN.JWT: if (!domain) throw new Error("Invalid params"); return new JwtHandler(clientId, redirect_uri, typeOfLogin, uxMode, redirectToOpener, jwtParams, customState); default: throw new Error("Invalid login type"); } }; /* harmony default export */ const HandlerFactory = (createHandler); ;// CONCATENATED MODULE: external "@oraichain/multifactors.js" const multifactors_js_namespaceObject = require("@oraichain/multifactors.js"); ;// CONCATENATED MODULE: external "web3-utils" const external_web3_utils_namespaceObject = require("web3-utils"); ;// CONCATENATED MODULE: external "@chaitanyapotti/register-service-worker" const register_service_worker_namespaceObject = require("@chaitanyapotti/register-service-worker"); ;// CONCATENATED MODULE: ./src/registerServiceWorker.ts const registerServiceWorker = baseUrl => new Promise((resolve, reject) => { const swUrl = `${baseUrl}sw.js`; if ("serviceWorker" in window.navigator) { // if swIntegrity is not calculated (0,register_service_worker_namespaceObject.register)(swUrl, { ready() { loglevel.info("App is being served from cache by a service worker.\n For more details, visit https://goo.gl/AFskqB"); resolve(undefined); }, registered() { loglevel.info("Service worker has been registered."); resolve(undefined); }, cached() { loglevel.info("Content has been cached for offline use."); resolve(undefined); }, updatefound() { loglevel.info("New content is downloading."); }, updated() { loglevel.info("New content is available; please refresh."); }, offline() { loglevel.info("No internet connection found. App is running in offline mode."); reject(new Error("App is offline")); }, error(error) { loglevel.error("Error during service worker registration:", error); reject(error); } }); } else { reject(new Error("Service workers are not supported")); } }); ;// CONCATENATED MODULE: ./src/utils/blockchain.ts let Network = /*#__PURE__*/function (Network) { Network["DEV"] = "development"; Network["TESTNET"] = "testnet"; Network["MAINNET"] = "mainnet"; Network["STAGING"] = "staging"; Network["PRODUCTION"] = "production"; return Network; }({}); const NetworkConfig = { [Network.DEV]: { rpc: "https://rpc.testnet.orai.io", lcd: "https://lcd.testnet.orai.io", chainId: "Oraichain-testnet", contract: "orai182z6mxeta4dgaxu6qyuu5fywc3p7cdyz2udphd0nz5vnqkrdhzrscu8zan" }, [Network.STAGING]: { rpc: "https://rpc.testnet.orai.io", lcd: "https://lcd.testnet.orai.io", chainId: "Oraichain-testnet", contract: "orai1j3ynfwl2gv7jujfhjqkwrgfwfsg2jth7fyv2g0ph9twc372ny7gqxhe5pj" }, [Network.TESTNET]: { rpc: "https://rpc.testnet.orai.io", lcd: "https://lcd.testnet.orai.io", chainId: "Oraichain-testnet", contract: "orai1v5hwd3w4dx3628suz3lrhd9hr8ktdgjytu95kfsa0vxxmxj42rtsxv4sdn" }, [Network.MAINNET]: { rpc: "https://rpc.orai.io", lcd: "https://lcd.orai.io", chainId: "Oraichain", contract: "orai1kvu7xclv2uvc5yl0mzgcux0cw40sjur2kksarva84376gq4qnnxqhk2hh5", loadBalancerEndpoint: "https://social-login.orai.io/jrpc" }, [Network.PRODUCTION]: { rpc: "https://rpc.orai.io", lcd: "https://lcd.orai.io", chainId: "Oraichain", contract: "orai1r7qwtfp7uc0jsemc8frnjgwc4gpspxnuhg7gjcv3slzul08gglds65tnrp", loadBalancerEndpoint: "https://executor-multifactor.orai.io/jrpc" } }; const metadataUrl = { [Network.DEV]: "http://127.0.0.1:5051", [Network.STAGING]: "https://metadata.social-login-staging.orai.io", [Network.TESTNET]: "https://metadata.social-login-testnet.orai.io", [Network.MAINNET]: "https://metadata-social-login.orai.io", [Network.PRODUCTION]: "https://metadata-social-login.orai.io" }; const getQueryUrl = (config, params) => `${config.lcd}/cosmwasm/wasm/v1/contract/${config.contract}/smart/${params}`; const query = async (config, input, requestInit, customOpts) => { const param = Buffer.from(JSON.stringify(input)).toString("base64"); const queryUrl = getQueryUrl(config, param); const resp = await (0,http_helpers_namespaceObject.get)(queryUrl, requestInit, customOpts); return resp.data; }; ;// CONCATENATED MODULE: ./src/utils/ws.ts var WEBSOCKET_CODE_ONCLOSE = /*#__PURE__*/function (WEBSOCKET_CODE_ONCLOSE) { WEBSOCKET_CODE_ONCLOSE[WEBSOCKET_CODE_ONCLOSE["ERROR"] = 4000] = "ERROR"; WEBSOCKET_CODE_ONCLOSE[WEBSOCKET_CODE_ONCLOSE["SUCCESS"] = 3000] = "SUCCESS"; return WEBSOCKET_CODE_ONCLOSE; }(WEBSOCKET_CODE_ONCLOSE || {}); function fromRPCtoWebsocket(url) { const rpcURL = new URL(url); rpcURL.protocol = "wss"; rpcURL.pathname = "/websocket"; return rpcURL.toString(); } const conditionTransform = queryTags => { let condition = ""; Object.keys(queryTags).forEach(key => { condition += condition ? ` AND ${key} = '${queryTags[key]}'` : `AND ${key} = '${queryTags[key]}'`; }); return condition; }; const subscribeTx = async function (url, tags) { let timeout = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 15000; const conditionString = conditionTransform(tags); return new Promise((resolve, reject) => { // Set up the timeout const ws = new WebSocket(url); const timer = setTimeout(() => { reject(new Error(`subscribe timed out after ${timeout} ms`)); ws.send(JSON.stringify({ jrpc: "2.0", method: "unsubscribe", id: "99", params: [] })); return ws.close(); }, timeout); ws.onopen = () => { ws.send(JSON.stringify({ jsonrpc: "2.0", method: "subscribe", params: [`tm.event = 'Tx' ${conditionString}`], id: "1" })); }; ws.onmessage = message => { const data = JSON.parse(message.data); if ("events" in data.result) { var _data$result; const events = data === null || data === void 0 || (_data$result = data.result) === null || _data$result === void 0 ? void 0 : _data$result.events; const keysFromTags = Object.keys(tags); const extractValueFromEvent = keysFromTags.reduce((acc, key) => { acc[key] = events[key]; return acc; }, {}); extractValueFromEvent.txHash = events["tx.hash"][0]; clearTimeout(timer); resolve(extractValueFromEvent); ws.send(JSON.stringify({ jrpc: "2.0", method: "unsubscribe", id: "99", params: [] })); return ws.close(WEBSOCKET_CODE_ONCLOSE.SUCCESS); } }; ws.onerror = errorEvent => { reject(new Error(`WebSocket error ${errorEvent.type}`)); ws.send(JSON.stringify({ jrpc: "2.0", method: "unsubscribe", id: "99", params: [] })); return ws.close(WEBSOCKET_CODE_ONCLOSE.ERROR); }; ws.onclose = event => { clearTimeout(timer); if (event.code !== WEBSOCKET_CODE_ONCLOSE.ERROR && event.code !== WEBSOCKET_CODE_ONCLOSE.SUCCESS) { return reject(new Error(`WebSocket closed unexpectedly with code ${event.code}`)); } }; }); }; ;// CONCATENATED MODULE: ./src/login.ts const login_excluded = ["access_token", "id_token"]; function login_ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } function login_objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? login_ownKeys(Object(t), !0).forEach(function (r) { defineProperty_default()(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : login_ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } class CustomAuth { constructor(_ref) { let { baseUrl, network = Network.MAINNET, enableLogging = true, redirectToOpener = false, redirectPathName = "redirect", uxMode = UX_MODE.POPUP, locationReplaceOnRedirect = false, popupFeatures, multifactors, networkConfig } = _ref; this.isInitialized = false; const baseUri = new URL(baseUrl); this.config = { baseUrl: padUrlString(baseUri), get redirect_uri() { return `${this.baseUrl}${redirectPathName}`; }, redirectToOpener, uxMode, locationReplaceOnRedirect, popupFeatures }; this.multifactors = multifactors; this.networkConfig = networkConfig ? login_objectSpread(login_objectSpread({}, NetworkConfig[network]), networkConfig) : NetworkConfig[network]; if (enableLogging) loglevel.enableAll();else loglevel.disableAll(); } async enableSentry(sentry) { const { members: nodes } = await this.getContractConfig(); const endpoints = nodes.map(node => node.end_point); (0,http_helpers_namespaceObject.enableSentryTracing)(sentry, endpoints, ["/get", "/set"]); } async init() { let { skipSw = false, skipInit = false, skipPrefetch = false } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; if (skipInit) { this.isInitialized = true; return; } if (!skipSw) { const fetchSwResponse = await fetch(`${this.config.baseUrl}sw.js`, { cache: "reload" }); if (fetchSwResponse.ok) { try { await registerServiceWorker(this.config.baseUrl); this.isInitialized = true; return; } catch (error) { loglevel.warn(error); } } else { throw new Error("Service worker is not being served. Please serve it"); } } if (!skipPrefetch) { // Skip the redirect check for firefox if (isFirefox()) { this.isInitialized = true; return; } await this.handlePrefetchRedirectUri(); return; } this.isInitialized = true; } async triggerLogin(args) { const { verifier, typeOfLogin } = args; const { userInfo, loginParams } = await this.getLoginParamsAndUserInfo(args); try { const multifactorsKey = await this.getMultifactorsKey(typeOfLogin, { verifier_id: userInfo === null || userInfo === void 0 ? void 0 : userInfo.verifierId, verifier }, loginParams.idToken || loginParams.accessToken, userInfo === null || userInfo === void 0 ? void 0 : userInfo.extraVerifierParams); return login_objectSpread(login_objectSpread({}, multifactorsKey), {}, { userInfo: login_objectSpread(login_objectSpread(login_objectSpread({}, userInfo), loginParams), {}, { verifierId: userInfo === null || userInfo === void 0 ? void 0 : userInfo.verifierId }) }); } catch (error) { loglevel.debug(error); throw new Error(`getMultifactorsKey::${stringtifyError(error)}`); } } async triggerLoginMobile(args) { const { verifier, typeOfLogin } = args; const { userInfo, loginParams } = await this.getLoginParamsAndUserInfo(args); try { const { sharesIndexes, shares,