2026-03-19 15:06:32 +03:00
|
|
|
import 'dotenv/config';
|
|
|
|
|
|
|
|
|
|
import cors from 'cors';
|
|
|
|
|
import express from 'express';
|
|
|
|
|
import { auth } from 'express-openid-connect';
|
|
|
|
|
|
|
|
|
|
const app = express();
|
|
|
|
|
|
|
|
|
|
const port = Number(process.env.PORT ?? 3001);
|
|
|
|
|
const frontendOrigin = process.env.FRONTEND_ORIGIN ?? 'http://localhost:5173';
|
|
|
|
|
|
2026-03-19 15:47:21 +03:00
|
|
|
const disableAuth = ['1', 'true', 'yes', 'on'].includes(
|
|
|
|
|
String(process.env.DISABLE_AUTH ?? '').trim().toLowerCase(),
|
|
|
|
|
);
|
|
|
|
|
|
2026-03-19 15:06:32 +03:00
|
|
|
const oidcConfig = {
|
|
|
|
|
authRequired: false,
|
|
|
|
|
auth0Logout: false,
|
|
|
|
|
secret: process.env.SESSION_SECRET ?? 'change-me-in-env',
|
|
|
|
|
baseURL: process.env.BASE_URL ?? `http://localhost:${port}`,
|
|
|
|
|
clientID: process.env.OIDC_CLIENT_ID ?? '',
|
|
|
|
|
issuerBaseURL: process.env.OIDC_ISSUER_BASE_URL ?? '',
|
|
|
|
|
clientSecret: process.env.OIDC_CLIENT_SECRET ?? '',
|
|
|
|
|
authorizationParams: {
|
|
|
|
|
response_type: 'code',
|
|
|
|
|
scope: process.env.OIDC_SCOPE ?? 'openid profile email',
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
|
2026-03-19 15:47:21 +03:00
|
|
|
if (!disableAuth && (!oidcConfig.clientID || !oidcConfig.issuerBaseURL || !oidcConfig.clientSecret)) {
|
2026-03-19 15:06:32 +03:00
|
|
|
// Keep a clear startup failure if OIDC is not configured.
|
|
|
|
|
throw new Error(
|
2026-03-19 15:47:21 +03:00
|
|
|
'OIDC config is missing. Set OIDC_ISSUER_BASE_URL, OIDC_CLIENT_ID, OIDC_CLIENT_SECRET in server/.env (or set DISABLE_AUTH=true)',
|
2026-03-19 15:06:32 +03:00
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
app.use(
|
|
|
|
|
cors({
|
|
|
|
|
origin: frontendOrigin,
|
|
|
|
|
credentials: true,
|
|
|
|
|
}),
|
|
|
|
|
);
|
|
|
|
|
app.use(express.json());
|
|
|
|
|
|
2026-03-19 15:47:21 +03:00
|
|
|
if (!disableAuth) {
|
|
|
|
|
app.use(auth(oidcConfig));
|
|
|
|
|
}
|
2026-03-19 15:06:32 +03:00
|
|
|
|
|
|
|
|
app.get('/api/health', (_req, res) => {
|
|
|
|
|
res.json({ ok: true });
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
app.get('/api/me', (req, res) => {
|
2026-03-19 15:47:21 +03:00
|
|
|
if (disableAuth) {
|
|
|
|
|
res.json({
|
|
|
|
|
authenticated: false,
|
|
|
|
|
bypassAuth: true,
|
|
|
|
|
user: {
|
|
|
|
|
sub: 'noauth',
|
|
|
|
|
name: 'No Auth',
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-19 15:06:32 +03:00
|
|
|
if (!req.oidc.isAuthenticated()) {
|
|
|
|
|
res.status(401).json({ authenticated: false });
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
res.json({
|
|
|
|
|
authenticated: true,
|
|
|
|
|
user: req.oidc.user,
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
app.get('/api/login', (req, res) => {
|
2026-03-19 15:47:21 +03:00
|
|
|
if (disableAuth) {
|
|
|
|
|
res.status(204).end();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-19 15:06:32 +03:00
|
|
|
res.oidc.login({
|
|
|
|
|
returnTo: frontendOrigin,
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
app.get('/api/logout', (req, res) => {
|
2026-03-19 15:47:21 +03:00
|
|
|
if (disableAuth) {
|
|
|
|
|
res.status(204).end();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-19 15:06:32 +03:00
|
|
|
res.oidc.logout({
|
|
|
|
|
returnTo: frontendOrigin,
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
app.listen(port, () => {
|
2026-03-19 15:47:21 +03:00
|
|
|
console.log(
|
|
|
|
|
`${disableAuth ? 'NO-AUTH' : 'OIDC auth'} server listening on http://localhost:${port}`,
|
|
|
|
|
);
|
2026-03-19 15:06:32 +03:00
|
|
|
});
|