From 8bc71792e3a0ce8e7008d498249a5985325f264d Mon Sep 17 00:00:00 2001 From: jessikitty Date: Mon, 7 Sep 2026 11:06:19 +1000 Subject: [PATCH] Server-side printing, roll type setting, cache headers --- package.json | 1 + scripts/version.mjs | 32 ++++++++++++++++++++++++++++++++ src/server.js | 14 +++++++++++++- 3 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 scripts/version.mjs diff --git a/package.json b/package.json index 2bffc4e..7550009 100644 --- a/package.json +++ b/package.json @@ -7,6 +7,7 @@ "scripts": { "start": "node src/server.js", "dev": "node --watch src/server.js", + "version": "node scripts/version.mjs", "gen-secret": "node -e \"console.log(require('crypto').randomBytes(32).toString('hex'))\"" }, "engines": { diff --git a/scripts/version.mjs b/scripts/version.mjs new file mode 100644 index 0000000..3a56f5b --- /dev/null +++ b/scripts/version.mjs @@ -0,0 +1,32 @@ +// Reports what this container is actually running, so an upgrade that did not +// land can be spotted without guesswork. +import fs from 'node:fs'; +import path from 'node:path'; +import { fileURLToPath } from 'node:url'; + +const here = path.dirname(fileURLToPath(import.meta.url)); +const root = path.join(here, '..'); + +const FEATURES = [ + ['server-side printing', 'src/printer.js', null], + ['roll type is a separate setting', 'src/routes/admin.js', 'printer_label'], + ['roll type in the console', 'public/js/admin.js', 'printerLabel'], + ['company field', 'src/routes/kiosk.js', 'company'], + ['separate login page', 'public/login.html', 'step-password'], + ['per-site branding', 'src/branding.js', null], + ['CA in DER form for Jamf', 'src/tls.js', 'caCertificateDer'], +]; + +console.log(''); +for (const [name, file, needle] of FEATURES) { + const full = path.join(root, file); + let state = 'MISSING'; + if (fs.existsSync(full)) { + state = !needle || fs.readFileSync(full, 'utf8').includes(needle) ? 'present' : 'OLD VERSION'; + } + console.log(` ${state.padEnd(12)} ${name}`); +} +console.log(''); +console.log('Anything not "present" means this container is running older code.'); +console.log('On the docker host: git pull && docker compose up -d --build'); +console.log(''); diff --git a/src/server.js b/src/server.js index 3ea6366..09c0c5f 100644 --- a/src/server.js +++ b/src/server.js @@ -72,7 +72,19 @@ app.get('/admin/login', (req, res) => { // Nobody should land on the raw filenames; keep one address per page. app.get(['/admin.html', '/login.html'], (req, res) => res.redirect('/admin')); -app.use(express.static(publicDir, { extensions: ['html'], index: false })); +// no-cache still allows a 304 on an unchanged file, but forces the browser to ask +// first. Without it a cached admin.js survives an upgrade and the console keeps +// running yesterday's code against today's server, which is impossible to diagnose +// from the outside. +app.use( + express.static(publicDir, { + extensions: ['html'], + index: false, + setHeaders: (res, filePath) => { + if (/\.(html|js|css)$/.test(filePath)) res.setHeader('Cache-Control', 'no-cache'); + }, + }) +); app.get('/favicon.ico', (req, res) => res.redirect(301, '/favicon.svg')); app.use((req, res) => res.status(404).sendFile(path.join(publicDir, 'index.html')));