96 lines
3.1 KiB
TypeScript
96 lines
3.1 KiB
TypeScript
/**
|
||
* Form 16 permission middleware – enforces API-driven config (submission viewers, 26AS viewers).
|
||
* Use after authenticateToken so req.user is set.
|
||
*/
|
||
|
||
import { Request, Response, NextFunction } from 'express';
|
||
import { ResponseHandler } from '../utils/responseHandler';
|
||
import { canViewForm16Submission, canView26As } from '../services/form16Permission.service';
|
||
import { getDealerCodeForUser } from '../services/form16.service';
|
||
|
||
/**
|
||
* Require RE user only (block dealers). Use for endpoints that are RE-only (e.g. withdraw credit note, non-submitted dealers).
|
||
* Call after authenticateToken; use before or with requireForm16SubmissionAccess as needed.
|
||
*/
|
||
export const requireForm16ReOnly = async (
|
||
req: Request,
|
||
res: Response,
|
||
next: NextFunction
|
||
): Promise<void> => {
|
||
try {
|
||
const user = req.user;
|
||
if (!user?.userId || !user?.email) {
|
||
ResponseHandler.unauthorized(res, 'Authentication required');
|
||
return;
|
||
}
|
||
const dealerCode = await getDealerCodeForUser(user.userId);
|
||
if (dealerCode) {
|
||
ResponseHandler.forbidden(res, 'This action is only available to RE users, not dealers');
|
||
return;
|
||
}
|
||
next();
|
||
} catch (error) {
|
||
ResponseHandler.error(res, 'Permission check failed', 500, error instanceof Error ? error.message : 'Unknown error');
|
||
}
|
||
};
|
||
|
||
/**
|
||
* Require Form 16 submission data access.
|
||
* Admin has full access. Dealers are always allowed. RE users must be in submissionViewerEmails (or list empty).
|
||
*/
|
||
export const requireForm16SubmissionAccess = async (
|
||
req: Request,
|
||
res: Response,
|
||
next: NextFunction
|
||
): Promise<void> => {
|
||
try {
|
||
const user = req.user;
|
||
if (!user?.userId || !user?.email) {
|
||
ResponseHandler.unauthorized(res, 'Authentication required');
|
||
return;
|
||
}
|
||
if ((user as any).role === 'ADMIN') {
|
||
next();
|
||
return;
|
||
}
|
||
const allowed = await canViewForm16Submission(user.email, user.userId, (user as any).role);
|
||
if (!allowed) {
|
||
ResponseHandler.forbidden(res, 'You do not have permission to view Form 16 submission data');
|
||
return;
|
||
}
|
||
next();
|
||
} catch (error) {
|
||
ResponseHandler.error(res, 'Permission check failed', 500, error instanceof Error ? error.message : 'Unknown error');
|
||
}
|
||
};
|
||
|
||
/**
|
||
* Require 26AS access (view/upload/manage 26AS data).
|
||
* Admin has full access. Otherwise user must be in twentySixAsViewerEmails (or list empty).
|
||
*/
|
||
export const requireForm1626AsAccess = async (
|
||
req: Request,
|
||
res: Response,
|
||
next: NextFunction
|
||
): Promise<void> => {
|
||
try {
|
||
const user = req.user;
|
||
if (!user?.userId || !user?.email) {
|
||
ResponseHandler.unauthorized(res, 'Authentication required');
|
||
return;
|
||
}
|
||
if ((user as any).role === 'ADMIN') {
|
||
next();
|
||
return;
|
||
}
|
||
const allowed = await canView26As(user.email, (user as any).role);
|
||
if (!allowed) {
|
||
ResponseHandler.forbidden(res, 'You do not have permission to access 26AS data');
|
||
return;
|
||
}
|
||
next();
|
||
} catch (error) {
|
||
ResponseHandler.error(res, 'Permission check failed', 500, error instanceof Error ? error.message : 'Unknown error');
|
||
}
|
||
};
|