UNPKG

@kinde-oss/kinde-auth-react

Version:

Kinde React SDK for authentication

1,441 lines (1,440 loc) 41.2 kB
var ge = /* @__PURE__ */ ((e) => (e.email = "email", e.profile = "profile", e.openid = "openid", e.offline_access = "offline", e))(ge || {}), Z = /* @__PURE__ */ ((e) => (e.none = "none", e.create = "create", e.login = "login", e))(Z || {}), Q = /* @__PURE__ */ ((e) => (e.organizationDetails = "organization_details", e.organizationMembers = "organization_members", e.organizationPlanDetails = "organization_plan_details", e.organizationPaymentDetails = "organization_payment_details", e.organizationPlanSelection = "organization_plan_selection", e.paymentDetails = "payment_details", e.planSelection = "plan_selection", e.planDetails = "plan_details", e.profile = "profile", e))(Q || {}), pe = /* @__PURE__ */ ((e) => (e.organizationDetails = "organization_details", e.organizationMembers = "organization_members", e.organizationPlanDetails = "organization_plan_details", e.organizationPaymentDetails = "organization_payment_details", e.organizationPlanSelection = "organization_plan_selection", e.profile = "profile", e))(pe || {}), j = /* @__PURE__ */ ((e) => (e.logout = "logout", e.login = "login", e.register = "registration", e.token = "token", e.profile = "profile", e))(j || {}), T = /* @__PURE__ */ ((e) => (e[e.refreshToken = 0] = "refreshToken", e[e.cookie = 1] = "cookie", e))(T || {}); const G = (e) => { const t = (o) => btoa(o).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, ""); if (e instanceof ArrayBuffer) { const o = new Uint8Array(e), a = String.fromCharCode(...o); return t(a); } const r = new TextEncoder().encode(e), n = String.fromCharCode(...r); return t(n); }, D = (e = 28) => { if (crypto) { const t = new Uint8Array(e / 2); return crypto.getRandomValues(t), Array.from(t, ye).join(""); } else return we(e); }; function ye(e) { return e.toString(16).padStart(2, "0"); } function we(e = 28) { const t = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; let r = ""; const n = t.length; for (let o = 0; o < e; o++) r += t.charAt(Math.floor(Math.random() * n)); return r; } const Ke = (e) => { e = e.split("?")[1]; const t = new URLSearchParams(e); return { accessToken: t.get("access_token"), idToken: t.get("id_token"), expiresIn: +(t.get("expires_in") || 0) }; }, V = (e) => { let t = e.replace(/([^:]\/)\/+/g, "$1"); return t.match(/^\/\/[^/?]+/) && t.includes(".") ? t = t.replace(/^\/\/\/+/, "//") : t.match(/^\/\/+/) && (t = t.replace(/^\/\/+/, "/")), t !== "/" && (t = t.replace(/\/$/, "")), t; }, ke = (e, t = !1) => { const r = Array.isArray(e.audience) ? e.audience.join(" ") : e.audience || "", n = { login_hint: e.loginHint, is_create_org: e.isCreateOrg?.toString(), connection_id: e.connectionId, redirect_uri: e.redirectURL ? t ? e.redirectURL : V(e.redirectURL) : void 0, audience: r, scope: e.scope?.join(" ") || "email profile openid offline", prompt: e.prompt, lang: e.lang, org_code: e.orgCode, org_name: e.orgName, has_success_page: e.hasSuccessPage?.toString(), workflow_deployment_id: e.workflowDeploymentId, supports_reauth: e.supportsReauth?.toString(), plan_interest: e.planInterest, pricing_table_key: e.pricingTableKey, pages_mode: e.pagesMode }; return Object.keys(n).forEach( (o) => n[o] === void 0 && delete n[o] ), n; }, O = (e) => typeof e != "object" || e === null ? e : Array.isArray(e) ? e.map((t) => O(t)) : Object.fromEntries( Object.entries(e).map(([t, r]) => [ t.replace(/_([a-z])/g, (n, o) => o.toUpperCase()), O(r) ]) ), Te = [ // UTM tags "utm_source", "utm_medium", "utm_campaign", "utm_content", "utm_term", // Google Ads smart campaign tracking "gclid", "click_id", "hsa_acc", "hsa_cam", "hsa_grp", "hsa_ad", "hsa_src", "hsa_tgt", "hsa_kw", "hsa_mt", "hsa_net", "hsa_ver", // Marketing category "match_type", "keyword", "device", "ad_group_id", "campaign_id", "creative", "network", "ad_position", "fbclid", "li_fat_id", "msclkid", "twclid", "ttclid" ], Be = async (e, t = j.login, r, n) => { const o = `${e}/oauth2/auth`, a = $(); if (r.reauthState) try { const c = O( JSON.parse(atob(r.reauthState)) ); r = { ...r, ...c }, delete r.reauthState; } catch (c) { const d = c instanceof Error ? c.message : "Unknown error"; throw new Error(`Error handing reauth state: ${d}`); } if (!r.clientId) throw new Error("Error generating auth URL: Client ID missing"); const l = { client_id: r.clientId, response_type: r.responseType || "code", ...ke(r, n?.disableUrlSanitization) }; r.state || (r.state = D(32)), a && a.setSessionItem(s.state, r.state), l.state = r.state, r.nonce || (r.nonce = D(16)), l.nonce = r.nonce, a && a.setSessionItem(s.nonce, r.nonce); let f = ""; if (r.codeChallenge) l.code_challenge = r.codeChallenge; else { const { codeVerifier: c, codeChallenge: d } = await _e(); f = c, a && a.setSessionItem(s.codeVerifier, c), l.code_challenge = d; } l.code_challenge_method = "S256", r.codeChallengeMethod && (l.code_challenge_method = r.codeChallengeMethod), !r.prompt && t === j.register && (l.prompt = Z.create), r.properties && Object.keys(r.properties).forEach((c) => { if (!Te.includes(c)) { console.warn("Unsupported Property for url generation: ", c); return; } const d = r.properties?.[c]; d !== void 0 && (l[c] = d); }); const u = new URLSearchParams(l).toString(); return { url: new URL(`${o}?${u}`), state: l.state, nonce: l.nonce, codeChallenge: l.code_challenge, codeVerifier: f }; }; async function _e() { const e = D(52), t = new TextEncoder().encode(e); let r = ""; if (!crypto) r = G(btoa(e)); else { const n = await crypto.subtle.digest("SHA-256", t); r = G(n); } return { codeVerifier: e, codeChallenge: r }; } const A = () => typeof window < "u"; let E; function X(e, t) { if (K(), !A()) throw new Error("setRefreshTimer requires a browser environment"); if (e <= 0) throw new Error("Timer duration must be positive"); E = window.setTimeout( t, Math.min(e * 1e3 - 1e4, 864e5) ); } function K() { A() && E !== void 0 && (window.clearTimeout(E), E = void 0); } const v = { framework: "", frameworkVersion: "", sdkVersion: "" }, J = async () => { await $()?.removeItems( s.state, s.nonce, s.codeVerifier ); }, Se = () => `${v.framework}/${v.sdkVersion}/${v.frameworkVersion}/Javascript`, He = async ({ urlParams: e, domain: t, clientId: r, clientSecret: n, redirectURL: o, autoRefresh: a = !1, onRefresh: l }) => { const f = e.get("state"), u = e.get("code"); if (!f || !u) return console.error("Invalid state or code"), { success: !1, error: "Invalid state or code" }; const c = $(); if (!c) return console.error("No active storage found"), { success: !1, error: "Authentication storage is not initialized" }; (!v.framework || !v.frameworkVersion) && console.warn( "Framework and version not set. Please set the framework and version in the config object" ); const d = await c.getSessionItem(s.state); if (f !== d) return console.error("Invalid state"), { success: !1, error: `Invalid state; supplied ${f}, expected ${d}` }; const m = await c.getSessionItem( s.codeVerifier ); if (m === null) return console.error("Code verifier not found"), { success: !1, error: "Code verifier not found" }; const k = { "Content-type": "application/x-www-form-urlencoded; charset=UTF-8" }; v.framework && (k["Kinde-SDK"] = Se()); const I = !i.useInsecureForRefreshToken && C(t) ? { credentials: "include" } : {}, b = new URLSearchParams({ client_id: r, code: u, code_verifier: m, grant_type: "authorization_code", redirect_uri: o }); n && b.append("client_secret", n); const me = { method: "POST", ...I, headers: new Headers(k), body: b }; let S; K(); try { if (S = await fetch(`${t}/oauth2/token`, me), !S?.ok) { const h = await S.text(); return console.error("Token exchange failed:", S.status, h), { success: !1, error: `Token exchange failed: ${S.status} - ${h}` }; } } catch (h) { return J(), console.error("Token exchange failed:", h), { success: !1, error: `Token exchange failed: ${h}` }; } const g = await S.json(), q = y(); if (q) try { await q.setItems({ [s.accessToken]: g.access_token, [s.idToken]: g.id_token, [s.refreshToken]: g.refresh_token }); } catch (h) { return console.error("Failed to persist tokens to secure storage:", h), { success: !1, error: `Failed to persist tokens: ${h}` }; } (i.useInsecureForRefreshToken || !C(t)) && c.setSessionItem(s.refreshToken, g.refresh_token), a && X(g.expires_in, async () => { P({ domain: t, clientId: r, onRefresh: l }); }), J(); const he = (h) => (h.search = "", h); if (A()) { const h = he(new URL(window.location.toString())); window.history.replaceState(window.history.state, "", h); } return !g.access_token || !g.id_token || !g.refresh_token ? { success: !1, error: "No access token received" } : { success: !0, [s.accessToken]: g.access_token, [s.idToken]: g.id_token, [s.refreshToken]: g.refresh_token }; }; function ve(e) { const t = document.cookie.split("; ").find((r) => r.startsWith(`${e}=`)); if (!t) return null; try { const r = t.split("=")[1]; return r ? decodeURIComponent(r) : null; } catch (r) { return console.error(`Error parsing cookie ${e}:`, r), null; } } const $e = "_kbrte", qe = async ({ domain: e, clientId: t }) => { if (!e) return { success: !1, error: "Domain is required for authentication check" }; if (!t) return { success: !1, error: "Client ID is required for authentication check" }; const r = y(); if (r) { const { [s.accessToken]: l, [s.idToken]: f, [s.refreshToken]: u } = await r.getItems( s.accessToken, s.idToken, s.refreshToken ); if (l && f && u) return await de({ threshold: 10 }) ? await P({ domain: e, clientId: t, refreshType: T.refreshToken }) : { success: !0, accessToken: l, idToken: f, refreshToken: u }; } const n = C(e), o = i.useInsecureForRefreshToken; let a = null; return n && !o && (a = ve($e)), await P({ domain: e, clientId: t, refreshType: a ? T.cookie : T.refreshToken }); }, C = (e) => !e.match( /^(?:https?:\/\/)?[a-zA-Z0-9][.-a-zA-Z0-9]*\.kinde\.com$/i ); function B(e, t) { return t <= 0 ? [] : e.match(new RegExp(`.{1,${t}}`, "g")) || []; } var s = /* @__PURE__ */ ((e) => (e.accessToken = "accessToken", e.idToken = "idToken", e.refreshToken = "refreshToken", e.state = "state", e.nonce = "nonce", e.codeVerifier = "codeVerifier", e))(s || {}), W = /* @__PURE__ */ ((e) => (e.preWarning = "preWarning", e.timeout = "timeout", e))(W || {}); class H { listeners = /* @__PURE__ */ new Set(); notificationScheduled = !1; notifyListeners() { this.listeners.size !== 0 && this.scheduleNotification(); } async scheduleNotification() { this.notificationScheduled || (this.notificationScheduled = !0, await new Promise((t) => { setTimeout(async () => { await Promise.all( Array.from(this.listeners).map((r) => r()) ), this.notificationScheduled = !1, t(); }, 0); })); } subscribe(t) { return this.listeners.add(t), () => { this.listeners.delete(t); }; } async setItems(t) { await Promise.all( Object.entries(t).map( ([r, n]) => this.setSessionItem(r, n) ) ); } async getItems(...t) { const r = t.map(async (o) => { const a = await this.getSessionItem(o); return [o, a]; }), n = await Promise.all(r); return Object.fromEntries(n); } async removeItems(...t) { await Promise.all( t.map((r) => this.removeSessionItem(r)) ); } } class Ge extends H { asyncStore = !1; memCache = {}; /** * Clears all items from session store. * @returns {void} */ destroySession() { this.memCache = {}, this.notifyListeners(); } /** * Sets the provided key-value store to the memory cache. * @param {string} itemKey * @param {unknown} itemValue * @returns {void} */ setSessionItem(t, r) { if (this.removeSessionItem(t), typeof r == "string") { B(r, i.maxLength).forEach( (n, o) => { this.memCache[`${i.keyPrefix}${t}${o}`] = n; } ), this.notifyListeners(); return; } this.memCache[`${i.keyPrefix}${String(t)}0`] = r, this.notifyListeners(); } /** * Gets the item for the provided key from the memory cache. * @param {string} itemKey * @returns {unknown | null} */ getSessionItem(t) { if (this.memCache[`${i.keyPrefix}${String(t)}0`] === void 0) return null; let r = "", n = 0, o = `${i.keyPrefix}${String(t)}${n}`; for (; this.memCache[o] !== void 0; ) r += this.memCache[o], n++, o = `${i.keyPrefix}${String(t)}${n}`; return r; } /** * Removes the item for the provided key from the memory cache. * @param {string} itemKey * @returns {void} */ removeSessionItem(t) { for (const r in this.memCache) r.startsWith(`${i.keyPrefix}${String(t)}`) && delete this.memCache[r]; this.notifyListeners(); } } function L(e) { return new Promise((t, r) => { chrome.storage.local.get([e], function(n) { chrome.runtime.lastError ? r(void 0) : t(n[e]); }); }); } class Je extends H { asyncStore = !0; /** * Clears all items from session store. * @returns {void} */ async destroySession() { await chrome.storage.local.clear(), this.notifyListeners(); } /** * Sets the provided key-value store to the chrome.store.local. * @param {string} itemKey * @param {unknown} itemValue * @returns {void} */ async setSessionItem(t, r) { if (await this.removeSessionItem(t), typeof r == "string") { const n = B(r, i.maxLength); await Promise.all( n.map( (o, a) => chrome.storage.local.set({ [`${i.keyPrefix}${t}${a}`]: o }) ) ), this.notifyListeners(); return; } await chrome.storage.local.set({ [`${i.keyPrefix}${t}0`]: r }), this.notifyListeners(); } /** * Gets the item for the provided key from the chrome.store.local cache. * @param {string} itemKey * @returns {unknown | null} */ async getSessionItem(t) { let r = "", n = 0, o = `${i.keyPrefix}${String(t)}${n}`; for (; await L( `${i.keyPrefix}${String(t)}${n}` ) !== void 0; ) r += await L(o), n++, o = `${i.keyPrefix}${String(t)}${n}`; return r; } /** * Removes the item for the provided key from the chrome.store.local cache. * @param {string} itemKey * @returns {void} */ async removeSessionItem(t) { let r = 0; for (; await L( `${i.keyPrefix}${String(t)}${r}` ) !== void 0; ) await chrome.storage.local.remove( `${i.keyPrefix}${String(t)}${r}` ), r++; this.notifyListeners(); } } class Ze extends H { asyncStore = !1; constructor() { super(), i.useInsecureForRefreshToken && console.warn("LocalStorage store should not be used in production"); } internalItems = /* @__PURE__ */ new Set(); /** * Clears all items from session store. * @returns {void} */ destroySession() { Array.from(this.internalItems).forEach( (t) => this.removeSessionItem(t) ), this.notifyListeners(); } /** * Sets the provided key-value store to the localStorage cache. * @param {V} itemKey * @param {unknown} itemValue * @returns {void} */ setSessionItem(t, r) { if (this.removeSessionItem(t), this.internalItems.add(t), typeof r == "string") { B(r, i.maxLength).forEach( (n, o) => { localStorage.setItem( `${i.keyPrefix}${t}${o}`, n ); } ), this.notifyListeners(); return; } localStorage.setItem( `${i.keyPrefix}${t}0`, r ), this.notifyListeners(); } /** * Gets the item for the provided key from the localStorage cache. * @param {string} itemKey * @returns {unknown | null} */ getSessionItem(t) { if (localStorage.getItem(`${i.keyPrefix}${t}0`) === null) return null; let r = "", n = 0, o = `${i.keyPrefix}${String(t)}${n}`; for (; localStorage.getItem(o) !== null; ) r += localStorage.getItem(o), n++, o = `${i.keyPrefix}${String(t)}${n}`; return r; } /** * Removes the item for the provided key from the localStorage cache. * @param {V} itemKey * @returns {void} */ removeSessionItem(t) { let r = 0; for (; localStorage.getItem( `${i.keyPrefix}${String(t)}${r}` ) !== null; ) localStorage.removeItem( `${i.keyPrefix}${String(t)}${r}` ), r++; this.internalItems.delete(t), this.notifyListeners(); } } const i = { /** * The prefix to use for the storage keys. */ keyPrefix: "kinde-", /** * The maximum length of the storage. * * If the length is exceeded the items will be split into multiple storage items. */ maxLength: 2e3, /** * Use insecure storage for refresh token. * * Warning: This should only be used when you're not using a custom domain and no backend app to authenticate on. */ useInsecureForRefreshToken: !1, /** * The number of minutes of inactivity before tokens are considered expired. * * When undefined, activity tracking is disabled. */ activityTimeoutMinutes: void 0, /** * The number of minutes of inactivity before a pre-warning is shown. * * When undefined, pre-warning is disabled. */ activityTimeoutPreWarningMinutes: void 0, /** * The function to call when the activity timeout is reached. * * @param timeoutType - The type of timeout that occurred. */ onActivityTimeout: void 0 }; let M = null, z = null, F = !1; const Ie = () => { if (F) return; const e = y() ?? $(); if (!e) throw new Error("Session manager not found"); if (!i.activityTimeoutMinutes) throw new Error("No activity timeout minutes set"); if (i.activityTimeoutPreWarningMinutes !== void 0 && i.activityTimeoutPreWarningMinutes >= i.activityTimeoutMinutes) throw new Error( "activityTimeoutPreWarningMinutes must be less than activityTimeoutMinutes" ); M && clearTimeout(M), z && clearTimeout(z), z = setTimeout( async () => { F = !0; const t = { accessToken: null, idToken: null, refreshToken: null }; try { const n = await e.getItems( s.accessToken, s.idToken, s.refreshToken ); t.accessToken = n[s.accessToken] ?? null, t.idToken = n[s.idToken] ?? null, t.refreshToken = n[s.refreshToken] ?? null; } catch (n) { console.error("Failed to capture tokens:", n); } const r = $(); if (r && r !== e) try { const n = await r.getItems( s.refreshToken ); t.refreshToken = n[s.refreshToken] ?? null; } catch (n) { console.error( "Failed to capture refresh token from insecure storage:", n ); } F = !1; try { await e.destroySession(); } catch (n) { console.error("Failed to destroy secure session:", n); } if (r && r !== e) try { await r.destroySession(); } catch (n) { console.error("Failed to destroy insecure session:", n); } try { i.onActivityTimeout?.( W.timeout, t ); } catch (n) { console.error( "[activityTimeout] onActivityTimeout(timeout) threw:", n ); } }, i.activityTimeoutMinutes * 60 * 1e3 ), i.activityTimeoutPreWarningMinutes !== void 0 && (M = setTimeout( () => { try { i.onActivityTimeout?.(W.preWarning); } catch (t) { console.error( "[activityTimeout] onActivityTimeout(preWarning) threw:", t ); } }, i.activityTimeoutPreWarningMinutes * 60 * 1e3 )); }, Y = (e) => { if (!e) throw new Error("Session manager not found"); if (!i.activityTimeoutMinutes) return e; if (i.activityTimeoutPreWarningMinutes !== void 0 && i.activityTimeoutPreWarningMinutes >= i.activityTimeoutMinutes) throw new Error( "activityTimeoutPreWarningMinutes must be less than activityTimeoutMinutes" ); const t = { get(r, n) { const o = r[n]; return typeof o == "function" ? (n !== "destroySession" && Ie(), o.bind(r)) : o; } }; return new Proxy(e, t); }; function Pe(e, t) { if (!e) return null; const r = e.split("."); if (r.length !== 3) return null; const n = r[ 1 /* body */ ].replace(/-/g, "+").replace(/_/g, "/"), o = decodeURIComponent( atob(n).split("").map((a) => "%" + ("00" + a.charCodeAt(0).toString(16)).slice(-2)).join("") ); return JSON.parse(o); } const ee = (e) => { if (!e) return null; const t = Pe(e); return t || console.warn("No decoded token found"), t; }, w = async (e = s.accessToken) => { const t = y(); if (!t) return null; const r = await t.getSessionItem( e === "accessToken" ? s.accessToken : s.idToken ); return ee(r); }, _ = (e = s.accessToken) => { const t = y(); if (!t) return null; if (t.asyncStore) throw new Error("Active storage is async-only. Use the async helpers."); const r = t.getSessionItem( e === "accessToken" ? s.accessToken : s.idToken ); return ee(r); }, te = (e, t) => { if (Array.isArray(e) && Array.isArray(t)) return Array.from(/* @__PURE__ */ new Set([...e, ...t])); if (e && typeof e == "object" && t && typeof t == "object") { const r = { ...e }; for (const n of Object.keys(t)) n in r ? r[n] = te(r[n], t[n]) : r[n] = t[n]; return r; } return t; }; async function R(e) { const t = y(); if (!t) throw new Error("No active storage found."); const r = await t.getSessionItem(s.accessToken); if (!r) throw new Error("Authentication token not found."); const n = await U("iss"); if (!n?.value) throw new Error("Domain (iss claim) not found."); let o; try { o = await fetch(`${n.value}/${e}`, { method: "GET", headers: { Authorization: `Bearer ${r}`, "Content-Type": "application/json" } }); } catch (a) { throw new Error(`Failed to fetch from ${n.value}/${e}: ${a}`); } if (!o.ok) throw new Error(`API request failed with status ${o.status}`); return await o.json(); } const x = async ({ url: e }) => { let t = [], r = await R(e); if (t = r.data, r.metadata?.has_more) { let n = r.metadata.next_page_starting_after; for (; r.metadata.has_more; ) r = await R( `${e}?starting_after=${n}` ), t = te(t, r.data), n = r.metadata.next_page_starting_after; } return t; }, re = (e) => { if (!e) return { orgCode: null, permissions: [] }; const t = e.permissions || e["x-hasura-permissions"] || []; return { orgCode: e.org_code || e["x-hasura-org-code"], permissions: t }; }, Ae = async (e) => { if (e?.forceApi) { const r = await x({ url: "account_api/v1/permissions" }); return { orgCode: r.org_code, permissions: r.permissions?.map((n) => n.key) || [] }; } const t = await w(); return re(t); }, Qe = (e) => { if (e?.forceApi) throw new Error("forceApi cannot be used in sync mode"); const t = _(); return re(t); }, xe = (e) => typeof e == "object" && e !== null && "permission" in e && "condition" in e, be = async (e) => { if (!e || !e.permissions || e?.permissions?.length === 0) return !0; const { permissions: t } = e; let r; try { r = await Ae({ forceApi: e.forceApi }); } catch (n) { return console.error("[hasPermissions] Error getting permissions", n), !1; } return (await Promise.all( t.map(async (n) => xe(n) ? r.permissions.find( (o) => o === n.permission ) ? await n.condition({ permissionKey: n.permission, orgCode: r.orgCode }) : !1 : !!r.permissions.find( (o) => o === n )) )).every((n) => n === !0); }, ne = (e) => e ? !e.roles && !e["x-hasura-roles"] ? (console.warn( "No roles found in token, ensure roles have been included in the token customisation within the application settings" ), []) : e.roles || e["x-hasura-roles"] : [], Ee = async (e) => { const t = await U("roles"); if (e?.forceApi || !t?.value) return (await x({ url: "account_api/v1/roles" })).roles?.map((n) => ({ id: n.id, name: n.name, key: n.key })) || []; const r = await w(); return ne(r); }, Xe = (e) => { if (e?.forceApi) throw new Error("forceApi cannot be used in sync mode"); const t = _(); if (!t) throw new Error("Authentication token not found."); return ne(t); }, Ce = (e) => typeof e == "object" && e !== null && "role" in e && "condition" in e, Re = async (e) => { if (!e || !e.roles || e?.roles?.length === 0) return !0; const { roles: t } = e; let r; try { r = await Ee({ forceApi: e.forceApi }); } catch (n) { return console.error("[hasRoles] Error getting roles", n), !1; } return (await Promise.all( t.map(async (n) => { if (Ce(n)) { const o = r.find( (a) => a.key === n.role ); return o ? await n.condition(o) : !1; } else return r.map((o) => o.key).includes(n); }) )).every((n) => n === !0); }, Ue = async (e) => { if (e?.forceApi) return (await x({ url: "account_api/v1/feature_flags" })).feature_flags?.map((r) => ({ key: r.key, value: r.value, type: r.type })) || []; const t = await w(); return Le(t); }, Le = (e) => { if (!e) return null; const t = e.feature_flags || e["x-hasura-feature-flags"]; return t ? Object.entries(t).map(([r, n]) => ({ key: r, value: n.v, type: n.t })) : null; }, Me = (e) => typeof e == "object" && e !== null && "flag" in e && "value" in e, ze = async (e) => { if (!e || !e.featureFlags || e?.featureFlags?.length === 0) return !0; const { featureFlags: t } = e; let r; try { r = await Ue({ forceApi: e.forceApi }); } catch (n) { return console.error("[hasFeatureFlags] Error getting feature flags", n), !1; } return t.map((n) => { if (Me(n)) { const o = r?.find((a) => a.key === n.flag); return o !== void 0 && o.value === n.value; } else return r?.find((o) => o.key === n) !== void 0; }).every((n) => n === !0); }, Fe = async () => { const e = await x({ url: "account_api/v1/entitlements" }); return { orgCode: e.org_code, plans: e.plans?.map((t) => ({ key: t.key, subscribedOn: t.subscribed_on })) || [], entitlements: e.entitlements?.map((t) => ({ id: t.id, fixedCharge: t.fixed_charge, priceName: t.price_name, unitAmount: t.unit_amount, featureKey: t.feature_key, featureName: t.feature_name, entitlementLimitMax: t.entitlement_limit_max, entitlementLimitMin: t.entitlement_limit_min })) || [] }; }, Ne = (e) => typeof e == "object" && e !== null && "entitlement" in e && "condition" in e, je = async (e) => { if (!e || !e.billingEntitlements || e?.billingEntitlements?.length === 0) return !0; const { billingEntitlements: t } = e; let r; try { r = await Fe(); } catch (n) { return console.error("[hasBillingEntitlements] Error getting entitlements", n), !1; } return (await Promise.all( t.map(async (n) => { if (Ne(n)) { const o = r.entitlements.find( (a) => a.priceName === n.entitlement ); return o ? await n.condition(o) : !1; } else return r.entitlements.map( (o) => o.priceName ).includes(n); }) )).every((n) => n === !0); }, N = (e) => e !== void 0 && typeof e == "object", Ye = async (e) => { const t = []; return e.roles && t.push( Re({ roles: e.roles, forceApi: N(e.forceApi) ? e.forceApi.roles : e.forceApi }) ), e.permissions && t.push( be({ permissions: e.permissions, forceApi: N(e.forceApi) ? e.forceApi.permissions : e.forceApi }) ), e.featureFlags && t.push( ze({ featureFlags: e.featureFlags, forceApi: N(e.forceApi) ? e.forceApi.featureFlags : e.forceApi }) ), e.billingEntitlements && t.push( je({ billingEntitlements: e.billingEntitlements }) ), (await Promise.all(t)).every(Boolean); }, oe = async (e = "accessToken") => w(e), se = (e = "accessToken") => _(e), ie = (e, t) => e ? { name: t, value: e[t] } : null, U = async (e, t = "accessToken") => { const r = await oe(t); return ie(r, e); }, et = (e, t = "accessToken") => { const r = se(t); return ie(r, e); }, tt = async () => { const e = await w(); return ae(e); }, rt = () => { const e = _(); return ae(e); }, ae = (e) => e ? e.org_code || e["x-hasura-org-code"] : null, nt = async (e = s.accessToken) => { const t = y(); return t && await t.getSessionItem( e === "accessToken" ? s.accessToken : s.idToken ) || null; }, ot = (e = s.accessToken) => { const t = y(); if (!t) return null; if (t.asyncStore) throw new Error("Active storage is async-only. Use the async helpers."); return t.getSessionItem( e === "accessToken" ? s.accessToken : s.idToken ) || null; }, st = async (e, t) => { if (t?.forceApi) { const n = (await x({ url: "account_api/v1/feature_flags" })).feature_flags.find((o) => o.name === e); return n ? n.value : null; } const r = await w(); return ce(r, e); }, it = (e, t) => { if (t?.forceApi) throw new Error("forceApi cannot be used in sync mode"); const r = _(); return ce(r, e); }, ce = (e, t) => { if (!e) return null; const r = e.feature_flags || e["x-hasura-feature-flags"]; return r ? r[t]?.v ?? null : null; }, le = (e) => { if (!e) return null; const { sub: t } = e; return t ? { id: e.sub, givenName: e.given_name, familyName: e.family_name, email: e.email, picture: e.picture } : (console.error("No sub in idToken"), null); }, at = async () => { const e = await oe("idToken"); return le(e); }, ct = () => { const e = se("idToken"); return le(e); }, ue = (e, t) => { if (!e) return { permissionKey: t, orgCode: null, isGranted: !1 }; const r = e.permissions || e["x-hasura-permissions"] || [], n = e.org_code || e["x-hasura-org-code"] || null; return { permissionKey: t, orgCode: n, isGranted: !!r.includes(t) }; }, lt = async (e, t) => { if (t?.forceApi) return R( `account_api/v1/permission/${encodeURIComponent(e)}` ); const r = await w(); return ue(r, e); }, ut = (e, t) => { if (t?.forceApi) throw new Error("forceApi cannot be used in sync mode"); const r = _(); return ue(r, e); }, ft = async () => { const e = await w("idToken"); return fe(e); }, dt = () => { const e = _("idToken"); return fe(e); }, fe = (e) => e ? !e.org_codes && !e["x-hasura-org-codes"] ? (console.warn( "Org codes not found in token, ensure org codes have been included in the token customisation within the application settings" ), null) : e.org_codes || e["x-hasura-org-codes"] : null, mt = async (e) => { try { const t = await de({ threshold: e?.expiredThreshold }); return t && e?.useRefreshToken ? (await P({ domain: e.domain, clientId: e.clientId })).success : !t; } catch (t) { return console.error("Error checking authentication:", t), !1; } }, de = async (e) => { try { const t = await w("accessToken"); return t ? t.exp ? t.exp < Math.floor(Date.now() / 1e3) + (e?.threshold || 0) : (console.error("Token does not have an expiry"), !0) : !0; } catch (t) { return console.error("Error checking authentication:", t), !1; } }, P = async ({ domain: e, clientId: t, clientSecret: r, refreshType: n = T.refreshToken, onRefresh: o }) => { const a = (d) => (o && o(d), d); if (!e) return a({ success: !1, error: "Domain is required for token refresh" }); if (!t) return a({ success: !1, error: "Client ID is required for token refresh" }); let l = "", f; if (i.useInsecureForRefreshToken || !C(e) ? f = $() : f = y(), n === T.refreshToken) { if (!f) return a({ success: !1, error: "No active storage found" }); if (l = await f.getSessionItem( s.refreshToken ), !l) return a({ success: !1, error: "No refresh token found" }); } K(); let u, c; try { if (i.onRefreshHandler) u = await i.onRefreshHandler(n); else { const d = new URLSearchParams({ ...n === T.refreshToken && { refresh_token: l }, grant_type: "refresh_token", client_id: t }); r && d.append("client_secret", r); const m = await fetch(`${V(e)}/oauth2/token`, { method: "POST", ...n === T.cookie && { credentials: "include" }, headers: { "Content-type": "application/x-www-form-urlencoded; charset=UTF-8" }, body: d.toString() }); if (!m.ok) return a({ success: !1, error: "Failed to refresh token" }); c = await m.json(), u = { success: !0, [s.accessToken]: c.access_token, [s.idToken]: c.id_token, [s.refreshToken]: c.refresh_token }; } if (u.accessToken) { const d = y(); if (!d) return a({ success: !1, error: "No active storage found" }); if (await d.setSessionItem( s.accessToken, u.accessToken ), u.idToken && await d.setSessionItem(s.idToken, u.idToken), f && u.refreshToken && await f.setSessionItem( s.refreshToken, u.refreshToken ), A()) { const m = Number((await U("exp"))?.value); if (Number.isFinite(m) || c?.expires_in) { let k = 0; if (!c?.expires_in) { const I = Math.floor(Date.now() / 1e3); k = Math.max(m - I, 1); } X(c?.expires_in || k, async () => { P({ domain: e, clientId: t, refreshType: n, onRefresh: o }); }); } } return a(u); } } catch (d) { return a({ success: !1, error: `No access token received: ${d}` }); } return a({ success: !1, error: "No access token received" }); }, ht = async (e) => { const t = await R( `account_api/v1/entitlement/${encodeURIComponent(e)}` ); return { orgCode: t.data.org_code, entitlement: { id: t.data.entitlement.id, fixedCharge: t.data.entitlement.fixed_charge, priceName: t.data.entitlement.price_name, unitAmount: t.data.entitlement.unit_amount, featureKey: t.data.entitlement.feature_key, featureName: t.data.entitlement.feature_name, entitlementLimitMax: t.data.entitlement.entitlement_limit_max, entitlementLimitMin: t.data.entitlement.entitlement_limit_min } }; }, p = { secure: null, insecure: null }, gt = (e) => { if (i.activityTimeoutMinutes) { p.secure = Y(e); return; } p.secure = e; }, y = () => p.secure || null, pt = () => p.secure !== null, yt = () => { p.secure = null; }, wt = (e) => { if (i.activityTimeoutMinutes) { p.insecure = Y(e); return; } p.insecure = e; }, $ = () => p.insecure || p.secure || null, kt = () => p.insecure !== null, Tt = () => { p.insecure = null; }, _t = async (e) => (console.warn( "Warning: generateProfileUrl is deprecated. Please use generatePortalUrl instead." ), Oe({ domain: e.domain, returnUrl: e.returnUrl, subNav: e.subNav })); function De(e, t = []) { try { const r = new URL(e); return !t.includes(r.protocol) && !!r.host; } catch { return !1; } } const Oe = async ({ domain: e, returnUrl: t, subNav: r }) => { const n = y(); if (!n) throw new Error("generatePortalUrl: Active storage not found"); const o = await n.getSessionItem( s.accessToken ); if (!o) throw new Error("generatePortalUrl: Access Token not found"); if (!e || typeof e != "string") { const u = await U("iss"); if (!u?.value || typeof u.value != "string") throw new Error( "generatePortalUrl: Unable to determine domain from access token" ); e = u.value; } if (!De(t, ["ftp:", "ws:"])) throw new Error("generatePortalUrl: returnUrl must be an absolute URL"); const a = new URLSearchParams({ subnav: r || Q.profile, return_url: t }), l = await fetch( `${V(e)}/account_api/v1/portal_link?${a.toString()}`, { headers: { Authorization: `Bearer ${o}` } } ); if (!l.ok) throw new Error( `Failed to fetch profile URL: ${l.status} ${l.statusText}` ); const f = await l.json(); if (!f.url || typeof f.url != "string") throw new Error("Invalid URL received from API"); try { return { url: new URL(f.url) }; } catch (u) { throw console.error(u), new Error(`Invalid URL format received from API: ${f.url}`); } }, We = () => window.self !== window.top, St = async ({ url: e, popupOptions: t = {}, handleResult: r, forcePopup: n = !1 }) => { We() || n ? await Ve({ url: e, popupOptions: t, handleResult: r }) : document.location = e; }, Ve = async ({ url: e, popupOptions: t = {}, handleResult: r }) => { const { width: n = 500, height: o = 600, left: a = (window.screen.width - n) / 2, top: l = (window.screen.height - o) / 2 } = t, f = window.open( e, "kinde_auth_popup", `width=${n},height=${o},left=${a},top=${l},scrollbars=yes,resizable=yes,toolbar=no,menubar=no,location=no,status=no` ); if (!f) throw new Error("Popup was blocked by the browser"); const u = () => new Promise((c) => { const d = (m) => { if (m.origin === window.location.origin && m.data && m.data.type === "KINDE_AUTH_RESULT") { window.removeEventListener("message", d); const k = new URLSearchParams(); Object.entries(m.data.result).forEach(([I, b]) => { k.append(I, b); }), r?.(k).then(() => c()); } }; window.addEventListener("message", d); }); try { await u(); } catch (c) { throw new Error("Popup authentication failed: " + c); } return f; }, vt = () => !A(), $t = { __esModule: !0, default: async () => (await import( /* webpackIgnore: true */ "./expoSecureStore-D7t_Z1p2-You5WAjH.js" )).ExpoSecureStore }; export { Je as ChromeStore, $t as ExpoSecureStore, j as IssuerRouteTypes, Ze as LocalStorage, Ge as MemoryStorage, Q as PortalPage, pe as ProfilePage, Z as PromptTypes, T as RefreshType, ge as Scopes, H as SessionBase, s as StorageKeys, W as TimeoutActivityType, G as base64UrlEncode, qe as checkAuth, yt as clearActiveStorage, Tt as clearInsecureStorage, K as clearRefreshTimer, He as exchangeAuthCode, Ke as extractAuthResults, v as frameworkSettings, Be as generateAuthUrl, Se as generateKindeSDKHeader, Oe as generatePortalUrl, _t as generateProfileUrl, D as generateRandomString, y as getActiveStorage, U as getClaim, et as getClaimSync, oe as getClaims, se as getClaimsSync, tt as getCurrentOrganization, rt as getCurrentOrganizationSync, w as getDecodedToken, _ as getDecodedTokenSync, ht as getEntitlement, Fe as getEntitlements, st as getFlag, it as getFlagSync, $ as getInsecureStorage, lt as getPermission, ut as getPermissionSync, Ae as getPermissions, Qe as getPermissionsSync, nt as getRawToken, ot as getRawTokenSync, Ee as getRoles, Xe as getRolesSync, ft as getUserOrganizations, dt as getUserOrganizationsSync, at as getUserProfile, ct as getUserProfileSync, Ye as has, pt as hasActiveStorage, je as hasBillingEntitlements, ze as hasFeatureFlags, kt as hasInsecureStorage, be as hasPermissions, Re as hasRoles, mt as isAuthenticated, A as isClient, C as isCustomDomain, vt as isServer, de as isTokenExpired, ke as mapLoginMethodParamsForUrl, St as navigateToKinde, P as refreshToken, V as sanitizeUrl, Y as sessionManagerActivityProxy, gt as setActiveStorage, wt as setInsecureStorage, X as setRefreshTimer, B as splitString, i as storageSettings, Ie as updateActivityTimestamp };