← back to Qwen38 Viewer
multi-user basic auth (admin + Dave)
e9ac061c4001bbcb9807563bfa49d8b9e3db5aac · 2026-08-19 10:22:27 -0700 · steve
Files touched
Diff
commit e9ac061c4001bbcb9807563bfa49d8b9e3db5aac
Author: steve <steve@designerwallcoverings.com>
Date: Wed Aug 19 10:22:27 2026 -0700
multi-user basic auth (admin + Dave)
---
server.js | 18 +++++++++++++-----
1 file changed, 13 insertions(+), 5 deletions(-)
diff --git a/server.js b/server.js
index f2d4717..bc35216 100644
--- a/server.js
+++ b/server.js
@@ -16,16 +16,24 @@ const OLLAMA = process.env.OLLAMA_URL || 'http://127.0.0.1:11434';
const MODEL = process.env.MODEL || 'qwen3.8-27b-heretic';
const KEEP_ALIVE = process.env.KEEP_ALIVE || '30m'; // keep model warm to avoid ~2min cold loads
-// ---- Basic auth gate (fleet convention admin / DW2024!) --------------------
-const USER = process.env.BASIC_USER || 'admin';
-const PASS = process.env.BASIC_PASS || 'DW2024!';
+// ---- Basic auth gate — multi-user ------------------------------------------
+// USERS env = "user1:pass1,user2:pass2". Falls back to admin/DW2024!.
+const USERS = (process.env.USERS || 'admin:DW2024!')
+ .split(',').map(s => s.trim()).filter(Boolean)
+ .reduce((m, pair) => {
+ const i = pair.indexOf(':');
+ if (i > 0) m[pair.slice(0, i)] = pair.slice(i + 1);
+ return m;
+ }, {});
app.use((req, res, next) => {
if (req.path === '/health') return next(); // health is open for canaries
const hdr = req.headers.authorization || '';
const [scheme, b64] = hdr.split(' ');
if (scheme === 'Basic' && b64) {
- const [u, p] = Buffer.from(b64, 'base64').toString().split(':');
- if (u === USER && p === PASS) return next();
+ const s = Buffer.from(b64, 'base64').toString();
+ const i = s.indexOf(':');
+ const u = s.slice(0, i), p = s.slice(i + 1);
+ if (USERS[u] !== undefined && USERS[u] === p) return next();
}
res.set('WWW-Authenticate', 'Basic realm="qwen38"');
return res.status(401).send('Auth required');
← 5db1398 keep model warm (keep_alive 30m) to avoid ~2min cold loads
·
back to Qwen38 Viewer
·
add case-insensitive shared access code Dust2026 18c37a5 →