Account creation user experience/Engineering/Experiment

Out-of-scope

 * logged-in users creating accounts &mdash; only anonymous users are candidates for the experiment
 * users without JavaScript &mdash; 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

 * 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 NaN $1 characterss.' (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.'

. Bug: In Firefox, the CAPTCHA input field remembers previous entries, even though it has  attributes.
 * Validate if email is valid
 * Note client-side code is already provided a JavaScript  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.

Issues
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, 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

 * 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 &mdash; 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
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
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 ( Enter a valid e-mail address ) 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

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
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
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
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
Existence of &lt;div class="errorbox"&gt; 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.

arbitrary messaging and campaign bucketing
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

 * See m:Research:Account creation UX

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 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-eventname-bucketing
 * whether the user is logged in; the experiment is only active for anonymous users, so this should be 0
 * 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
 * document.referrer (if any) on the end

The three log actions are
 * 1 user bucketing: assignment-bucketname (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.
 * 2 when the experiment (the possibly-modified account creation form) is shown: ACUX-bucketname
 * 3 when the user clicks [Create Account] on the form: CreateAccountClick, with the extra information of the would-be new user name after the referrer, separated by a colon.

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: You can approximately infer that the form redisplayed because the Document referrer in events will be the form URL rather than some other page, e.g.
 * 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.

Successful account creations
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
 * MW probably trims whitespace

The Research page requests:
 * Successful account creation events, including userids generated by funnel. Not sure what "userids generated by funnel" means.

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.)"
 * the clicktracking-session cookie should suffice. It seems it doesn't make sense to create a userToken in addition since at the beginning of account creation the user is guaranteed anonymous (logged in users creating additional accounts are excluded from ACUX).

Unneeded? log events for successful account creation
A successful account submission remains on the Special:Userlogin?type=signup URL, but does not redisplay the form. Instead of calling UserCreateForm hooks, MW calls AddNewAccount and BeforeWelcomeCreation hooks. It is possible to hook into these, set flags, and either on the server or in separate JS code log a 4th event for NewlyCreatedAccount, in which we log the new mw.user.id which will be the new successful username.

Con: However, this requires extra code (both PHP and a new separate "ACUX New Account" JavaScript environment), testing, and data analysis validation of the additional event; and it would still not be as reliable as consulting the user table.

Pro: Trying to work out successful account creations by looking in the user table for usernames matching the CreateAccountClick in the appropriate timeframe is difficult and unreliable.

Earlier Account Creation impressions in August
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.
 * collecting Account Creation submit button clicks, named "userloginSubmit",

Description of current program flow
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.

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.

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</tt> 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 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. Finally if none of these failed it calls to addUser, which may may itself fail.
 * 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)
 * allows hook point AbortNewAccount to kill account creation
 * throttles account creation

(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.