File size: 3,396 Bytes
e3eb984 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 |
import { Request, Response, NextFunction } from 'express'
import jwt from 'jsonwebtoken'
import { prisma } from '../config/database'
export interface AuthRequest extends Request {
// Use a loose type here to avoid dependency on generated Prisma types
user?: any
}
export const authMiddleware = async (
req: AuthRequest,
res: Response,
next: NextFunction
) => {
try {
const authHeader = req.headers.authorization
if (!authHeader || !authHeader.startsWith('Bearer ')) {
return res.status(401).json({
success: false,
error: 'Access token required'
})
}
const token = authHeader.substring(7) // Remove 'Bearer ' prefix
if (!token) {
return res.status(401).json({
success: false,
error: 'Access token required'
})
}
// 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) {
return res.status(401).json({
success: false,
error: 'Invalid token - user not found'
})
}
// Attach user to request
req.user = user
next()
} catch (error) {
if (error instanceof jwt.JsonWebTokenError) {
return res.status(401).json({
success: false,
error: 'Invalid token'
})
}
if (error instanceof jwt.TokenExpiredError) {
return res.status(401).json({
success: false,
error: 'Token expired'
})
}
console.error('Auth middleware error:', error)
return res.status(500).json({
success: false,
error: 'Authentication failed'
})
}
}
export const adminMiddleware = (
req: AuthRequest,
res: Response,
next: NextFunction
) => {
if (!req.user) {
return res.status(401).json({
success: false,
error: 'Authentication required'
})
}
if (!req.user.isAdmin) {
return res.status(403).json({
success: false,
error: 'Admin access required'
})
}
next()
}
export const optionalAuthMiddleware = async (
req: AuthRequest,
res: Response,
next: NextFunction
) => {
try {
const authHeader = req.headers.authorization
if (!authHeader || !authHeader.startsWith('Bearer ')) {
return next()
}
const token = authHeader.substring(7)
if (!token) {
return next()
}
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()
}
}
|