Merge branch 'main' of https://git.profit-planet.partners/DK404/CentralBackend
This commit is contained in:
commit
02a30c3a17
@ -1,6 +1,7 @@
|
|||||||
const UnitOfWork = require('../../database/UnitOfWork');
|
const UnitOfWork = require('../../database/UnitOfWork');
|
||||||
const PermissionService = require('../../services/permissions/PermissionService');
|
const PermissionService = require('../../services/permissions/PermissionService');
|
||||||
const PermissionRepository = require('../../repositories/permissions/PermissionRepository');
|
const PermissionRepository = require('../../repositories/permissions/PermissionRepository');
|
||||||
|
const { logger } = require('../../middleware/logger');
|
||||||
|
|
||||||
class PermissionController {
|
class PermissionController {
|
||||||
static async list(req, res) {
|
static async list(req, res) {
|
||||||
@ -35,12 +36,24 @@ class PermissionController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static async getUserPermissions(req, res) {
|
static async getUserPermissions(req, res) {
|
||||||
|
// Prevent caching of permission responses
|
||||||
|
res.set('Cache-Control', 'no-store, no-cache, must-revalidate, private');
|
||||||
|
res.set('Pragma', 'no-cache');
|
||||||
|
res.set('Vary', 'Authorization');
|
||||||
|
|
||||||
// Access control: only self or admin/super_admin can view
|
// Access control: only self or admin/super_admin can view
|
||||||
const requestedUserId = Number(req.params.id);
|
const requestedUserId = Number(req.params.id);
|
||||||
const requesterUserId = req.user.userId;
|
const requesterUserId = Number(req.user.userId ?? req.user.id ?? req.user.sub);
|
||||||
const requesterRole = req.user.role;
|
const requesterRole = req.user.role;
|
||||||
|
|
||||||
if (requestedUserId !== requesterUserId && requesterRole !== 'admin' && requesterRole !== 'super_admin') {
|
if (requestedUserId !== requesterUserId && requesterRole !== 'admin' && requesterRole !== 'super_admin') {
|
||||||
|
const requesterIdLog = Number.isNaN(requesterUserId) ? (req.user.userId ?? req.user.id ?? req.user.sub) : requesterUserId;
|
||||||
|
logger.warn('PermissionController.getUserPermissions:forbidden', {
|
||||||
|
requestedUserId,
|
||||||
|
requesterUserId: requesterIdLog,
|
||||||
|
requesterRole,
|
||||||
|
route: req.originalUrl
|
||||||
|
});
|
||||||
return res.status(403).json({ success: false, message: 'Forbidden' });
|
return res.status(403).json({ success: false, message: 'Forbidden' });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
16
middleware/adminOnly.js
Normal file
16
middleware/adminOnly.js
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
const { logger } = require('./logger');
|
||||||
|
|
||||||
|
function adminOnly(req, res, next) {
|
||||||
|
const role = req.user?.role;
|
||||||
|
if (!role || !['admin', 'super_admin'].includes(role)) {
|
||||||
|
logger.warn('adminOnly:forbidden', {
|
||||||
|
role,
|
||||||
|
route: req.originalUrl,
|
||||||
|
method: req.method
|
||||||
|
});
|
||||||
|
return res.status(403).json({ success: false, message: 'Admin role required' });
|
||||||
|
}
|
||||||
|
next();
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = adminOnly;
|
||||||
@ -4,6 +4,10 @@ const { logger } = require('./logger');
|
|||||||
function authMiddleware(req, res, next) {
|
function authMiddleware(req, res, next) {
|
||||||
const authHeader = req.headers.authorization;
|
const authHeader = req.headers.authorization;
|
||||||
if (!authHeader || !authHeader.startsWith('Bearer ')) {
|
if (!authHeader || !authHeader.startsWith('Bearer ')) {
|
||||||
|
logger.warn('authMiddleware:missingToken', {
|
||||||
|
method: req.method,
|
||||||
|
route: req.originalUrl
|
||||||
|
});
|
||||||
return res.status(401).json({ success: false, message: 'No access token provided' });
|
return res.status(401).json({ success: false, message: 'No access token provided' });
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -33,9 +37,15 @@ function authMiddleware(req, res, next) {
|
|||||||
// console fallback for local dev
|
// console fallback for local dev
|
||||||
console.log('[authMiddleware] verified', authDebug);
|
console.log('[authMiddleware] verified', authDebug);
|
||||||
|
|
||||||
|
// Normalize common user fields for downstream checks
|
||||||
|
const normalizedUserId = payload.userId ?? payload.id ?? payload.sub;
|
||||||
|
const normalizedRole = payload.role ?? payload.userRole ?? payload.user_role ?? payload.type;
|
||||||
|
|
||||||
// Attach user info to request (with normalized userType for downstream checks)
|
// Attach user info to request (with normalized userType for downstream checks)
|
||||||
req.user = {
|
req.user = {
|
||||||
...payload,
|
...payload,
|
||||||
|
userId: normalizedUserId,
|
||||||
|
role: normalizedRole ?? payload.role,
|
||||||
userType: payload.userType ?? payload.user_type,
|
userType: payload.userType ?? payload.user_type,
|
||||||
user_type: payload.user_type ?? payload.userType
|
user_type: payload.user_type ?? payload.userType
|
||||||
};
|
};
|
||||||
|
|||||||
@ -2,6 +2,7 @@ const express = require('express');
|
|||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
|
|
||||||
const authMiddleware = require('../middleware/authMiddleware');
|
const authMiddleware = require('../middleware/authMiddleware');
|
||||||
|
const adminOnly = require('../middleware/adminOnly');
|
||||||
const AdminUserController = require('../controller/admin/AdminUserController');
|
const AdminUserController = require('../controller/admin/AdminUserController');
|
||||||
const DocumentTemplateController = require('../controller/documentTemplate/DocumentTemplateController');
|
const DocumentTemplateController = require('../controller/documentTemplate/DocumentTemplateController');
|
||||||
const CompanyStampController = require('../controller/companyStamp/CompanyStampController');
|
const CompanyStampController = require('../controller/companyStamp/CompanyStampController');
|
||||||
@ -10,12 +11,6 @@ const AffiliateController = require('../controller/affiliate/AffiliateController
|
|||||||
const NewsController = require('../controller/news/NewsController');
|
const NewsController = require('../controller/news/NewsController');
|
||||||
|
|
||||||
// Helper middlewares for company-stamp
|
// Helper middlewares for company-stamp
|
||||||
function adminOnly(req, res, next) {
|
|
||||||
if (!req.user || !['admin','super_admin'].includes(req.user.role)) {
|
|
||||||
return res.status(403).json({ error: 'Admin role required' });
|
|
||||||
}
|
|
||||||
next();
|
|
||||||
}
|
|
||||||
function forceCompanyForAdmin(req, res, next) {
|
function forceCompanyForAdmin(req, res, next) {
|
||||||
if (req.user && ['admin','super_admin'].includes(req.user.role) && req.user.user_type !== 'company') {
|
if (req.user && ['admin','super_admin'].includes(req.user.role) && req.user.user_type !== 'company') {
|
||||||
req.user.user_type = 'company';
|
req.user.user_type = 'company';
|
||||||
|
|||||||
@ -6,6 +6,7 @@ const router = express.Router();
|
|||||||
// CORS must allow credentials and a non-* origin; otherwise refreshToken cookies won't be sent.
|
// CORS must allow credentials and a non-* origin; otherwise refreshToken cookies won't be sent.
|
||||||
|
|
||||||
const authMiddleware = require('../middleware/authMiddleware');
|
const authMiddleware = require('../middleware/authMiddleware');
|
||||||
|
const adminOnly = require('../middleware/adminOnly');
|
||||||
const UserSettingsController = require('../controller/auth/UserSettingsController');
|
const UserSettingsController = require('../controller/auth/UserSettingsController');
|
||||||
const ReferralTokenController = require('../controller/referral/ReferralTokenController');
|
const ReferralTokenController = require('../controller/referral/ReferralTokenController');
|
||||||
const ReferralRegistrationController = require('../controller/referral/ReferralRegistrationController');
|
const ReferralRegistrationController = require('../controller/referral/ReferralRegistrationController');
|
||||||
@ -27,18 +28,6 @@ const NewsController = require('../controller/news/NewsController');
|
|||||||
const InvoiceController = require('../controller/invoice/InvoiceController'); // NEW
|
const InvoiceController = require('../controller/invoice/InvoiceController'); // NEW
|
||||||
|
|
||||||
// small helpers copied from original files
|
// small helpers copied from original files
|
||||||
function adminOnly(req, res, next) {
|
|
||||||
if (!req.user || !['admin', 'super_admin'].includes(req.user.role)) {
|
|
||||||
return res.status(403).json({ error: 'Forbidden: Admins only' });
|
|
||||||
}
|
|
||||||
next();
|
|
||||||
}
|
|
||||||
function requireAdmin(req, res, next) {
|
|
||||||
if (!req.user || req.user.role !== 'admin') {
|
|
||||||
return res.status(403).json({ success: false, message: 'Forbidden: Admins only.' });
|
|
||||||
}
|
|
||||||
next();
|
|
||||||
}
|
|
||||||
|
|
||||||
// NEW helper used by company-stamp routes
|
// NEW helper used by company-stamp routes
|
||||||
function forceCompanyForAdmin(req, res, next) {
|
function forceCompanyForAdmin(req, res, next) {
|
||||||
@ -58,19 +47,19 @@ router.get('/users/:id/full', authMiddleware, UserController.getFullUserData);
|
|||||||
router.get('/user/settings', authMiddleware, UserSettingsController.getSettings);
|
router.get('/user/settings', authMiddleware, UserSettingsController.getSettings);
|
||||||
router.get('/users/:id/permissions', authMiddleware, PermissionController.getUserPermissions);
|
router.get('/users/:id/permissions', authMiddleware, PermissionController.getUserPermissions);
|
||||||
router.get('/admin/users/:id/full', authMiddleware, adminOnly, AdminUserController.getFullUserAccountDetails);
|
router.get('/admin/users/:id/full', authMiddleware, adminOnly, AdminUserController.getFullUserAccountDetails);
|
||||||
router.get('/admin/users/:id/detailed', authMiddleware, requireAdmin, AdminUserController.getDetailedUserInfo);
|
router.get('/admin/users/:id/detailed', authMiddleware, adminOnly, AdminUserController.getDetailedUserInfo);
|
||||||
router.get('/users/:id/documents', authMiddleware, UserController.getUserDocumentsAndContracts);
|
router.get('/users/:id/documents', authMiddleware, UserController.getUserDocumentsAndContracts);
|
||||||
router.get('/verify-password-reset', (req, res) => { /* Note: was moved from PasswordResetController.verifyPasswordResetToken */ res.status(204).end(); }); // keep placeholder if controller already registered via other verb
|
router.get('/verify-password-reset', (req, res) => { /* Note: was moved from PasswordResetController.verifyPasswordResetToken */ res.status(204).end(); }); // keep placeholder if controller already registered via other verb
|
||||||
|
|
||||||
// admin.js GETs
|
// admin.js GETs
|
||||||
router.get('/admin/user-stats', authMiddleware, requireAdmin, AdminUserController.getUserStats);
|
router.get('/admin/user-stats', authMiddleware, adminOnly, AdminUserController.getUserStats);
|
||||||
router.get('/admin/user-list', authMiddleware, requireAdmin, AdminUserController.getUserList);
|
router.get('/admin/user-list', authMiddleware, adminOnly, AdminUserController.getUserList);
|
||||||
router.get('/admin/verification-pending-users', authMiddleware, requireAdmin, AdminUserController.getVerificationPendingUsers);
|
router.get('/admin/verification-pending-users', authMiddleware, adminOnly, AdminUserController.getVerificationPendingUsers);
|
||||||
router.get('/admin/unverified-users', authMiddleware, requireAdmin, AdminUserController.getUnverifiedUsers);
|
router.get('/admin/unverified-users', authMiddleware, adminOnly, AdminUserController.getUnverifiedUsers);
|
||||||
router.get('/admin/user/:id/documents', authMiddleware, requireAdmin, UserDocumentController.getAllDocumentsForUser);
|
router.get('/admin/user/:id/documents', authMiddleware, adminOnly, UserDocumentController.getAllDocumentsForUser);
|
||||||
router.get('/admin/server-status', authMiddleware, requireAdmin, ServerStatusController.getStatus);
|
router.get('/admin/server-status', authMiddleware, adminOnly, ServerStatusController.getStatus);
|
||||||
// Contract preview for admin: latest active by user type
|
// Contract preview for admin: latest active by user type
|
||||||
router.get('/admin/contracts/:id/preview', authMiddleware, requireAdmin, DocumentTemplateController.previewLatestForUser);
|
router.get('/admin/contracts/:id/preview', authMiddleware, adminOnly, DocumentTemplateController.previewLatestForUser);
|
||||||
|
|
||||||
// permissions.js GETs
|
// permissions.js GETs
|
||||||
router.get('/permissions', authMiddleware, PermissionController.list);
|
router.get('/permissions', authMiddleware, PermissionController.list);
|
||||||
|
|||||||
@ -2,6 +2,7 @@ const express = require('express');
|
|||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
|
|
||||||
const authMiddleware = require('../middleware/authMiddleware');
|
const authMiddleware = require('../middleware/authMiddleware');
|
||||||
|
const adminOnly = require('../middleware/adminOnly');
|
||||||
const DocumentTemplateController = require('../controller/documentTemplate/DocumentTemplateController');
|
const DocumentTemplateController = require('../controller/documentTemplate/DocumentTemplateController');
|
||||||
const CompanyStampController = require('../controller/companyStamp/CompanyStampController'); // <-- added
|
const CompanyStampController = require('../controller/companyStamp/CompanyStampController'); // <-- added
|
||||||
const CoffeeController = require('../controller/admin/CoffeeController');
|
const CoffeeController = require('../controller/admin/CoffeeController');
|
||||||
@ -16,12 +17,6 @@ const multer = require('multer');
|
|||||||
const upload = multer({ storage: multer.memoryStorage() });
|
const upload = multer({ storage: multer.memoryStorage() });
|
||||||
|
|
||||||
// Helper middlewares for company-stamp
|
// Helper middlewares for company-stamp
|
||||||
function adminOnly(req, res, next) {
|
|
||||||
if (!req.user || !['admin','super_admin'].includes(req.user.role)) {
|
|
||||||
return res.status(403).json({ error: 'Admin role required' });
|
|
||||||
}
|
|
||||||
next();
|
|
||||||
}
|
|
||||||
function forceCompanyForAdmin(req, res, next) {
|
function forceCompanyForAdmin(req, res, next) {
|
||||||
if (req.user && ['admin','super_admin'].includes(req.user.role) && req.user.user_type !== 'company') {
|
if (req.user && ['admin','super_admin'].includes(req.user.role) && req.user.user_type !== 'company') {
|
||||||
req.user.user_type = 'company';
|
req.user.user_type = 'company';
|
||||||
|
|||||||
@ -2,6 +2,7 @@ const express = require('express');
|
|||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
|
|
||||||
const authMiddleware = require('../middleware/authMiddleware');
|
const authMiddleware = require('../middleware/authMiddleware');
|
||||||
|
const adminOnly = require('../middleware/adminOnly');
|
||||||
|
|
||||||
// Controllers used by POST routes
|
// Controllers used by POST routes
|
||||||
const LoginController = require('../controller/login/LoginController');
|
const LoginController = require('../controller/login/LoginController');
|
||||||
@ -110,15 +111,6 @@ router.post('/admin/send-password-reset/:userId', authMiddleware, adminOnly, asy
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Helper middleware for company-stamp routes
|
|
||||||
function adminOnly(req, res, next) {
|
|
||||||
if (!req.user || !['admin','super_admin'].includes(req.user.role)) {
|
|
||||||
return res.status(403).json({ error: 'Admin role required' });
|
|
||||||
}
|
|
||||||
next();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// NEW: ensure service sees a "company" user_type for admin users
|
// NEW: ensure service sees a "company" user_type for admin users
|
||||||
function forceCompanyForAdmin(req, res, next) {
|
function forceCompanyForAdmin(req, res, next) {
|
||||||
if (req.user && ['admin','super_admin'].includes(req.user.role) && req.user.user_type !== 'company') {
|
if (req.user && ['admin','super_admin'].includes(req.user.role) && req.user.user_type !== 'company') {
|
||||||
|
|||||||
@ -2,20 +2,13 @@ const express = require('express');
|
|||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
|
|
||||||
const authMiddleware = require('../middleware/authMiddleware');
|
const authMiddleware = require('../middleware/authMiddleware');
|
||||||
|
const adminOnly = require('../middleware/adminOnly');
|
||||||
const AdminUserController = require('../controller/admin/AdminUserController');
|
const AdminUserController = require('../controller/admin/AdminUserController');
|
||||||
const DocumentTemplateController = require('../controller/documentTemplate/DocumentTemplateController');
|
const DocumentTemplateController = require('../controller/documentTemplate/DocumentTemplateController');
|
||||||
const CoffeeController = require('../controller/admin/CoffeeController');
|
const CoffeeController = require('../controller/admin/CoffeeController');
|
||||||
const multer = require('multer');
|
const multer = require('multer');
|
||||||
const upload = multer({ storage: multer.memoryStorage() });
|
const upload = multer({ storage: multer.memoryStorage() });
|
||||||
|
|
||||||
// Helper middleware for admin-only routes (keeps consistency with other route files)
|
|
||||||
function adminOnly(req, res, next) {
|
|
||||||
if (!req.user || !['admin','super_admin'].includes(req.user.role)) {
|
|
||||||
return res.status(403).json({ error: 'Admin role required' });
|
|
||||||
}
|
|
||||||
next();
|
|
||||||
}
|
|
||||||
|
|
||||||
// PUT /admin/users/:id/permissions (moved from routes/admin.js)
|
// PUT /admin/users/:id/permissions (moved from routes/admin.js)
|
||||||
router.put('/admin/users/:id/permissions', authMiddleware, adminOnly, AdminUserController.updateUserPermissions);
|
router.put('/admin/users/:id/permissions', authMiddleware, adminOnly, AdminUserController.updateUserPermissions);
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user