From c45a4e7f1885427fe6a4e180686ef6f18af19e2e Mon Sep 17 00:00:00 2001 From: ekwe7 Date: Tue, 28 Jul 2026 17:48:02 +0100 Subject: [PATCH 1/2] test(admin): add regression test for issue #559 duplicate const declaration Adds a module-load regression test that verifies admin.js cannot be broken by duplicate const declarations of IMPERSONATION_TTL_SECONDS. - Test 1: Requires admin.js and fails only on SyntaxError - Test 2: Static source analysis to detect duplicate const declarations --- backend/src/routes/admin.module-load.test.js | 65 ++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 backend/src/routes/admin.module-load.test.js diff --git a/backend/src/routes/admin.module-load.test.js b/backend/src/routes/admin.module-load.test.js new file mode 100644 index 0000000..8cf2c56 --- /dev/null +++ b/backend/src/routes/admin.module-load.test.js @@ -0,0 +1,65 @@ +const { describe, it } = require('node:test'); +const assert = require('node:assert'); + +/** + * Regression test for issue #559: + * Duplicate `const IMPERSONATION_TTL_SECONDS` declaration caused a + * SyntaxError at module load time, crashing all admin routes. + * + * This test ensures the admin router module can be required without + * throwing any syntax or initialization errors. + */ +describe('Admin Module Load (issue #559)', () => { + it('should require admin.js without SyntaxError', () => { + // If there is a duplicate const declaration, require() will throw: + // SyntaxError: Identifier 'IMPERSONATION_TTL_SECONDS' has already been declared + try { + require('./admin'); + } catch (err) { + if (err instanceof SyntaxError) { + assert.fail( + `admin.js threw SyntaxError on load — likely a duplicate const declaration: ${err.message}` + ); + } + // MODULE_NOT_FOUND or other runtime errors are expected in isolated tests + } + // If we get here without a SyntaxError, the module loaded successfully + }); + + it('should not redeclare constants already imported from config/constants', () => { + const fs = require('fs'); + const path = require('path'); + + const adminSource = fs.readFileSync( + path.join(__dirname, 'admin.js'), + 'utf-8' + ); + + // Find all const declarations of IMPERSONATION_TTL_SECONDS + const constDeclarations = adminSource.match( + /(?:const|let|var)\s+(?:\{[^}]*\bIMPERSONATION_TTL_SECONDS\b[^}]*\}|\bIMPERSONATION_TTL_SECONDS\b)\s*=/g + ); + + assert.ok(constDeclarations, 'Should find at least one const declaration'); + + // There should be exactly one declaration (the destructured import from constants.js) + const destructuredImports = constDeclarations.filter((d) => + d.includes('{') + ); + assert.strictEqual( + destructuredImports.length, + 1, + `Expected exactly 1 destructured import of IMPERSONATION_TTL_SECONDS, found ${destructuredImports.length}: ${constDeclarations}` + ); + + // Ensure no standalone `const IMPERSONATION_TTL_SECONDS =` (without destructuring) + const standaloneDeclarations = constDeclarations.filter( + (d) => !d.includes('{') + ); + assert.strictEqual( + standaloneDeclarations.length, + 0, + `Found standalone const IMPERSONATION_TTL_SECONDS declaration(s) which would shadow the import — remove them` + ); + }); +}); From 4416e6bd4a5934e62b8e9d0f42a64e2d97f60c47 Mon Sep 17 00:00:00 2001 From: ekwe7 Date: Tue, 28 Jul 2026 17:52:38 +0100 Subject: [PATCH 2/2] fix(test): clear require cache before module load test Ensures admin.js is re-evaluated from scratch each test run, preventing cached modules from masking duplicate const errors. --- backend/src/routes/admin.module-load.test.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/backend/src/routes/admin.module-load.test.js b/backend/src/routes/admin.module-load.test.js index 8cf2c56..421ffd5 100644 --- a/backend/src/routes/admin.module-load.test.js +++ b/backend/src/routes/admin.module-load.test.js @@ -14,6 +14,8 @@ describe('Admin Module Load (issue #559)', () => { // If there is a duplicate const declaration, require() will throw: // SyntaxError: Identifier 'IMPERSONATION_TTL_SECONDS' has already been declared try { + // Clear module cache to ensure we re-evaluate admin.js from scratch + delete require.cache[require.resolve('./admin')]; require('./admin'); } catch (err) { if (err instanceof SyntaxError) {