From 12db1cb091832dd52c8a654e48e3e587b400aa2f Mon Sep 17 00:00:00 2001 From: Alex Date: Fri, 7 Nov 2025 22:45:00 +0100 Subject: [PATCH] fix(expo): account linking flow on mobile (#5836) --- packages/expo/src/client.ts | 4 +++- packages/expo/test/expo.test.ts | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/packages/expo/src/client.ts b/packages/expo/src/client.ts index a88949d714..9dc2d87d62 100644 --- a/packages/expo/src/client.ts +++ b/packages/expo/src/client.ts @@ -373,7 +373,9 @@ export const expoClient = (opts: ExpoClientOptions) => { const url = new URL(result.url); const cookie = String(url.searchParams.get("cookie")); if (!cookie) return; - storage.setItem(cookieName, getSetCookie(cookie)); + const prevCookie = await storage.getItem(cookieName); + const toSetCookie = getSetCookie(cookie, prevCookie ?? undefined); + storage.setItem(cookieName, toSetCookie); store?.notify("$sessionSignal"); } }, diff --git a/packages/expo/test/expo.test.ts b/packages/expo/test/expo.test.ts index ddecd50528..fb47ca5c4a 100644 --- a/packages/expo/test/expo.test.ts +++ b/packages/expo/test/expo.test.ts @@ -307,6 +307,39 @@ describe("expo", async () => { }); expect(origin).toBe(null); }); + + it("should preserve existing cookies on link-social", async () => { + await client.signIn.email({ + email: "test@test.com", + password: "password", + }); + const testCookie = "better-auth.test-key"; + const testCookieValue = "abc"; + + const storedCookieBefore = storage.get("better-auth_cookie"); + expect(storedCookieBefore).toBeDefined(); + const parsedCookieBefore = JSON.parse(storedCookieBefore || ""); + expect(parsedCookieBefore[testCookie]).toBeUndefined(); + + const expoWebBrowser = await import("expo-web-browser"); + vi.mocked(expoWebBrowser.openAuthSessionAsync).mockResolvedValueOnce({ + type: "success", + url: `better-auth://?cookie=${testCookie}=${testCookieValue}`, + }); + + await client.linkSocial({ provider: "google" }); + + const storedCookieAfter = storage.get("better-auth_cookie"); + expect(storedCookieAfter).toBeDefined(); + const parsedCookieAfter = JSON.parse(storedCookieAfter || ""); + expect(parsedCookieAfter[testCookie]?.value).toBe(testCookieValue); + Object.keys(parsedCookieBefore).forEach((key) => { + expect( + parsedCookieAfter[key]?.value, + `cookie "${key}" value is preserved`, + ).toBe(parsedCookieBefore[key]?.value); + }); + }); }); describe("expo with cookieCache", async () => {