-
Notifications
You must be signed in to change notification settings - Fork 1.1k
fix(gui): never ask a local dashboard for an admin token #3496
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
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 |
|---|---|---|
| @@ -1,6 +1,13 @@ | ||
| import { promptForAdminToken, type AdminTokenVerifier } from "./admin-token-dialog"; | ||
| import { createBoundedFetch } from "./bounded-fetch"; | ||
| import { standaloneApiTargets, type ApiPlane, type ApiTarget, type ApiTargets } from "./api-targets"; | ||
| import { adminTokenPromptAllowed, standaloneApiTargets, type ApiPlane, type ApiTarget, type ApiTargets } from "./api-targets"; | ||
|
|
||
| /** | ||
| * Fired instead of the admin-token prompt when the dashboard cannot start a session on a | ||
| * deployment that has no admin token to type. The shell renders it as a notice; nothing | ||
| * blocks on it. | ||
| */ | ||
| export const SESSION_UNAVAILABLE_EVENT = "opencodex:session-unavailable"; | ||
|
|
||
| const LEGACY_TOKEN_KEY = "opencodex-api-token"; | ||
| const ADMIN_TOKEN_VALIDATION_PATH = "/api/settings"; | ||
|
|
@@ -35,6 +42,18 @@ let rebootstrapTimeoutMs = SESSION_REBOOTSTRAP_TIMEOUT_MS; | |
| let resolutionWatchdogMs = RESOLUTION_WATCHDOG_MS; | ||
| const runtimes = new Map<ApiPlane, TargetRuntime>(); | ||
|
|
||
| function reportSessionUnavailable(plane: ApiPlane): void { | ||
| if (typeof window === "undefined") return; | ||
| // Take the constructor off the same window we dispatch on: a test harness (and a | ||
| // sandboxed embed) can supply a document without installing CustomEvent globally. | ||
| const Ctor = (window as unknown as { CustomEvent?: typeof CustomEvent }).CustomEvent | ||
| ?? (typeof CustomEvent === "function" ? CustomEvent : null); | ||
| if (!Ctor) return; | ||
| try { | ||
| window.dispatchEvent(new Ctor(SESSION_UNAVAILABLE_EVENT, { detail: { plane } })); | ||
| } catch { /* a shell that cannot receive the notice must not break the fetch path */ } | ||
| } | ||
|
|
||
| function blankSession(): ApiSessionState { | ||
| return { token: null, csrfToken: null, browserOrigin: null, serverOrigin: null }; | ||
| } | ||
|
|
@@ -258,6 +277,14 @@ async function resolveTokenAfter401(plane: ApiPlane, failedToken: string | null, | |
| ]).finally(() => clearTimeout(watchdog)); | ||
| if (renewed.kind === "minted") return renewed.token; | ||
| if (renewed.kind === "failed") return null; | ||
| // A non-hub deployment has no admin token the user could supply: the server mints the | ||
| // session itself, so a refusal is a Host/Origin misconfiguration. Surface that instead | ||
| // of a password box the user cannot answer (#3353, #3483). | ||
| if (!adminTokenPromptAllowed()) { | ||
| state.promptCancelled = true; | ||
| reportSessionUnavailable(plane); | ||
|
Comment on lines
+283
to
+285
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
When a connected client's shared hub session expires or renewal is refused, the document was served by AGENTS.md reference: gui/AGENTS.md:L9-L10 Useful? React with 👍 / 👎. |
||
| return null; | ||
| } | ||
| const prompted = await requestAdminToken(token => verifyAdminToken(plane, token)); | ||
| if (prompted) { | ||
| state.session = { token: prompted, csrfToken: null, browserOrigin: null, serverOrigin: state.target.serverOrigin }; | ||
|
|
||
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.
For the standalone Host/Origin-mismatch path introduced here, this event is the only replacement for the removed admin-token prompt, but no production module in the commit subscribes to
SESSION_UNAVAILABLE_EVENTor its literal event name. Thus the advertised actionable notice is never displayed; users only see unrelated page-level load failures and still receive no explanation of how to correct the dashboard address. Add a shell listener that renders a translated, accessible notice and cover the rendered result rather than merely asserting that an event fired.AGENTS.md reference: gui/AGENTS.md:L14-L18
Useful? React with 👍 / 👎.