import express from 'express'; import cookieParser from 'cookie-parser'; import path from 'path'; import { cfg } from './env'; import { Issuer, TokenSet } from 'openid-client'; import { setupAuthRoutes } from './auth'; async function bootstrap() { const app = express(); app.use(cookieParser(cfg.cookieSecret)); app.use(express.json()); // OIDC discovery e client const issuer = await Issuer.discover(cfg.issuerDiscoveryUrl); const client = new issuer.Client({ client_id: cfg.clientId, client_secret: cfg.clientSecret, redirect_uris: [cfg.redirectUri], response_types: ['code'], token_endpoint_auth_method: 'client_secret_basic' }); const cookieOptionsBase = { httpOnly: true, signed: true, sameSite: 'lax' as const, secure: cfg.isProd }; // setup delle route di login/callback → salva tokenSet nel cookie setupAuthRoutes(app, client, cfg.redirectUri, cfg.scope, cookieOptionsBase); // 👉 Middleware per refresh automatico sulle rotte protette app.use('/api', async (req, res, next) => { const raw = req.signedCookies?.tokenSet; if (!raw) return res.redirect('/login'); const tokenSet = new TokenSet(raw); if (tokenSet.expired()) { try { const refreshed = await client.refresh(tokenSet.refresh_token); res.cookie('tokenSet', refreshed, { ...cookieOptionsBase, maxAge: 7 * 24 * 60 * 60 * 1000 // opzionale: persistenza 7 giorni }); console.log('[OIDC] Access token rinnovato automaticamente'); } catch (err) { console.error('[OIDC] Errore nel refresh:', err); res.clearCookie('tokenSet'); return res.redirect('/login'); } } next(); }, (req, res) => { res.json({ message: 'Accesso con token valido!' }); }); // Vite middleware in dev, static in prod if (!cfg.isProd) { const vite = await (await import('vite')).createServer({ root: path.join(process.cwd(), 'client'), server: { middlewareMode: true, hmr: false, host: '0.0.0.0' }, plugins: [(await import('@vitejs/plugin-react')).default()] }); app.use(vite.middlewares); } else { const dist = path.join(process.cwd(), 'client', 'dist'); app.use(express.static(dist)); app.get('*', (_req, res) => res.sendFile(path.join(dist, 'index.html'))); } app.listen(cfg.port, '192.168.1.3', () => console.log(`Server running on http://192.168.1.3:${cfg.port}`) ); } bootstrap().catch((err) => { console.error('Bootstrap failed:', err); process.exit(1); });