mirror of
https://github.com/pelican-dev/panel.git
synced 2025-09-21 20:44:47 +02:00
Remove username rules and allow to change it in profile (#1702)
This commit is contained in:
parent
c10280af4b
commit
e5c24fe8b6
@ -123,10 +123,8 @@ class UserResource extends Resource
|
|||||||
->components([
|
->components([
|
||||||
TextInput::make('username')
|
TextInput::make('username')
|
||||||
->label(trans('admin/user.username'))
|
->label(trans('admin/user.username'))
|
||||||
->alphaNum()
|
|
||||||
->required()
|
->required()
|
||||||
->unique()
|
->unique()
|
||||||
->minLength(3)
|
|
||||||
->maxLength(255),
|
->maxLength(255),
|
||||||
TextInput::make('email')
|
TextInput::make('email')
|
||||||
->label(trans('admin/user.email'))
|
->label(trans('admin/user.email'))
|
||||||
|
@ -90,16 +90,14 @@ class EditProfile extends BaseEditProfile
|
|||||||
->schema([
|
->schema([
|
||||||
Tab::make('account')
|
Tab::make('account')
|
||||||
->label(trans('profile.tabs.account'))
|
->label(trans('profile.tabs.account'))
|
||||||
->icon('tabler-user')
|
->icon('tabler-user-cog')
|
||||||
->schema([
|
->schema([
|
||||||
TextInput::make('username')
|
TextInput::make('username')
|
||||||
|
->prefixIcon('tabler-user')
|
||||||
->label(trans('profile.username'))
|
->label(trans('profile.username'))
|
||||||
->disabled()
|
->required()
|
||||||
->readOnly()
|
|
||||||
->dehydrated(false)
|
|
||||||
->maxLength(255)
|
->maxLength(255)
|
||||||
->unique()
|
->unique(),
|
||||||
->autofocus(),
|
|
||||||
TextInput::make('email')
|
TextInput::make('email')
|
||||||
->prefixIcon('tabler-mail')
|
->prefixIcon('tabler-mail')
|
||||||
->label(trans('profile.email'))
|
->label(trans('profile.email'))
|
||||||
@ -114,8 +112,8 @@ class EditProfile extends BaseEditProfile
|
|||||||
->revealable(filament()->arePasswordsRevealable())
|
->revealable(filament()->arePasswordsRevealable())
|
||||||
->rule(Password::default())
|
->rule(Password::default())
|
||||||
->autocomplete('new-password')
|
->autocomplete('new-password')
|
||||||
->dehydrated(fn ($state): bool => filled($state))
|
->dehydrated(fn ($state) => filled($state))
|
||||||
->dehydrateStateUsing(fn ($state): string => Hash::make($state))
|
->dehydrateStateUsing(fn ($state) => Hash::make($state))
|
||||||
->live(debounce: 500)
|
->live(debounce: 500)
|
||||||
->same('passwordConfirmation'),
|
->same('passwordConfirmation'),
|
||||||
TextInput::make('passwordConfirmation')
|
TextInput::make('passwordConfirmation')
|
||||||
@ -124,7 +122,7 @@ class EditProfile extends BaseEditProfile
|
|||||||
->prefixIcon('tabler-password-fingerprint')
|
->prefixIcon('tabler-password-fingerprint')
|
||||||
->revealable(filament()->arePasswordsRevealable())
|
->revealable(filament()->arePasswordsRevealable())
|
||||||
->required()
|
->required()
|
||||||
->visible(fn (Get $get): bool => filled($get('password')))
|
->visible(fn (Get $get) => filled($get('password')))
|
||||||
->dehydrated(false),
|
->dehydrated(false),
|
||||||
Select::make('timezone')
|
Select::make('timezone')
|
||||||
->label(trans('profile.timezone'))
|
->label(trans('profile.timezone'))
|
||||||
|
@ -11,7 +11,6 @@ use App\Contracts\Validatable;
|
|||||||
use App\Enums\CustomizationKey;
|
use App\Enums\CustomizationKey;
|
||||||
use App\Exceptions\DisplayException;
|
use App\Exceptions\DisplayException;
|
||||||
use App\Extensions\Avatar\AvatarService;
|
use App\Extensions\Avatar\AvatarService;
|
||||||
use App\Rules\Username;
|
|
||||||
use App\Traits\HasValidation;
|
use App\Traits\HasValidation;
|
||||||
use DateTimeZone;
|
use DateTimeZone;
|
||||||
use Filament\Models\Contracts\FilamentUser;
|
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['language'][] = new In(array_values(array_filter(ResourceBundle::getLocales(''), fn ($lang) => preg_match('/^[a-z]{2}$/', $lang))));
|
||||||
$rules['timezone'][] = new In(DateTimeZone::listIdentifiers());
|
$rules['timezone'][] = new In(DateTimeZone::listIdentifiers());
|
||||||
$rules['username'][] = new Username();
|
|
||||||
|
|
||||||
return $rules;
|
return $rules;
|
||||||
}
|
}
|
||||||
|
@ -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';
|
|
||||||
}
|
|
||||||
}
|
|
@ -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_'],
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
x
Reference in New Issue
Block a user