|
import { Request, Response, NextFunction } from 'express' |
|
import jwt from 'jsonwebtoken' |
|
import { prisma } from '../config/database' |
|
|
|
export interface AuthRequest extends Request { |
|
|
|
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) |
|
|
|
if (!token) { |
|
return res.status(401).json({ |
|
success: false, |
|
error: 'Access token required' |
|
}) |
|
} |
|
|
|
|
|
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) { |
|
return res.status(401).json({ |
|
success: false, |
|
error: 'Invalid token - user not found' |
|
}) |
|
} |
|
|
|
|
|
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) { |
|
|
|
next() |
|
} |
|
} |
|
|