This commit is contained in:
bipproduction
2025-10-28 16:04:14 +08:00
parent 3edcc52e74
commit b52da1c4bd

View File

@@ -1,62 +1,51 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import { Elysia } from 'elysia'
import jwt, { type JWTPayloadSpec } from '@elysiajs/jwt'
import bearer from '@elysiajs/bearer'
import Elysia from 'elysia'
import { prisma } from '../lib/prisma'
// =========================================================
// JWT Secret Validation
// =========================================================
const secret = process.env.JWT_SECRET
if (!secret) throw new Error('JWT_SECRET environment variable is missing')
// =========================================================
// Auth Middleware Plugin
// =========================================================
export default function apiAuth(app: Elysia) {
if (!secret) throw new Error('JWT_SECRET environment variable is missing')
if (!secret) {
throw new Error('JWT_SECRET is not defined')
}
return app
// Register Bearer and JWT plugins
.use(bearer()) // ✅ Extracts Bearer token automatically (case-insensitive)
.use(
jwt({
name: 'jwt',
secret,
})
)
.derive(async ({ cookie, headers, jwt }) => {
let token: string | undefined
// Derive user from JWT or cookie
.derive(async ({ bearer, cookie, jwt }) => {
// Normalize token type to string or undefined
const token =
(typeof bearer === 'string' ? bearer : undefined) ??
(typeof cookie?.token?.value === 'string' ? cookie.token.value : undefined)
let user: Awaited<ReturnType<typeof prisma.user.findUnique>> | null = null
if (cookie?.token?.value) {
token = cookie.token.value as any
}
if (headers['x-token']?.startsWith('Bearer ')) {
token = (headers['x-token'] as string).slice(7)
}
if (headers['authorization']?.startsWith('Bearer ')) {
token = (headers['authorization'] as string).slice(7)
}
let user: null | Awaited<ReturnType<typeof prisma.user.findUnique>> = null
if (token) {
try {
const decoded = (await jwt.verify(token)) as JWTPayloadSpec
if (decoded?.sub && typeof decoded.sub === 'string') {
if (decoded.sub) {
user = await prisma.user.findUnique({
where: { id: decoded.sub },
where: { id: decoded.sub as string },
})
}
} catch (err) {
console.warn('[SERVER][apiAuth] Invalid token:', (err as Error).message)
console.warn('[SERVER][apiAuth] Invalid token', err)
}
}
return { user }
})
// Protect all routes by default
.onBeforeHandle(({ user, set, request }) => {
// Whitelist public routes if needed
const publicPaths = ['/auth/login', '/auth/register', '/public']
if (publicPaths.some((path) => request.url.includes(path))) return
.onBeforeHandle(({ user, set }) => {
if (!user) {
set.status = 401
return { error: 'Unauthorized' }