fix(auth): stop erasing a reset link the signed-in tree never reads (E9.5 review round 4)

Round 4 came back converged — nothing above low, and both findings in one family. This is the half
worth fixing, because the branch introduced it.

Only the signed-out auth card consumes a `#reset=` token, and S2 moved the address-bar cleanup up to
a hook App mounts unconditionally. So opening a password-reset link in a browser that already holds a
session erased the token from the URL while nothing had read it: the page loads, nothing is said, and
clicking the link again does exactly the same, because the token is untouched and the session is
still there. That is the dead end this epic exists to remove, and `main` did not have it — the strip
used to live inside the card, which a signed-in visitor never renders.

An unspent reset fragment now stays, which restores the recovery that shape always had: signing out
reloads with the fragment intact and the form is waiting. Once the card has spent the token a later
reload meets S4's named dead-link screen, which is true. The affirmative version — a banner telling a
signed-in visitor that reset links open in a signed-out window — is logged with DX-15, along with the
`hashchange` half that still only recognises `#verify=`.
This commit is contained in:
2026-09-04 23:14:46 +02:00
parent 3dc14402b0
commit a03bf8d371
3 changed files with 30 additions and 6 deletions
+3 -2
View File
@@ -52,8 +52,9 @@ export function useVerifyEntry(): VerifyEntry {
}, []);
useEffect(() => {
// Clear the address bar even with no token to consume: a `#reset=` fragment opened in a
// signed-in browser is equally spent, and leaving either in history re-sends it on a reload.
// Clear the address bar even with no token to consume, so a spent one leaves no trace on a
// reload. An unspent `#reset=` is the exception and `clearEntryUrl` says why: nothing in a
// signed-in tree reads it, so erasing it there is a dead end rather than a cleanup.
clearEntryUrl();
if (!token || consumed.current.has(token)) return;
consumed.current.add(token);