UNPKG

expo-ii-integration

Version:

Expo library to enable smartphone native applications to invoke Internet Identity through a web application

571 lines (570 loc) 16.9 kB
var ce = Object.defineProperty; var ue = (n, r, o) => r in n ? ce(n, r, { enumerable: !0, configurable: !0, writable: !0, value: o }) : n[r] = o; var T = (n, r, o) => ue(n, typeof r != "symbol" ? r + "" : r, o); import le, { createContext as fe, useContext as de, useState as $, useEffect as z } from "react"; import * as me from "expo-linking"; import { router as ye } from "expo-router"; import { Ed25519KeyIdentity as F, DelegationChain as X } from "@dfinity/identity"; import { StringValueStorageWrapper as G } from "expo-storage-universal"; import { AnonymousIdentity as ve, toHex as Ee } from "@dfinity/agent"; import { buildIdentity as B, isAuthenticationExpiredError as pe } from "expo-icp-frontend-helpers"; import { connectToApp as he, handleURL as ge, dismissBrowser as we } from "expo-icp-app-connect"; var Y = { exports: {} }, S = {}; /** * @license React * react-jsx-runtime.production.js * * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ var K; function be() { if (K) return S; K = 1; var n = Symbol.for("react.transitional.element"), r = Symbol.for("react.fragment"); function o(a, s, c) { var f = null; if (c !== void 0 && (f = "" + c), s.key !== void 0 && (f = "" + s.key), "key" in s) { c = {}; for (var m in s) m !== "key" && (c[m] = s[m]); } else c = s; return s = c.ref, { $$typeof: n, type: a, key: f, ref: s !== void 0 ? s : null, props: c }; } return S.Fragment = r, S.jsx = o, S.jsxs = o, S; } var A = {}; /** * @license React * react-jsx-runtime.development.js * * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ var q; function Re() { return q || (q = 1, process.env.NODE_ENV !== "production" && function() { function n(e) { if (e == null) return null; if (typeof e == "function") return e.$$typeof === ae ? null : e.displayName || e.name || null; if (typeof e == "string") return e; switch (e) { case g: return "Fragment"; case w: return "Profiler"; case _: return "StrictMode"; case re: return "Suspense"; case te: return "SuspenseList"; case oe: return "Activity"; } if (typeof e == "object") switch (typeof e.tag == "number" && console.error( "Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue." ), e.$$typeof) { case k: return "Portal"; case Q: return (e.displayName || "Context") + ".Provider"; case Z: return (e._context.displayName || "Context") + ".Consumer"; case ee: var t = e.render; return e = e.displayName, e || (e = t.displayName || t.name || "", e = e !== "" ? "ForwardRef(" + e + ")" : "ForwardRef"), e; case ne: return t = e.displayName || null, t !== null ? t : n(e.type) || "Memo"; case D: t = e._payload, e = e._init; try { return n(e(t)); } catch { } } return null; } function r(e) { return "" + e; } function o(e) { try { r(e); var t = !1; } catch { t = !0; } if (t) { t = console; var i = t.error, u = typeof Symbol == "function" && Symbol.toStringTag && e[Symbol.toStringTag] || e.constructor.name || "Object"; return i.call( t, "The provided key is an unsupported type %s. This value must be coerced to a string before using it here.", u ), r(e); } } function a(e) { if (e === g) return "<>"; if (typeof e == "object" && e !== null && e.$$typeof === D) return "<...>"; try { var t = n(e); return t ? "<" + t + ">" : "<...>"; } catch { return "<...>"; } } function s() { var e = P.A; return e === null ? null : e.getOwner(); } function c() { return Error("react-stack-top-frame"); } function f(e) { if (L.call(e, "key")) { var t = Object.getOwnPropertyDescriptor(e, "key").get; if (t && t.isReactWarning) return !1; } return e.key !== void 0; } function m(e, t) { function i() { W || (W = !0, console.error( "%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://react.dev/link/special-props)", t )); } i.isReactWarning = !0, Object.defineProperty(e, "key", { get: i, configurable: !0 }); } function p() { var e = n(this.type); return J[e] || (J[e] = !0, console.error( "Accessing element.ref was removed in React 19. ref is now a regular prop. It will be removed from the JSX Element type in a future release." )), e = this.props.ref, e !== void 0 ? e : null; } function v(e, t, i, u, E, d, N, j) { return i = d.ref, e = { $$typeof: h, type: e, key: t, props: d, _owner: E }, (i !== void 0 ? i : null) !== null ? Object.defineProperty(e, "ref", { enumerable: !1, get: p }) : Object.defineProperty(e, "ref", { enumerable: !1, value: null }), e._store = {}, Object.defineProperty(e._store, "validated", { configurable: !1, enumerable: !1, writable: !0, value: 0 }), Object.defineProperty(e, "_debugInfo", { configurable: !1, enumerable: !1, writable: !0, value: null }), Object.defineProperty(e, "_debugStack", { configurable: !1, enumerable: !1, writable: !0, value: N }), Object.defineProperty(e, "_debugTask", { configurable: !1, enumerable: !1, writable: !0, value: j }), Object.freeze && (Object.freeze(e.props), Object.freeze(e)), e; } function O(e, t, i, u, E, d, N, j) { var l = t.children; if (l !== void 0) if (u) if (se(l)) { for (u = 0; u < l.length; u++) b(l[u]); Object.freeze && Object.freeze(l); } else console.error( "React.jsx: Static children should always be an array. You are likely explicitly calling React.jsxs or React.jsxDEV. Use the Babel transform instead." ); else b(l); if (L.call(t, "key")) { l = n(e); var R = Object.keys(t).filter(function(ie) { return ie !== "key"; }); u = 0 < R.length ? "{key: someKey, " + R.join(": ..., ") + ": ...}" : "{key: someKey}", V[l + u] || (R = 0 < R.length ? "{" + R.join(": ..., ") + ": ...}" : "{}", console.error( `A props object containing a "key" prop is being spread into JSX: let props = %s; <%s {...props} /> React keys must be passed directly to JSX without using spread: let props = %s; <%s key={someKey} {...props} />`, u, l, R, l ), V[l + u] = !0); } if (l = null, i !== void 0 && (o(i), l = "" + i), f(t) && (o(t.key), l = "" + t.key), "key" in t) { i = {}; for (var C in t) C !== "key" && (i[C] = t[C]); } else i = t; return l && m( i, typeof e == "function" ? e.displayName || e.name || "Unknown" : e ), v( e, l, d, E, s(), i, N, j ); } function b(e) { typeof e == "object" && e !== null && e.$$typeof === h && e._store && (e._store.validated = 1); } var y = le, h = Symbol.for("react.transitional.element"), k = Symbol.for("react.portal"), g = Symbol.for("react.fragment"), _ = Symbol.for("react.strict_mode"), w = Symbol.for("react.profiler"), Z = Symbol.for("react.consumer"), Q = Symbol.for("react.context"), ee = Symbol.for("react.forward_ref"), re = Symbol.for("react.suspense"), te = Symbol.for("react.suspense_list"), ne = Symbol.for("react.memo"), D = Symbol.for("react.lazy"), oe = Symbol.for("react.activity"), ae = Symbol.for("react.client.reference"), P = y.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE, L = Object.prototype.hasOwnProperty, se = Array.isArray, x = console.createTask ? console.createTask : function() { return null; }; y = { "react-stack-bottom-frame": function(e) { return e(); } }; var W, J = {}, U = y["react-stack-bottom-frame"].bind( y, c )(), M = x(a(c)), V = {}; A.Fragment = g, A.jsx = function(e, t, i, u, E) { var d = 1e4 > P.recentlyCreatedOwnerStacks++; return O( e, t, i, !1, u, E, d ? Error("react-stack-top-frame") : U, d ? x(a(e)) : M ); }, A.jsxs = function(e, t, i, u, E) { var d = 1e4 > P.recentlyCreatedOwnerStacks++; return O( e, t, i, !0, u, E, d ? Error("react-stack-top-frame") : U, d ? x(a(e)) : M ); }; }()), A; } process.env.NODE_ENV === "production" ? Y.exports = be() : Y.exports = Re(); var ke = Y.exports; const H = fe( void 0 ), We = () => { const n = de(H); if (n === void 0) throw new Error( "useIIIntegrationContext must be used within an IIIntegrationProvider" ); return n; }, Je = ({ children: n, value: r }) => /* @__PURE__ */ ke.jsx(H.Provider, { value: r, children: n }), _e = async ({ appKeyStorage: n, delegationStorage: r, onSuccess: o, onError: a, onFinally: s }) => { try { const c = await n.find(), f = await r.find(); c && f && o(); } catch (c) { a(c); } finally { s(); } }; class Te { /** * Creates a new instance of Ed25519KeyIdentityValueStorageWrapper. * @param storage - The storage implementation to use for persistence * @param key - The key under which the Ed25519KeyIdentity will be stored */ constructor(r, o) { T(this, "storage"); T(this, "key"); this.storage = r, this.key = o; } /** * Attempts to find and retrieve an Ed25519KeyIdentity from storage. * @returns A Promise that resolves to the found Ed25519KeyIdentity or undefined if not found */ async find() { const r = await this.storage.find(this.key); if (r) return F.fromJSON(r); } /** * Retrieves an Ed25519KeyIdentity from storage, throwing an error if not found. * @returns A Promise that resolves to the found Ed25519KeyIdentity * @throws {Error} If no Ed25519KeyIdentity is found for the configured key */ async retrieve() { const r = await this.find(); if (!r) throw new Error(`No value found for key ${this.key}`); return r; } /** * Saves an Ed25519KeyIdentity to storage. * @param value - The Ed25519KeyIdentity to save * @returns A Promise that resolves when the save operation is complete */ async save(r) { return this.storage.save(this.key, JSON.stringify(r.toJSON())); } /** * Removes the stored Ed25519KeyIdentity from storage. * @returns A Promise that resolves when the removal operation is complete */ async remove() { return this.storage.remove(this.key); } } class Se { /** * Creates a new instance of DelegationChainValueStorageWrapper. * @param storage - The storage implementation to use for persistence * @param key - The key under which the DelegationChain will be stored */ constructor(r, o) { T(this, "storage"); T(this, "key"); this.storage = r, this.key = o; } /** * Attempts to find and retrieve a DelegationChain from storage. * If the stored delegation chain is invalid, it will be automatically removed from storage. * @returns A Promise that resolves to the found DelegationChain or undefined if not found or invalid */ async find() { const r = await this.storage.find(this.key); if (r) return X.fromJSON(r); } /** * Retrieves a DelegationChain from storage, throwing an error if not found or invalid. * @returns A Promise that resolves to the found and valid DelegationChain * @throws {Error} If no valid DelegationChain is found for the configured key */ async retrieve() { const r = await this.find(); if (!r) throw new Error(`No value found for key ${this.key}`); return r; } /** * Saves a DelegationChain to storage. * @param value - The DelegationChain to save * @returns A Promise that resolves when the save operation is complete */ async save(r) { return this.storage.save(this.key, JSON.stringify(r.toJSON())); } /** * Removes the stored DelegationChain from storage. * @returns A Promise that resolves when the removal operation is complete */ async remove() { return this.storage.remove(this.key); } } const Ae = async ({ appKeyStorage: n, delegationStorage: r }) => { const o = await n.find(), a = await r.find(); if (o && a) try { return await B({ appKey: o, delegationChain: a }); } catch (s) { throw pe(s) && await r.remove(), s; } else if (!o) { const s = F.generate(); await n.save(s), await r.remove(); } }, Oe = async ({ appKeyStorage: n, delegationStorage: r, onError: o }) => { try { const a = await Ae({ appKeyStorage: n, delegationStorage: r }); return a || new ve(); } catch (a) { throw console.error("Get identity failed:", a), o(a), a; } }, Ie = async ({ iiIntegrationUrl: n, deepLinkType: r, redirectPath: o, appKeyStorage: a, redirectPathStorage: s, sessionIdStorage: c, cryptoModule: f, openBrowserOptions: m = {} }) => { const p = await F.generate(); await a.save(p); const v = Ee(p.getPublicKey().toDer()); console.log("login redirectPath", o), await he({ url: n, params: { pubkey: v, deepLinkType: r, pathname: "/" }, redirectPath: o, redirectPathStorage: s, sessionIdStorage: c, cryptoModule: f, openBrowserOptions: m }); }, Pe = async ({ delegationStorage: n, onFinally: r }) => { try { await n.remove(); } finally { r(); } }, xe = async ({ delegation: n, delegationStorage: r, appKeyStorage: o }) => { const a = X.fromJSON(n), s = await o.retrieve(), c = await B({ appKey: s, delegationChain: a }); return await r.save(a), c; }, I = "expo-ii-integration", Ue = ({ iiIntegrationUrl: n, deepLinkType: r, secureStorage: o, regularStorage: a, cryptoModule: s }) => { const c = me.useURL(), [f, m] = $(!1), [p, v] = $(!1), [O, b] = $(void 0), y = new Te( o, `${I}.appKey` ), h = new Se( a, `${I}.delegation` ), k = new G( a, `${I}.redirectPath` ), g = new G( a, `${I}.sessionId` ); return z(() => { f || _e({ appKeyStorage: y, delegationStorage: h, onSuccess: () => { v(!0); }, onError: b, onFinally: () => m(!0) }); }, []), z(() => { p || !c || ge({ url: new URL(c), sessionIdStorage: g, onSuccess: async ({ delegation: _ }) => { await xe({ delegation: _, delegationStorage: h, appKeyStorage: y }), console.log("Authenticated from delegation"), v(!0), await g.remove(); const w = await k.find(); w && (console.log("Redirecting to", w), await k.remove(), ye.replace(w)), we(); }, onError: b // onFinally: async () => { // await sessionIdStorage.remove(); // await redirectPathStorage.remove(); // }, }); }, [c]), { isAuthReady: f, isAuthenticated: p, getIdentity: () => Oe({ appKeyStorage: y, delegationStorage: h, onError: () => v(!1) }), login: ({ redirectPath: _, openBrowserOptions: w } = {}) => Ie({ iiIntegrationUrl: n, deepLinkType: r, appKeyStorage: y, redirectPath: _, redirectPathStorage: k, sessionIdStorage: g, cryptoModule: s, openBrowserOptions: w }), logout: () => Pe({ delegationStorage: h, onFinally: () => v(!1) }), authError: O, clearAuthError: () => b(void 0) }; }; export { Se as DelegationChainValueStorageWrapper, Te as Ed25519KeyIdentityValueStorageWrapper, Je as IIIntegrationProvider, Ue as useIIIntegration, We as useIIIntegrationContext };