cnmksjs's picture
Upload 60 files
583e79b verified
import { Request, Response, NextFunction } from 'express'
import jwt from 'jsonwebtoken'
import { prisma } from '../config/database'
export interface AuthUser {
id: string
email: string
username: string
displayName: string
avatar: string | null
bio: string | null
isOnline: boolean
lastSeen: Date
isAdmin: boolean
isVerified: boolean
createdAt: Date
updatedAt: Date
}
export interface AuthRequest extends Request {
user?: AuthUser
}
export const authMiddleware = async (
req: AuthRequest,
res: Response,
next: NextFunction
): Promise<void> => {
try {
const authHeader = req.headers.authorization
if (!authHeader || !authHeader.startsWith('Bearer ')) {
res.status(401).json({
success: false,
error: 'Access token required'
})
return
}
const token = authHeader.substring(7) // Remove 'Bearer ' prefix
if (!token) {
res.status(401).json({
success: false,
error: 'Access token required'
})
return
}
// Verify JWT token
const decoded = jwt.verify(token, process.env.JWT_SECRET!) as { userId: string }
// Get user from database
const user = await prisma.user.findUnique({
where: { id: decoded.userId },
select: {
id: true,
email: true,
username: true,
displayName: true,
avatar: true,
bio: true,
isOnline: true,
lastSeen: true,
isAdmin: true,
isVerified: true,
createdAt: true,
updatedAt: true,
}
})
if (!user) {
res.status(401).json({
success: false,
error: 'Invalid token - user not found'
})
return
}
// Attach user to request
req.user = user
next()
} catch (error) {
if (error instanceof jwt.JsonWebTokenError) {
res.status(401).json({
success: false,
error: 'Invalid token'
})
return
}
if (error instanceof jwt.TokenExpiredError) {
res.status(401).json({
success: false,
error: 'Token expired'
})
return
}
console.error('Auth middleware error:', error)
res.status(500).json({
success: false,
error: 'Authentication failed'
})
}
}
export const adminMiddleware = (
req: AuthRequest,
res: Response,
next: NextFunction
): void => {
if (!req.user) {
res.status(401).json({
success: false,
error: 'Authentication required'
})
return
}
if (!req.user.isAdmin) {
res.status(403).json({
success: false,
error: 'Admin access required'
})
return
}
next()
}
export const optionalAuthMiddleware = async (
req: AuthRequest,
res: Response,
next: NextFunction
): Promise<void> => {
try {
const authHeader = req.headers.authorization
if (!authHeader || !authHeader.startsWith('Bearer ')) {
next()
return
}
const token = authHeader.substring(7)
if (!token) {
next()
return
}
const decoded = jwt.verify(token, process.env.JWT_SECRET!) as { userId: string }
const user = await prisma.user.findUnique({
where: { id: decoded.userId },
select: {
id: true,
email: true,
username: true,
displayName: true,
avatar: true,
bio: true,
isOnline: true,
lastSeen: true,
isAdmin: true,
isVerified: true,
createdAt: true,
updatedAt: true,
}
})
if (user) {
req.user = user
}
next()
} catch (error) {
// Ignore auth errors for optional auth
next()
}
}