Visitor sign in kiosk: multi-site, badge printing, WWCC expiry warnings, admin accounts with 2FA

This commit is contained in:
2026-09-04 14:55:59 +10:00
commit 3278890491
41 changed files with 8920 additions and 0 deletions
+32
View File
@@ -0,0 +1,32 @@
#!/usr/bin/env bash
# Creates the kiosk certificates: a long lived local authority, and a server
# certificate signed by it. Install the authority on each kiosk device once.
#
# ./scripts/gen-cert.sh use HTTPS_HOSTNAMES from .env
# ./scripts/gen-cert.sh visitors.local 10.0.0.5 override the names
# ./scripts/gen-cert.sh --force replace the authority too
#
# The server normally does this by itself on start, so you only need this to
# change the address list or to inspect the result before going live.
set -euo pipefail
cd "$(dirname "$0")/.."
FORCE=""
NAMES=()
for arg in "$@"; do
if [ "$arg" = "--force" ]; then FORCE="--force"; else NAMES+=("$arg"); fi
done
if [ ${#NAMES[@]} -gt 0 ]; then
HTTPS_HOSTNAMES="$(IFS=,; echo "${NAMES[*]}")"
export HTTPS_HOSTNAMES
echo "Using names: ${HTTPS_HOSTNAMES}"
fi
if docker compose ps --status running 2>/dev/null | grep -q visitor-signin; then
docker compose exec -T visitor-signin node scripts/make-cert.mjs $FORCE
echo "Restarting so the new certificate is served..."
docker compose restart visitor-signin
else
node scripts/make-cert.mjs $FORCE
fi
+13
View File
@@ -0,0 +1,13 @@
// Container healthcheck. Works whether the app is serving http or self-signed https.
const secure = ['1', 'true', 'yes', 'on'].includes(String(process.env.HTTPS_ENABLED).toLowerCase());
const port = process.env.PORT || 3000;
const url = `${secure ? 'https' : 'http'}://127.0.0.1:${port}/healthz`;
if (secure) process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
try {
const res = await fetch(url, { signal: AbortSignal.timeout(4000) });
process.exit(res.ok ? 0 : 1);
} catch {
process.exit(1);
}
+22
View File
@@ -0,0 +1,22 @@
// Creates or renews the kiosk certificates without starting the server.
// node scripts/make-cert.mjs renew the server certificate if needed
// node scripts/make-cert.mjs --force new certificate authority as well
import { ensureCertificates, describe } from '../src/tls.js';
const force = process.argv.includes('--force');
try {
ensureCertificates({ force });
const info = describe();
console.log('');
console.log('Certificate authority :', info.caPath);
console.log(' fingerprint :', info.ca?.fingerprint);
console.log(' expires :', info.ca?.validTo, `(${info.ca?.daysLeft} days)`);
console.log('Server certificate :', info.server?.validTo, `(${info.server?.daysLeft} days)`);
console.log(' valid for :', (info.server?.names || []).join(', '));
console.log('');
console.log('Install the authority certificate on each kiosk device, then restart the container.');
} catch (err) {
console.error('Could not create certificates:', err.message);
process.exit(1);
}