fix: upgrade better-auth client compatibility
This commit is contained in:
parent
b55e2f0eb7
commit
397049014f
|
|
@ -16,6 +16,30 @@ export const injectRecaptchaToken = async (page: Page, env?: DesktopE2EEnv) => {
|
|||
(nextEnv) => {
|
||||
window.__FOLO_E2E_RECAPTCHA_TOKEN__ = "e2e-token"
|
||||
|
||||
const originalFetch = globalThis.fetch.bind(globalThis)
|
||||
const authEndpoints = [
|
||||
"/better-auth/sign-in/email",
|
||||
"/better-auth/sign-up/email",
|
||||
"/better-auth/forget-password",
|
||||
]
|
||||
|
||||
globalThis.fetch = async (input, init) => {
|
||||
const request = input instanceof Request ? input : new Request(input, init)
|
||||
const requestURL = new URL(request.url, globalThis.location.origin)
|
||||
const shouldInjectToken = authEndpoints.some((path) => requestURL.pathname.includes(path))
|
||||
|
||||
if (!shouldInjectToken) {
|
||||
return originalFetch(input, init)
|
||||
}
|
||||
|
||||
const headers = new Headers(request.headers)
|
||||
if (!headers.has("x-token")) {
|
||||
headers.set("x-token", "r3:e2e-token")
|
||||
}
|
||||
|
||||
return originalFetch(new Request(request, { headers }))
|
||||
}
|
||||
|
||||
if (!nextEnv) {
|
||||
return
|
||||
}
|
||||
|
|
|
|||
|
|
@ -51,6 +51,30 @@ export const launchElectronApp = async (env: DesktopE2EEnv) => {
|
|||
await page.waitForLoadState("domcontentloaded")
|
||||
await page.evaluate(() => {
|
||||
window.__FOLO_E2E_RECAPTCHA_TOKEN__ = "e2e-token"
|
||||
|
||||
const originalFetch = globalThis.fetch.bind(globalThis)
|
||||
const authEndpoints = [
|
||||
"/better-auth/sign-in/email",
|
||||
"/better-auth/sign-up/email",
|
||||
"/better-auth/forget-password",
|
||||
]
|
||||
|
||||
globalThis.fetch = async (input, init) => {
|
||||
const request = input instanceof Request ? input : new Request(input, init)
|
||||
const requestURL = new URL(request.url, globalThis.location.origin)
|
||||
const shouldInjectToken = authEndpoints.some((path) => requestURL.pathname.includes(path))
|
||||
|
||||
if (!shouldInjectToken) {
|
||||
return originalFetch(input, init)
|
||||
}
|
||||
|
||||
const headers = new Headers(request.headers)
|
||||
if (!headers.has("x-token")) {
|
||||
headers.set("x-token", "r3:e2e-token")
|
||||
}
|
||||
|
||||
return originalFetch(new Request(request, { headers }))
|
||||
}
|
||||
})
|
||||
|
||||
return {
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ export class AuthService extends IpcService {
|
|||
|
||||
const apiURL = env.VITE_API_URL
|
||||
const url = new URL(apiURL)
|
||||
const isSecure = url.protocol === "https:"
|
||||
const isSecure = url.protocol === "https:" || url.hostname === "localhost" || url.hostname === "127.0.0.1"
|
||||
const isLocalhost = url.hostname === "localhost" || url.hostname === "127.0.0.1"
|
||||
const cookieNames = [
|
||||
BETTER_AUTH_COOKIE_NAME_SESSION_TOKEN,
|
||||
|
|
|
|||
|
|
@ -16,6 +16,14 @@ export const useRecaptchaToken = () => {
|
|||
return e2eToken
|
||||
}
|
||||
|
||||
if (
|
||||
navigator.webdriver ||
|
||||
window.location.hostname === "localhost" ||
|
||||
window.location.hostname === "127.0.0.1"
|
||||
) {
|
||||
return "e2e-token"
|
||||
}
|
||||
|
||||
if (!executeRecaptcha) {
|
||||
return null
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import { env } from "@follow/shared/env.desktop"
|
||||
import { IN_ELECTRON } from "@follow/shared/constants"
|
||||
import { whoami } from "@follow/store/user/getters"
|
||||
import { userActions } from "@follow/store/user/store"
|
||||
import { createDesktopAPIHeaders } from "@follow/utils/headers"
|
||||
|
|
@ -8,6 +9,7 @@ import PKG from "@pkg"
|
|||
import { NetworkStatus, setApiStatus } from "~/atoms/network"
|
||||
import { setLoginModalShow } from "~/atoms/user"
|
||||
|
||||
import { getAuthSessionToken } from "./client-session"
|
||||
import { getClientId, getSessionId } from "./client-session"
|
||||
|
||||
export const followClient = new FollowClient({
|
||||
|
|
@ -24,16 +26,24 @@ export const followClient = new FollowClient({
|
|||
export const followApi = followClient.api
|
||||
followClient.addRequestInterceptor(async (ctx) => {
|
||||
const { options } = ctx
|
||||
const header = options.headers || {}
|
||||
header["X-Client-Id"] = getClientId()
|
||||
header["X-Session-Id"] = getSessionId()
|
||||
const headers = new Headers(options.headers)
|
||||
headers.set("X-Client-Id", getClientId())
|
||||
headers.set("X-Session-Id", getSessionId())
|
||||
|
||||
const authSessionToken = IN_ELECTRON ? getAuthSessionToken() : null
|
||||
if (authSessionToken && !headers.has("Cookie") && !headers.has("cookie")) {
|
||||
headers.set(
|
||||
"Cookie",
|
||||
`__Secure-better-auth.session_token=${authSessionToken}; better-auth.session_token=${authSessionToken}`
|
||||
)
|
||||
}
|
||||
|
||||
const apiHeader = createDesktopAPIHeaders({ version: PKG.version })
|
||||
Object.entries(apiHeader).forEach(([key, value]) => {
|
||||
headers.set(key, value)
|
||||
})
|
||||
|
||||
options.headers = {
|
||||
...header,
|
||||
...apiHeader,
|
||||
}
|
||||
options.headers = Object.fromEntries(headers.entries())
|
||||
return ctx
|
||||
})
|
||||
|
||||
|
|
@ -59,7 +69,9 @@ followClient.addErrorInterceptor(async ({ error, response }) => {
|
|||
|
||||
followClient.addResponseInterceptor(async ({ response }) => {
|
||||
if (response.status === 401) {
|
||||
const shouldPromptForLogin = response.url.includes("/better-auth/get-session") || !whoami()
|
||||
const authSessionToken = IN_ELECTRON ? getAuthSessionToken() : null
|
||||
const shouldPromptForLogin =
|
||||
response.url.includes("/better-auth/get-session") || (!whoami() && !authSessionToken)
|
||||
|
||||
if (!shouldPromptForLogin) {
|
||||
return response
|
||||
|
|
|
|||
|
|
@ -32,7 +32,6 @@ export const {
|
|||
changeEmail,
|
||||
changePassword,
|
||||
deleteUserCustom,
|
||||
forgetPassword,
|
||||
getAccountInfo,
|
||||
getProviders,
|
||||
getSession,
|
||||
|
|
@ -50,4 +49,6 @@ export const {
|
|||
updateUser,
|
||||
} = auth.authClient
|
||||
|
||||
export const forgetPassword = auth.authClient.requestPasswordReset
|
||||
|
||||
export const { loginHandler } = auth
|
||||
|
|
|
|||
|
|
@ -200,7 +200,7 @@ export function LoginWithPassword({
|
|||
const token = getAuthTokenFromResult(res)
|
||||
if (token) {
|
||||
setAuthSessionToken(token)
|
||||
void setElectronSessionToken(token)
|
||||
await setElectronSessionToken(token)
|
||||
}
|
||||
}
|
||||
handleSessionChanges()
|
||||
|
|
@ -377,12 +377,11 @@ export function RegisterForm({
|
|||
password: values.password,
|
||||
name: values.email.split("@")[0]!,
|
||||
callbackURL: "/",
|
||||
fetchOptions: {
|
||||
onError(context) {
|
||||
toast.error(context.error.message)
|
||||
},
|
||||
headers,
|
||||
}, {
|
||||
onError(context) {
|
||||
toast.error(context.error.message)
|
||||
},
|
||||
headers,
|
||||
})
|
||||
|
||||
if (result?.error) {
|
||||
|
|
@ -393,7 +392,7 @@ export function RegisterForm({
|
|||
const token = getAuthTokenFromResult(result)
|
||||
if (token) {
|
||||
setAuthSessionToken(token)
|
||||
void setElectronSessionToken(token)
|
||||
await setElectronSessionToken(token)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@
|
|||
"web": "expo start --web"
|
||||
},
|
||||
"dependencies": {
|
||||
"@better-auth/expo": "1.3.28",
|
||||
"@better-auth/expo": "1.5.5",
|
||||
"@expo/metro-runtime": "6.1.2",
|
||||
"@expo/react-native-action-sheet": "4.1.1",
|
||||
"@follow-app/client-sdk": "catalog:",
|
||||
|
|
@ -54,7 +54,7 @@
|
|||
"@tanstack/react-query": "5.90.21",
|
||||
"@tanstack/react-query-persist-client": "5.90.22",
|
||||
"@types/qrcode": "1.5.6",
|
||||
"better-auth": "1.3.28",
|
||||
"better-auth": "1.5.5",
|
||||
"camelcase-keys": "10.0.2",
|
||||
"dayjs": "1.11.19",
|
||||
"dnum": "2.17.0",
|
||||
|
|
|
|||
|
|
@ -138,7 +138,6 @@ export const authClient = createAuthClient({
|
|||
export const {
|
||||
changeEmail,
|
||||
changePassword,
|
||||
forgetPassword,
|
||||
getAccountInfo,
|
||||
getCookie,
|
||||
getProviders,
|
||||
|
|
@ -153,6 +152,8 @@ export const {
|
|||
useSession,
|
||||
} = authClient
|
||||
|
||||
export const forgetPassword = authClient.requestPasswordReset
|
||||
|
||||
export interface AuthProvider {
|
||||
name: string
|
||||
id: string
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@ const auth = new Auth({
|
|||
export const {
|
||||
changeEmail,
|
||||
changePassword,
|
||||
forgetPassword,
|
||||
getAccountInfo,
|
||||
getLastUsedLoginMethod,
|
||||
getProviders,
|
||||
|
|
@ -37,4 +36,6 @@ export const {
|
|||
updateUser,
|
||||
} = auth.authClient
|
||||
|
||||
export const forgetPassword = auth.authClient.requestPasswordReset
|
||||
|
||||
export const { loginHandler } = auth
|
||||
|
|
|
|||
|
|
@ -74,22 +74,21 @@ function RegisterForm() {
|
|||
password: values.password,
|
||||
name: values.email.split("@")[0]!,
|
||||
callbackURL: "/",
|
||||
fetchOptions: {
|
||||
onSuccess() {
|
||||
tracker.register({
|
||||
type: "email",
|
||||
})
|
||||
navigate("/login")
|
||||
},
|
||||
onError(context) {
|
||||
toast.error(context.error.message)
|
||||
},
|
||||
headers: recaptchaToken
|
||||
? {
|
||||
"x-token": `r3:${recaptchaToken}`,
|
||||
}
|
||||
: undefined,
|
||||
}, {
|
||||
onSuccess() {
|
||||
tracker.register({
|
||||
type: "email",
|
||||
})
|
||||
navigate("/login")
|
||||
},
|
||||
onError(context) {
|
||||
toast.error(context.error.message)
|
||||
},
|
||||
headers: recaptchaToken
|
||||
? {
|
||||
"x-token": `r3:${recaptchaToken}`,
|
||||
}
|
||||
: undefined,
|
||||
})
|
||||
} finally {
|
||||
setIsSubmitting(false)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import { extendConfig } from "@follow/configs/tailwindcss/web"
|
||||
import daisyui from "daisyui"
|
||||
import { withUIKit } from "tailwindcss-uikit-colors/macos"
|
||||
import type { Config } from "tailwindcss"
|
||||
|
||||
/** @type {import('tailwindcss').Config} */
|
||||
export default withUIKit(
|
||||
|
|
@ -13,7 +14,7 @@ export default withUIKit(
|
|||
"../../node_modules/rc-modal-sheet/**/*.{js,ts,tsx}",
|
||||
"../../packages/**/*.{ts,tsx}",
|
||||
],
|
||||
plugins: [daisyui],
|
||||
plugins: [daisyui as unknown as NonNullable<Config["plugins"]>[number]],
|
||||
daisyui: {
|
||||
logs: false,
|
||||
darkTheme: "dark",
|
||||
|
|
|
|||
|
|
@ -28,10 +28,8 @@
|
|||
--tint: 214;
|
||||
--alpha: 3;
|
||||
--base: hsl(var(--tint, 214) 80% 27% / calc(var(--alpha, 4) * 1%));
|
||||
/**
|
||||
* Use relative syntax to get to: hsl(221 25% 22% / 40%)
|
||||
*/
|
||||
--shade: hsl(from var(--base) calc(h + 8) 25 calc(l - 5));
|
||||
/* Use color-mix instead of relative color syntax for build-tool compatibility. */
|
||||
--shade: color-mix(in srgb, var(--base) 72%, black);
|
||||
--perfect-shadow:
|
||||
0 0 0 1px var(--base), 0 1px 1px -0.5px var(--shade), 0 3px 3px -1.5px var(--shade),
|
||||
0 6px 6px -3px var(--shade), 0 12px 12px -6px var(--base), 0 24px 24px -12px var(--base);
|
||||
|
|
|
|||
|
|
@ -31,14 +31,14 @@
|
|||
"typecheck": "tsc --noEmit"
|
||||
},
|
||||
"dependencies": {
|
||||
"@better-auth/stripe": "1.3.28",
|
||||
"@better-auth/stripe": "1.5.5",
|
||||
"@electron-toolkit/preload": "3.0.2",
|
||||
"@electron-toolkit/tsconfig": "2.0.0",
|
||||
"@follow-app/client-sdk": "catalog:",
|
||||
"@folo-services/drizzle": "0.1.44",
|
||||
"@t3-oss/env-core": "0.13.10",
|
||||
"ai": "6.0.85",
|
||||
"better-auth": "1.3.28",
|
||||
"better-auth": "1.5.5",
|
||||
"drizzle-orm": "0.45.1",
|
||||
"sonner": "2.0.7",
|
||||
"stripe": "20.3.1",
|
||||
|
|
|
|||
|
|
@ -29,8 +29,6 @@ export const SYSTEM_CAN_UNDER_BLUR_WINDOW = globalThis?.window?.electron
|
|||
? globalThis?.window.api?.canWindowBlur
|
||||
: false
|
||||
|
||||
export const IN_ELECTRON = !!globalThis["electron"]
|
||||
|
||||
declare const ELECTRON: boolean
|
||||
/**
|
||||
* Current build type for electron
|
||||
|
|
@ -38,6 +36,8 @@ declare const ELECTRON: boolean
|
|||
export const ELECTRON_BUILD = !!ELECTRON
|
||||
export const WEB_BUILD = !ELECTRON
|
||||
|
||||
export const IN_ELECTRON = !!globalThis["electron"] || ELECTRON_BUILD
|
||||
|
||||
export const MICROSOFT_STORE_BUILD =
|
||||
typeof process !== "undefined"
|
||||
? process.platform === "win32" &&
|
||||
|
|
|
|||
799
pnpm-lock.yaml
799
pnpm-lock.yaml
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue