Skip to content
This repository has been archived by the owner on Sep 11, 2024. It is now read-only.

Commit

Permalink
Improve taken username warning in registration for when request fails (
Browse files Browse the repository at this point in the history
  • Loading branch information
t3chguy committed Jan 25, 2022
1 parent 68024c1 commit 1d02e61
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 12 deletions.
34 changes: 25 additions & 9 deletions src/components/views/auth/RegistrationForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,13 @@ enum RegistrationField {
PasswordConfirm = "field_password_confirm",
}

enum UsernameAvailableStatus {
Unknown,
Available,
Unavailable,
Error,
}

export const PASSWORD_MIN_SCORE = 3; // safely unguessable: moderate protection from offline slow-hash scenario.

interface IProps {
Expand Down Expand Up @@ -348,13 +355,25 @@ export default class RegistrationForm extends React.PureComponent<IProps, IState
return result;
};

private validateUsernameRules = withValidation({
private validateUsernameRules = withValidation<this, UsernameAvailableStatus>({
description: (_, results) => {
// omit the description if the only failing result is the `available` one as it makes no sense for it.
if (results.every(({ key, valid }) => key === "available" || valid)) return;
return _t("Use lowercase letters, numbers, dashes and underscores only");
},
hideDescriptionIfValid: true,
async deriveData(this: RegistrationForm, { value }) {
if (!value) {
return UsernameAvailableStatus.Unknown;
}

try {
const available = await this.props.matrixClient.isUsernameAvailable(value);
return available ? UsernameAvailableStatus.Available : UsernameAvailableStatus.Unavailable;
} catch (err) {
return UsernameAvailableStatus.Error;
}
},
rules: [
{
key: "required",
Expand All @@ -369,19 +388,16 @@ export default class RegistrationForm extends React.PureComponent<IProps, IState
{
key: "available",
final: true,
test: async ({ value }) => {
test: async ({ value }, usernameAvailable) => {
if (!value) {
return true;
}

try {
await this.props.matrixClient.isUsernameAvailable(value);
return true;
} catch (err) {
return false;
}
return usernameAvailable === UsernameAvailableStatus.Available;
},
invalid: () => _t("Someone already has that username. Try another or if it is you, sign in below."),
invalid: (usernameAvailable) => usernameAvailable === UsernameAvailableStatus.Error
? _t("Unable to check if username has been taken. Try again later.")
: _t("Someone already has that username. Try another or if it is you, sign in below."),
},
],
});
Expand Down
6 changes: 3 additions & 3 deletions src/components/views/elements/Validation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ export default function withValidation<T = undefined, D = void>({
}

const data = { value, allowEmpty };
const derivedData = deriveData ? await deriveData(data) : undefined;
const derivedData: D | undefined = deriveData ? await deriveData.call(this, data) : undefined;

const results: IResult[] = [];
let valid = true;
Expand All @@ -106,13 +106,13 @@ export default function withValidation<T = undefined, D = void>({
continue;
}

if (rule.skip && rule.skip.call(this, data, derivedData)) {
if (rule.skip?.call(this, data, derivedData)) {
continue;
}

// We're setting `this` to whichever component holds the validation
// function. That allows rules to access the state of the component.
const ruleValid = await rule.test.call(this, data, derivedData);
const ruleValid: boolean = await rule.test.call(this, data, derivedData);
valid = valid && ruleValid;
if (ruleValid && rule.valid) {
// If the rule's result is valid and has text to show for
Expand Down
1 change: 1 addition & 0 deletions src/i18n/strings/en_EN.json
Original file line number Diff line number Diff line change
Expand Up @@ -2939,6 +2939,7 @@
"Other users can invite you to rooms using your contact details": "Other users can invite you to rooms using your contact details",
"Enter phone number (required on this homeserver)": "Enter phone number (required on this homeserver)",
"Use lowercase letters, numbers, dashes and underscores only": "Use lowercase letters, numbers, dashes and underscores only",
"Unable to check if username has been taken. Try again later.": "Unable to check if username has been taken. Try again later.",
"Someone already has that username. Try another or if it is you, sign in below.": "Someone already has that username. Try another or if it is you, sign in below.",
"Phone (optional)": "Phone (optional)",
"Register": "Register",
Expand Down

0 comments on commit 1d02e61

Please sign in to comment.