fix(auth): delete demo cookie in middleware (#93)

The demo cookie deletion in getCurrentUser() was a no-op from
Server Component context (cookies().delete() only works in
Server Actions and Route Handlers). The cookie persisted for
its full 24h lifetime, causing middleware to short-circuit auth
checks even when a real WorkOS session existed.

- Middleware: real session now takes priority over demo cookie,
  stale cookie actively deleted via Set-Cookie on response
- auth.ts: remove early demo-first check and dead deletion code,
  WorkOS session checked before demo fallback
- /demo route: clear compass-active-org so demo doesn't inherit
  a real user's workspace selection

Co-authored-by: Nicholai <nicholaivogelfilms@gmail.com>
This commit is contained in:
Nicholai 2026-02-15 22:45:34 -07:00 committed by GitHub
parent c75b043259
commit b1f6780166
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 20 additions and 22 deletions

View File

@ -10,5 +10,8 @@ export async function GET() {
path: "/",
maxAge: 60 * 60 * 24, // 24 hours
})
// clear stale org preference so demo doesn't inherit
// a real user's last-active workspace
cookieStore.delete("compass-active-org")
redirect("/dashboard")
}

View File

@ -53,15 +53,6 @@ export function toSidebarUser(user: AuthUser): SidebarUser {
export async function getCurrentUser(): Promise<AuthUser | null> {
try {
// check for demo session cookie first
try {
const cookieStore = await cookies()
const isDemoSession = cookieStore.get("compass-demo")?.value === "true"
if (isDemoSession) return DEMO_USER
} catch {
// cookies() may throw in non-request contexts
}
// check if workos is configured
const isWorkOSConfigured =
process.env.WORKOS_API_KEY &&
@ -115,15 +106,8 @@ export async function getCurrentUser(): Promise<AuthUser | null> {
return null
}
// real session exists -- clear stale demo cookie if present
try {
const cookieStore = await cookies()
if (cookieStore.get("compass-demo")) {
cookieStore.delete("compass-demo")
}
} catch {
// cookies() may throw in non-request contexts
}
// demo cookie cleanup handled by middleware (can't delete
// cookies from Server Components -- only actions/routes)
const workosUser = session.user

View File

@ -41,9 +41,18 @@ export default async function middleware(request: NextRequest) {
return handleAuthkitHeaders(request, headers)
}
// demo sessions bypass auth
const isDemoSession = request.cookies.get("compass-demo")?.value === "true"
if (isDemoSession) {
const hasDemoCookie =
request.cookies.get("compass-demo")?.value === "true"
// real session trumps demo cookie -- clear the stale cookie
if (session.user && hasDemoCookie) {
const response = handleAuthkitHeaders(request, headers)
response.cookies.delete("compass-demo")
return response
}
// demo sessions bypass auth (no real session present)
if (hasDemoCookie) {
return handleAuthkitHeaders(request, headers)
}
@ -51,7 +60,9 @@ export default async function middleware(request: NextRequest) {
if (!session.user) {
const loginUrl = new URL("/login", request.url)
loginUrl.searchParams.set("from", pathname)
return handleAuthkitHeaders(request, headers, { redirect: loginUrl.toString() })
return handleAuthkitHeaders(request, headers, {
redirect: loginUrl.toString(),
})
}
// authenticated - continue with authkit headers