Files
HKSingleParty/03_source/api_server.del/src/middlewares/auth.ts
2025-05-28 09:55:51 +08:00

49 lines
1.4 KiB
TypeScript

import passport from 'passport';
import httpStatus from 'http-status';
import ApiError from '../utils/ApiError';
import { roleRights } from '../config/roles';
import { NextFunction, Request, Response } from 'express';
import { User } from '@prisma/client';
const verifyCallback =
(
req: any,
resolve: (value?: unknown) => void,
reject: (reason?: unknown) => void,
requiredRights: string[]
) =>
async (err: unknown, user: User | false, info: unknown) => {
if (err || info || !user) {
return reject(new ApiError(httpStatus.UNAUTHORIZED, 'Please authenticate'));
}
req.user = user;
if (requiredRights.length) {
const userRights = roleRights.get(user.role) ?? [];
const hasRequiredRights = requiredRights.every((requiredRight) =>
userRights.includes(requiredRight)
);
if (!hasRequiredRights && req.params.userId !== user.id) {
return reject(new ApiError(httpStatus.FORBIDDEN, 'Forbidden'));
}
}
resolve();
};
const auth =
(...requiredRights: string[]) =>
async (req: Request, res: Response, next: NextFunction) => {
return new Promise((resolve, reject) => {
passport.authenticate(
'jwt',
{ session: false },
verifyCallback(req, resolve, reject, requiredRights)
)(req, res, next);
})
.then(() => next())
.catch((err) => next(err));
};
export default auth;