Spaces:
Running
Running
MichaelEdou
Fix OAuth on reverse proxy (HuggingFace): trust proxy, secure cookies, error display
907039a | // Force Eastern Time for all date operations (Gatineau, QC) | |
| process.env.TZ = 'America/Toronto'; | |
| import express from 'express'; | |
| import { createServer } from 'http'; | |
| import { Server as SocketIOServer } from 'socket.io'; | |
| import cors from 'cors'; | |
| import helmet from 'helmet'; | |
| import cookieParser from 'cookie-parser'; | |
| import pino from 'pino'; | |
| import { resolve, dirname } from 'path'; | |
| import { fileURLToPath } from 'url'; | |
| import { existsSync } from 'fs'; | |
| import { config } from './config/env.js'; | |
| import { db } from './db/index.js'; | |
| import { setupScanEvents } from './websocket/scanEvents.js'; | |
| import authRoutes from './routes/auth.js'; | |
| import emailRoutes from './routes/emails.js'; | |
| import transactionRoutes from './routes/transactions.js'; | |
| import settingsRoutes from './routes/settings.js'; | |
| import receiptRoutes from './routes/receipts.js'; | |
| import senderRoutes from './routes/senders.js'; | |
| import screenshotRoutes from './routes/screenshots.js'; | |
| import { errorHandler } from './middleware/errorHandler.js'; | |
| const logger = pino({ | |
| level: 'info', | |
| transport: { | |
| target: 'pino-pretty', | |
| options: { colorize: true }, | |
| }, | |
| }); | |
| const app = express(); | |
| const httpServer = createServer(app); | |
| const corsOrigin = config.APP_URL === '*' ? true : config.APP_URL; | |
| const io = new SocketIOServer(httpServer, { | |
| cors: { | |
| origin: corsOrigin, | |
| methods: ['GET', 'POST'], | |
| credentials: true, | |
| }, | |
| path: '/ws', | |
| }); | |
| // Trust reverse proxy (HuggingFace, nginx, etc.) | |
| app.set('trust proxy', true); | |
| // Middleware | |
| app.use( | |
| helmet({ | |
| contentSecurityPolicy: false, | |
| crossOriginEmbedderPolicy: false, | |
| }) | |
| ); | |
| app.use(cors({ origin: corsOrigin, credentials: true })); | |
| app.use(express.json({ limit: '10mb' })); | |
| app.use(cookieParser()); | |
| // Health check | |
| app.get('/api/health', (_req, res) => { | |
| res.json({ status: 'ok', timestamp: new Date().toISOString() }); | |
| }); | |
| // Routes | |
| app.use('/api/auth', authRoutes); | |
| app.use('/api/scan', emailRoutes); | |
| app.use('/api/transactions', transactionRoutes); | |
| app.use('/api/settings', settingsRoutes); | |
| app.use('/api/receipts', receiptRoutes); | |
| app.use('/api/senders', senderRoutes); | |
| app.use('/api/screenshots', screenshotRoutes); | |
| // Serve frontend static files in production | |
| const __dirname_server = dirname(fileURLToPath(import.meta.url)); | |
| const frontendDist = resolve(__dirname_server, '../../web/dist'); | |
| if (existsSync(frontendDist)) { | |
| app.use(express.static(frontendDist)); | |
| // SPA fallback — serve index.html for non-API routes (Express 5 syntax) | |
| app.get('{*path}', (_req, res) => { | |
| res.sendFile(resolve(frontendDist, 'index.html')); | |
| }); | |
| logger.info(`Serving frontend from ${frontendDist}`); | |
| } | |
| // Error handler | |
| app.use(errorHandler); | |
| // WebSocket setup | |
| setupScanEvents(io); | |
| // Export io for use in services | |
| export { io }; | |
| const PORT = config.PORT; | |
| httpServer.listen(PORT, () => { | |
| logger.info(`ICC Interac Manager API running on http://localhost:${PORT}`); | |
| }); | |