fix(login): post-#538 UX bonuses — Forgejo scope, login-loop, native logout #541
No reviewers
Labels
No labels
area:agents
area:dashboard
area:database
area:design
area:design-review
area:flows
area:infra
area:meta
area:security
area:sessions
area:webhook
area:workdir
security
type:bug
type:chore
type:meta
type:user-story
No milestone
No project
No assignees
3 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
charles/claude-hooks!541
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "fix/login-bonus-fixes"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Three small fixes the operator hit during sign-in immediately after #538 merged. Each is independent; all live tested against the production deployment today.
1.
forgejo-oauth.ts— addread:userscopeFORGEJO_SCOPES = "read:repository write:repository write:hook"— fine for repo + webhook operations but the callback'sGET /api/v1/userprofile fetch requiresread:user. Without it the operator's first sign-in attempt logged[forgejo-oauth] profile fetch failed: HTTP 403three times and bounced them to/login?error=profile_failed. Addsread:userto the scope list.Note for operators: revoke + re-grant the existing Forgejo OAuth app authorisation once after merging — Forgejo caches the prior narrower scope set on the grant.
2.
login.tsx— break the login-page-stuck loopbuildInitHrefcapturedwindow.location.pathnameas the OAuthreturnparam. When the operator was on/app/login(the natural entry point) that captured path WAS/app/login, so the callback redirected back to the login page after a successful sign-in and the SPA stayed put. Falls back to/when the current path is the login surface; deep-link semantics preserved everywhere else. Drops thetypeof window === "undefined"SSR-defence cruft — this is a pure-client SPA, no SSR.3.
app-shell.tsx+useFlowAuth.ts— native logout buttonThe header logout link relied on
cfg.auth.authelia_logout_urlexposed via/whoami. With the Authelia layer ripped on the proxy side earlier today (proxmox-iac/services/caddy/.../Caddyfile.j2), that field is dead — clicking Logout did nothing. Replaces the anchor with<form method="POST" action="/logout">+ a styled submit button — hits the existing session-clear endpoint that already 302s back to/login. Dropslogout_urlfrom theWhoamiResponseshape in bothAppShellanduseFlowAuth.4.
__root.tsx— bidirectional/whoamiredirectExtends the mount-time probe added in #538 so it also redirects "authed + on the login page →
/". Mirrors fix #2 on the SPA side: even if the operator lands on/app/loginwhile already authed (back button, bookmark, stale tab), they get bounced to the dashboard instead of staring at the login form. Uses TanStack'suseNavigateto keep router state.Verification
bun run typecheckclean/app/monitorafter sign-in/login/app/loginwhile authed redirects to/Test plan
forge.jacquin.app/user/settings/applications, re-grant viaSign in with Forgejobutton, confirm dashboard rendersoperator_sessionsis gone and cookie is clearedOut of scope
/api/*boundary refactor (closed PR #539, will reopen as a separate issue)auth.authelia_logout_urlschema removal (#540 covers the bigger config split)auth.operator_user/auth.trust_proxypost-Authelia (separate audit)Reviewer concern verified — no regression
Reviewer flagged the unconditional
__root.tsx/whoamiprobe as a potential test-breaker. Ran the full suite with the test bypass set:The 4 fails are pre-existing on
main, all unrelated to the PR:session JSONL pruning > …(FS / time-based)foreman session CRUD > listSessions returns newest-first …(timing)No
__root.tsx//whoamitest broke. Probe runs at component mount; tests that don't render the SPA root never fire it.Web suite (
bun x vitest runinapps/web) has the sametheme-toggle.test.tsx+theme.test.tslocalStorage.clear is not a functionflake we've been seeing onmainsince this morning — also pre-existing.Verdict: ready to merge once a human gives the LGTM. Reviewer comment thread is resolved by verification rather than a code change.
Scope and correctness all check out. CI green.
read:userscope addition is the right fix; profile fetch on/api/v1/useralways required it.login.tsxand mirror redirect in__root.tsxare consistent — same threeisLoginPathconditions in both places.<form method="POST" action="/logout">is cleaner than the dead Authelia URL anchor;data-testidpreserved.logout_urlremoval fromWhoamiResponsein bothapp-shell.tsxanduseFlowAuth.tsis clean.Nit (non-blocking):
routeTree.gen.tscarries an unexplained settings-route rename (SettingsRoute→SettingsIndexRoute) not mentioned in the PR description — looks like a generated-file side-effect of unrelated route restructuring. Harmless.