From eb560596bd65619b84e22714d90de413049b7d85 Mon Sep 17 00:00:00 2001 From: admtracksteel Date: Tue, 31 Mar 2026 10:52:42 +0000 Subject: [PATCH] Eliminando middleware legado do Clerk e corrigindo rotas/controllers para Logto --- api/app.ts | 4 +- .../applicationRecordController.ts | 2 +- src/server/controllers/dataSheetController.ts | 2 +- .../controllers/geometryTypeController.ts | 2 +- .../controllers/inspectionController.ts | 2 +- .../controllers/instrumentController.ts | 2 +- src/server/controllers/partController.ts | 2 +- src/server/controllers/projectController.ts | 2 +- src/server/controllers/stockController.ts | 2 +- src/server/middleware/authMiddleware.ts | 4 +- src/server/middleware/logtoAuth.ts | 11 +- src/server/middleware/roleMiddleware.ts | 174 ------------------ src/server/routes/applicationRecordRoutes.ts | 2 +- src/server/routes/backupRoutes.ts | 2 +- src/server/routes/dataSheetRoutes.ts | 2 +- src/server/routes/geometryTypeRoutes.ts | 2 +- src/server/routes/inspectionRoutes.ts | 2 +- src/server/routes/instrumentRoutes.ts | 2 +- src/server/routes/messageRoutes.ts | 2 +- src/server/routes/paintingSchemeRoutes.ts | 2 +- src/server/routes/partRoutes.ts | 2 +- src/server/routes/projectRoutes.ts | 2 +- src/server/routes/stockRoutes.ts | 2 +- src/server/routes/systemSettingsRoutes.ts | 2 +- src/server/routes/userRoutes.ts | 2 +- src/server/routes/yieldStudyRoutes.ts | 2 +- 26 files changed, 29 insertions(+), 208 deletions(-) delete mode 100644 src/server/middleware/roleMiddleware.ts diff --git a/api/app.ts b/api/app.ts index 77dc1cf..3b87f8d 100644 --- a/api/app.ts +++ b/api/app.ts @@ -14,7 +14,7 @@ import geometryTypeRoutes from '../src/server/routes/geometryTypeRoutes.js'; import stockRoutes from '../src/server/routes/stockRoutes.js'; import notificationRoutes from '../src/server/routes/notificationRoutes.js'; import instrumentRoutes from '../src/server/routes/instrumentRoutes.js'; -import { extractUser } from '../src/server/middleware/roleMiddleware.js'; +import { extractUser } from '../src/server/middleware/authMiddleware.js'; import path from 'path'; const app = express(); @@ -22,7 +22,7 @@ const app = express(); app.use(cors({ origin: '*', // Be more specific in production methods: ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS'], - allowedHeaders: ['Content-Type', 'Authorization', 'x-clerk-user-id', 'x-organization-id', 'x-organization-name'] + allowedHeaders: ['Content-Type', 'Authorization', 'x-organization-id', 'x-organization-name'] })); app.use(express.json()); diff --git a/src/server/controllers/applicationRecordController.ts b/src/server/controllers/applicationRecordController.ts index 5898005..1f3f5fa 100644 --- a/src/server/controllers/applicationRecordController.ts +++ b/src/server/controllers/applicationRecordController.ts @@ -1,6 +1,6 @@ import { Request, Response } from 'express'; import * as appRecordService from '../services/applicationRecordService.js'; -import '../middleware/roleMiddleware.js'; // Ensure type augmentation +import '../middleware/authMiddleware.js'; // Ensure type augmentation export const createApplicationRecord = async (req: Request, res: Response) => { try { diff --git a/src/server/controllers/dataSheetController.ts b/src/server/controllers/dataSheetController.ts index 670abf3..d3ac33b 100644 --- a/src/server/controllers/dataSheetController.ts +++ b/src/server/controllers/dataSheetController.ts @@ -2,7 +2,7 @@ import { Request, Response } from 'express'; import * as dataSheetService from '../services/dataSheetService.js'; import fs from 'fs'; import * as pdfExtractionService from '../services/pdfExtractionService.js'; -import { IAppUser } from '../middleware/roleMiddleware.js'; +import { IAppUser } from '../middleware/authMiddleware.js'; import { notificationService } from '../services/notificationService.js'; interface AuthRequest extends Request { diff --git a/src/server/controllers/geometryTypeController.ts b/src/server/controllers/geometryTypeController.ts index 577367c..2fa337a 100644 --- a/src/server/controllers/geometryTypeController.ts +++ b/src/server/controllers/geometryTypeController.ts @@ -1,6 +1,6 @@ import { Request, Response } from 'express'; import GeometryType from '../models/GeometryType.js'; -import { IAppUser } from '../middleware/roleMiddleware.js'; +import { IAppUser } from '../middleware/authMiddleware.js'; interface AuthRequest extends Request { appUser?: IAppUser; diff --git a/src/server/controllers/inspectionController.ts b/src/server/controllers/inspectionController.ts index 7683d6e..b9479d5 100644 --- a/src/server/controllers/inspectionController.ts +++ b/src/server/controllers/inspectionController.ts @@ -1,7 +1,7 @@ import { Request, Response } from 'express'; import * as inspectionService from '../services/inspectionService.js'; import { notificationService } from '../services/notificationService.js'; -import '../middleware/roleMiddleware.js'; // Ensure type augmentation +import '../middleware/authMiddleware.js'; // Ensure type augmentation export const createInspection = async (req: Request, res: Response) => { try { diff --git a/src/server/controllers/instrumentController.ts b/src/server/controllers/instrumentController.ts index 7fd879b..7b16239 100644 --- a/src/server/controllers/instrumentController.ts +++ b/src/server/controllers/instrumentController.ts @@ -1,6 +1,6 @@ import { Request, Response } from 'express'; import Instrument from '../models/Instrument.js'; -import { IAppUser } from '../middleware/roleMiddleware.js'; +import { IAppUser } from '../middleware/authMiddleware.js'; interface AuthRequest extends Request { appUser?: IAppUser; diff --git a/src/server/controllers/partController.ts b/src/server/controllers/partController.ts index 04c3b75..e16b969 100644 --- a/src/server/controllers/partController.ts +++ b/src/server/controllers/partController.ts @@ -1,6 +1,6 @@ import { Request, Response } from 'express'; import * as partService from '../services/partService.js'; -import { IAppUser } from '../middleware/roleMiddleware.js'; +import { IAppUser } from '../middleware/authMiddleware.js'; interface AuthRequest extends Request { appUser?: IAppUser; diff --git a/src/server/controllers/projectController.ts b/src/server/controllers/projectController.ts index 2f70b2e..b0893a2 100644 --- a/src/server/controllers/projectController.ts +++ b/src/server/controllers/projectController.ts @@ -1,6 +1,6 @@ import { Request, Response } from 'express'; import * as projectService from '../services/projectService.js'; -import { IAppUser } from '../middleware/roleMiddleware.js'; +import { IAppUser } from '../middleware/authMiddleware.js'; import { notificationService } from '../services/notificationService.js'; interface AuthRequest extends Request { diff --git a/src/server/controllers/stockController.ts b/src/server/controllers/stockController.ts index 7109802..3820cb5 100644 --- a/src/server/controllers/stockController.ts +++ b/src/server/controllers/stockController.ts @@ -2,7 +2,7 @@ import { Request, Response } from 'express'; import StockItem from '../models/StockItem.js'; import StockMovement from '../models/StockMovement.js'; -import { IAppUser } from '../middleware/roleMiddleware.js'; +import { IAppUser } from '../middleware/authMiddleware.js'; import { notificationService } from '../services/notificationService.js'; interface AuthRequest extends Request { diff --git a/src/server/middleware/authMiddleware.ts b/src/server/middleware/authMiddleware.ts index e9a980f..932b9c0 100644 --- a/src/server/middleware/authMiddleware.ts +++ b/src/server/middleware/authMiddleware.ts @@ -2,7 +2,7 @@ import { Request, Response, NextFunction } from 'express'; import { authenticateRequest } from './logtoAuth.js'; import { findOneGpi } from '../config/supabase.js'; -export interface AppUser { +export interface IAppUser { id: string; logtoId: string; email: string; @@ -14,7 +14,7 @@ export interface AppUser { declare module 'express-serve-static-core' { interface Request { - appUser?: any; + appUser?: IAppUser; } } diff --git a/src/server/middleware/logtoAuth.ts b/src/server/middleware/logtoAuth.ts index 4fd0f9c..1d967e4 100644 --- a/src/server/middleware/logtoAuth.ts +++ b/src/server/middleware/logtoAuth.ts @@ -1,19 +1,14 @@ import { createRemoteJWKSet, jwtVerify } from 'jose'; import { supabase, findOneGpi } from '../config/supabase.js'; +import { IAppUser } from './authMiddleware.js'; const LOGTO_URL = process.env.LOGTO_URL || 'https://logto-admin-bzlued1boxl3t8ewsyn99an9.187.77.227.172.sslip.io'; const APP_ID = process.env.LOGTO_APP_ID || 'gpi-app-001'; const jwks = createRemoteJWKSet(new URL(`${LOGTO_URL}/oidc/jwks`)); -export interface AppUser { - id: string; - logtoId: string; - email: string; - name: string; - role: string; -} +export type AppUser = IAppUser; -export async function authenticateRequest(req: any): Promise { +export async function authenticateRequest(req: any): Promise { const authHeader = req.headers.authorization; if (!authHeader?.startsWith('Bearer ')) { diff --git a/src/server/middleware/roleMiddleware.ts b/src/server/middleware/roleMiddleware.ts deleted file mode 100644 index 957b9ae..0000000 --- a/src/server/middleware/roleMiddleware.ts +++ /dev/null @@ -1,174 +0,0 @@ -import { Request, Response, NextFunction } from 'express'; -import User, { IUser } from '../models/User.js'; -import OrganizationMember, { OrgRole } from '../models/OrganizationMember.js'; -import Organization from '../models/Organization.js'; - -// Extended user info with organization context -export interface IAppUser extends IUser { - organizationId?: string; - organizationRole?: OrgRole; - organizationBanned?: boolean; -} - -// Module augmentation for Express Request -declare module 'express-serve-static-core' { - interface Request { - appUser?: IAppUser; - } -} - -/** - * Middleware to extract and verify user from Clerk ID header - * Also loads organization-specific role if organization context is provided - */ -export const extractUser = async (req: Request, res: Response, next: NextFunction) => { - try { - const clerkId = req.headers['x-clerk-user-id'] as string; - const organizationId = req.headers['x-organization-id'] as string; - - if (!clerkId) { - return next(); // No user, continue without - } - - const user = await User.findOne({ clerkId }); - - if (user) { - if (user.isBanned) { - return res.status(403).json({ error: 'Conta bloqueada. Entre em contato com o administrador.' }); - } - - // Create extended user object - const appUser: IAppUser = user.toObject() as IAppUser; - appUser.organizationId = organizationId; - - // If organization context, get org-specific role - if (organizationId) { - // Check if Organization is globally banned (subscription specific, etc.) - const orgStatus = await Organization.findOne({ clerkId: organizationId }); - const orgName = req.headers['x-organization-name'] ? decodeURIComponent(req.headers['x-organization-name'] as string) : undefined; - - if (orgStatus) { - // Update name if different and present - if (orgName && orgStatus.name !== orgName) { - try { - await Organization.updateOne( - { clerkId: organizationId }, - { name: orgName } - ); - } catch (err) { - console.warn('Failed to update organization name', err); - } - } - - if (orgStatus.isBanned) { - return res.status(403).json({ - error: 'Acesso bloqueado: Esta organização está suspensa. Entre em contato com o suporte.' - }); - } - } else { - // Create new org with name if present - try { - await Organization.create({ - clerkId: organizationId, - name: orgName - }); - } catch (_e) { - console.warn('Organization auto-create race condition', _e); - } - } - - const member = await OrganizationMember.findOne({ clerkUserId: clerkId, organizationId }); - if (member) { - if (member.isBanned) { - return res.status(403).json({ error: 'Acesso bloqueado nesta organização.' }); - } - appUser.organizationRole = member.role; - appUser.role = member.role; // Override global role with org role - } else { - // User exists but is not a member of this org yet - appUser.organizationRole = 'guest'; - appUser.role = 'guest'; - } - } - - req.appUser = appUser; - // console.log(`✅ Request authenticated as: ${appUser.name} (${appUser.role})`); - } else { - console.warn(`⚠️ User with Clerk ID ${clerkId} not found in MongoDB. Sync required.`); - } - - next(); - } catch (error) { - console.error('Error extracting user:', error); - next(); - } -}; - -/** - * Middleware to require specific roles for a route - * @param allowedRoles Array of roles that can access the route - */ -export const requireRole = (allowedRoles: OrgRole[]) => { - return (req: Request, res: Response, next: NextFunction) => { - if (!req.appUser) { - return res.status(401).json({ error: 'Autenticação necessária.' }); - } - - // DEV Bypass: Developer has full power - if (req.appUser.email === 'admtracksteel@gmail.com') { - return next(); - } - - const effectiveRole = req.appUser.organizationRole || req.appUser.role; - - if (!allowedRoles.includes(effectiveRole as OrgRole)) { - return res.status(403).json({ error: 'Acesso negado. Permissões insuficientes.' }); - } - - next(); - }; -}; - -/** - * Middleware to require admin role - */ -export const requireAdmin = requireRole(['admin']); - -/** - * Middleware to require at least user role (user or admin) - */ -export const requireUser = requireRole(['user', 'admin']); - -/** - * Middleware to check if user can edit (user or admin, not guest) - */ -export const canEdit = (req: Request, res: Response, next: NextFunction) => { - if (!req.appUser) { - return res.status(401).json({ error: 'Autenticação necessária.' }); - } - - const effectiveRole = req.appUser.organizationRole || req.appUser.role; - - if (effectiveRole === 'guest') { - return res.status(403).json({ error: 'Convidados não podem editar. Solicite acesso ao administrador.' }); - } - - next(); -}; - -/** - * Middleware to require Developer (Super Admin) access - * Hardcoded to specific email for security - */ -export const requireDeveloper = (req: Request, res: Response, next: NextFunction) => { - if (!req.appUser) { - return res.status(401).json({ error: 'Autenticação necessária.' }); - } - - if (req.appUser.email !== 'admtracksteel@gmail.com') { - console.warn(`⛔ Attempted unauthorized developer access by: ${req.appUser.email}`); - return res.status(403).json({ error: 'Acesso restrito ao desenvolvedor.' }); - } - - next(); -}; diff --git a/src/server/routes/applicationRecordRoutes.ts b/src/server/routes/applicationRecordRoutes.ts index b7ad442..d99f33d 100644 --- a/src/server/routes/applicationRecordRoutes.ts +++ b/src/server/routes/applicationRecordRoutes.ts @@ -1,6 +1,6 @@ import { Router } from 'express'; import * as appRecordController from '../controllers/applicationRecordController.js'; -import { extractUser, requireUser } from '../middleware/roleMiddleware.js'; +import { extractUser, requireUser } from '../middleware/authMiddleware.js'; const router = Router(); diff --git a/src/server/routes/backupRoutes.ts b/src/server/routes/backupRoutes.ts index dde4929..7ff3d71 100644 --- a/src/server/routes/backupRoutes.ts +++ b/src/server/routes/backupRoutes.ts @@ -1,6 +1,6 @@ import { Router, Request, Response } from 'express'; import { backupService } from '../services/backupService.js'; -import { requireRole } from '../middleware/roleMiddleware.js'; +import { requireRole } from '../middleware/authMiddleware.js'; const router = Router(); diff --git a/src/server/routes/dataSheetRoutes.ts b/src/server/routes/dataSheetRoutes.ts index 18d5012..cf55325 100644 --- a/src/server/routes/dataSheetRoutes.ts +++ b/src/server/routes/dataSheetRoutes.ts @@ -3,7 +3,7 @@ import multer from 'multer'; import path from 'path'; import { v4 as uuidv4 } from 'uuid'; import * as dataSheetController from '../controllers/dataSheetController.js'; -import { extractUser, requireAdmin } from '../middleware/roleMiddleware.js'; +import { extractUser, requireAdmin } from '../middleware/authMiddleware.js'; import os from 'os'; const router = Router(); diff --git a/src/server/routes/geometryTypeRoutes.ts b/src/server/routes/geometryTypeRoutes.ts index 9f231e3..99a9354 100644 --- a/src/server/routes/geometryTypeRoutes.ts +++ b/src/server/routes/geometryTypeRoutes.ts @@ -1,6 +1,6 @@ import { Router } from 'express'; import * as geometryTypeController from '../controllers/geometryTypeController.js'; -import { extractUser, requireAdmin } from '../middleware/roleMiddleware.js'; +import { extractUser, requireAdmin } from '../middleware/authMiddleware.js'; const router = Router(); diff --git a/src/server/routes/inspectionRoutes.ts b/src/server/routes/inspectionRoutes.ts index a8fe8c5..2188651 100644 --- a/src/server/routes/inspectionRoutes.ts +++ b/src/server/routes/inspectionRoutes.ts @@ -1,6 +1,6 @@ import { Router } from 'express'; import * as inspectionController from '../controllers/inspectionController.js'; -import { extractUser, requireUser } from '../middleware/roleMiddleware.js'; +import { extractUser, requireUser } from '../middleware/authMiddleware.js'; import multer from 'multer'; import path from 'path'; import { v4 as uuidv4 } from 'uuid'; diff --git a/src/server/routes/instrumentRoutes.ts b/src/server/routes/instrumentRoutes.ts index b09251c..84bc97d 100644 --- a/src/server/routes/instrumentRoutes.ts +++ b/src/server/routes/instrumentRoutes.ts @@ -1,6 +1,6 @@ import { Router } from 'express'; import * as instrumentController from '../controllers/instrumentController.js'; -import { extractUser, requireAdmin } from '../middleware/roleMiddleware.js'; +import { extractUser, requireAdmin } from '../middleware/authMiddleware.js'; const router = Router(); diff --git a/src/server/routes/messageRoutes.ts b/src/server/routes/messageRoutes.ts index d104e4c..b755871 100644 --- a/src/server/routes/messageRoutes.ts +++ b/src/server/routes/messageRoutes.ts @@ -1,6 +1,6 @@ import express from 'express'; import { sendMessage, getUnreadMessages, markMessageAsRead, getMyPendingMessages, deleteMessage, archiveMessage, recipientDeleteMessage } from '../controllers/messageController.js'; -import { extractUser } from '../middleware/roleMiddleware.js'; +import { extractUser } from '../middleware/authMiddleware.js'; const router = express.Router(); diff --git a/src/server/routes/paintingSchemeRoutes.ts b/src/server/routes/paintingSchemeRoutes.ts index 3178bea..7fb13c9 100644 --- a/src/server/routes/paintingSchemeRoutes.ts +++ b/src/server/routes/paintingSchemeRoutes.ts @@ -1,6 +1,6 @@ import { Router } from 'express'; import * as paintingSchemeController from '../controllers/paintingSchemeController.js'; -import { extractUser, requireAdmin } from '../middleware/roleMiddleware.js'; +import { extractUser, requireAdmin } from '../middleware/authMiddleware.js'; const router = Router(); diff --git a/src/server/routes/partRoutes.ts b/src/server/routes/partRoutes.ts index 677ab3b..a37ea6e 100644 --- a/src/server/routes/partRoutes.ts +++ b/src/server/routes/partRoutes.ts @@ -1,6 +1,6 @@ import { Router } from 'express'; import * as partController from '../controllers/partController.js'; -import { extractUser, requireAdmin } from '../middleware/roleMiddleware.js'; +import { extractUser, requireAdmin } from '../middleware/authMiddleware.js'; const router = Router(); diff --git a/src/server/routes/projectRoutes.ts b/src/server/routes/projectRoutes.ts index 6230176..d1e2781 100644 --- a/src/server/routes/projectRoutes.ts +++ b/src/server/routes/projectRoutes.ts @@ -1,6 +1,6 @@ import { Router } from 'express'; import * as projectController from '../controllers/projectController.js'; -import { extractUser, requireAdmin } from '../middleware/roleMiddleware.js'; +import { extractUser, requireAdmin } from '../middleware/authMiddleware.js'; const router = Router(); diff --git a/src/server/routes/stockRoutes.ts b/src/server/routes/stockRoutes.ts index 65bf14d..9547873 100644 --- a/src/server/routes/stockRoutes.ts +++ b/src/server/routes/stockRoutes.ts @@ -1,6 +1,6 @@ import { Router } from 'express'; import * as stockController from '../controllers/stockController.js'; -import { extractUser, requireAdmin, requireUser } from '../middleware/roleMiddleware.js'; +import { extractUser, requireAdmin, requireUser } from '../middleware/authMiddleware.js'; const router = Router(); diff --git a/src/server/routes/systemSettingsRoutes.ts b/src/server/routes/systemSettingsRoutes.ts index 03f6c4e..fbf72f2 100644 --- a/src/server/routes/systemSettingsRoutes.ts +++ b/src/server/routes/systemSettingsRoutes.ts @@ -1,6 +1,6 @@ import express from 'express'; import { getSettings, updateSettings, uploadLogo, serveLogo } from '../controllers/systemSettingsController.js'; -import { extractUser, requireDeveloper } from '../middleware/roleMiddleware.js'; +import { extractUser, requireDeveloper } from '../middleware/authMiddleware.js'; import { uploadLogoDetails } from '../middleware/uploadMiddleware.js'; const router = express.Router(); diff --git a/src/server/routes/userRoutes.ts b/src/server/routes/userRoutes.ts index 5486b0e..e00b03e 100644 --- a/src/server/routes/userRoutes.ts +++ b/src/server/routes/userRoutes.ts @@ -1,6 +1,6 @@ import express from 'express'; import { syncUser, getCurrentUser, getAllUsers, updateUserRole, toggleBanUser, heartbeat, getActiveUsers, deleteUser } from '../controllers/userController.js'; -import { extractUser, requireAdmin } from '../middleware/roleMiddleware.js'; +import { extractUser, requireAdmin } from '../middleware/authMiddleware.js'; const router = express.Router(); diff --git a/src/server/routes/yieldStudyRoutes.ts b/src/server/routes/yieldStudyRoutes.ts index 9365e06..d3a3f55 100644 --- a/src/server/routes/yieldStudyRoutes.ts +++ b/src/server/routes/yieldStudyRoutes.ts @@ -1,6 +1,6 @@ import { Router } from 'express'; import * as yieldStudyController from '../controllers/yieldStudyController.js'; -import { extractUser, requireAdmin } from '../middleware/roleMiddleware.js'; +import { extractUser, requireAdmin } from '../middleware/authMiddleware.js'; const router = Router();