add first files
This commit is contained in:
@@ -0,0 +1,60 @@
|
||||
import { Request, Response, NextFunction } from 'express'
|
||||
import jwt from 'jsonwebtoken'
|
||||
import { prisma } from '../lib/prisma'
|
||||
import { AdminRole } from '@rentaldrivego/database'
|
||||
|
||||
const ROLE_RANK: Record<AdminRole, number> = {
|
||||
SUPER_ADMIN: 5,
|
||||
ADMIN: 4,
|
||||
SUPPORT: 3,
|
||||
FINANCE: 2,
|
||||
VIEWER: 1,
|
||||
}
|
||||
|
||||
export async function requireAdminAuth(req: Request, res: Response, next: NextFunction) {
|
||||
const authHeader = req.headers.authorization
|
||||
const token = authHeader?.startsWith('Bearer ') ? authHeader.slice(7) : null
|
||||
|
||||
if (!token) {
|
||||
return res.status(401).json({ error: 'unauthenticated', message: 'Admin authentication required', statusCode: 401 })
|
||||
}
|
||||
|
||||
try {
|
||||
const payload = jwt.verify(token, process.env.JWT_SECRET!) as { sub: string; type: string }
|
||||
if (payload.type !== 'admin') {
|
||||
return res.status(401).json({ error: 'invalid_token', message: 'Invalid token type', statusCode: 401 })
|
||||
}
|
||||
|
||||
const admin = await prisma.adminUser.findUnique({ where: { id: payload.sub } })
|
||||
if (!admin || !admin.isActive) {
|
||||
return res.status(401).json({ error: 'unauthenticated', message: 'Admin account not found or deactivated', statusCode: 401 })
|
||||
}
|
||||
|
||||
req.admin = admin
|
||||
next()
|
||||
} catch {
|
||||
return res.status(401).json({ error: 'invalid_token', message: 'Invalid or expired admin token', statusCode: 401 })
|
||||
}
|
||||
}
|
||||
|
||||
export function requireAdminRole(minimumRole: AdminRole) {
|
||||
return (req: Request, res: Response, next: NextFunction) => {
|
||||
const admin = req.admin
|
||||
if (!admin) {
|
||||
return res.status(401).json({ error: 'unauthenticated', message: 'Admin authentication required', statusCode: 401 })
|
||||
}
|
||||
|
||||
const rank = ROLE_RANK[admin.role] ?? 0
|
||||
const required = ROLE_RANK[minimumRole] ?? 99
|
||||
|
||||
if (rank < required) {
|
||||
return res.status(403).json({
|
||||
error: 'forbidden',
|
||||
message: `This action requires the ${minimumRole} role or higher`,
|
||||
statusCode: 403,
|
||||
})
|
||||
}
|
||||
|
||||
next()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user