Page MenuHomePhabricator

mw.Api.assertCurrentUser() does not work well when temporary accounts are involved
Open, MediumPublic

Description

In Wikibase, we are trying to use the mw.Api.assertCurrentUser() method to ensure that users don’t accidentally edit after logging out in another tab. However, we noticed a problem: if the user loads the page while logged out, then makes an edit that creates a temporary account for them, and then tries to make a second edit without reloading the page, assertCurrentUser() will add a parameter assert=anon, and the second API request will fail because the session is no longer anonymous.

I believe this is a general assertCurrentUser() problem that should be fixed in that method, though it currently doesn’t seem to be reproducible elsewhere: the method is used relatively rarely according to codesearch, and the issue described above doesn’t seem to be reproducible in any of the other places that use it (except maybe Wikidata Bridge, but I haven’t tried it there). Special:NewLexeme always redirects after an edit, the ConvenientDiscussions gadget can’t be used by anons, Flow disallows anonymous editing if temporary accounts are enabled, and CommunityRequests doesn’t seem to allow anonymous voting either.

Alternatively, we could work around the problem with assertCurrentUser() in Wikibase by not using it (compare the legacy desktop UI), or only using it if the user is logged in. But that would run counter to how assertCurrentUser() is supposed to be used, and it seems a shame to have a method in MediaWiki core that’s not fit for its intended purpose.

Note that, in Wikimedia production, this problem wouldn’t really occur if the API is used correctly, because the API response for any request that created a temporary account should include some kind of redirect URL to finish setting up the account in CentralAuth (compare T357020), and once the user has finished following the redirect and ended up back where they started, assertCurrentUser() will know that they’re “logged in” with a temp account, so it would no longer send the incorrect assert=anon parameter. But this only applies to wikis with CentralAuth installed (or other extensions with a TempUserCreatedRedirect hook handler), so generally speaking the assertCurrentUser() shipped by MediaWiki core still has a problem.

Details

Event Timeline

Restricted Application added a subscriber: Aklapper. · View Herald Transcript
Lucas_Werkmeister_WMDE added subscribers: kostajh, Tgr.

Not sure if there’s a good Phabricator tag for assertCurrentUser() (the Gerrit change adding it had no attached task, and T217774 was a Flow-specific issue), but CC @Tgr and @kostajh from there.

IMHO there’s no reason to assert that the user is anonymous – if the user logged in in another tab, that doesn’t leak information in the same way that logging out does. We could add a second parameter to assertCurrentUser() to control whether it asserts only logged in or all session states (boolean onlyAssertIfLoggedIn?), but given that it’s not used that frequently yet (codesearch), maybe we can get away with just changing its default behavior.

Alternative idea: add a value like assert=!user to the parameter (by analogy with rcshow’s anon/!anon – I thought we had !user somewhere in the API too but apparently I misremembered that) which would allow either IPs or temporary accounts, and make assertCurrentUser() emit that.

Change #1196402 had a related patch set uploaded (by Lucas Werkmeister (WMDE); author: Lucas Werkmeister (WMDE)):

[mediawiki/core@master] mw.Api.assertCurrentUser: Don’t add assert=anon

https://gerrit.wikimedia.org/r/1196402

Note, since I was wondering: once you have a temporary account and reload the page, assertCurrentUser() does work correctly. It sends a request like assert=user + assertuser=~2025-30, and apparently the API accepts that (i.e. assert=user seems to correspond to User::isRegistered(), not User::isNamed()).

(i.e. assert=user seems to correspond to User::isRegistered(), not User::isNamed()).

(Which suggests that my assert=!user idea above isn’t so great, because that would imply that temporary accounts fulfill both assert=user and assert=!user, which is nonsense. I guess it could be assert=!named instead, if we want to go with that approach.)

aaron triaged this task as Medium priority.Oct 16 2025, 6:54 AM
aaron moved this task from Incoming (Needs Triage) to Bugs & Chores on the MW-Interfaces-Team board.

assertCurrentUser() tries to prevent you from making an edit under a different username than what the UI implies. If the UI says the edit will be anonymous but then it goes under some logged-in username, that's still not great.

One option would be to make assertCurrentUser() not differentiate between anon and temp users (!named as you suggest). When temp users are enabled, the UI will always tell the user a temp account will be created so that can't be very misleading.

Another option would be to assert the "potential current user", which would be a temp user during an editing workflow - EditPage::getUserForPreview() has the concept of a "placeholder temp user" to be shown for edit preview, maybe that could be exposed somehow. Seems really messy though.

The third option would be to update the state assertCurrentUser() asserts against. @matmarex worked on updating some JS variables in-place after login, maybe such a capability would be useful here.