From f44487eeacb66d3be8ec17245804d104aa6c294b Mon Sep 17 00:00:00 2001 From: Marc Mintel Date: Thu, 5 Feb 2026 23:29:34 +0100 Subject: [PATCH] feat: Add configurable cookie domain to gatekeeper and enhance Varnish backend configuration with health probes and increased timeouts. --- docker-compose.yml | 1 + gatekeeper/index.js | 57 +++++++++++++++++++++++++-------------------- varnish/default.vcl | 15 +++++++++--- 3 files changed, 45 insertions(+), 28 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 8c5214d1..d7407960 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -66,6 +66,7 @@ services: - ${ENV_FILE:-.env} environment: PORT: 3000 + COOKIE_DOMAIN: ${COOKIE_DOMAIN} labels: - "traefik.enable=true" - "traefik.http.services.${PROJECT_NAME:-klz-cables}-gatekeeper.loadbalancer.server.port=3000" diff --git a/gatekeeper/index.js b/gatekeeper/index.js index 46f90e1c..f6aa0b25 100644 --- a/gatekeeper/index.js +++ b/gatekeeper/index.js @@ -5,6 +5,7 @@ const path = require('path'); const app = express(); const PORT = process.env.PORT || 3000; const GATEKEEPER_PASSWORD = process.env.GATEKEEPER_PASSWORD || 'klz2026'; +const COOKIE_DOMAIN = process.env.COOKIE_DOMAIN; const AUTH_COOKIE_NAME = 'klz_gatekeeper_session'; app.set('view engine', 'ejs'); @@ -15,46 +16,52 @@ app.use(express.static(path.join(__dirname, 'public'))); // ForwardAuth check endpoint app.get('/verify', (req, res) => { - const session = req.cookies[AUTH_COOKIE_NAME]; + const session = req.cookies[AUTH_COOKIE_NAME]; - if (session === GATEKEEPER_PASSWORD) { - return res.status(200).send('OK'); - } + if (session === GATEKEEPER_PASSWORD) { + return res.status(200).send('OK'); + } - // Traefik will use this to redirect if requested - const originalUrl = req.headers['x-forwarded-uri'] || '/'; - const host = req.headers['x-forwarded-host'] || ''; - const proto = req.headers['x-forwarded-proto'] || 'https'; + // Traefik will use this to redirect if requested + const originalUrl = req.headers['x-forwarded-uri'] || '/'; + const host = req.headers['x-forwarded-host'] || ''; + const proto = req.headers['x-forwarded-proto'] || 'https'; - // Redirect to login - res.redirect(`${proto}://${host}/gatekeeper/login?redirect=${encodeURIComponent(originalUrl)}`); + // Redirect to login + res.redirect(`${proto}://${host}/gatekeeper/login?redirect=${encodeURIComponent(originalUrl)}`); }); // Login page app.get('/gatekeeper/login', (req, res) => { - res.render('login', { - error: req.query.error ? 'Invalid password' : null, - redirect: req.query.redirect || '/' - }); + res.render('login', { + error: req.query.error ? 'Invalid password' : null, + redirect: req.query.redirect || '/', + }); }); // Handle login app.post('/gatekeeper/login', (req, res) => { - const { password, redirect } = req.body; + const { password, redirect } = req.body; - if (password === GATEKEEPER_PASSWORD) { - res.cookie(AUTH_COOKIE_NAME, GATEKEEPER_PASSWORD, { - httpOnly: true, - secure: true, - path: '/', - maxAge: 30 * 24 * 60 * 60 * 1000 // 30 days - }); - return res.redirect(redirect || '/'); + if (password === GATEKEEPER_PASSWORD) { + const cookieOptions = { + httpOnly: true, + secure: true, + path: '/', + maxAge: 30 * 24 * 60 * 60 * 1000, // 30 days + }; + + if (COOKIE_DOMAIN) { + cookieOptions.domain = COOKIE_DOMAIN; } - res.redirect(`/gatekeeper/login?error=1&redirect=${encodeURIComponent(redirect || '/')}`); + res.cookie(AUTH_COOKIE_NAME, GATEKEEPER_PASSWORD, cookieOptions); + return res.redirect(redirect || '/'); + } + + res.redirect(`/gatekeeper/login?error=1&redirect=${encodeURIComponent(redirect || '/')}`); }); app.listen(PORT, () => { - console.log(`Gatekeeper listening on port ${PORT}`); + console.log(`Gatekeeper listening on port ${PORT}`); }); diff --git a/varnish/default.vcl b/varnish/default.vcl index 08e61269..1b4eb445 100644 --- a/varnish/default.vcl +++ b/varnish/default.vcl @@ -2,12 +2,21 @@ vcl 4.1; import std; +probe default_probe { + .url = "/en"; + .timeout = 2s; + .interval = 5s; + .window = 5; + .threshold = 3; +} + backend default { .host = "klz-app"; .port = "3000"; - .connect_timeout = 5s; - .first_byte_timeout = 90s; - .between_bytes_timeout = 5s; + .connect_timeout = 10s; + .first_byte_timeout = 300s; + .between_bytes_timeout = 10s; + .probe = default_probe; } acl purge {