Skip to content

[3.0] Let the registration form ask whether a username is taken - #9486

Merged
live627 merged 1 commit into
SimpleMachines:release-3.0from
albertlast:3.0/username-check-403
Aug 11, 2026
Merged

[3.0] Let the registration form ask whether a username is taken#9486
live627 merged 1 commit into
SimpleMachines:release-3.0from
albertlast:3.0/username-check-403

Conversation

@albertlast

Copy link
Copy Markdown
Collaborator

Description

The registration form's "is this username free?" check has never returned an
answer on 3.0. It has been answering 403 to everybody it exists for, and 3.0
now treats a 403 as no answer at all.

The guard asks for a login cookie.

if (empty($_COOKIE) || empty($_COOKIE[Config::$cookiename]) || empty($_SERVER['HTTP_REFERER']) || …) {
    Utils::sendHttpStatus(403);
}

Config::$cookiename is the login cookie. Somebody filling in the registration
form does not have one — that is what registering is for — so the only people who
get past it are the ones who already have an account.

And it does not stop. sendHttpStatus(403) returns, and the XML it just
refused is written out underneath the refusal. 2.1 got away with that: its raw
XMLHttpRequest never looked at the status, so the body came through and the
check worked.

3.0's wrapper does look:

const promise = fetch(sUrl, options)
    .then(res => res.ok ? res : Promise.reject(res))

so the promise rejects, getXMLDocument() calls the callback with false, and
checkUsernameCallback() reads XMLDoc.getElementsByTagName(…) off it and
throws. Whatever is typed, the icon beside the field never moves.

Reproducing it needs a browser, because curl sends no cookies of its own — that
is probably why it has gone unnoticed. In the console on the registration page:

> await smc_Request.fetchXML(smf_prepareScriptUrl(smf_scripturl) + 'action=signup;sa=usernamecheck;xml;username=zzzfreshname')
Uncaught Error: Network request failed: undefined

What changes

Asks for a session and a referer from this forum — which is what the check was
after — and stops when it refuses, rather than sending the refusal and then the
thing it refused.

Testing

With this, on the registration page: an unused name turns the icon green with
"Username is available", an existing member's name and a name on the reserved
list turn it red, and typing again puts it back to "Check if username is
available". Clicking the icon asks again on demand. No console errors.

(#9483 is what makes a taken name come back as valid="0" rather than an error
page — without it this shows the same red icon, from a parse failure rather than
an answer. Each stands alone.)

Issues References (Fixes|Related|Closes)

Related to #7933

The check the form makes as the username is typed answers 403 to everyone it
exists for, and 3.0 now treats that as no answer at all.

The guard wants Config::$cookiename in $_COOKIE. That is the login cookie, so
the only people who get past it are the ones who already have an account. It
then does not stop: sendHttpStatus(403) returns, and the XML it was refusing is
written out underneath the refusal. 2.1 got away with that because its raw
XMLHttpRequest never looked at the status.

3.0's wrapper does - smc_Request.fetch() rejects anything that is not res.ok -
so the promise fails, getXMLDocument() calls the callback with false, and the
icon beside the field never moves whatever is typed into it.

Asks for a session and a referer from this forum, which is what the check was
after, and stops when it refuses.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Signed-off-by: albertlast <mathiaspapealbert@hotmail.com>
@live627
live627 merged commit 50f364f into SimpleMachines:release-3.0 Aug 11, 2026
4 checks passed
@jdarwood007 jdarwood007 modified the milestones: 3.0 Alpha 6, 3.0 Alpha 5 Aug 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants