-
Notifications
You must be signed in to change notification settings - Fork 1
[security] Fix API demo auth bypass and dashboard token validation #195
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
9c8bad5
bb0e9cb
7168583
0288443
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -452,6 +452,35 @@ <h3 class="text-lg font-bold text-purple-300 mb-4">Quick Actions</h3> | |
| })(); | ||
| }); | ||
|
|
||
| // Validate token and initialize dashboard | ||
| async function validateAndInit() { | ||
| const token = localStorage.getItem('spiralsafe_admin_token') || | ||
| sessionStorage.getItem('spiralsafe_admin_token'); | ||
|
|
||
| try { | ||
| const response = await fetch(`${API_BASE}/admin/auth/me`, { | ||
| method: 'GET', | ||
| headers: { | ||
| 'Authorization': `Bearer ${token}`, | ||
| 'Accept': 'application/json' | ||
| } | ||
| }); | ||
|
|
||
| if (!response.ok) { | ||
| // Invalid or expired token, clear it and redirect to login | ||
| logout(); | ||
| return; | ||
| } | ||
|
|
||
| // Token is valid - initialize charts and load metrics | ||
| initCharts(); | ||
| loadMetrics(); | ||
| } catch (error) { | ||
| // On network or other errors, clear token and redirect to login | ||
| logout(); | ||
| } | ||
| } | ||
|
Comment on lines
+455
to
+482
|
||
|
|
||
| // Logout function | ||
| function logout() { | ||
| localStorage.removeItem('spiralsafe_admin_token'); | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -605,10 +605,24 @@ <h3 class="text-lg font-bold text-green-400 mb-2">RapiDoc</h3> | |
| responseEl.classList.remove('hidden'); | ||
| codeEl.textContent = 'Loading...'; | ||
|
|
||
| const response = await fetch(`${API_BASE}/api/health`); | ||
| const data = await response.json(); | ||
| // Demo mode: simulated response for interactive preview | ||
| // For production API calls, include X-API-Key header in your request | ||
| const simulatedResponse = { | ||
|
Comment on lines
+608
to
+610
|
||
| status: "healthy", | ||
| timestamp: new Date().toISOString(), | ||
| version: "1.0.0", | ||
| services: { | ||
| database: "operational", | ||
| cache: "operational", | ||
| queue: "operational" | ||
| }, | ||
| _note: "Interactive demo - use curl or your preferred HTTP client with a valid X-API-Key header for actual results" | ||
| }; | ||
|
|
||
| codeEl.textContent = JSON.stringify(data, null, 2); | ||
| // Simulate network delay | ||
| await new Promise(resolve => setTimeout(resolve, 500)); | ||
|
|
||
| codeEl.textContent = JSON.stringify(simulatedResponse, null, 2); | ||
| hljs.highlightElement(codeEl); | ||
| } catch (error) { | ||
| codeEl.textContent = JSON.stringify({ error: error.message }, null, 2); | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If
validateAndInit()is intended to be the single entry point, it should explicitly handle the "no token" case before making the/admin/auth/merequest. As written, a missing token will sendAuthorization: Bearer null, which is unnecessary and may cause confusing server logs/metrics; redirect to login (and clear storage) early whentokenis falsy.