Skip to content

Commit 84d7efd

Browse files
Ubuntuclaude
andcommitted
Fix auth: serve UI without key, support ?apiKey= URL param
- Static files load without auth (UI handles it client-side) - API routes still require X-API-Key header - Also accept ?apiKey= query param for API calls - UI reads key from URL on first load, saves to localStorage, cleans URL Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 2d4f095 commit 84d7efd

2 files changed

Lines changed: 13 additions & 4 deletions

File tree

src/public/index.html

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -730,7 +730,14 @@
730730
let sending = false;
731731

732732
// --- API Key ---
733-
let apiKey = localStorage.getItem('apiKey') || '';
733+
// Pick up key from ?apiKey= param, then localStorage
734+
const urlKey = new URLSearchParams(location.search).get('apiKey');
735+
let apiKey = urlKey || localStorage.getItem('apiKey') || '';
736+
if (urlKey) {
737+
localStorage.setItem('apiKey', urlKey);
738+
// Clean URL so key isn't visible in address bar
739+
history.replaceState(null, '', location.pathname);
740+
}
734741

735742
function authHeaders(extra = {}) {
736743
return { 'X-API-Key': apiKey, ...extra };

src/server.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ function requireApiKey(req: Request, res: Response, next: NextFunction): void {
1616
next();
1717
return;
1818
}
19-
const provided = req.header("X-API-Key") ?? "";
19+
const provided = req.header("X-API-Key") ?? req.query.apiKey ?? "";
2020
if (provided === API_KEY) {
2121
next();
2222
return;
@@ -29,10 +29,12 @@ app.get("/health", (_req: Request, res: Response) => {
2929
res.json({ status: "ok" });
3030
});
3131

32-
// Static files and all API routes require the key
33-
app.use(requireApiKey);
32+
// Static files are public (UI handles auth via JS)
3433
app.use(express.static(path.join(__dirname, "public")));
3534

35+
// API routes require the key
36+
app.use(requireApiKey);
37+
3638
// Base directory where session working dirs live
3739
const BASE_DIR = path.resolve(process.env.BASE_DIR ?? path.join(process.cwd(), "workspaces"));
3840

0 commit comments

Comments
 (0)