From 9a7fd0d33517d51313d66b8efc090de299cc12ef Mon Sep 17 00:00:00 2001 From: CallMeTechie <34693633+CallMeTechie@users.noreply.github.com> Date: Thu, 25 Jun 2026 14:08:45 +0200 Subject: [PATCH] fix(settings): inject gateway_down_threshold_s so the slider shows the saved value The gw-down-threshold slider is the only server-rendered settings value; the 'settings' template var was never injected into the page render, so the slider always showed the hardcoded default 90 regardless of the persisted value (and a subsequent slider touch would overwrite the real DB value with 90). Inject just that one key (not getAll(), to avoid exposing secrets) for the settings page. --- src/routes/index.js | 13 +++++++++++++ tests/gateway_failover_render.test.js | 28 +++++++++++++++++++++++++++ 2 files changed, 41 insertions(+) create mode 100644 tests/gateway_failover_render.test.js diff --git a/src/routes/index.js b/src/routes/index.js index c787f2f5..44525992 100644 --- a/src/routes/index.js +++ b/src/routes/index.js @@ -228,6 +228,19 @@ pages.forEach(({ path, template, titleKey }) => { } catch { extraLocals.pools = []; extraLocals.gatewayPeers = []; } } + // Settings page: gw-down-threshold is the only server-rendered settings + // value (template reads `settings.gateway_down_threshold_s`). The `settings` + // template var is otherwise never injected, so the slider always showed the + // hardcoded default 90. Inject just that one key (not getAll(), to avoid + // exposing secrets) so the slider reflects the persisted value. + if (template === 'settings') { + try { + extraLocals.settings = { + gateway_down_threshold_s: require('../services/settings').get('gateway_down_threshold_s'), + }; + } catch { extraLocals.settings = {}; } + } + // Dashboard-only: gateways that need re-pairing after master-key rotation if (template === 'dashboard') { try { diff --git a/tests/gateway_failover_render.test.js b/tests/gateway_failover_render.test.js new file mode 100644 index 00000000..61635017 --- /dev/null +++ b/tests/gateway_failover_render.test.js @@ -0,0 +1,28 @@ +'use strict'; + +// The gateway-failover slider is the only server-rendered settings value +// (`value="{{ settings.gateway_down_threshold_s or 90 }}"`). The settings +// template var was never injected into the page render, so the slider always +// showed the hardcoded default 90 regardless of the persisted value — the save +// round-trip looked broken in the UI. This verifies the render reflects the DB. +const crypto = require('crypto'); +process.env.GC_ENCRYPTION_KEY = process.env.GC_ENCRYPTION_KEY || crypto.randomBytes(32).toString('hex'); +const { test, beforeEach, afterEach } = require('node:test'); +const assert = require('node:assert/strict'); +const { setup, teardown, getAgent, getCsrf } = require('./helpers/setup'); + +beforeEach(async () => { await setup(); }); +afterEach(teardown); + +test('settings page renders the persisted gateway_down_threshold_s on the slider', async () => { + const agent = getAgent(); + const csrf = getCsrf(); + await agent.put('/api/v1/settings/gateway-failover') + .set('X-CSRF-Token', csrf) + .send({ gateway_down_threshold_s: 150 }) + .expect(200); + const page = await agent.get('/settings').expect(200); + // slider must reflect the saved value, not the hardcoded default 90 + assert.match(page.text, /id="gw-down-threshold"[^>]*value="150"/); + assert.doesNotMatch(page.text, /id="gw-down-threshold"[^>]*value="90"/); +});