everything-dev
Version:
A consolidated product package for building Module Federation apps with oRPC APIs.
260 lines (258 loc) • 9.98 kB
JavaScript
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
const require_ui_runtime = require('./runtime.cjs');
const require_plugin_path = require('./plugin-path.cjs');
const require_auth_guards = require('./auth-guards.cjs');
let _tanstack_react_router = require("@tanstack/react-router");
let _better_auth_api_key_client = require("@better-auth/api-key/client");
let _better_auth_passkey_client = require("@better-auth/passkey/client");
let _simplewebauthn_browser = require("@simplewebauthn/browser");
let _tanstack_react_query = require("@tanstack/react-query");
let better_auth_client_plugins = require("better-auth/client/plugins");
let better_auth_react = require("better-auth/react");
let better_near_auth_client = require("better-near-auth/client");
//#region src/ui/auth.ts
function hasAuthVariables(auth) {
return !!auth && typeof auth === "object" && typeof auth.variables === "object";
}
function readRuntimeConfig(config) {
if (config) return config;
if (typeof window === "undefined") return void 0;
try {
return require_ui_runtime.getRuntimeConfig();
} catch {
return;
}
}
function getAuthVariables(config) {
const runtimeConfig = readRuntimeConfig(config);
if (!runtimeConfig || !hasAuthVariables(runtimeConfig.auth)) throw new Error("Missing auth runtime configuration");
return runtimeConfig.auth.variables;
}
function getSiwnClientConfig(options) {
const runtimeConfig = readRuntimeConfig(options.runtimeConfig);
const siwn = getAuthVariables(options.runtimeConfig).siwn;
const mainnetRecipient = siwn.recipients?.mainnet ?? siwn.recipient;
if (!mainnetRecipient) throw new Error("Missing auth SIWN recipient");
const networkId = runtimeConfig?.networkId ?? (mainnetRecipient.endsWith(".testnet") ? "testnet" : "mainnet");
const testnetRecipient = siwn.recipients?.testnet;
if (testnetRecipient) return {
recipients: {
mainnet: mainnetRecipient,
testnet: testnetRecipient
},
networkId,
cspNonce: options.cspNonce
};
return {
recipient: mainnetRecipient,
networkId,
cspNonce: options.cspNonce
};
}
function getHostUrl(config) {
const runtimeConfig = readRuntimeConfig(config);
if (runtimeConfig?.hostUrl) return runtimeConfig.hostUrl;
if (typeof window !== "undefined") return window.location.origin;
return "";
}
function getDeviceLinkClientId(config) {
return (readRuntimeConfig(config)?.auth?.variables)?.deviceLink?.clientId ?? better_near_auth_client.DEFAULT_DEVICE_LINK_CLIENT_ID;
}
/**
* Typed client surface for the auth plugin's referral endpoints — a local
* plugin (like custodyClient) instead of the upstream client plugin, whose
* single-module entry drags its server-side nanoid → node:crypto imports
* into every browser bundle that includes this file.
*/
function referralClient() {
return {
id: "better-auth-referral",
$InferServerPlugin: {},
getActions: ($fetch) => ({ referrals: {
dashboard: async () => {
return await $fetch("/referrals", { method: "GET" });
},
list: async (params) => {
return await $fetch("/referrals/list-referrals", {
method: "GET",
query: params
});
}
} })
};
}
/**
* Typed client surface for the auth plugin's custody endpoints — the
* escape-hatch replacement for raw `auth.$fetch("/custody/register")` on the
* device approval page.
*/
function custodyClient() {
return {
id: "custody",
$InferServerPlugin: {},
getActions: ($fetch) => ({ custody: { register: async (params) => {
return await $fetch("/custody/register", {
method: "POST",
body: params
});
} } })
};
}
function createAuthClient(options = {}) {
const nearAuthConfig = getSiwnClientConfig(options);
return (0, better_auth_react.createAuthClient)({
baseURL: getHostUrl(options.runtimeConfig),
fetchOptions: {
credentials: "include",
...options.headers ? { headers: options.headers } : {}
},
plugins: [
(0, better_auth_client_plugins.inferAdditionalFields)({ user: { locale: {
type: "string",
required: false,
input: true
} } }),
(0, better_near_auth_client.siwnClient)(nearAuthConfig),
(0, better_auth_client_plugins.adminClient)(),
(0, better_auth_client_plugins.anonymousClient)(),
(0, better_auth_client_plugins.phoneNumberClient)(),
(0, _better_auth_passkey_client.passkeyClient)(),
(0, better_auth_client_plugins.organizationClient)({ teams: { enabled: true } }),
(0, _better_auth_api_key_client.apiKeyClient)(),
(0, better_auth_client_plugins.deviceAuthorizationClient)(),
custodyClient(),
referralClient()
]
});
}
function useAuthClient() {
return (0, _tanstack_react_router.useRouter)().options.context.authClient;
}
const sessionQueryKey = ["session"];
function sessionQueryOptions(authClient) {
return {
queryKey: sessionQueryKey,
queryFn: async () => {
const { data: session, error } = await authClient.getSession({ query: { disableCookieCache: true } });
if (error) throw new Error(error.message || "Unable to load your session");
return session ?? null;
},
staleTime: 6e4,
gcTime: 6e5
};
}
async function refreshSessionCache(authClient, queryClient) {
return queryClient.fetchQuery({
...sessionQueryOptions(authClient),
staleTime: 0
});
}
/**
* Resolves the session for the root route: the query cache wins (it is kept
* authoritative by the single sessionQueryOptions read path), and a populated
* router-context session — the host's SSR resolution — seeds an empty cache so
* the dehydrated state carries it to the client.
*
* A null context session is "the host did not resolve one", not a verified
* sign-out: seeding it handed requireSession a freshly-cached null and the
* guard 307'd to /login without ever running the fetch (#527). The explicit
* signed-out entry still wins — clearAuthenticatedQueries writes it itself.
*/
function resolveSessionFromCache(queryClient, contextSession) {
if (!queryClient) return contextSession;
const cachedSession = queryClient.getQueryData(sessionQueryKey);
if (cachedSession !== void 0) return cachedSession;
if (contextSession !== null && contextSession !== void 0) queryClient.setQueryData(sessionQueryKey, contextSession);
return contextSession;
}
function useRelayHistory(session, authClient) {
return (0, _tanstack_react_query.useQuery)({
queryKey: ["relay-history"],
queryFn: async () => {
return (await authClient.near.relayHistory())?.data?.transactions ?? [];
},
enabled: !!session,
refetchInterval: 2e3
});
}
const UNSUPPORTED_AUTHENTICATOR_CODES = /* @__PURE__ */ new Set([
"PASSKEY_UNSUPPORTED_AUTHENTICATOR",
"ERROR_AUTHENTICATOR_NO_SUPPORTED_PUBKEYCREDPARAMS_ALG",
"ERROR_AUTHENTICATOR_MISSING_DISCOVERABLE_CREDENTIAL_SUPPORT",
"ERROR_AUTHENTICATOR_MISSING_USER_VERIFICATION_SUPPORT"
]);
function isUnsupportedAuthenticatorError(error) {
if (!(error instanceof Error) || !("code" in error)) return false;
return typeof error.code === "string" && UNSUPPORTED_AUTHENTICATOR_CODES.has(error.code);
}
function toPasskeyError(error, fallback) {
return Object.assign(new Error(error?.message || fallback), { code: error?.code });
}
async function isPasskeyAutofillAvailable() {
if (typeof window === "undefined" || !window.PublicKeyCredential) return false;
try {
return await window.PublicKeyCredential.isConditionalMediationAvailable?.() === true;
} catch {
return false;
}
}
/**
* Aborts any pending passkey ceremony (modal or conditional-mediation).
* Targets the same `WebAuthnAbortService` singleton instance
* `@better-auth/passkey` resolves, so the abort reaches the request the
* browser is holding.
*/
function cancelPasskeyCeremony() {
_simplewebauthn_browser.WebAuthnAbortService.cancelCeremony();
}
function isPasskeyCeremonyAborted(error) {
return error instanceof Error && "code" in error && error.code === "ERROR_CEREMONY_ABORTED";
}
async function createAccountWithPasskey(authClient, options) {
try {
const headers = options?.referralCode ? { "x-referral-code": options.referralCode } : void 0;
const { data, error } = await authClient.passkey.addPasskey(void 0, { headers });
if (error || !data) {
options?.onError?.(toPasskeyError(error, "Could not create your account"));
return;
}
const { passkeyWallet } = data;
options?.onSuccess?.({ passkeyWallet });
} catch (error) {
options?.onError?.(toPasskeyError(error instanceof Error ? error : null, "Could not create your account"));
}
}
async function signInWithPasskey(authClient, options) {
try {
const { data, error } = await authClient.signIn.passkey({ autoFill: options?.autoFill });
if (error || !data) {
options?.onError?.(toPasskeyError(error, "Passkey sign-in failed"));
return;
}
options?.onSuccess?.();
} catch (error) {
options?.onError?.(toPasskeyError(error instanceof Error ? error : null, "Passkey sign-in failed"));
}
}
//#endregion
exports.cancelPasskeyCeremony = cancelPasskeyCeremony;
exports.clearAuthenticatedQueries = require_auth_guards.clearAuthenticatedQueries;
exports.createAccountWithPasskey = createAccountWithPasskey;
exports.createAuthClient = createAuthClient;
exports.getDeviceLinkClientId = getDeviceLinkClientId;
exports.isPasskeyAutofillAvailable = isPasskeyAutofillAvailable;
exports.isPasskeyCeremonyAborted = isPasskeyCeremonyAborted;
exports.isUnsupportedAuthenticatorError = isUnsupportedAuthenticatorError;
exports.pluginHref = require_plugin_path.pluginHref;
exports.pluginPath = require_plugin_path.pluginPath;
exports.pluginSearch = require_plugin_path.pluginSearch;
exports.refreshSessionCache = refreshSessionCache;
exports.requireAdmin = require_auth_guards.requireAdmin;
exports.requireSession = require_auth_guards.requireSession;
exports.resolveSessionFromCache = resolveSessionFromCache;
exports.sessionQueryKey = sessionQueryKey;
exports.sessionQueryOptions = sessionQueryOptions;
exports.signInWithPasskey = signInWithPasskey;
exports.useAuthClient = useAuthClient;
exports.useRelayHistory = useRelayHistory;
//# sourceMappingURL=auth.cjs.map