Page MenuHomePhabricator

Provide a JavaScript library for logging in / signing up to MediaWiki via a popup
Closed, ResolvedPublic

Description

T362706: Permit displaying the login / signup page in a popup or iframe adds the ability to do the login / signup flow inside a popup window. One use case for this is "asynchronous login": you are prevented in some workflow (e.g. trying to save an edit) because you are not logged in, maybe because your session just expired; the UI detects this and offers a login button, which opens a popup with a login screen, and after successful popup, the UI updates accordingly.

In practice this means:

  • Provide a convenience Javascript method for opening a login or signup popup (which should be fairly straightforward, but we don't want to force callers to hardcode things like window size, so it's better to centralize it)
  • Skip post-login/signup output that's not meant for a popup window (UserLoginComplete, BeforeWelcomeCreation, PostLoginRedirect; possibly / CentralAuthPostLoginRedirect although that's going to be more tricky because sometimes the redirect is used for data transfer, not UI purposes).
  • Somehow (postMessage?) communicate back the result of the process to the method that initiated the popup. Maybe also things like the PostLoginRedirect URL or the BeforeWelcomeCreation HTML snippet.

This might also be a good time to do something about the CentralAuth feature of updating the personal toolbar after a successful autologin: either migrate it to core and provide a proper extension point for affected features (like the Echo notification badges), or kill it and alwayws request a reload. (See T245441, T122652.)

We can probably merge T71596: Provide JavaScript login widget into this.

Event Timeline

Restricted Application added a subscriber: Aklapper. · View Herald Transcript
matmarex renamed this task from Provide a Javascript library for logging in / singing up to Media via a popup to Provide a JavaScript library for logging in / signing up to MediaWiki via a popup.May 14 2024, 10:40 PM

Change #1031120 had a related patch set uploaded (by Bartosz Dziewoński; author: Bartosz Dziewoński):

[mediawiki/core@master] [WIP] JavaScript login popup

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

I've been looking for a place to integrate this as a demonstration.

MediaWiki-extensions-Translate is an obvious candidate, with the task T72122 asking for this being filed 10 years ago ;)

ContentTranslation actually includes a very similar, but simpler feature: https://gerrit.wikimedia.org/g/mediawiki/extensions/ContentTranslation/+/bfad76098338c5016369808efdbbcc38547f7bed/modules/ui/mw.cx.ui.LoginDialog.js

VisualEditor has an error message for this case, a button to launch the new popup would probably fit well there: https://gerrit.wikimedia.org/g/mediawiki/extensions/VisualEditor/+/22e6758092525d90d71f9b6e92c22233bfbab45f/modules/ve-mw/init/targets/ve.init.mw.ArticleTarget.js#869

I'm hoping someone maintaining one of these tools volunteers. If not, I will probably write an unsolicited patch or two myself.

In practice this means:

  • Provide a convenience Javascript method for opening a login or signup popup (which should be fairly straightforward, but we don't want to force callers to hardcode things like window size, so it's better to centralize it)

While this can be as simple as window.open( mw.util.getUrl( 'Special:UserLogin' ) ), doing it well requires IMO two additional features that we definitely want to centralize:

  1. Handle the case where the popup is blocked, by displaying a message in the original tab and providing a link to the normal login form. The library would ideally also recognize when the user logs in in the background using the normal login form.
  2. Handle the case where the user closes the popup without logging in, or switches back to another window and loses track of it. The library should give them a way to retry, and ideally it would also avoid leaving behind forgotten browser popup windows.

I'm doing this using a message dialog shown in the original window that serves as a "backdrop" for the browser popup window.

  • Skip post-login/signup output that's not meant for a popup window (UserLoginComplete, BeforeWelcomeCreation, PostLoginRedirect; possibly / CentralAuthPostLoginRedirect although that's going to be more tricky because sometimes the redirect is used for data transfer, not UI purposes).
  • Somehow (postMessage?) communicate back the result of the process to the method that initiated the popup. Maybe also things like the PostLoginRedirect URL or the BeforeWelcomeCreation HTML snippet.

I think we can do this by just setting the returnto parameter to a page that will communicate back. MediaWiki will run whatever hooks it wishes and then redirect to our page, which will close itself. (Coincidentally, this is also how OAuth popups commonly work.)

This might also be a good time to do something about the CentralAuth feature of updating the personal toolbar after a successful autologin: either migrate it to core and provide a proper extension point for affected features (like the Echo notification badges), or kill it and alwayws request a reload. (See T245441, T122652.)

I think this out of scope for this task, as here we mostly want the popup in a case where the personal toolbar and the rest of the interface already reflects a logged-in user, it's only the cookies that got out of date and need to be refreshed.

It would be nice for T364941, but we can probably get away with just reloading the page. We should discuss it in that task.

Based on the design review, would it make sense to also add an iframe-in-a-modal version?

On the one hand, for wikis which are on a single second-level domain, the cookie-handling-related benefits of a popup don't exist, and a modal is much nicer UX.

On the other hand, currently we disallow opening the login page in an iframe, even if the parent is same-origin; it can be used to elevate an XSS into password theft via clickjacking. (See T255881 and related tasks.)

Based on the design review, would it make sense to also add an iframe-in-a-modal version?

On the one hand, for wikis which are on a single second-level domain, the cookie-handling-related benefits of a popup don't exist, and a modal is much nicer UX.

On the other hand, currently we disallow opening the login page in an iframe, even if the parent is same-origin; it can be used to elevate an XSS into password theft via clickjacking. (See T255881 and related tasks.)

I agree that a modal would be a good alternative to a popup, since plenty of users probably have popups blocked by default, and a modal would be a bit nicer than the fallback provided in the patch. But do we need to have an iframe involved?

The alternative would be to basically reimplement the login page in JS. The clientlogin API provides basic information on what fields are needed, but it's pretty barebones (e.g. the captcha field is just a link to the image). On the server side, some of the formatting is added via the AuthChangeFormFields hook, which relies on HTMLForm descriptors, which cannot be processed on the frontend.

(…), since plenty of users probably have popups blocked by default, (…)

I doubt that this is the case. If anything, browser popup windows are probably more reliable than a few years ago. The HTML spec now specifies when you're allowed to open them (basically, only in response to a user action, like clicking a button): https://developer.mozilla.org/en-US/docs/Web/Security/User_activation#transient_activation. Ad blocker extensions now mostly focus on blocking elements within the page. There are probably still some obscure settings deep in browser preferences to block them all by default, but I would expect very few people to use them.


The proposed library now has both a popup and an iframe mode (plus a fullscreen window mode too), to be experimented with.

Change #1031120 merged by jenkins-bot:

[mediawiki/core@master] Add library to display the login form in a JavaScript modal dialog

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

Change #1037200 had a related patch set uploaded (by Bartosz Dziewoński; author: Bartosz Dziewoński):

[mediawiki/core@master] Add JSDoc for mediawiki.authenticationPopup module

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

Change #1037200 merged by jenkins-bot:

[mediawiki/core@master] Add JSDoc for mediawiki.authenticationPopup module

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