Skip to content

Commit e4268eb

Browse files
committed
feat: refactor demo sign-up flow by replacing POST endpoint with GET for better cookie handling
1 parent a5632bd commit e4268eb

3 files changed

Lines changed: 66 additions & 72 deletions

File tree

app/pages/auth/fresh-signup.vue

Lines changed: 7 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3,26 +3,13 @@ definePageMeta({ layout: 'auth' })
33
44
useSeoMeta({ robots: 'noindex, nofollow' })
55
6-
const localePath = useLocalePath()
7-
8-
onMounted(async () => {
9-
try {
10-
// Single server-side call: checks demo status AND signs out if needed.
11-
// The server deletes the session from the DB and clears auth cookies
12-
// via Set-Cookie headers — no client-side sign-out quirks.
13-
const { action } = await $fetch('/api/auth/demo-fresh-signup', { method: 'POST' })
14-
15-
if (action === 'dashboard') {
16-
window.location.href = localePath('/dashboard')
17-
}
18-
else {
19-
window.location.href = localePath('/auth/sign-up')
20-
}
21-
}
22-
catch {
23-
// On any error, default to sign-up
24-
window.location.href = localePath('/auth/sign-up')
25-
}
6+
onMounted(() => {
7+
// Full browser navigation to the server endpoint. The server checks
8+
// the session, destroys it if it belongs to the demo org, clears
9+
// auth cookies via Set-Cookie headers, and returns a 302 redirect
10+
// to either /auth/sign-up or /dashboard. Using native navigation
11+
// (not $fetch) guarantees the browser processes Set-Cookie headers.
12+
window.location.replace('/api/auth/demo-fresh-signup')
2613
})
2714
</script>
2815

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import { eq } from 'drizzle-orm'
2+
import * as schema from '../../database/schema'
3+
4+
/**
5+
* Demo-aware signup redirect endpoint.
6+
*
7+
* Called via full browser navigation (not $fetch) when a marketing-site
8+
* visitor clicks "Use Cloud". If the browser carries a demo-org session
9+
* cookie, the session is destroyed server-side and the auth cookies are
10+
* expired before redirecting to /auth/sign-up with a clean slate.
11+
*
12+
* Using a GET → 302 redirect (instead of $fetch → JSON) guarantees the
13+
* browser processes Set-Cookie headers during native navigation, which
14+
* is the only fully reliable way to clear HttpOnly cookies.
15+
*/
16+
export default defineEventHandler(async (event) => {
17+
const session = await auth.api.getSession({ headers: event.headers })
18+
19+
if (!session) {
20+
return sendRedirect(event, '/auth/sign-up')
21+
}
22+
23+
const demoSlug = useRuntimeConfig().public.demoOrgSlug as string
24+
const activeOrgId = (session.session as { activeOrganizationId?: string }).activeOrganizationId
25+
26+
if (!demoSlug || !activeOrgId) {
27+
// Real user with an active org — send to dashboard
28+
return sendRedirect(event, '/dashboard')
29+
}
30+
31+
const [org] = await db
32+
.select({ slug: schema.organization.slug })
33+
.from(schema.organization)
34+
.where(eq(schema.organization.id, activeOrgId))
35+
.limit(1)
36+
37+
if (org?.slug !== demoSlug) {
38+
// Real org — send to dashboard
39+
return sendRedirect(event, '/dashboard')
40+
}
41+
42+
// ── Demo session — destroy it server-side ──────────────────────
43+
44+
// 1. Remove the session row from the database so the token is invalid
45+
// even if a cookie somehow survives.
46+
await db.delete(schema.session).where(eq(schema.session.id, session.session.id))
47+
48+
// 2. Expire auth cookies. Better Auth prefixes with __Secure- when
49+
// baseURL starts with https://. Behind a reverse proxy (Railway,
50+
// Cloudflare) the request protocol is http even in production,
51+
// so we clear BOTH variants to guarantee removal.
52+
for (const prefix of ['better-auth', '__Secure-better-auth']) {
53+
for (const name of ['session_token', 'session_data']) {
54+
deleteCookie(event, `${prefix}.${name}`, { path: '/' })
55+
}
56+
}
57+
58+
return sendRedirect(event, '/auth/sign-up')
59+
})

server/api/auth/demo-fresh-signup.post.ts

Lines changed: 0 additions & 52 deletions
This file was deleted.

0 commit comments

Comments
 (0)