feat: Add configurable cookie domain to gatekeeper and enhance Varnish backend configuration with health probes and increased timeouts.
Some checks failed
Build & Deploy KLZ Cables / 🔍 Prepare Environment (push) Successful in 11s
Build & Deploy KLZ Cables / 🧪 Quality Assurance (push) Successful in 1m41s
Build & Deploy KLZ Cables / 🏗️ Build Gatekeeper (push) Successful in 28s
Build & Deploy KLZ Cables / 🏗️ Build App (push) Successful in 3m56s
Build & Deploy KLZ Cables / 🚀 Deploy (push) Successful in 46s
Build & Deploy KLZ Cables / ⚡ PageSpeed (push) Failing after 3m7s
Build & Deploy KLZ Cables / 🔔 Notifications (push) Successful in 3s

This commit is contained in:
2026-02-05 23:29:34 +01:00
parent a82b95a28f
commit f44487eeac
3 changed files with 45 additions and 28 deletions

View File

@@ -66,6 +66,7 @@ services:
- ${ENV_FILE:-.env} - ${ENV_FILE:-.env}
environment: environment:
PORT: 3000 PORT: 3000
COOKIE_DOMAIN: ${COOKIE_DOMAIN}
labels: labels:
- "traefik.enable=true" - "traefik.enable=true"
- "traefik.http.services.${PROJECT_NAME:-klz-cables}-gatekeeper.loadbalancer.server.port=3000" - "traefik.http.services.${PROJECT_NAME:-klz-cables}-gatekeeper.loadbalancer.server.port=3000"

View File

@@ -5,6 +5,7 @@ const path = require('path');
const app = express(); const app = express();
const PORT = process.env.PORT || 3000; const PORT = process.env.PORT || 3000;
const GATEKEEPER_PASSWORD = process.env.GATEKEEPER_PASSWORD || 'klz2026'; const GATEKEEPER_PASSWORD = process.env.GATEKEEPER_PASSWORD || 'klz2026';
const COOKIE_DOMAIN = process.env.COOKIE_DOMAIN;
const AUTH_COOKIE_NAME = 'klz_gatekeeper_session'; const AUTH_COOKIE_NAME = 'klz_gatekeeper_session';
app.set('view engine', 'ejs'); app.set('view engine', 'ejs');
@@ -15,46 +16,52 @@ app.use(express.static(path.join(__dirname, 'public')));
// ForwardAuth check endpoint // ForwardAuth check endpoint
app.get('/verify', (req, res) => { app.get('/verify', (req, res) => {
const session = req.cookies[AUTH_COOKIE_NAME]; const session = req.cookies[AUTH_COOKIE_NAME];
if (session === GATEKEEPER_PASSWORD) { if (session === GATEKEEPER_PASSWORD) {
return res.status(200).send('OK'); return res.status(200).send('OK');
} }
// Traefik will use this to redirect if requested // Traefik will use this to redirect if requested
const originalUrl = req.headers['x-forwarded-uri'] || '/'; const originalUrl = req.headers['x-forwarded-uri'] || '/';
const host = req.headers['x-forwarded-host'] || ''; const host = req.headers['x-forwarded-host'] || '';
const proto = req.headers['x-forwarded-proto'] || 'https'; const proto = req.headers['x-forwarded-proto'] || 'https';
// Redirect to login // Redirect to login
res.redirect(`${proto}://${host}/gatekeeper/login?redirect=${encodeURIComponent(originalUrl)}`); res.redirect(`${proto}://${host}/gatekeeper/login?redirect=${encodeURIComponent(originalUrl)}`);
}); });
// Login page // Login page
app.get('/gatekeeper/login', (req, res) => { app.get('/gatekeeper/login', (req, res) => {
res.render('login', { res.render('login', {
error: req.query.error ? 'Invalid password' : null, error: req.query.error ? 'Invalid password' : null,
redirect: req.query.redirect || '/' redirect: req.query.redirect || '/',
}); });
}); });
// Handle login // Handle login
app.post('/gatekeeper/login', (req, res) => { app.post('/gatekeeper/login', (req, res) => {
const { password, redirect } = req.body; const { password, redirect } = req.body;
if (password === GATEKEEPER_PASSWORD) { if (password === GATEKEEPER_PASSWORD) {
res.cookie(AUTH_COOKIE_NAME, GATEKEEPER_PASSWORD, { const cookieOptions = {
httpOnly: true, httpOnly: true,
secure: true, secure: true,
path: '/', path: '/',
maxAge: 30 * 24 * 60 * 60 * 1000 // 30 days maxAge: 30 * 24 * 60 * 60 * 1000, // 30 days
}); };
return res.redirect(redirect || '/');
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, () => { app.listen(PORT, () => {
console.log(`Gatekeeper listening on port ${PORT}`); console.log(`Gatekeeper listening on port ${PORT}`);
}); });

View File

@@ -2,12 +2,21 @@ vcl 4.1;
import std; import std;
probe default_probe {
.url = "/en";
.timeout = 2s;
.interval = 5s;
.window = 5;
.threshold = 3;
}
backend default { backend default {
.host = "klz-app"; .host = "klz-app";
.port = "3000"; .port = "3000";
.connect_timeout = 5s; .connect_timeout = 10s;
.first_byte_timeout = 90s; .first_byte_timeout = 300s;
.between_bytes_timeout = 5s; .between_bytes_timeout = 10s;
.probe = default_probe;
} }
acl purge { acl purge {