79 lines
2.1 KiB
TypeScript
79 lines
2.1 KiB
TypeScript
import jwt from 'jsonwebtoken';
|
|
import httpStatus from 'http-status';
|
|
import ApiError from '../../utils/helper/ApiError';
|
|
import config from '../../../config/config';
|
|
import { ROLE } from '@/common/utils/constants/common.constant';
|
|
import { prisma } from '../../database/prisma.client';
|
|
|
|
interface DecodedToken {
|
|
id?: number;
|
|
sub?: string | number;
|
|
role?: string;
|
|
iat: number;
|
|
exp: number;
|
|
}
|
|
|
|
export async function verifyAnyToken(
|
|
token: string
|
|
): Promise<{ id: number; roleXid: number; role?: string }> {
|
|
if (!token) {
|
|
throw new ApiError(httpStatus.UNAUTHORIZED, 'Please authenticate');
|
|
}
|
|
|
|
try {
|
|
const decoded = jwt.verify(token, config.jwt.secret) as unknown as DecodedToken;
|
|
|
|
const userId = decoded.id ?? (decoded.sub ? Number(decoded.sub) : null);
|
|
if (!userId) {
|
|
throw new ApiError(httpStatus.UNAUTHORIZED, 'Invalid token payload');
|
|
}
|
|
|
|
const user = await prisma.user.findUnique({
|
|
where: { id: userId },
|
|
include: { role: true },
|
|
});
|
|
|
|
const latestToken = await prisma.token.findFirst({
|
|
where: { userXid: userId },
|
|
orderBy: { id: 'desc' },
|
|
});
|
|
|
|
if (latestToken?.isBlackListed === true) {
|
|
throw new ApiError(401, 'This session is expired. Please login.');
|
|
}
|
|
|
|
if (!user) {
|
|
throw new ApiError(httpStatus.UNAUTHORIZED, 'User not found');
|
|
}
|
|
|
|
if (user.isActive === false) {
|
|
throw new ApiError(
|
|
httpStatus.FORBIDDEN,
|
|
'Your account is deactivated by admin.'
|
|
);
|
|
}
|
|
|
|
if (user.roleXid !== ROLE.USER && user.roleXid !== ROLE.HOST) {
|
|
throw new ApiError(httpStatus.FORBIDDEN, 'Access denied.');
|
|
}
|
|
|
|
return { id: user.id, roleXid: user.roleXid || 0, role: user.role?.roleName };
|
|
} catch (error) {
|
|
if (error instanceof jwt.TokenExpiredError) {
|
|
throw new ApiError(
|
|
httpStatus.UNAUTHORIZED,
|
|
'Your session has expired. Please log in again.'
|
|
);
|
|
}
|
|
|
|
if (error instanceof ApiError) {
|
|
throw error;
|
|
}
|
|
|
|
throw new ApiError(
|
|
httpStatus.FORBIDDEN,
|
|
'Invalid or expired authentication token.'
|
|
);
|
|
}
|
|
}
|