Skip to content

Commit ea1777d

Browse files
refactor(sessions): drop custom CSRF checks; migrate to NextAuth server session for authentication to align with API keys route and reduce surface area.
🤖 Generated with Codebuff Co-Authored-By: Codebuff <noreply@codebuff.com>
1 parent 1661aa9 commit ea1777d

File tree

1 file changed

+20
-25
lines changed

1 file changed

+20
-25
lines changed

web/src/app/api/sessions/route.ts

Lines changed: 20 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -5,37 +5,27 @@ import * as schema from '@codebuff/common/db/schema'
55
import { and, eq, inArray } from 'drizzle-orm'
66
import { sha256 } from '@/lib/crypto'
77
import { authOptions } from '@/app/api/auth/[...nextauth]/auth-options'
8-
import { siteConfig } from '@/lib/constant'
9-
10-
function isSameOrigin(request: NextRequest) {
11-
try {
12-
const base = new URL(siteConfig.url()).origin
13-
const origin = request.headers.get('origin')
14-
const referer = request.headers.get('referer')
15-
if (origin && new URL(origin).origin === base) return true
16-
if (referer && new URL(referer).origin === base) return true
17-
} catch {}
18-
return false
19-
}
208

219
// DELETE /api/sessions
2210
// Body: { sessionIds?: string[]; tokenIds?: string[] }
2311
export async function DELETE(req: NextRequest) {
2412
try {
25-
if (!isSameOrigin(req)) {
26-
return new NextResponse('Forbidden', { status: 403 })
27-
}
28-
2913
const session = await getServerSession(authOptions)
3014
if (!session?.user?.id) {
3115
return new NextResponse('Unauthorized', { status: 401 })
3216
}
3317

34-
const { sessionIds, tokenIds }: { sessionIds?: string[]; tokenIds?: string[] } = await req
18+
const {
19+
sessionIds,
20+
tokenIds,
21+
}: { sessionIds?: string[]; tokenIds?: string[] } = await req
3522
.json()
36-
.catch(() => ({} as any))
23+
.catch(() => ({}) as any)
3724

38-
if ((!sessionIds || sessionIds.length === 0) && (!tokenIds || tokenIds.length === 0)) {
25+
if (
26+
(!sessionIds || sessionIds.length === 0) &&
27+
(!tokenIds || tokenIds.length === 0)
28+
) {
3929
return NextResponse.json({ revokedSessions: 0, revokedTokens: 0 })
4030
}
4131

@@ -46,13 +36,18 @@ export async function DELETE(req: NextRequest) {
4636
// 1) Map provided sessionIds (raw token or sha256(token)) to actual session tokens
4737
if (sessionIds && sessionIds.length > 0) {
4838
const userSessions = await db
49-
.select({ sessionToken: schema.session.sessionToken, type: schema.session.type })
39+
.select({
40+
sessionToken: schema.session.sessionToken,
41+
type: schema.session.type,
42+
})
5043
.from(schema.session)
5144
.where(eq(schema.session.userId, userId))
5245

5346
const tokenSet = new Set(userSessions.map((s) => s.sessionToken))
5447
const hashToToken = new Map(
55-
userSessions.map((s) => [sha256(s.sessionToken), s.sessionToken] as const),
48+
userSessions.map(
49+
(s) => [sha256(s.sessionToken), s.sessionToken] as const
50+
)
5651
)
5752

5853
const tokensToDelete: string[] = []
@@ -72,8 +67,8 @@ export async function DELETE(req: NextRequest) {
7267
and(
7368
eq(schema.session.userId, userId),
7469
eq(schema.session.type, 'web'), // do not delete PATs here
75-
inArray(schema.session.sessionToken, tokensToDelete),
76-
),
70+
inArray(schema.session.sessionToken, tokensToDelete)
71+
)
7772
)
7873
.returning({ sessionToken: schema.session.sessionToken })
7974
revokedSessions = result.length
@@ -88,8 +83,8 @@ export async function DELETE(req: NextRequest) {
8883
and(
8984
eq(schema.session.userId, userId),
9085
eq(schema.session.type, 'pat'),
91-
inArray(schema.session.sessionToken, tokenIds),
92-
),
86+
inArray(schema.session.sessionToken, tokenIds)
87+
)
9388
)
9489
.returning({ sessionToken: schema.session.sessionToken })
9590
revokedTokens = result.length

0 commit comments

Comments
 (0)