Skip to content

feat(ui): add sign out and stop the idle dialog offering re-authentication - #28

Merged
yashau merged 1 commit into
mainfrom
claude/ui-sign-out
Aug 20, 2026
Merged

feat(ui): add sign out and stop the idle dialog offering re-authentication#28
yashau merged 1 commit into
mainfrom
claude/ui-sign-out

Conversation

@yashau

@yashau yashau commented Aug 20, 2026

Copy link
Copy Markdown
Owner

Why

The idle dialog offered Reload and re-authenticate beside Carry on, which read as an identity check you were allowed to wave off. It wasn't one. The watcher wipes every revealed value before raising its flag, so by the time the dialog mounts the values are already gone and neither button can bring them back. Access owns the identity check, its session is measured in hours, and the app had no sign out to pair a sign-in with — so the reload was theatre.

What changed

The dialog is now a notice with one Continue. Copy drops the "confirm you are still you" framing; the only cost of continuing is revealing again, and it now says so.

Dismissal moves to onOpenChange, replacing the escapeKeydownBehavior/interactOutsideBehavior "ignore" pair. open is driven by the store, so a close Bits performed on its own left the flag set and the dialog wedged — routing every close through resume() keeps the two in step, and a notice with nothing to decide should take Escape for an answer.

Signing out becomes a deliberate act, in the sidebar footer. The viewer button is now a dropdown (same idiom as project-switcher) carrying the address as a heading and a Sign out item pointing at Cloudflare's /cdn-cgi/access/logout.

Three things worth a reviewer's attention:

  • data-sveltekit-reload is load-bearing. The path is same-origin, so the router would otherwise claim the click and look for a route that doesn't exist. The endpoint is served at the edge and never reaches the Worker, so it has to be a real document request.
  • Logout is team-wide, not per-app. Cloudflare is explicit that there's no per-application logout; this revokes the session across every Access app in the team, and issued tokens keep working for another 20–30 seconds.
  • Service tokens get a disabled item saying they hold no session, rather than a button that would do nothing — they authenticate per request with a client id and secret, so there's no cookie to clear.

Verification

  • mise run lint:js, fmt:check:js, lint:typos, lint:loc — green
  • svelte-check — 2158 files, 0 errors, 0 warnings
  • App unit tests — 34 files, 1152 passed
  • pre-push gate (typecheck, clippy, rust + js tests) — green

Not verified by me: that Entra lands on its account picker rather than a password prompt when several accounts are signed in. That's the motivating use case and it's asserted in a code comment, but confirming it needs a real sign-out against the live instance. There's also no documented returnTo on the logout endpoint, so you land on Cloudflare's own logout page rather than back here.

🤖 Generated with Claude Code

…ation

The idle dialog offered "Reload and re-authenticate" beside "Carry on", which
implied dismissing it skipped a security step. It never did: the watcher wipes
every revealed value BEFORE raising the flag, so by the time the dialog mounts
the values are already gone and neither button can bring them back. Access owns
the identity check, its session is measured in hours, and the app had no sign
out to pair a sign-in with -- so the reload was theatre. It is now a single
"Continue".

Dismissal also moves to `onOpenChange`, replacing the escape/interact-outside
"ignore" pair. `open` is driven by the store, so a close Bits performed on its
own left the flag set and the dialog wedged.

Signing out becomes a deliberate act instead, in the sidebar footer: the viewer
button is now a dropdown carrying the address and a Sign out item pointing at
Cloudflare's `/cdn-cgi/access/logout`. Notes for the reader:

- `data-sveltekit-reload` is load-bearing. The path is same-origin, so the
  router would otherwise claim the click and look for a route that does not
  exist; the endpoint is served at the edge and never reaches the Worker.
- Logout is team-wide, not per-app, and issued tokens stop being accepted after
  20-30 seconds. Entra keeps its own session, so signing back in lands on its
  account picker -- which is the point, since switching account is the reason to
  reach for this.
- A service token has no cookie to clear, so it gets a disabled item saying so
  rather than a button that would do nothing.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@yashau
yashau merged commit 47f14b4 into main Aug 20, 2026
16 checks passed
@yashau
yashau deleted the claude/ui-sign-out branch August 20, 2026 14:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant