-
Notifications
You must be signed in to change notification settings - Fork 10
Dev #12
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
Dev #12
Changes from all commits
49bdb9a
ef6354c
f8a2e99
6b0548e
3419589
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 | ||||
|---|---|---|---|---|---|---|
|
|
@@ -68,7 +68,7 @@ <h1 class="text-xl font-bold text-gray-800 flex items-center gap-2"> | |||||
| <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" | ||||||
| d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" /> | ||||||
| </svg> | ||||||
| <span>SimpleAudit Scenario Viewer</span> | ||||||
| <a href="/" class="hover:underline text-indigo-700">SimpleAudit Scenario Viewer</a> | ||||||
|
||||||
| <a href="/" class="hover:underline text-indigo-700">SimpleAudit Scenario Viewer</a> | |
| <span class="text-indigo-700">SimpleAudit Scenario Viewer</span> |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -13,6 +13,14 @@ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| app = FastAPI(title="SimpleAudit Visualizer") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # read secret from environment variable; if blank, authentication is disabled | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| SECRET = os.getenv("SIMPLEAUDIT_VISUALIZER_SECRET", "") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # contact email that will be shown in the frontend when auth is enabled; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # this mirrors the behaviour of the secret variable. if not set we fall | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # back to the historical default address. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| CONTACT_EMAIL = os.getenv("SIMPLEAUDIT_VISUALIZER_EMAIL", "sushant@simula.no") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Global variable to store results directory | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| RESULTS_DIR = None | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -103,7 +111,7 @@ async def root(): | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| with open(html_path, "r", encoding="utf-8") as f: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| content = f.read() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return HTMLResponse(content=content) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -135,7 +143,41 @@ async def favicon(): | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return FileResponse(favicon_path, media_type="image/png") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| @app.get("/api/files") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # --- authentication helpers ------------------------------------------------ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| from fastapi import Request, Depends, status | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| def check_secret(request: Request): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| """Raise HTTP 401 if a secret is configured and the request does not | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| provide the correct value in an X-Secret header. When no secret is | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| configured the check is a no-op. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| """ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if not SECRET: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| token = request.headers.get("X-Secret") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if token != SECRET: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Unauthorized") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+155
to
+159
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| @app.get("/api/auth") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| async def auth_check(request: Request): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| """Endpoint used by the frontend to verify a key and learn if auth | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| is enabled. When the server has no secret configured it still | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| returns 200 but sets ``enabled`` to False. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| The response also includes ``contact_email`` which is read from the | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ``SIMPLEAUDIT_VISUALIZER_EMAIL`` environment variable and defaults | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| to the original maintainer address. The frontend uses this to | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| populate the authentication overlay message. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| """ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| try: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| check_secret(request) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| except HTTPException as exc: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # propagate unauthorized status | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| raise | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+172
to
+176
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| try: | |
| check_secret(request) | |
| except HTTPException as exc: | |
| # propagate unauthorized status | |
| raise | |
| check_secret(request) |
Copilot
AI
Apr 20, 2026
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.
/api/auth returns HTTP 401 when the secret is missing/invalid, which prevents the frontend from reading contact_email (and even enabled) from the response. This makes the SIMPLEAUDIT_VISUALIZER_EMAIL override ineffective when the overlay is shown. Consider returning a 200 with a JSON payload like {enabled: true, ok: false, contact_email: ...} for missing/invalid secrets (or include contact_email in the 401 body and have the client parse it).
| is enabled. When the server has no secret configured it still | |
| returns 200 but sets ``enabled`` to False. | |
| The response also includes ``contact_email`` which is read from the | |
| ``SIMPLEAUDIT_VISUALIZER_EMAIL`` environment variable and defaults | |
| to the original maintainer address. The frontend uses this to | |
| populate the authentication overlay message. | |
| """ | |
| try: | |
| check_secret(request) | |
| except HTTPException as exc: | |
| # propagate unauthorized status | |
| raise | |
| return JSONResponse(content={"ok": True, "enabled": bool(SECRET), "contact_email": CONTACT_EMAIL}) | |
| is enabled. It always returns 200 so the frontend can read both | |
| ``enabled`` and ``contact_email`` even when the secret is missing | |
| or invalid. | |
| The response also includes ``contact_email`` which is read from the | |
| ``SIMPLEAUDIT_VISUALIZER_EMAIL`` environment variable and defaults | |
| to the original maintainer address. The frontend uses this to | |
| populate the authentication overlay message. | |
| """ | |
| enabled = bool(SECRET) | |
| token = request.headers.get("X-Secret") | |
| ok = (not enabled) or (token == SECRET) | |
| return JSONResponse( | |
| content={ | |
| "ok": ok, | |
| "enabled": enabled, | |
| "contact_email": CONTACT_EMAIL, | |
| } | |
| ) |
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.
This README states that setting
SIMPLEAUDIT_VISUALIZER_EMAILwill change the contact email shown in the auth overlay, but with the current/api/authbehavior returning 401 for missing/invalid secrets, the frontend can’t readcontact_emailwhen the overlay is shown. Either adjust the API/frontend so the email is available pre-auth, or update the docs to match the actual behavior.