feat(ui): add sign out and stop the idle dialog offering re-authentication - #28
Merged
Conversation
…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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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 theescapeKeydownBehavior/interactOutsideBehavior"ignore"pair.openis driven by the store, so a close Bits performed on its own left the flag set and the dialog wedged — routing every close throughresume()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-reloadis 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.Verification
mise run lint:js,fmt:check:js,lint:typos,lint:loc— greensvelte-check— 2158 files, 0 errors, 0 warningsNot 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
returnToon the logout endpoint, so you land on Cloudflare's own logout page rather than back here.🤖 Generated with Claude Code