mirror of
https://github.com/nfonteyne/octane-website.git
synced 2026-09-03 23:24:48 +02:00
update: create production env
This commit is contained in:
parent
d8d4a45483
commit
c3380179ce
6 changed files with 135 additions and 15 deletions
|
|
@ -6,9 +6,63 @@ const asyncHandler = require('../lib/asyncHandler');
|
|||
|
||||
const router = express.Router();
|
||||
|
||||
function escapeHtml(str) {
|
||||
return String(str ?? '').replace(/[&<>"']/g, (c) => ({
|
||||
'&': '&', '<': '<', '>': '>', '"': '"', "'": ''',
|
||||
}[c]));
|
||||
}
|
||||
|
||||
function establishSession(req, res, user, returnTo) {
|
||||
req.session.regenerate((err) => {
|
||||
if (err) throw err;
|
||||
req.session.userId = user.id;
|
||||
req.session.save((saveErr) => {
|
||||
if (saveErr) throw saveErr;
|
||||
res.redirect(returnTo || '/');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Dev-only login: no Authentik involved, lets you pick a name/admin flag
|
||||
// to test the app locally. Only active when DEV_BYPASS_AUTH=true.
|
||||
async function devLogin(req, res) {
|
||||
const { name, admin, returnTo } = req.query;
|
||||
|
||||
if (!name) {
|
||||
res.set('Content-Type', 'text/html');
|
||||
return res.send(`<!doctype html>
|
||||
<html lang="fr">
|
||||
<head><meta charset="utf-8"><title>Connexion (mode dev)</title></head>
|
||||
<body style="font-family: system-ui, sans-serif; max-width: 400px; margin: 60px auto;">
|
||||
<h1>Connexion (mode dev)</h1>
|
||||
<p>Authentik n'est pas connecté (DEV_BYPASS_AUTH=true). Choisissez une identité de test.</p>
|
||||
<form method="get" action="/auth/login">
|
||||
<input type="hidden" name="returnTo" value="${escapeHtml(returnTo || '/')}">
|
||||
<p><label>Nom : <input name="name" required autofocus></label></p>
|
||||
<p><label><input type="checkbox" name="admin" value="1"> Compte admin</label></p>
|
||||
<button type="submit">Se connecter</button>
|
||||
</form>
|
||||
</body>
|
||||
</html>`);
|
||||
}
|
||||
|
||||
const user = await usersRepo.upsertFromClaims({
|
||||
sub: `dev:${name}`,
|
||||
name,
|
||||
email: `${String(name).toLowerCase().replace(/\s+/g, '.')}@dev.local`,
|
||||
isAdmin: admin === '1' || admin === 'true',
|
||||
});
|
||||
|
||||
establishSession(req, res, user, returnTo);
|
||||
}
|
||||
|
||||
router.get(
|
||||
'/login',
|
||||
asyncHandler(async (req, res) => {
|
||||
if (config.devBypassAuth) {
|
||||
return devLogin(req, res);
|
||||
}
|
||||
|
||||
const oidcConfig = getOidcConfig();
|
||||
const codeVerifier = client.randomPKCECodeVerifier();
|
||||
const codeChallenge = await client.calculatePKCECodeChallenge(codeVerifier);
|
||||
|
|
@ -36,6 +90,10 @@ router.get(
|
|||
router.get(
|
||||
'/callback',
|
||||
asyncHandler(async (req, res) => {
|
||||
if (config.devBypassAuth) {
|
||||
return res.redirect('/auth/login');
|
||||
}
|
||||
|
||||
const oidcConfig = getOidcConfig();
|
||||
const pending = req.session.oidc;
|
||||
if (!pending) {
|
||||
|
|
@ -68,14 +126,7 @@ router.get(
|
|||
delete req.session.oidc;
|
||||
delete req.session.returnTo;
|
||||
|
||||
req.session.regenerate((err) => {
|
||||
if (err) throw err;
|
||||
req.session.userId = user.id;
|
||||
req.session.save((saveErr) => {
|
||||
if (saveErr) throw saveErr;
|
||||
res.redirect(returnTo);
|
||||
});
|
||||
});
|
||||
establishSession(req, res, user, returnTo);
|
||||
})
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
require('dotenv').config();
|
||||
|
||||
const devBypassAuth = process.env.DEV_BYPASS_AUTH === 'true';
|
||||
|
||||
function required(name) {
|
||||
const value = process.env[name];
|
||||
if (!value && process.env.NODE_ENV !== 'test') {
|
||||
|
|
@ -13,9 +15,13 @@ module.exports = {
|
|||
port: parseInt(process.env.PORT, 10) || 3000,
|
||||
databaseUrl: required('DATABASE_URL'),
|
||||
sessionSecret: required('SESSION_SECRET'),
|
||||
authentikIssuerUrl: required('AUTHENTIK_ISSUER_URL'),
|
||||
oidcClientId: required('OIDC_CLIENT_ID'),
|
||||
oidcClientSecret: required('OIDC_CLIENT_SECRET'),
|
||||
oidcRedirectUri: required('OIDC_REDIRECT_URI'),
|
||||
// DEV_BYPASS_AUTH lets you run the app locally without a real Authentik
|
||||
// instance: /auth/login prompts for a name instead of redirecting to OIDC.
|
||||
// Never enable this outside local development.
|
||||
devBypassAuth,
|
||||
authentikIssuerUrl: devBypassAuth ? process.env.AUTHENTIK_ISSUER_URL : required('AUTHENTIK_ISSUER_URL'),
|
||||
oidcClientId: devBypassAuth ? process.env.OIDC_CLIENT_ID : required('OIDC_CLIENT_ID'),
|
||||
oidcClientSecret: devBypassAuth ? process.env.OIDC_CLIENT_SECRET : required('OIDC_CLIENT_SECRET'),
|
||||
oidcRedirectUri: devBypassAuth ? process.env.OIDC_REDIRECT_URI : required('OIDC_REDIRECT_URI'),
|
||||
adminGroupName: process.env.ADMIN_GROUP_NAME || 'octane-admins',
|
||||
};
|
||||
|
|
|
|||
|
|
@ -5,7 +5,11 @@ const { runMigrations } = require('./db/migrate');
|
|||
|
||||
async function main() {
|
||||
await runMigrations();
|
||||
await initOidc();
|
||||
if (config.devBypassAuth) {
|
||||
console.warn('DEV_BYPASS_AUTH is enabled — Authentik/OIDC is skipped. Do not use this in production.');
|
||||
} else {
|
||||
await initOidc();
|
||||
}
|
||||
|
||||
const app = createApp();
|
||||
app.listen(config.port, () => {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue