← back to Dw Pitch Followup
Skip Basic Auth for direct-loopback access so the localhost viewer loads without inline creds (tunnel still gated)
0524e783f2aa8e8c9d08d4ac822c7327ed76070f · 2026-07-07 13:30:43 -0700 · Steve Abrams
Files touched
Diff
commit 0524e783f2aa8e8c9d08d4ac822c7327ed76070f
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Tue Jul 7 13:30:43 2026 -0700
Skip Basic Auth for direct-loopback access so the localhost viewer loads without inline creds (tunnel still gated)
---
server.js | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/server.js b/server.js
index eefe808..3772451 100644
--- a/server.js
+++ b/server.js
@@ -32,10 +32,21 @@ const app = express();
app.use(express.json({ limit: '512kb' }));
// Basic auth (admin / DW2024!) — every route except /healthz.
+// EXCEPTION: skip auth for DIRECT local-machine access (loopback socket, not
+// forwarded through the cloudflared tunnel). The server binds 127.0.0.1 only,
+// so a direct-loopback request can only come from someone already at this Mac —
+// requiring a password there just breaks browsers (Safari drops user:pass@ in
+// URLs, and inline creds don't propagate to the /api/lists fetch → blank grid).
+// Tunnel/remote requests still require auth: cloudflared stamps proxied requests
+// with cf-connecting-ip / x-forwarded-for, so they don't get the loopback pass.
const BASIC_AUTH = process.env.BASIC_AUTH || 'admin:DW2024!';
const AUTH_HEADER = 'Basic ' + Buffer.from(BASIC_AUTH).toString('base64');
+const LOOPBACK = new Set(['127.0.0.1', '::1', '::ffff:127.0.0.1']);
app.use((req, res, next) => {
if (req.path === '/healthz') return next();
+ const remote = req.socket && req.socket.remoteAddress;
+ const proxied = req.get('cf-connecting-ip') || req.get('x-forwarded-for');
+ if (LOOPBACK.has(remote) && !proxied) return next(); // direct local access
if (req.get('authorization') === AUTH_HEADER) return next();
res.set('WWW-Authenticate', 'Basic realm="dw-pitch-followup"');
res.status(401).send('auth required');
← 2507156 chore: version bump (session close — anti-hallucination guar
·
back to Dw Pitch Followup
·
Frontend: build API URLs from location.host so fetches work 8a5b1ac →