Remove username rules and allow to change it in profile (#1702)

This commit is contained in:
Boy132 2025-09-21 00:37:42 +02:00 committed by GitHub
parent c10280af4b
commit e5c24fe8b6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 7 additions and 131 deletions

View File

@ -123,10 +123,8 @@ class UserResource extends Resource
->components([
TextInput::make('username')
->label(trans('admin/user.username'))
->alphaNum()
->required()
->unique()
->minLength(3)
->maxLength(255),
TextInput::make('email')
->label(trans('admin/user.email'))

View File

@ -90,16 +90,14 @@ class EditProfile extends BaseEditProfile
->schema([
Tab::make('account')
->label(trans('profile.tabs.account'))
->icon('tabler-user')
->icon('tabler-user-cog')
->schema([
TextInput::make('username')
->prefixIcon('tabler-user')
->label(trans('profile.username'))
->disabled()
->readOnly()
->dehydrated(false)
->required()
->maxLength(255)
->unique()
->autofocus(),
->unique(),
TextInput::make('email')
->prefixIcon('tabler-mail')
->label(trans('profile.email'))
@ -114,8 +112,8 @@ class EditProfile extends BaseEditProfile
->revealable(filament()->arePasswordsRevealable())
->rule(Password::default())
->autocomplete('new-password')
->dehydrated(fn ($state): bool => filled($state))
->dehydrateStateUsing(fn ($state): string => Hash::make($state))
->dehydrated(fn ($state) => filled($state))
->dehydrateStateUsing(fn ($state) => Hash::make($state))
->live(debounce: 500)
->same('passwordConfirmation'),
TextInput::make('passwordConfirmation')
@ -124,7 +122,7 @@ class EditProfile extends BaseEditProfile
->prefixIcon('tabler-password-fingerprint')
->revealable(filament()->arePasswordsRevealable())
->required()
->visible(fn (Get $get): bool => filled($get('password')))
->visible(fn (Get $get) => filled($get('password')))
->dehydrated(false),
Select::make('timezone')
->label(trans('profile.timezone'))

View File

@ -11,7 +11,6 @@ use App\Contracts\Validatable;
use App\Enums\CustomizationKey;
use App\Exceptions\DisplayException;
use App\Extensions\Avatar\AvatarService;
use App\Rules\Username;
use App\Traits\HasValidation;
use DateTimeZone;
use Filament\Models\Contracts\FilamentUser;
@ -213,7 +212,6 @@ class User extends Model implements AuthenticatableContract, AuthorizableContrac
$rules['language'][] = new In(array_values(array_filter(ResourceBundle::getLocales(''), fn ($lang) => preg_match('/^[a-z]{2}$/', $lang))));
$rules['timezone'][] = new In(DateTimeZone::listIdentifiers());
$rules['username'][] = new Username();
return $rules;
}

View File

@ -1,45 +0,0 @@
<?php
namespace App\Rules;
use Illuminate\Contracts\Validation\Rule;
class Username implements Rule
{
/**
* Regex to use when validating usernames.
*/
public const VALIDATION_REGEX = '/^[a-z0-9]([\w\.-]+)[a-z0-9]$/';
/**
* Validate that a username contains only the allowed characters and starts/ends
* with alphanumeric characters.
*
* Allowed characters: a-z0-9_-.
*
* @param string $attribute
* @param mixed $value
*/
public function passes($attribute, $value): bool
{
return preg_match(self::VALIDATION_REGEX, mb_strtolower($value));
}
/**
* Return a validation message for use when this rule fails.
*/
public function message(): string
{
return 'The :attribute must start and end with alpha-numeric characters and
contain only letters, numbers, dashes, underscores, and periods.';
}
/**
* Convert the rule to a validation string. This is necessary to avoid
* issues with Eloquence which tries to use this rule as a string.
*/
public function __toString(): string
{
return 'p_username';
}
}

View File

@ -1,73 +0,0 @@
<?php
namespace App\Tests\Unit\Rules;
use App\Rules\Username;
use App\Tests\TestCase;
use PHPUnit\Framework\Attributes\DataProvider;
class UsernameTest extends TestCase
{
/**
* Test that this rule can be cast to a string correctly.
*/
public function test_rule_is_stringable(): void
{
$this->assertSame('p_username', (string) new Username());
}
/**
* Test valid usernames.
*/
#[DataProvider('validUsernameDataProvider')]
public function test_valid_usernames(string $username): void
{
$this->assertTrue((new Username())->passes('test', $username), 'Assert username is valid.');
}
/**
* Test invalid usernames return false.
*/
#[DataProvider('invalidUsernameDataProvider')]
public function test_invalid_usernames(string $username): void
{
$this->assertFalse((new Username())->passes('test', $username), 'Assert username is not valid.');
}
/**
* Provide valid usernames.
*/
public static function validUsernameDataProvider(): array
{
return [
['username'],
['user_name'],
['user.name'],
['user-name'],
['123username123'],
['123-user.name'],
['123456'],
];
}
/**
* Provide invalid usernames.
*/
public static function invalidUsernameDataProvider(): array
{
return [
['_username'],
['username_'],
['_username_'],
['-username'],
['.username'],
['username-'],
['username.'],
['user*name'],
['user^name'],
['user#name'],
['user+name'],
['1234_'],
];
}
}