Account creation user experience/Engineering/Experiment

From mediawiki.org
This describes the experiment that modified "Create account" for new users of English Wikipedia by adding JavaScript code to Extension:E3Experiments that modified the page appearance and behavior. The experiment has been running since late in 2012.

Out-of-scope[edit]

  • logged-in users creating accounts — only anonymous users are candidates for the experiment
  • users without JavaScript — E3 experiments "bucket" users in JavaScript code
  • variations of account creation that aren't enabled in En-wiki's specific configuration
  • It's even OK to fail in various edge cases on en-wiki TBD.

Front-end API[edit]

  • Ensure that API conforms to WMF JavaScript guidelines and effectively uses jQuery over the DOM API for consistency and cross-browser compatibility
  • Validate if username exists (-> server-side API call)
  • Research real-time username checking in accordance with our Username Policy (e.g. check for notable names, usage of the word "bot," etc.)
  • Validate that password meets requirements. This is just:
    • check length against $wgMinimalPasswordLength server variable which is 1 on En-wiki.
      The existing server message is 'passwordtooshort' => 'Passwords must be at least $1 characters.' (Surely should be singular "Password must be..."? Or could just show 'Password is too short' until user types enough?
    • check that password is different from username.
      The existing server message is 'password-name-match' => 'Your password must be different from your username.'
  • DECIDE: do we bother with a client-side password strength meter, when 'a' is a valid password?
  • Validate that "Retype password" field matches
    The existing server message is 'badretype' => 'The passwords you entered do not match.'
  • Validate if email is valid
    • Note client-side code is already provided a JavaScript mw.util.validateEmail() function.
  • Do not store password length or any other security configuration variables to window, add it to the mw API.
  • Insert CAPTCHA into the correct location
    • Captcha is in a div class="captcha", but it's also full of the text from fancycaptcha-createaccount, and this is not in an enclosing divi and is not just about the captcha. Instead it's a random set of
      • div quotebox with the Username policy
      • bolded paragraph about register and benefits
      • info about username and password
      • paragraph about
      • unordered list about the fancy captcha
    • then the div class="captcha" has
      • an unidentified p with the captcha image
      • a hidden input field need this
      • a p with the wpCaptcha text field need this and its label (which is why it doesn't align properly, the rest of the form is in table cells)
    • Maybe there's a way to get the acux_1 experiment to pull in a different, much simpler message, like acux_1-createaccount, the way that Extension:CustomUserSignup worked when it first try to load customusertemplate-campaign-signupstart. But it would still be in the wrong order.

.
Bug: In Firefox, the CAPTCHA input field remembers previous entries, even though it has autocorrect="off" attributes.

Issues[edit]

If the AJAX-y thinks the form isn't acceptable, should it disable [Create account] or allow the user to submit anyway?

  • it could be wrong about acceptability
  • if client-side warns that password is weak, but En-wiki accepts a single-character password, should allow submission despite warning.
  • Need English validation strings for front-end validation. The server-side validation messages seem to be in languages/messages/MessagesEn.php , ACUX can reuse them or use its own strings.
  • Need list of server-side error strings to rewrite into more friendly English, if any. (perhaps these could be overridden with special MediaWiki:acux_original message messages, as the Account Creation Improvement Project extension did).

Deferred features[edit]

  • If you enter "john", with current signup MW will actually create username "John" and welcome "John".
    • StevenW says: OK to leave current behavior. In future iteration may provide heads up: your actual username will be John feedback.
    • Note Akshay Agarwal has added this to Extension:SignupAPI's validate API (see IRC log)
  • No server API for validating passwords.
    • Unclear if a validate API can call into User.php's checkPassword() when we don't have a valid user yet — we're validating before creating one.
  • MW also tests for certain username-password pairs at account creation (in User.php getPasswordValidity()), and rejects them with 'password-login-forbidden' => 'The use of this username and password has been forbidden.'
    • 'Useruser' => 'Passpass', 'Useruser1' => 'Passpass1', 'Apitestsysop' => 'testpass', 'Apitestuser' => 'testpass' # r75605. Test these

Validation[edit]

A proposed UI approach from 2011 with icons is Style guide/Error handling and validation, but jorm comments "is a conversation point", and he doesn't think any code uses it as is.

Related software efforts[edit]

In AFTv5, if you browse enabled pages anonymously and claim "I am highly knowledgeable about this topic" and enter an e-mail, the e-mail field's background switches from pink to green (style changes from invalid to valid) as you enter an e-mail address. It's driven by ArticleFeedback/modules/jquery.articleFeedback/jquery.articleFeedback.js

On Special:ChangeEmail, if you enter an invalid address, it shows a pink half-rounded error label (<label class="invalid" for="wpNewEmail" id="mw-emailaddress-validity">Enter a valid e-mail address</label>) or a green half-rounded "E-mail address appears valid". It's driven by resources/mediawiki.special/mediawiki.special.changeemail.js adding behavior to the field #wpNewEmail. The localized message text is email-address-validity-valid/invalid

Each has a similar updateMailValidityLabel() that calls mw.util.validateEmail() and adds CSS class valid/invalid accordingly. Neither uses resources/jquery/jquery.validate.js

Server requirements[edit]

Server needs to respond to AJAX-y validation requests from the front-end, primarily for "Username already in use" when someone enters "Jimbo".

Use an API module to do this.

Server validation API[edit]

Decided to do this

      • note Terry does not want any visible API (cf. http://en.wikipedia.org/w/api.php ) from the experiment, because people will spot and use the API and get mad when we take it down. Somehow have to make API-like requests to the main server.
        • If we can't hide an API, then register like FlaggedRevs? browser can call www.mediawiki.org/w/index.php?action=ajax&rs=RevisionReview::AjaxReview ,
    • or client or server could make fake submissions to Special:Userlogin?action=submit and parse the results (see next section)

Server account creation[edit]

Actually create account upon submission

  • For the experiment, rather than create an account creation API that would require extensive testing, the browser simply submits to the existing Special:Userlogin?action=submit URL. If it fails, the form redisplays and is re-modified if the user is in the acux_1 bucket. This modified form reformats the server's response but doesn't (currently) change it.
  • "mail an account" feature—is this active on en wiki?

Parsing server errors[edit]

Existence of <div class="errorbox"> is evidence of error, and the set of possible errors (in English) is somewhat manageable e.g.

Login error
Username entered already in use.

Please choose a different name.

Likewise "Passwords must be at least 1 character", etc. Tyler Romeo's gerrit changes to SpecialUserlogin.php internals would make this easier to parse.

Maybe client JS could just have a div in which it presents any server errors and not try to figure out what they mean. Trick is, how does it know when to blank out the server error box?

Client (or dummy server API) could validate individual fields by crafting various fake requests that are perfect apart from the one field and one last test that stops an unintended account creation.

OR, client just submits everything it has and shows the current server error. Maybe it doesn't contact server until the end, so it only does client-side processing. Biggest problem is you don't get told your username is taken until you submit.

Seems the only part of Special:UserLogiin to care about is DIV#content.mw-body. Don't know how to request only this part from MediaWiki.

Desired/future features[edit]

arbitrary messaging and campaign bucketing[edit]

The now-disabled Extension:CustomUserSignup showed different messages based on the URL parameter ?campaign=somevalue. This allowed links to present arbitrary messages to users during and after account creation, e.g. http://en.wikipedia.org/w/index.php?title=Special:UserLogin&type=signup&returnto=Main+Page&campaign=apswi would show messaging including en:MediaWiki:Customusertemplate-apswi-welcomecreation.

The same feature could/did also set the user in an ACP bucket named e.g. apswi, for future analysis.

Data collection[edit]

See m:Research:Account creation UX#Data collection requirements

Note that ACUX is different from PEF in that user bucketing isn't separate from performing the experiment. Every anonymous user who arrives at the Create account form is bucketed at that point, the form she sees is recorded in the userbuckets cookie.

The logging is similar to Post-Edit Feedback 1. The experiment adds JavaScript to the account creation page to log using ClickTracking. The events always include ClickTracking's stuff.

  • ext.accountCreationUX@1-bucketing-eventname
  • whether the user is logged in; the experiment is only active for anonymous users, so this should be 0
  • the clicktracking-session cookie value. (Since this is a session cookie it is insufficient to track users who view the form, get bucketed, don't successfully create an account right away, but later (maybe days later) come back and succeed.)
  • the namespace, which is always -1 for special pages
  • the experiment is only active for anonymous users, so the following should all be 0:
    • isAnonymous
    • lifetime edits
    • 1-3-6 month edit counts
  • The mw.user.id anonymous user token/cookie and document.referrer (if any) on the end, separated by |

The Research page comments "(This means that we need to set an anonymous token in a session cookie, to be able to match impressions and successful accounts created.)" We use the mw.user.id token, different from the clicktracking-session. The JavaScript that generates the mw.user.id token gets/sets the cookie mediaWiki.user.id with a long expiration, so it will persist if the user makes multiple visits to the form before successfully creating an account.

The three log actions are

  • 1 user bucketing: bucketname-assignment (whether the user is bucketed for ACUX as "control" or "acux_1"). Note that every eligible user arriving at the "Create account" page during the experiment gets bucketed, using ClickTracking's userbucket cookie.
ext.accountCreationUX@1-acux_1-assignment       20121003210607  0       ahqXleDKnVMqzmFAbUu8Jhn3iPgN02keL       -1      0       0       0       0       PQbpbZWZmAxTnEyp4QsY0b1Yzrfq4IAo|http://localhost/wiki/index.php/Sandbox
  • 2 when the experiment (the possibly-modified account creation form) is shown: bucketname--impression
ext.accountCreationUX@1-acux_1-impression       20121003210607  0       ahqXleDKnVMqzmFAbUu8Jhn3iPgN02keL       -1      0       0       0       0       PQbpbZWZmAxTnEyp4QsY0b1Yzrfq4IAo|http://localhost/wiki/index.php/Sandbox
  • 3 when the user clicks [Create Account] on the form: submit , with the extra information of the would-be new user name after the referrer, separated by '|'
ext.accountCreationUX@1-acux_1-submit   20121003210629  0       ahqXleDKnVMqzmFAbUu8Jhn3iPgN02keL       -1      0       0       0       0       PQbpbZWZmAxTnEyp4QsY0b1Yzrfq4IAo|http://localhost/wiki/index.php/Sandbox|DarTar UX

Each time the user reloads, or submits the form and there's a problem so the form is redisplayed, some of these events will log again:

  1. userbucketing assignment 1 should only happen first time unless user disables cookies.
  2. form reload or redisplay will log form display 2 again
  3. another CreateAccountClick 3 when/if the user clicks [Create Account]
    • Dario: would be nice to know if and when the form is redisplayed with an error, but StevenW points out this was not part of the original spec.

You can approximately infer that the form redisplayed because the Document referrer in events will be the form URL rather than some other page, thus something like ?title=Special:UserLogin...&type=signup

Successful account creations[edit]

The user table is the gold standard for whether an account was created. If create account succeeded, the would-be username logged in the CreateAccountClick submit event will be in the user table.

  • MW capitalizes the first letter, probably trims whitespace

(MW also logs an entry with log_type new_user, log_action create or create2, etc... The log_comment contains the "Reason:" field from the form with "password sent by e-mail" appended if that's what happened.)

The Research page requests:

  • Successful account creation events, including userids generated by funnel. Not sure what "userids generated by funnel" means.

Generic event for successful account creation[edit]

A successful account creation remains on the Special:Userlogin?type=signup URL, but displays a welcome message instead of the form. MW does not call the UserCreateForm hook, instead it calls AddNewAccount and BeforeWelcomeCreation hooks.

4th event: Independent of this experiment, we log a general account_create event on AddNewAccount from PHP , and relate the users in the experiment and their impressions and clicks described above to this 4th event by the mw.user.id() token. See Event logging/Events#Account creation for details of this account-create event.

?event_id=account_create&user_id=70&timestamp=1349298389&username=DarTar+UX&self_made=1&creator_user_id=70&by_email=0&mw_user_token=PQbpbZWZmAxTnEyp4QsY0b1Yzrfq4IAo

Earlier logging of Account Creation impressions[edit]

Earlier, E3 Experiments enabled then disabled in August:

  • tracking Account Creation impressions including the referring page, named "userLoginImpression" (slightly misnamed as these are only for type=signup). E.g.
userloginImpression     20120827173719  0       YD6QLOMKrV6RquHehS40Ja7n7EaMrUamH       -1      0       0       0       0       http://localhost/wiki/index.php/Main_Page
  • collecting Account Creation submit button clicks, named "userloginSubmit",
userloginSubmit 20120827174135  0       YD6QLOMKrV6RquHehS40Ja7n7EaMrUamH       -1      0       0       0       0       @spageTest0730

No JavaScript, no cookies?[edit]

With JavaScript disabled, the user always sees the old form. The client events 1-3 don't occur (the ClickTracking events are POSTed by JavaScript code). The server-side account_create occurs but there are no earlier events with the same usertoken.

With cookies disabled the client events 1-3 (bucketing, impression, click) occur, but account creation fails without a login token:

The user account was not created, as we could not confirm its source. Ensure you have cookies enabled, reload this page and try again.

So event 4 never happens and the user is back on the form with new bucketing and a new mw.user.id.

Description of current program flow[edit]

One way or another the user winds up seeing index.php?title=Special:UserLogin&type=signup . The MediaWiki PHP code in SpecialUserlogin.php detects type=signup and creates new UsercreateTemplate() , implemented in templates/Usercreate.php, to build the HTML form. This is not documented anywhere on MediaWiki.org. We will be ignoring this template as part of this test, but may choose to refactor or replace it later.

The form supports arbitrary user messaging in the messages w:MediaWiki:signupstart, w:MediaWiki:signupend and w:MediaWiki:signupend-https messages.

On production Wikimedia wikis Extension:ConfirmEdit interposes on hook UserCreateForm and adds FancyCaptcha to the page. FancyCaptcha.class.php overrides getMessage() to first look for more tailored messages, thus it finds the fancycaptcha-createaccount, and this adds a huge chunk of "Registering a free account... Username policy..." text at the top of the form that's nothing to do with the CAPTCHA. (It's not clear why all this "Registering a free account" stuff was not put in w:MediaWiki:signupstart. We could use this for the new benefits text.

The form can be modified by $wgAuth->modifyUITemplate(), and then wfRunHooks( 'UserCreateForm', array( &$template ) ) is called, so hooks can modify the form. This is where the extension steps in, adding a chunk of CSS and JS to the page.

When the user clicks [Create Account], the form posts to self with action=submitlogin&type=signup and the button adds wpCreateaccount. If info was posted and wpCreateaccount is set, then the MediaWiki PHP code runs addNewAccount(), which in turn calls addNewAccountInternal(), which does things like

  • check if wiki even allows creating new accounts
  • validate a createaccount token that should be present in the form (hidden field wpCreateaccount)
  • check if request comes from blacklisted IP
  • check if username is OK
  • check if username already exists
  • check if password and retyped password match
  • check password validity (mostly, minimal length?)
  • check valid email address (if supplied)

If any of these goes wrong it immediately returns by calling mainLoginForm() with its error, which triggers redisplay. This makes it hard to reuse addNewAccountInternal() from an API call, as it wants to redisplay a form rather than return a useful set of errors.

  • allows hook point AbortNewAccount to kill account creation
  • throttles account creation

Finally if none of these failed it calls to addUser(), which may may itself fail.

(There is also CreateaccountMail, creating an account by mail.

  • $wgUseCombinedLoginLink controls whether to output a combined login / create account link in the personal bar, or to output separate login and create account links. wmf-config/CommonSettings.php sets it to false (separate links) for WikiMedia wikis.
  • $wgLoginLanguageSelector controls whether to output a language selector paragraph. This is true in general for MW wikis (e.g. test.wikipedia.org), but false on en-wiki. The extension does not restyle it.
  • $wgAllowRealName controls whether to have a "Real name" form field. This is set to false for MW wikis in wmf-config/CommonSettings.php.

Upon success[edit]

The new user is logged in. successfulCreation() shows welcomecreation message, :

== Welcome, $1! ==
Your account has been created. Do not forget to change your MediaWiki preferences.

Note en:MediaWiki:welcomecreation as of September 2012 attempts to override this with a redirect to w:Community Portal.

Extension:CustomUserSignup part of Account creation improvement program allowed campaign-based overrides of this and other messages, see e.g. en:MediaWiki:Customusertemplate-ACP1-welcomecreation

successfulLogin() wraps this welcomecreation message with

  • title loginsuccesstitle
  • possibly, a link to "Return to <page you were on before account creation>"

Other stuff on success page[edit]

If you entered an e-mail, the success page displays confirmemail_oncreate message above the Welcome:

Login successful
A confirmation code was sent to your e-mail address. This code is not required to log in, but you will need to provide it before enabling any e-mail-based features in the wiki.

You also get

Logging you in to Wikimedia's other projects: (what's this?)

A logged-in user creating a new account gets a different success message.


Auth plugins[edit]

Ryan Lane quoth

it [a new version of the login/signupform] should be HTMLForm'd; someone tried to do so (maybe it was happy-melon, it would be a branch in svn) and it broke all auth plugins
OATHAuth, OpenStackManager, LdapAuthentication, all three of those add things to the authentication forms. OATH doesn't add something to the creation page, though; OSM and Ldap do, though