Page MenuHomePhabricator

Replace 'editToken' from mw.user.tokens by 'csrfToken' in on-wiki gadgets
Closed, ResolvedPublic

Description

Event Timeline

DannyS712 subscribed.

Such a request should be made onwiki - its a request for edits. It would probably be in the scope of global interface editors, so posting at https://meta.wikimedia.org/wiki/Steward_requests/Miscellaneous should work. In the future, I suggest that such user-facing removals be announced on tech news, but there is nothing that can be done about it now

Information about how to update the code is available at:
https://www.mediawiki.org/wiki/ResourceLoader/Migration_guide_(users)#user.tokens_editToken

As a reminder, it is ultimately the community's responsibility to look after their gadgets. This is an extremely powerful feature, allowing execution software code without review or oversight. There are currently no limitations of any kind to what a gadget can do. As such, they receive no support from MediaWiki developers. If they were supported, they wouldn't need to be gadgets (given our open code review systems etc.). If a gadget has no active volunteer maintaining it, it cannot exist.

Having said that, as volunteer Interface editor I did personally fix 1000+ scripts across the wikis this month to prepare for the removal of mw.tokens.get('editToken'). The search query in this taks' description is actually too generic and does not represent broken gadgets. For example code like page.edittoken, getElementById( 'EditToken' ), editToken: null is unrelated to this week's change and continues to work fine.

A better query is https://tools.wmflabs.org/global-search/?q=tokens.*get.*%5B%27%22%5DeditToken%5B%27%22%5D&regex=1&namespaces=8.

There's only a dozen search results left, which are cases I was unable to fix. For example, because the script contains invalid syntax (hence not passing syntax check before nor after my would-be edit, but still matching the search query), or because the wiki has unwelcoming abusefilters that reject my edits, or because the wiki is a fishbowl (like idwikimedia).

Can you be more specific about which gadgets were affected in a way that was actually noticed/reported by end-users?

@Krinkle I had been following this, but didn't easily associate it with the failures of the https://en.wikinews.org/wiki/Help:Dialog feature on enwikinews; see edit request made at https://en.wikinews.org/wiki/MediaWiki_talk:Common.js/Wikinews:Dialog/do - was this one of the sites that abuse filters prevented you from fixing?

@Krinkle I had been following this, but didn't easily associate it with the failures of the https://en.wikinews.org/wiki/Help:Dialog feature on enwikinews; see edit request made at https://en.wikinews.org/wiki/MediaWiki_talk:Common.js/Wikinews:Dialog/do - was this one of the sites that abuse filters prevented you from fixing?

This page was missed due the search being restricted to pages of type "JavaScript". However this page is using an uncommon way of storing the JavaScript, as subpage without ending in .js. It also does not have its content model set to JS by other means (e.g. Special:ChangeContentModel).

While it is possible to load any page (e.g. [[Wikipedia:Sandbox]]) as JavaScript via importScript(), the seach tool I use only looks at pages with JavaScript as their indicated content type.

Say that developers don't manage scripts and users are responsible for keeping them working in theory, but I haven't seen the information pass through Tech News or elsewhere (maybe I just missed it) and thus maintainers was not able to do the update. It should also be noted for example that we are volunteers, and that overnight the creator of the script can disappear, leaving users alone in the face of change. "Gadgets receive no support from MediaWiki developers" would work mostly for commercial products, here we are talking about a community of volunteers, and I don't think that can be applied to that.
I think that any such important API modification must take into account a part of updating existing gadgets, in the process of being able to mark a task as resolved.
If you have done that for our case, thank you very much!
To answer about breakings I've seen, I can note https://fr.wikipedia.org/wiki/Discussion_Projet:JavaScript#xpatrol.js_:_Vous_n'%C3%AAtes_plus_connect%C3%A9, and after that the change was discovered here, seeing in whitelist updates of my scripts by sysops.

I'm well aware that we are volunteers, I spend a good portion of me time in that capacity on our wikis. The bottom line is: Gadgets are created without oversight by volunteers. Developers or WMF have no input on what they do, how they do it, or how many thousands of gadgets will exist at any point in time. I think it is fair to expect those same volunteers to also be responsible for looking after it.

When major changes happen to documented parts of the JavaScript interface of MediaWiki, these changes are announced. However, when a gadget author reaches into an internal part of the software and repurposes it for something it wasn't designed for, and does so without asking what the supported way of doing this is in a gadget on Phabricator, then that same part may also change without notice by developers. It's a two-way system. This is done on purpose. As a volunteer, I would not want to have to ask for permission before using an unofficial part of the software for my own purposes. Even if something is not officially possible, I creatively find a way unofficially to make my gadgets work. But that also means it will stop working at some point, and then until I have time to think of another creative way, it will not work.

We make hundreds of changes every week. Anyone using mw.Api#getToken('edit') in their gadget did not have to make changes because that is a publicly documented method that will continue to work. The change to mw.user.tokens seemed to me like it was not worth announcing through Tech News, as it is mainly an internal feature for use by mediawiki.api. Looking at the search results, it had only a handful of uses left after I ran my script-fixer bot.

I'm glad to see the frwiki user script was fixed. To reduce risk of changes in the future, my advice would be to only use public methods from https://doc.wikimedia.org/mediawiki-core/master/js/ and to make the user script an official gadget in the MediaWiki-namespace. Anything in the User space or that uses non-official methods, can change at any time.

When that happens, you can use https://www.mediawiki.org/wiki/ResourceLoader/Migration_guide_(users) where you'll probably find the cause and an advice from me on how to fix it. If that still doesn't help, always welcome to create a task on Phabricator again, no problem :)

Just to mention the "de facto" documentation hadn't been updated.

Also, although it was obsolete for 3 years, it seems that the communities didn't get any notification of the deprecation. So, it could have been obsolete for 10 years, there would have been the same issue.
No biggie, just to point out there was a communication issue here.

Great explanation by Krinkle above, in particular the following:

Anyone using mw.Api#getToken('edit') in their gadget did not have to make changes because that is a publicly documented method that will continue to work.

… and even better, there is the getEditToken() method :)
(simpler, and doesn't rely on the mapLegacyToken)

Just to mention the "de facto" documentation hadn't been updated.

Thanks, now updated. Note that this page is not a signal of support per-se. Many internal functions have ended up documented there, were added by volunteers (including yourself) – to share with others what they have found in the internal code. That's useful, but doesn't always mean it is supported or will get notified of changes. Public supported functions are documented at doc.wikimedia.org and marked as such in the code.

I have spent some time earlier this week, removing many outdated portions of that page. I am unsure what to do with the page long-term as I do find it useful myself as well. But I want to avoid confusion about what it means. Ideas welcome :)

FWIW I imagine folks will continue to use mw.user.tokens where possible because it's just plain easier

@Krinkle:

  • If I documented something private/internal that should be by mistake, as it's something I would like to avoid too. Maybe you found an example of this?
  • Indeed I have noticed your maintenance work on this page (amongst all the rest of course). That's very appreciated.

@Amorymeltzer:

  • Yes I just found out getToken() is async… much less appealing to use.

Ok, I got the point of, basically, not duplicating the API documentation into the page ResourceLoader/Core modules, and just making the latter link to the former. Entirely agree with this.