From 1d180bb01bd3e3c4965b1529af20865333dc72c1 Mon Sep 17 00:00:00 2001 From: Aykhan Date: Wed, 22 Jul 2026 19:52:03 +0400 Subject: [PATCH 1/2] fix:(cross-domain): support async storage implementations --- src/plugins/cross-domain/client.test.ts | 20 +++++++-------- src/plugins/cross-domain/client.ts | 25 +++++++++---------- src/plugins/cross-domain/client.types.test.ts | 2 +- 3 files changed, 23 insertions(+), 24 deletions(-) diff --git a/src/plugins/cross-domain/client.test.ts b/src/plugins/cross-domain/client.test.ts index 56dc9261..fcf3a60c 100644 --- a/src/plugins/cross-domain/client.test.ts +++ b/src/plugins/cross-domain/client.test.ts @@ -159,34 +159,34 @@ describe("crossDomainClient", () => { } describe("getSessionData", () => { - it("returns null when storage is empty", () => { + it("returns null when storage is empty", async () => { const actions = getActions(); - expect(actions.getSessionData()).toBeNull(); + expect(await actions.getSessionData()).toBeNull(); }); - it("returns null for empty object in storage", () => { + it("returns null for empty object in storage", async () => { storage.set(localCacheName, "{}"); const actions = getActions(); - expect(actions.getSessionData()).toBeNull(); + expect(await actions.getSessionData()).toBeNull(); }); - it("returns parsed session data", () => { + it("returns parsed session data", async () => { const sessionData = { session: { id: "123" }, user: { name: "test" } }; storage.set(localCacheName, JSON.stringify(sessionData)); const actions = getActions(); - expect(actions.getSessionData()).toEqual(sessionData); + expect(await actions.getSessionData()).toEqual(sessionData); }); - it("returns null for stored 'null' string", () => { + it("returns null for stored 'null' string", async () => { storage.set(localCacheName, "null"); const actions = getActions(); - expect(actions.getSessionData()).toBeNull(); + expect(await actions.getSessionData()).toBeNull(); }); - it("returns null for corrupt JSON in storage", () => { + it("returns null for corrupt JSON in storage", async () => { storage.set(localCacheName, "not-valid-json"); const actions = getActions(); - expect(actions.getSessionData()).toBeNull(); + expect(await actions.getSessionData()).toBeNull(); }); }); diff --git a/src/plugins/cross-domain/client.ts b/src/plugins/cross-domain/client.ts index 381c0783..9c5b299b 100644 --- a/src/plugins/cross-domain/client.ts +++ b/src/plugins/cross-domain/client.ts @@ -1,6 +1,5 @@ import type { BetterAuthClientPlugin, ClientStore } from "better-auth/client"; import { parseSetCookieHeader } from "better-auth/cookies"; -import type { BetterFetchOption } from "@better-fetch/fetch"; import type { crossDomain } from "./index.js"; import { VERSION } from "../../version.js"; @@ -10,9 +9,9 @@ interface StoredCookie { } type CrossDomainActions = { - getCookie: () => string; + getCookie: () => Promise; updateSession: () => void; - getSessionData: () => Record | null; + getSessionData: () => Promise | null>; }; type CrossDomainClientPlugin = Omit< @@ -74,7 +73,7 @@ export const crossDomainClient = ( opts: { storage?: { setItem: (key: string, value: string) => any; - getItem: (key: string) => string | null; + getItem: (key: string) => Promise | string | null; }; storagePrefix?: string; disableCache?: boolean; @@ -108,8 +107,8 @@ export const crossDomainClient = ( * }, * }); */ - getCookie: () => { - const cookie = storage?.getItem(cookieName); + getCookie: async () => { + const cookie = await storage?.getItem(cookieName); return getCookie(cookie || "{}"); }, /** @@ -134,8 +133,8 @@ export const crossDomainClient = ( * const sessionData = client.getSessionData(); * ``` */ - getSessionData: (): Record | null => { - const sessionData = storage?.getItem(localCacheName); + getSessionData: async (): Promise | null> => { + const sessionData = await storage?.getItem(localCacheName); if (!sessionData) return null; try { const parsed = JSON.parse(sessionData); @@ -166,7 +165,7 @@ export const crossDomainClient = ( "set-better-auth-cookie" ); if (setCookie) { - const prevCookie = storage.getItem(cookieName); + const prevCookie = await storage.getItem(cookieName); const toSetCookie = getSetCookie( setCookie || "", prevCookie ?? undefined @@ -208,7 +207,7 @@ export const crossDomainClient = ( // Previously this unconditionally set cookieName to "{}", // which wiped the two_factor challenge token needed for // verifyTotp in cross-domain setups. - const prev = storage.getItem(cookieName); + const prev = await storage.getItem(cookieName); try { const parsed = JSON.parse(prev || "{}") as Record< string, @@ -236,11 +235,11 @@ export const crossDomainClient = ( if (!storage) { return { url, - options: options as BetterFetchOption, + options: options, }; } options = options || {}; - const storedCookie = storage.getItem(cookieName); + const storedCookie = await storage.getItem(cookieName); const cookie = getCookie(storedCookie || "{}"); options.credentials = "omit"; options.headers = { @@ -258,7 +257,7 @@ export const crossDomainClient = ( } return { url, - options: options as BetterFetchOption, + options: options , }; }, }, diff --git a/src/plugins/cross-domain/client.types.test.ts b/src/plugins/cross-domain/client.types.test.ts index a1d0714c..7581f598 100644 --- a/src/plugins/cross-domain/client.types.test.ts +++ b/src/plugins/cross-domain/client.types.test.ts @@ -15,5 +15,5 @@ it("composes with Better Auth client plugins and infers cross-domain actions", ( plugins: [convexClient(), crossDomainClient({ storage }), adminClient()], }); - expectTypeOf(authClient.getCookie).toEqualTypeOf<() => string>(); + expectTypeOf(authClient.getCookie).toEqualTypeOf<() => Promise>(); }); From eb84ac3918dee4efc7085480f69056507dcdc412 Mon Sep 17 00:00:00 2001 From: Aykhan Date: Wed, 22 Jul 2026 23:37:59 +0400 Subject: [PATCH 2/2] fix: update comments and setItem type --- src/plugins/cross-domain/client.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/plugins/cross-domain/client.ts b/src/plugins/cross-domain/client.ts index 9c5b299b..7740ed9b 100644 --- a/src/plugins/cross-domain/client.ts +++ b/src/plugins/cross-domain/client.ts @@ -72,7 +72,7 @@ export function getCookie(cookie: string) { export const crossDomainClient = ( opts: { storage?: { - setItem: (key: string, value: string) => any; + setItem: (key: string, value: string) => void | Promise; getItem: (key: string) => Promise | string | null; }; storagePrefix?: string; @@ -100,7 +100,7 @@ export const crossDomainClient = ( * * @example * ```ts - * const cookie = client.getCookie(); + * const cookie = await client.getCookie(); * fetch("https://api.example.com", { * headers: { * cookie, @@ -130,7 +130,7 @@ export const crossDomainClient = ( * * @example * ```ts - * const sessionData = client.getSessionData(); + * const sessionData = await client.getSessionData(); * ``` */ getSessionData: async (): Promise | null> => {