From bb0c93edb405947208ba969458fae754add3c603 Mon Sep 17 00:00:00 2001 From: RainbowBird Date: Sat, 28 Mar 2026 15:47:19 +0800 Subject: [PATCH] fix(server/auth): skip state_mismatch check --- apps/server/src/libs/auth.ts | 11 ++++++----- apps/server/src/utils/origin.ts | 9 +++++++-- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/apps/server/src/libs/auth.ts b/apps/server/src/libs/auth.ts index 44673c180..9d5cd6d36 100644 --- a/apps/server/src/libs/auth.ts +++ b/apps/server/src/libs/auth.ts @@ -43,13 +43,14 @@ export function createAuth(db: Database, env: Env, metrics?: AuthMetrics | null) }, }, - // NOTICE: Store OAuth state in the database instead of cookies to avoid - // state_mismatch errors on mobile browsers (iOS Safari/Chrome) where - // cross-site cookies are blocked by system-level privacy restrictions. + // NOTICE: skipStateCookieCheck required for Capacitor mobile apps. + // Default state strategy is 'database' (we have a DB), but better-auth + // still validates a signed state cookie (state.mjs L89-94). In Capacitor, + // OAuth opens a system browser with a separate cookie jar from the WebView, + // so the signed cookie is always missing → state_security_mismatch. // https://github.com/better-auth/better-auth/issues/5892 - // https://github.com/better-auth/better-auth/issues/6207 account: { - storeStateStrategy: 'database', + skipStateCookieCheck: true, }, socialProviders: { diff --git a/apps/server/src/utils/origin.ts b/apps/server/src/utils/origin.ts index f7e812cf5..9332af50c 100644 --- a/apps/server/src/utils/origin.ts +++ b/apps/server/src/utils/origin.ts @@ -15,12 +15,17 @@ export function getTrustedOrigin(origin: string): string { return origin } - // 2. Allow Production (Exact Match) + // 2. Allow Capacitor mobile app origins (iOS: capacitor://, Android: http://localhost) + if (origin === 'capacitor://localhost') { + return origin + } + + // 3. Allow Production (Exact Match) if (origin === 'https://airi.moeru.ai') { return origin } - // 3. Allow Dynamic Subdomains (Strict Regex) + // 4. Allow Dynamic Subdomains (Strict Regex) // Matches: https://foo.kwaa.workers.dev if (/^https:\/\/.*\.kwaa\.workers\.dev$/.test(origin)) { return origin