This commit is contained in:
@@ -0,0 +1,29 @@
|
||||
// SPDX-License-Identifier: LicenseRef-ConusAI-Template-1.0
|
||||
// POST /auth/sign-out: revokes the session row and redirects to the provider's end-session
|
||||
// endpoint, which sends the browser to /auth/signed-out.
|
||||
//
|
||||
// POST, with the fetch-metadata half of csrf.ts's check: revoking a session is a state change, so
|
||||
// it must not hang on a GET, which a prefetch, a crawler or an <img> fires unprompted, and a
|
||||
// cross-site form POST is refused the same way the API refuses one. The synchronizer token itself
|
||||
// cannot be checked here -- a plain HTML form cannot send a header -- so the metadata a browser
|
||||
// always sends is the check.
|
||||
import { authRoutes } from "../../../src/server/app"
|
||||
import { authResponse } from "../../../src/server/auth-response"
|
||||
import { betterAuthSignOut } from "../../../src/server/better-auth-session" // kit:convex-better-auth
|
||||
|
||||
export const dynamic = "force-dynamic"
|
||||
export const runtime = "nodejs"
|
||||
|
||||
export async function GET(): Promise<Response> {
|
||||
return new Response("signing out is a POST", { status: 405, headers: { allow: "POST" } })
|
||||
}
|
||||
|
||||
export async function POST(request: Request): Promise<Response> {
|
||||
const site = request.headers.get("sec-fetch-site")
|
||||
if (site !== null && site !== "same-origin" && site !== "none") {
|
||||
return new Response("a cross-site sign-out is refused", { status: 403 })
|
||||
}
|
||||
const betterAuth = await betterAuthSignOut(request) // kit:convex-better-auth
|
||||
if (betterAuth) return betterAuth // kit:convex-better-auth
|
||||
return authResponse(request, async () => (await authRoutes()).signOut(request))
|
||||
}
|
||||
Reference in New Issue
Block a user