diff --git a/src/onboarding/onboarding-create-user.ts b/src/onboarding/onboarding-create-user.ts index 2d843b3b26..5f9d333e94 100644 --- a/src/onboarding/onboarding-create-user.ts +++ b/src/onboarding/onboarding-create-user.ts @@ -16,6 +16,8 @@ import type { ValueChangedEvent } from "../types"; import { onBoardingStyles } from "./styles"; import { debounce } from "../common/util/debounce"; +const CHECK_USERNAME_REGEX = /\s|[A-Z]/; + const CREATE_USER_SCHEMA: HaFormSchema[] = [ { name: "name", @@ -121,6 +123,7 @@ class OnboardingCreateUser extends LitElement { ev: ValueChangedEvent ): void { const nameChanged = ev.detail.value.name !== this._newUser.name; + const usernameChanged = ev.detail.value.username !== this._newUser.username; const passwordChanged = ev.detail.value.password !== this._newUser.password || ev.detail.value.password_confirm !== this._newUser.password_confirm; @@ -135,6 +138,9 @@ class OnboardingCreateUser extends LitElement { this._debouncedCheckPasswordMatch(); } } + if (usernameChanged) { + this._checkUsername(); + } } private _debouncedCheckPasswordMatch = debounce( @@ -164,6 +170,21 @@ class OnboardingCreateUser extends LitElement { const parts = String(this._newUser.name).split(" "); if (parts.length) { this._newUser.username = parts[0].toLowerCase(); + this._checkUsername(); + } + } + + private _checkUsername(): void { + const old = this._formError.username; + if (CHECK_USERNAME_REGEX.test(this._newUser.username as string)) { + this._formError.username = this.localize( + "ui.panel.page-onboarding.user.error.username_not_normalized" + ); + } else { + this._formError.username = ""; + } + if (old !== this._formError.username) { + this.requestUpdate("_formError"); } } diff --git a/src/translations/en.json b/src/translations/en.json index 0ac1eb9a12..80c7faebff 100644 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -7206,6 +7206,7 @@ }, "create_account": "Create account", "error": { + "username_not_normalized": "Username can only contain lowercase letters, and can not contain whitespace.", "password_not_match": "Passwords don't match" } },