ai-wpa/lib/admin-middleware.ts

76 lines
1.9 KiB
TypeScript

import { NextRequest, NextResponse } from 'next/server'
import jwt from 'jsonwebtoken'
import { connectDB } from './mongodb'
import { User } from '@/models/user'
export interface AdminUser {
id: string
email: string
name: string
role: 'admin'
siliconId: string
}
export async function verifyAdminToken(request: NextRequest): Promise<AdminUser | null> {
try {
const authHeader = request.headers.get('authorization')
const cookieToken = request.cookies.get('accessToken')?.value
// Extract token from auth header, but only if it's not "Bearer undefined"
let headerToken = null
if (authHeader && authHeader !== 'Bearer undefined' && authHeader.startsWith('Bearer ')) {
headerToken = authHeader.replace('Bearer ', '')
}
const token = headerToken || cookieToken
if (!token) {
return null
}
const JWT_SECRET = process.env.JWT_SECRET || 'your-jwt-secret-change-in-production'
const decoded = jwt.verify(token, JWT_SECRET) as any
await connectDB()
const user = await User.findById(decoded.userId).select('-password -refreshToken')
if (!user || user.role !== 'admin') {
return null
}
return {
id: user._id.toString(),
email: user.email,
name: user.name,
role: user.role,
siliconId: user.siliconId,
}
} catch (error) {
console.error('Admin token verification failed:', error)
return null
}
}
export function createAdminResponse(message: string, status: number = 403) {
return NextResponse.json(
{
error: message,
code: 'ADMIN_ACCESS_REQUIRED',
},
{ status }
)
}
export async function withAdminAuth(
request: NextRequest,
handler: (request: NextRequest, admin: AdminUser) => Promise<NextResponse>
): Promise<NextResponse> {
const admin = await verifyAdminToken(request)
if (!admin) {
return createAdminResponse('Admin access required')
}
return handler(request, admin)
}