Flow
Route pipeline with reject points
1POST only
A GET is refused before anything is read.
2Find the public address
In production with none set, it stops with an error.
3Check where it came from
A request from another site is refused, and nothing is deleted.
4Find the user
The normal session check first, then a direct token lookup. No user means nothing to delete.
5Audit, then delete
Both in one try block, audit first. If the audit write fails, the delete is skipped.
6Clear cookie, redirect
This runs either way, and the login page says signed out everywhere.
Flow
Requests worth testing, and what should happen
None of these tests exist yet. This is the list I'd start from.
1A GET to the route
Refused, and no session is touched.
2A POST marked as coming from another site
Refused, and every session is still there.
3A POST from the public address, through the real proxy
Accepted. If it's refused, the list of trusted addresses is missing the public one.
4A POST from a sibling subdomain with no Origin header
Accepted today. Decide on purpose whether it should be.
5A POST where the delete fails
The login page should not say everywhere. Today it does.
6An old cookie used after a real sign-out
Should be refused by a protected page. That's what shows the sessions are really gone.
The new "sign out on every device" button in my admin dashboard can say it worked when it didn't. I found that by reading my own diff back after I committed it.
How the button works
The button is a plain form that posts to a new route. The route does this, in order:
- It refuses a GET, so a link or a page preview can't set it off.
- It needs a public address in its settings for the redirect. With none set in production, it stops with an error.
- It refuses a request the browser marks as coming from another site.
- It reads your cookie, finds out who you are, writes an audit entry, and deletes all your sessions.
- It clears your cookie and sends you to the login page with a "signed out everywhere" note.
The cheap checks run first, before any stored data is read. That part is good.
When the delete gets skipped
The audit entry and the delete sit inside one try block, and the audit entry goes first. If writing it fails, the delete is skipped. The error gets logged by type, and the code still clears your cookie and shows the "everywhere" note. A failed delete ends the same way.
So the browser you used is signed out. Your phone and laptop may not be, and the page tells you they are. That's the one thing this button must not get wrong, because people press it when they're worried someone else is in their account.
If your cookie had already expired, nothing gets deleted and you still see "everywhere". That's mostly harmless, but it shows the note only means the route finished.
The audit gap
If the normal session check finds no one, the route looks your token up directly and still deletes your sessions. Good. But it only writes an audit entry when the normal check worked, so that path leaves no record.
A looser origin check
The same change let the existing sign-out route accept a few configured public addresses, not just the host the request arrived on, and gave the new route the same check. A reverse proxy probably made the hosts differ, so a real click could have been refused. I can't prove that from what I have.
The check still has soft spots. It ignores the scheme. With no Origin header, it accepts requests from sibling subdomains. And it's copy-pasted into both routes, so they can drift apart.
The redirect can't be steered
The login address comes from settings, never from the request, so nobody can steer it.
What I'd change
Delete the sessions first, log second, and give the login page a separate "this device only" message for when the delete fails. I haven't made those changes yet, and there's no test.