81 lines
2.5 KiB
Text
81 lines
2.5 KiB
Text
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);
|
|
});
|