mirror of
https://github.com/discourse/discourse.git
synced 2025-02-25 01:28:39 +08:00
DEV: refactor username validation mixin to helper class (#31107)
This PR refactors the use of the UsernameValidation mixin to a helper class for the SignupController component. We'll extend this to the CreateAccount modal and InvitesShowController in follow-up PRs.
This commit is contained in:
parent
c8ccf79545
commit
80fdb6f2e6
@ -15,17 +15,16 @@ import discourseDebounce from "discourse/lib/debounce";
|
||||
import discourseComputed, { bind } from "discourse/lib/decorators";
|
||||
import NameValidationHelper from "discourse/lib/name-validation-helper";
|
||||
import { userPath } from "discourse/lib/url";
|
||||
import UsernameValidationHelper from "discourse/lib/username-validation-helper";
|
||||
import { emailValid } from "discourse/lib/utilities";
|
||||
import PasswordValidation from "discourse/mixins/password-validation";
|
||||
import UserFieldsValidation from "discourse/mixins/user-fields-validation";
|
||||
import UsernameValidation from "discourse/mixins/username-validation";
|
||||
import { findAll } from "discourse/models/login-method";
|
||||
import User from "discourse/models/user";
|
||||
import { i18n } from "discourse-i18n";
|
||||
|
||||
export default class SignupPageController extends Controller.extend(
|
||||
PasswordValidation,
|
||||
UsernameValidation,
|
||||
UserFieldsValidation
|
||||
) {
|
||||
@service site;
|
||||
@ -44,6 +43,7 @@ export default class SignupPageController extends Controller.extend(
|
||||
passwordValidationVisible = false;
|
||||
emailValidationVisible = false;
|
||||
nameValidationHelper = new NameValidationHelper(this);
|
||||
usernameValidationHelper = new UsernameValidationHelper(this);
|
||||
|
||||
@notEmpty("authOptions") hasAuthOptions;
|
||||
@setting("enable_local_logins") canCreateLocal;
|
||||
@ -59,6 +59,11 @@ export default class SignupPageController extends Controller.extend(
|
||||
this.fetchConfirmationValue();
|
||||
}
|
||||
|
||||
@dependentKeyCompat
|
||||
get usernameValidation() {
|
||||
return this.usernameValidationHelper.usernameValidation;
|
||||
}
|
||||
|
||||
get nameTitle() {
|
||||
return this.nameValidationHelper.nameTitle;
|
||||
}
|
||||
@ -356,7 +361,11 @@ export default class SignupPageController extends Controller.extend(
|
||||
// If email is valid and username has not been entered yet,
|
||||
// or email and username were filled automatically by 3rd party auth,
|
||||
// then look for a registered username that matches the email.
|
||||
discourseDebounce(this, this.fetchExistingUsername, 500);
|
||||
discourseDebounce(
|
||||
this,
|
||||
this.usernameValidationHelper.fetchExistingUsername,
|
||||
500
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,116 @@
|
||||
import { tracked } from "@glimmer/tracking";
|
||||
import { isEmpty } from "@ember/utils";
|
||||
import discourseDebounce from "discourse/lib/debounce";
|
||||
import User from "discourse/models/user";
|
||||
import { i18n } from "discourse-i18n";
|
||||
|
||||
function failedResult(attrs) {
|
||||
return {
|
||||
shouldCheck: false,
|
||||
failed: true,
|
||||
ok: false,
|
||||
element: document.querySelector("#new-account-username"),
|
||||
...attrs,
|
||||
};
|
||||
}
|
||||
|
||||
function validResult(attrs) {
|
||||
return { ok: true, ...attrs };
|
||||
}
|
||||
|
||||
export default class UsernameValidationHelper {
|
||||
@tracked usernameValidationResult;
|
||||
checkedUsername = null;
|
||||
|
||||
constructor(owner) {
|
||||
this.owner = owner;
|
||||
}
|
||||
|
||||
async fetchExistingUsername() {
|
||||
const result = await User.checkUsername(null, this.owner.accountEmail);
|
||||
|
||||
if (
|
||||
result.suggestion &&
|
||||
(isEmpty(this.owner.accountUsername) ||
|
||||
this.owner.accountUsername === this.owner.get("authOptions.username"))
|
||||
) {
|
||||
this.owner.accountUsername = result.suggestion;
|
||||
this.owner.prefilledUsername = result.suggestion;
|
||||
}
|
||||
}
|
||||
|
||||
get usernameValidation() {
|
||||
if (
|
||||
this.usernameValidationResult &&
|
||||
this.checkedUsername === this.owner.accountUsername
|
||||
) {
|
||||
return this.usernameValidationResult;
|
||||
}
|
||||
|
||||
const result = this.basicUsernameValidation(this.owner.accountUsername);
|
||||
|
||||
if (result.shouldCheck) {
|
||||
discourseDebounce(this, this.checkUsernameAvailability, 500);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
basicUsernameValidation(username) {
|
||||
if (username && username === this.owner.prefilledUsername) {
|
||||
return validResult({ reason: i18n("user.username.prefilled") });
|
||||
}
|
||||
|
||||
if (isEmpty(username)) {
|
||||
return failedResult({
|
||||
message: i18n("user.username.required"),
|
||||
reason: this.owner.forceValidationReason
|
||||
? i18n("user.username.required")
|
||||
: null,
|
||||
});
|
||||
}
|
||||
|
||||
if (username.length < this.owner.siteSettings.min_username_length) {
|
||||
return failedResult({ reason: i18n("user.username.too_short") });
|
||||
}
|
||||
|
||||
if (username.length > this.owner.siteSettings.max_username_length) {
|
||||
return failedResult({ reason: i18n("user.username.too_long") });
|
||||
}
|
||||
|
||||
return failedResult({
|
||||
shouldCheck: true,
|
||||
reason: i18n("user.username.checking"),
|
||||
});
|
||||
}
|
||||
|
||||
async checkUsernameAvailability() {
|
||||
const result = await User.checkUsername(
|
||||
this.owner.accountUsername,
|
||||
this.owner.accountEmail
|
||||
);
|
||||
|
||||
if (this.owner.isDestroying || this.owner.isDestroyed) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.checkedUsername = this.owner.accountUsername;
|
||||
this.owner.isDeveloper = !!result.is_developer;
|
||||
|
||||
if (result.available) {
|
||||
this.usernameValidationResult = validResult({
|
||||
reason: i18n("user.username.available"),
|
||||
});
|
||||
} else if (result.suggestion) {
|
||||
this.usernameValidationResult = failedResult({
|
||||
reason: i18n("user.username.not_available", result),
|
||||
});
|
||||
} else {
|
||||
this.usernameValidationResult = failedResult({
|
||||
reason: result.errors
|
||||
? result.errors.join(" ")
|
||||
: i18n("user.username.not_available_no_suggestion"),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user