-
Notifications
You must be signed in to change notification settings - Fork 795
Expand file tree
/
Copy pathroute.ts
More file actions
79 lines (71 loc) · 2.25 KB
/
Copy pathroute.ts
File metadata and controls
79 lines (71 loc) · 2.25 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
import { genAuthCode } from '@codebuff/common/util/credentials'
import db from '@codebuff/internal/db'
import * as schema from '@codebuff/internal/db/schema'
import { env } from '@codebuff/internal/env'
import { and, eq, gt } from 'drizzle-orm'
import { NextResponse } from 'next/server'
import { z } from 'zod/v4'
import { logger } from '@/util/logger'
export async function POST(req: Request) {
const reqSchema = z.object({
fingerprintId: z.string(),
})
const requestBody = await req.json()
const result = reqSchema.safeParse(requestBody)
if (!result.success) {
return NextResponse.json({ error: 'Invalid request body' }, { status: 400 })
}
const { fingerprintId } = result.data
try {
const expiresAt = Date.now() + 60 * 60 * 1000 // 1 hour
const fingerprintHash = genAuthCode(
fingerprintId,
expiresAt.toString(),
env.NEXTAUTH_SECRET,
)
// Check if this fingerprint has any active sessions
const existingSession = await db
.select({
userId: schema.session.userId,
expires: schema.session.expires,
})
.from(schema.session)
.where(
and(
eq(schema.session.fingerprint_id, fingerprintId),
gt(schema.session.expires, new Date()),
),
)
.limit(1)
if (existingSession.length > 0) {
// There's an active session - log this for monitoring
logger.info(
{
fingerprintId,
existingUserId: existingSession[0].userId,
event: 'relogin_attempt_with_active_session',
},
'Login attempt for fingerprint with active session',
)
}
// Generate login URL on the same origin that issued the auth code. This
// avoids bouncing between apex/www hosts during the browser OAuth flow.
const loginUrl = new URL('/login', new URL(req.url).origin)
loginUrl.searchParams.set(
'auth_code',
`${fingerprintId}.${expiresAt}.${fingerprintHash}`,
)
return NextResponse.json({
fingerprintId,
fingerprintHash,
loginUrl: loginUrl.toString(),
expiresAt,
})
} catch (error) {
logger.error({ error }, 'Error generating login code')
return NextResponse.json(
{ error: 'Internal server error' },
{ status: 500 },
)
}
}