From ef56b47b09bcd1d14c6da4e5211c650374a06d03 Mon Sep 17 00:00:00 2001 From: M1 Date: Mon, 16 Mar 2026 17:25:59 +0400 Subject: [PATCH] feat: cookie-based auth, SSR dashboard, JS-optional login --- apps/web/src/dashboard/app.js | 31 ++---- apps/web/src/dashboard/index.html | 172 +++++++++++++----------------- apps/web/src/routes/auth.ts | 69 ++++++++++-- apps/web/src/routes/dashboard.ts | 94 +++++++++++++--- apps/web/src/routes/pings.ts | 5 +- apps/web/src/views/detail.ejs | 1 - apps/web/src/views/home.ejs | 34 ++++-- apps/web/src/views/new.ejs | 1 - apps/web/src/views/settings.ejs | 9 +- 9 files changed, 253 insertions(+), 163 deletions(-) diff --git a/apps/web/src/dashboard/app.js b/apps/web/src/dashboard/app.js index 29428ad..a986452 100644 --- a/apps/web/src/dashboard/app.js +++ b/apps/web/src/dashboard/app.js @@ -1,41 +1,27 @@ // PingQL Dashboard — shared utilities +// Auth is now cookie-based. No localStorage needed. const API_BASE = window.location.origin; -function getAccountKey() { - return localStorage.getItem('pingql_key'); -} - -function setAccountKey(key) { - localStorage.setItem('pingql_key', key); -} - function logout() { - localStorage.removeItem('pingql_key'); - window.location.href = '/dashboard'; + window.location.href = '/dashboard/logout'; } -function requireAuth() { - if (!getAccountKey()) { - window.location.href = '/dashboard'; - return false; - } - return true; -} +// requireAuth is a no-op now — server redirects to /dashboard if not authed +function requireAuth() { return true; } async function api(path, opts = {}) { - const key = getAccountKey(); const res = await fetch(`${API_BASE}${path}`, { ...opts, + credentials: 'same-origin', // send cookie automatically headers: { 'Content-Type': 'application/json', - ...(key ? { Authorization: `Bearer ${key}` } : {}), ...opts.headers, }, body: opts.body ? JSON.stringify(opts.body) : undefined, }); if (res.status === 401) { - logout(); + window.location.href = '/dashboard'; throw new Error('Unauthorized'); } const data = await res.json(); @@ -97,15 +83,12 @@ function escapeHtml(str) { // Subscribe to live ping updates for a monitor via SSE (fetch-based for auth header support) // Returns an AbortController — call .abort() to close function watchMonitor(monitorId, onPing) { - const key = localStorage.getItem('pingql_key'); - if (!key) return null; - const ac = new AbortController(); async function connect() { try { const res = await fetch(`/monitors/${monitorId}/stream`, { - headers: { Authorization: `Bearer ${key}` }, + credentials: 'same-origin', signal: ac.signal, }); if (!res.ok || !res.body) return; diff --git a/apps/web/src/dashboard/index.html b/apps/web/src/dashboard/index.html index 8d103ae..00c7d03 100644 --- a/apps/web/src/dashboard/index.html +++ b/apps/web/src/dashboard/index.html @@ -3,13 +3,9 @@ - PingQL — Login + PingQL — Sign In - +
@@ -18,58 +14,60 @@

Uptime monitoring for developers

- -
- - - - -
-

No account?

- -
-
+
- -