Download src/lib/auth/verify.server.ts from caustino/publish: direct link, hf CLI and curl.
- Browser
- Download file 3.87 kB
-
https://huggingface.co/spaces/caustino/publish/resolve/main/src/lib/auth/verify.server.ts
- Command line
-
hf download hf://spaces/caustino/publish/src/lib/auth/verify.server.ts
-
curl -L -o verify.server.ts https://huggingface.co/spaces/caustino/publish/resolve/main/src/lib/auth/verify.server.ts
3.87 kB
| import { getRequest } from "@tanstack/react-start/server"; | |
| import { gateIdentityEnabled } from "./gate-identity.server"; | |
| import { auth, authConfigured } from "./server"; | |
| /** | |
| * Server-side session resolution (server-only). | |
| * | |
| * Because this app runs its OWN Better Auth at same-origin `/api/auth/*`, the | |
| * session cookie is sent with every request to this app β server functions AND | |
| * SSR loaders included. So we resolve the user straight from the request cookies | |
| * via `auth.api.getSession` (no client-minted JWT needed). Never trust a | |
| * client-supplied user id β only the result of this verification. | |
| */ | |
| /** True when a real database is configured server-side. */ | |
| const databaseConfigured = Boolean(process.env.DATABASE_URL?.trim()); | |
| /** Re-export so callers can branch on it without importing `server.ts`. */ | |
| export { authConfigured }; | |
| if (databaseConfigured && !authConfigured) { | |
| console.error( | |
| "[auth] DATABASE_URL is set but auth is disabled (VITE_AUTH_ENABLED=false) " + | |
| "β requireUserId() will reject every request (fail closed) rather than " + | |
| "share one dev user on a real database.", | |
| ); | |
| } | |
| /** Dev fallback user id, used only when auth is disabled (VITE_AUTH_ENABLED=false). */ | |
| export const DEV_USER_ID = "dev-user"; | |
| /** | |
| * Thrown by `requireUserId` when the caller has no valid session. Carries | |
| * `status: 401`; the message is a stable contract β match | |
| * `err.message === "Unauthorized"` client-side to send the visitor to sign-in. | |
| */ | |
| export class UnauthorizedError extends Error { | |
| readonly status = 401; | |
| constructor() { | |
| super("Unauthorized"); | |
| this.name = "UnauthorizedError"; | |
| } | |
| } | |
| export type VerifiedUser = { id: string; email: string | null }; | |
| /** | |
| * Resolve the signed-in user from the current request, or `null` when auth isn't | |
| * configured / nobody is signed in. Safe to call from server functions and SSR | |
| * loaders. | |
| * | |
| * `bearerToken` is for the LIVE PREVIEW: the app runs in a partitioned iframe | |
| * whose cookies don't reach the server, so `authMiddleware` forwards the session | |
| * as a bearer token, which we present as `Authorization: Bearer β¦` (the `bearer` | |
| * plugin resolves it). When deployed no token is passed and the cookie is used. | |
| */ | |
| export async function getSessionUser( | |
| bearerToken?: string, | |
| ): Promise<VerifiedUser | null> { | |
| if (!authConfigured && !gateIdentityEnabled()) return null; | |
| const request = getRequest(); | |
| if (!request) return null; | |
| let headers = request.headers; | |
| if (bearerToken) { | |
| headers = new Headers(request.headers); | |
| headers.set("Authorization", `Bearer ${bearerToken}`); | |
| } | |
| const session = await auth.api.getSession({ headers }); | |
| if (!session?.user) return null; | |
| return { id: session.user.id, email: session.user.email ?? null }; | |
| } | |
| /** | |
| * Resolve the current user id for a server function, or throw when unauthorized. | |
| * Prefer `authMiddleware` (`./middleware`), which calls this for you. | |
| * - Auth enabled -> the verified session user id; throws | |
| * `UnauthorizedError` when signed out. Works in the sandbox preview too (real | |
| * sign-in via the baked preview client). | |
| * - Auth disabled (`VITE_AUTH_ENABLED=false`) + `DATABASE_URL` set -> throw (fail | |
| * closed): one shared dev user on a real database would let every visitor | |
| * read/write everyone's rows. | |
| * - Auth disabled + no database -> the shared dev user id. | |
| */ | |
| export async function requireUserId(bearerToken?: string): Promise<string> { | |
| if (!authConfigured && !gateIdentityEnabled()) { | |
| if (databaseConfigured) { | |
| throw new Error( | |
| "Auth is disabled (VITE_AUTH_ENABLED=false) but DATABASE_URL is set β " + | |
| "refusing to fall back to the shared dev user against a real database.", | |
| ); | |
| } | |
| return DEV_USER_ID; | |
| } | |
| const user = await getSessionUser(bearerToken); | |
| if (!user) throw new UnauthorizedError(); | |
| return user.id; | |
| } | |