🚀 Auto-deploy: GPI atualizado em 10/08/2026 00:57:32
This commit is contained in:
+67
-32
@@ -1,5 +1,12 @@
|
||||
import express from 'express';
|
||||
import cors from 'cors';
|
||||
import helmet from 'helmet';
|
||||
import rateLimit from 'express-rate-limit';
|
||||
import path from 'path';
|
||||
import fs from 'fs';
|
||||
|
||||
import { extractUser } from './middleware/authMiddleware.js';
|
||||
|
||||
import projectRoutes from './routes/projectRoutes.js';
|
||||
import partRoutes from './routes/partRoutes.js';
|
||||
import paintingSchemeRoutes from './routes/paintingSchemeRoutes.js';
|
||||
@@ -11,76 +18,104 @@ import yieldStudyRoutes from './routes/yieldStudyRoutes.js';
|
||||
import userRoutes from './routes/userRoutes.js';
|
||||
import systemSettingsRoutes from './routes/systemSettingsRoutes.js';
|
||||
import geometryTypeRoutes from './routes/geometryTypeRoutes.js';
|
||||
|
||||
import stockRoutes from './routes/stockRoutes.js';
|
||||
import notificationRoutes from './routes/notificationRoutes.js';
|
||||
import instrumentRoutes from './routes/instrumentRoutes.js';
|
||||
import messageRoutes from './routes/messageRoutes.js';
|
||||
import backupRoutes from './routes/backupRoutes.js';
|
||||
import path from 'path';
|
||||
|
||||
const app = express();
|
||||
|
||||
// Security Headers
|
||||
app.use(helmet({
|
||||
contentSecurityPolicy: false, // Pode interferir com o React em dev se não configurado direito
|
||||
crossOriginEmbedderPolicy: false
|
||||
}));
|
||||
|
||||
// Rate Limiter
|
||||
const apiLimiter = rateLimit({
|
||||
windowMs: 15 * 60 * 1000, // 15 minutes
|
||||
max: 1000, // limit each IP to 1000 requests per windowMs
|
||||
message: 'Too many requests from this IP, please try again later.'
|
||||
});
|
||||
|
||||
// Apply rate limiter only to API routes
|
||||
app.use('/api', apiLimiter);
|
||||
|
||||
// CORS
|
||||
const allowedOrigins = [
|
||||
'https://gpi.reifonas.cloud',
|
||||
'http://localhost:5173',
|
||||
'http://localhost:3000'
|
||||
];
|
||||
|
||||
app.use(cors({
|
||||
origin: '*',
|
||||
origin: (origin, callback) => {
|
||||
if (!origin || allowedOrigins.includes(origin)) {
|
||||
callback(null, true);
|
||||
} else {
|
||||
callback(new Error('Not allowed by CORS'));
|
||||
}
|
||||
},
|
||||
methods: ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS'],
|
||||
allowedHeaders: ['Content-Type', 'Authorization', 'x-organization-id']
|
||||
}));
|
||||
|
||||
app.use(express.json({ limit: '50mb' }));
|
||||
app.use(express.urlencoded({ limit: '50mb', extended: true }));
|
||||
import { extractUser } from './middleware/authMiddleware.js';
|
||||
app.use(extractUser);
|
||||
app.use(express.json({ limit: '5mb' }));
|
||||
app.use(express.urlencoded({ limit: '5mb', extended: true }));
|
||||
|
||||
// Static Uploads
|
||||
import fs from 'fs';
|
||||
const uploadsPath = path.join(process.cwd(), 'uploads');
|
||||
|
||||
if (!fs.existsSync(uploadsPath)) {
|
||||
fs.mkdirSync(uploadsPath, { recursive: true });
|
||||
}
|
||||
|
||||
app.use('/uploads', express.static(uploadsPath));
|
||||
|
||||
// Serve frontend static files
|
||||
const distPath = path.join(process.cwd(), 'dist');
|
||||
app.use(express.static(distPath));
|
||||
|
||||
// Routes
|
||||
app.use('/api/users', userRoutes);
|
||||
app.use('/api/projects', projectRoutes);
|
||||
app.use('/api/parts', partRoutes);
|
||||
app.use('/api/painting-schemes', paintingSchemeRoutes);
|
||||
app.use('/api/application-records', applicationRecordRoutes);
|
||||
app.use('/api/inspections', inspectionRoutes);
|
||||
app.use('/api', analysisRoutes);
|
||||
app.use('/api/datasheets', dataSheetRoutes);
|
||||
app.use('/api/datasheets', dataSheetRoutes);
|
||||
app.use('/api/yield-studies', yieldStudyRoutes);
|
||||
app.use('/api/system-settings', systemSettingsRoutes);
|
||||
app.use('/api/geometry-types', geometryTypeRoutes);
|
||||
app.use('/api/stock', stockRoutes);
|
||||
app.use('/api/notifications', notificationRoutes);
|
||||
app.use('/api/instruments', instrumentRoutes);
|
||||
app.use('/api/messages', messageRoutes);
|
||||
app.use('/api/backup', backupRoutes);
|
||||
// API Routes (all API routes pass through extractUser here, avoid duplication in route files)
|
||||
const apiRouter = express.Router();
|
||||
apiRouter.use(extractUser);
|
||||
|
||||
apiRouter.use('/users', userRoutes);
|
||||
apiRouter.use('/projects', projectRoutes);
|
||||
apiRouter.use('/parts', partRoutes);
|
||||
apiRouter.use('/painting-schemes', paintingSchemeRoutes);
|
||||
apiRouter.use('/application-records', applicationRecordRoutes);
|
||||
apiRouter.use('/inspections', inspectionRoutes);
|
||||
apiRouter.use('/', analysisRoutes);
|
||||
apiRouter.use('/datasheets', dataSheetRoutes);
|
||||
apiRouter.use('/yield-studies', yieldStudyRoutes);
|
||||
apiRouter.use('/system-settings', systemSettingsRoutes);
|
||||
apiRouter.use('/geometry-types', geometryTypeRoutes);
|
||||
apiRouter.use('/stock', stockRoutes);
|
||||
apiRouter.use('/notifications', notificationRoutes);
|
||||
apiRouter.use('/instruments', instrumentRoutes);
|
||||
apiRouter.use('/messages', messageRoutes);
|
||||
apiRouter.use('/backup', backupRoutes);
|
||||
|
||||
app.use('/api', apiRouter);
|
||||
|
||||
app.get('/health', (req, res) => {
|
||||
res.json({ status: 'ok', timestamp: new Date(), auth: 'logto' });
|
||||
});
|
||||
|
||||
app.get('/api/test', (req, res) => {
|
||||
res.json({ status: 'ok', message: 'Test endpoint working' });
|
||||
});
|
||||
|
||||
// SPA fallback - must be last
|
||||
app.use((req, res, next) => {
|
||||
if (req.path.startsWith('/api')) {
|
||||
return next(); // Do not return index.html for API 404s
|
||||
}
|
||||
res.sendFile(path.join(distPath, 'index.html'));
|
||||
});
|
||||
|
||||
// Error handler
|
||||
app.use((err: any, req: express.Request, res: express.Response, next: express.NextFunction) => {
|
||||
console.error('Express Error:', err);
|
||||
if (err.message === 'Not allowed by CORS') {
|
||||
return res.status(403).json({ error: 'CORS error' });
|
||||
}
|
||||
res.status(500).json({ error: 'Internal server error' });
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user