fix: skip FORCE_HTTPS redirect for /api/health endpoint

Health probes (K8s, Docker, LB health checks) hit the endpoint over plain
HTTP from inside the cluster/container. The catch-all HTTPS redirect was
causing all probe types to fail whenever FORCE_HTTPS=true was set.

Closes #735
This commit is contained in:
jubnl
2026-04-19 14:10:41 +02:00
parent 5978eec270
commit d0383c06c3
2 changed files with 18 additions and 2 deletions
+1
View File
@@ -112,6 +112,7 @@ export function createApp(): express.Application {
if (shouldForceHttps) { if (shouldForceHttps) {
app.use((req: Request, res: Response, next: NextFunction) => { app.use((req: Request, res: Response, next: NextFunction) => {
if (req.path === '/api/health') return next();
if (req.secure || req.headers['x-forwarded-proto'] === 'https') return next(); if (req.secure || req.headers['x-forwarded-proto'] === 'https') return next();
res.redirect(301, 'https://' + req.headers.host + req.url); res.redirect(301, 'https://' + req.headers.host + req.url);
}); });
+17 -2
View File
@@ -94,8 +94,22 @@ describe('Photo endpoint auth', () => {
}); });
describe('Force HTTPS redirect', () => { describe('Force HTTPS redirect', () => {
it('MISC-004 — FORCE_HTTPS redirect sends 301 for HTTP requests', async () => { it('MISC-004 — FORCE_HTTPS redirect sends 301 for HTTP requests on non-health paths', async () => {
// createApp() reads FORCE_HTTPS at call time, so we need a fresh app instance // createApp() reads FORCE_HTTPS at call time, so we need a fresh app instance
process.env.FORCE_HTTPS = 'true';
let httpsApp: Express;
try {
httpsApp = createApp();
} finally {
delete process.env.FORCE_HTTPS;
}
const res = await request(httpsApp)
.get('/api/addons')
.set('X-Forwarded-Proto', 'http');
expect(res.status).toBe(301);
});
it('MISC-008 — FORCE_HTTPS does not redirect /api/health (probes must reach it over HTTP)', async () => {
process.env.FORCE_HTTPS = 'true'; process.env.FORCE_HTTPS = 'true';
let httpsApp: Express; let httpsApp: Express;
try { try {
@@ -106,7 +120,8 @@ describe('Force HTTPS redirect', () => {
const res = await request(httpsApp) const res = await request(httpsApp)
.get('/api/health') .get('/api/health')
.set('X-Forwarded-Proto', 'http'); .set('X-Forwarded-Proto', 'http');
expect(res.status).toBe(301); expect(res.status).toBe(200);
expect(res.body.status).toBe('ok');
}); });
it('MISC-004 — no redirect when FORCE_HTTPS is not set', async () => { it('MISC-004 — no redirect when FORCE_HTTPS is not set', async () => {