import type { BetterAuthClientPlugin } from "@better-auth/core"; import { parseCookies } from "better-auth/cookies"; import type { electron } from "./index"; import type { ElectronProxyClientOptions } from "./types/client"; import { parseProtocolScheme } from "./utils"; import { PACKAGE_VERSION } from "./version"; export const electronProxyClient = (options: ElectronProxyClientOptions) => { const opts = { clientID: "electron", cookiePrefix: "better-auth", callbackPath: "/auth/callback", ...options, }; const redirectCookieName = `${opts.cookiePrefix}.${opts.clientID}`; const { scheme } = parseProtocolScheme(opts.protocol); return { id: "electron-proxy", version: PACKAGE_VERSION, getActions: () => { const getAuthorizationCode = () => { if (typeof document === "undefined") return null; const authorizationCode = parseCookies(document.cookie).get( redirectCookieName, ); return authorizationCode ?? null; }; return { electron: { /** * Gets the current authorization code from the cookie. */ getAuthorizationCode, }, /** * Ensures redirecting to the Electron app. * * Polls for a cookie set by the server to indicate that an authorization code is available. * * @returns The interval ID which can be used to clear the polling. */ ensureElectronRedirect: ( cfg?: | { /** * @default 10_000 */ timeout?: number | undefined; /** * @default 100 */ interval?: number | undefined; } | undefined, ) => { const timeout = cfg?.timeout || 10_000; const interval = cfg?.interval || 100; const handleRedirect = () => { const authorizationCode = getAuthorizationCode(); if (!authorizationCode) { return false; } document.cookie = `${redirectCookieName}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/`; window.location.replace( `${scheme}:/${opts.callbackPath}#token=${authorizationCode}`, ); return true; }; const start = Date.now(); const id = setInterval(() => { const success = handleRedirect(); if (success || Date.now() - start > timeout) { clearInterval(id); } }, interval); return id; }, }; }, pathMethods: { "/electron/transfer-user": "POST", }, $InferServerPlugin: {} as ReturnType, } satisfies BetterAuthClientPlugin; };