diff --git a/phpstan-baseline.php b/phpstan-baseline.php index c9817e23f..65f52c677 100644 --- a/phpstan-baseline.php +++ b/phpstan-baseline.php @@ -8,12 +8,12 @@ 'path' => __DIR__ . '/src/Authentication/Actions/Email2FA.php', ]; $ignoreErrors[] = [ - 'message' => '#^Construct empty\\(\\) is not allowed\\. Use more strict comparison\\.$#', + 'message' => '#^Call to function model with CodeIgniter\\\\Shield\\\\Models\\\\UserIdentityModel\\:\\:class is discouraged\\.$#', 'count' => 2, 'path' => __DIR__ . '/src/Authentication/Actions/Email2FA.php', ]; $ignoreErrors[] = [ - 'message' => '#^Call to function model with CodeIgniter\\\\Shield\\\\Models\\\\UserIdentityModel\\:\\:class is discouraged\\.$#', + 'message' => '#^Construct empty\\(\\) is not allowed\\. Use more strict comparison\\.$#', 'count' => 2, 'path' => __DIR__ . '/src/Authentication/Actions/Email2FA.php', ]; @@ -33,6 +33,16 @@ 'count' => 1, 'path' => __DIR__ . '/src/Authentication/Authentication.php', ]; +$ignoreErrors[] = [ + 'message' => '#^Call to function model with CodeIgniter\\\\Shield\\\\Models\\\\TokenLoginModel\\:\\:class is discouraged\\.$#', + 'count' => 1, + 'path' => __DIR__ . '/src/Authentication/Authenticators/AccessTokens.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Call to function model with CodeIgniter\\\\Shield\\\\Models\\\\UserIdentityModel\\:\\:class is discouraged\\.$#', + 'count' => 1, + 'path' => __DIR__ . '/src/Authentication/Authenticators/AccessTokens.php', +]; $ignoreErrors[] = [ 'message' => '#^Construct empty\\(\\) is not allowed\\. Use more strict comparison\\.$#', 'count' => 4, @@ -46,70 +56,70 @@ $ignoreErrors[] = [ 'message' => '#^Call to function model with CodeIgniter\\\\Shield\\\\Models\\\\TokenLoginModel\\:\\:class is discouraged\\.$#', 'count' => 1, - 'path' => __DIR__ . '/src/Authentication/Authenticators/AccessTokens.php', + 'path' => __DIR__ . '/src/Authentication/Authenticators/HmacSha256.php', ]; $ignoreErrors[] = [ 'message' => '#^Call to function model with CodeIgniter\\\\Shield\\\\Models\\\\UserIdentityModel\\:\\:class is discouraged\\.$#', 'count' => 1, - 'path' => __DIR__ . '/src/Authentication/Authenticators/AccessTokens.php', + 'path' => __DIR__ . '/src/Authentication/Authenticators/HmacSha256.php', ]; $ignoreErrors[] = [ - 'message' => '#^Parameter \\#1 \\$credentials \\(array\\{token\\?\\: string\\}\\) of method CodeIgniter\\\\Shield\\\\Authentication\\\\Authenticators\\\\JWT\\:\\:attempt\\(\\) should be contravariant with parameter \\$credentials \\(array\\) of method CodeIgniter\\\\Shield\\\\Authentication\\\\AuthenticatorInterface\\:\\:attempt\\(\\)$#', + 'message' => '#^Call to function model with CodeIgniter\\\\Shield\\\\Models\\\\TokenLoginModel\\:\\:class is discouraged\\.$#', 'count' => 1, 'path' => __DIR__ . '/src/Authentication/Authenticators/JWT.php', ]; $ignoreErrors[] = [ - 'message' => '#^Parameter \\#1 \\$credentials \\(array\\{token\\?\\: string\\}\\) of method CodeIgniter\\\\Shield\\\\Authentication\\\\Authenticators\\\\JWT\\:\\:check\\(\\) should be contravariant with parameter \\$credentials \\(array\\) of method CodeIgniter\\\\Shield\\\\Authentication\\\\AuthenticatorInterface\\:\\:check\\(\\)$#', + 'message' => '#^Parameter \\#1 \\$credentials \\(array\\{token\\?\\: string\\}\\) of method CodeIgniter\\\\Shield\\\\Authentication\\\\Authenticators\\\\JWT\\:\\:attempt\\(\\) should be contravariant with parameter \\$credentials \\(array\\) of method CodeIgniter\\\\Shield\\\\Authentication\\\\AuthenticatorInterface\\:\\:attempt\\(\\)$#', 'count' => 1, 'path' => __DIR__ . '/src/Authentication/Authenticators/JWT.php', ]; $ignoreErrors[] = [ - 'message' => '#^Call to function model with CodeIgniter\\\\Shield\\\\Models\\\\TokenLoginModel\\:\\:class is discouraged\\.$#', + 'message' => '#^Parameter \\#1 \\$credentials \\(array\\{token\\?\\: string\\}\\) of method CodeIgniter\\\\Shield\\\\Authentication\\\\Authenticators\\\\JWT\\:\\:check\\(\\) should be contravariant with parameter \\$credentials \\(array\\) of method CodeIgniter\\\\Shield\\\\Authentication\\\\AuthenticatorInterface\\:\\:check\\(\\)$#', 'count' => 1, 'path' => __DIR__ . '/src/Authentication/Authenticators/JWT.php', ]; $ignoreErrors[] = [ - 'message' => '#^Construct empty\\(\\) is not allowed\\. Use more strict comparison\\.$#', - 'count' => 3, + 'message' => '#^Call to function model with CodeIgniter\\\\Shield\\\\Models\\\\LoginModel\\:\\:class is discouraged\\.$#', + 'count' => 1, 'path' => __DIR__ . '/src/Authentication/Authenticators/Session.php', ]; $ignoreErrors[] = [ - 'message' => '#^Only booleans are allowed in an elseif condition, string\\|null given\\.$#', + 'message' => '#^Call to function model with CodeIgniter\\\\Shield\\\\Models\\\\RememberModel\\:\\:class is discouraged\\.$#', 'count' => 1, 'path' => __DIR__ . '/src/Authentication/Authenticators/Session.php', ]; $ignoreErrors[] = [ - 'message' => '#^Only booleans are allowed in an if condition, CodeIgniter\\\\Shield\\\\Entities\\\\UserIdentity\\|null given\\.$#', + 'message' => '#^Call to function model with CodeIgniter\\\\Shield\\\\Models\\\\UserIdentityModel\\:\\:class is discouraged\\.$#', 'count' => 1, 'path' => __DIR__ . '/src/Authentication/Authenticators/Session.php', ]; $ignoreErrors[] = [ - 'message' => '#^Only booleans are allowed in an if condition, int\\|string\\|null given\\.$#', + 'message' => '#^Construct empty\\(\\) is not allowed\\. Use more strict comparison\\.$#', 'count' => 3, 'path' => __DIR__ . '/src/Authentication/Authenticators/Session.php', ]; $ignoreErrors[] = [ - 'message' => '#^Parameter \\#1 \\$credentials \\(array\\{email\\?\\: string, username\\?\\: string, password\\?\\: string\\}\\) of method CodeIgniter\\\\Shield\\\\Authentication\\\\Authenticators\\\\Session\\:\\:attempt\\(\\) should be contravariant with parameter \\$credentials \\(array\\) of method CodeIgniter\\\\Shield\\\\Authentication\\\\AuthenticatorInterface\\:\\:attempt\\(\\)$#', + 'message' => '#^Only booleans are allowed in an elseif condition, string\\|null given\\.$#', 'count' => 1, 'path' => __DIR__ . '/src/Authentication/Authenticators/Session.php', ]; $ignoreErrors[] = [ - 'message' => '#^Parameter \\#1 \\$credentials \\(array\\{email\\?\\: string, username\\?\\: string, password\\?\\: string\\}\\) of method CodeIgniter\\\\Shield\\\\Authentication\\\\Authenticators\\\\Session\\:\\:check\\(\\) should be contravariant with parameter \\$credentials \\(array\\) of method CodeIgniter\\\\Shield\\\\Authentication\\\\AuthenticatorInterface\\:\\:check\\(\\)$#', + 'message' => '#^Only booleans are allowed in an if condition, CodeIgniter\\\\Shield\\\\Entities\\\\UserIdentity\\|null given\\.$#', 'count' => 1, 'path' => __DIR__ . '/src/Authentication/Authenticators/Session.php', ]; $ignoreErrors[] = [ - 'message' => '#^Call to function model with CodeIgniter\\\\Shield\\\\Models\\\\LoginModel\\:\\:class is discouraged\\.$#', - 'count' => 1, + 'message' => '#^Only booleans are allowed in an if condition, int\\|string\\|null given\\.$#', + 'count' => 3, 'path' => __DIR__ . '/src/Authentication/Authenticators/Session.php', ]; $ignoreErrors[] = [ - 'message' => '#^Call to function model with CodeIgniter\\\\Shield\\\\Models\\\\RememberModel\\:\\:class is discouraged\\.$#', + 'message' => '#^Parameter \\#1 \\$credentials \\(array\\{email\\?\\: string, username\\?\\: string, password\\?\\: string\\}\\) of method CodeIgniter\\\\Shield\\\\Authentication\\\\Authenticators\\\\Session\\:\\:attempt\\(\\) should be contravariant with parameter \\$credentials \\(array\\) of method CodeIgniter\\\\Shield\\\\Authentication\\\\AuthenticatorInterface\\:\\:attempt\\(\\)$#', 'count' => 1, 'path' => __DIR__ . '/src/Authentication/Authenticators/Session.php', ]; $ignoreErrors[] = [ - 'message' => '#^Call to function model with CodeIgniter\\\\Shield\\\\Models\\\\UserIdentityModel\\:\\:class is discouraged\\.$#', + 'message' => '#^Parameter \\#1 \\$credentials \\(array\\{email\\?\\: string, username\\?\\: string, password\\?\\: string\\}\\) of method CodeIgniter\\\\Shield\\\\Authentication\\\\Authenticators\\\\Session\\:\\:check\\(\\) should be contravariant with parameter \\$credentials \\(array\\) of method CodeIgniter\\\\Shield\\\\Authentication\\\\AuthenticatorInterface\\:\\:check\\(\\)$#', 'count' => 1, 'path' => __DIR__ . '/src/Authentication/Authenticators/Session.php', ]; @@ -158,6 +168,11 @@ 'count' => 1, 'path' => __DIR__ . '/src/Collectors/Auth.php', ]; +$ignoreErrors[] = [ + 'message' => '#^Call to function model with CodeIgniter\\\\Shield\\\\Models\\\\UserModel\\:\\:class is discouraged\\.$#', + 'count' => 9, + 'path' => __DIR__ . '/src/Commands/User.php', +]; $ignoreErrors[] = [ 'message' => '#^Construct empty\\(\\) is not allowed\\. Use more strict comparison\\.$#', 'count' => 1, @@ -175,13 +190,13 @@ 'path' => __DIR__ . '/src/Controllers/MagicLinkController.php', ]; $ignoreErrors[] = [ - 'message' => '#^Call to function model with CodeIgniter\\\\Shield\\\\Models\\\\UserIdentityModel\\:\\:class is discouraged\\.$#', - 'count' => 2, + 'message' => '#^Call to function model with CodeIgniter\\\\Shield\\\\Models\\\\LoginModel\\:\\:class is discouraged\\.$#', + 'count' => 1, 'path' => __DIR__ . '/src/Controllers/MagicLinkController.php', ]; $ignoreErrors[] = [ - 'message' => '#^Call to function model with CodeIgniter\\\\Shield\\\\Models\\\\LoginModel\\:\\:class is discouraged\\.$#', - 'count' => 1, + 'message' => '#^Call to function model with CodeIgniter\\\\Shield\\\\Models\\\\UserIdentityModel\\:\\:class is discouraged\\.$#', + 'count' => 2, 'path' => __DIR__ . '/src/Controllers/MagicLinkController.php', ]; $ignoreErrors[] = [ @@ -240,13 +255,18 @@ 'path' => __DIR__ . '/src/Entities/Group.php', ]; $ignoreErrors[] = [ - 'message' => '#^Construct empty\\(\\) is not allowed\\. Use more strict comparison\\.$#', - 'count' => 8, + 'message' => '#^Call to function model with CodeIgniter\\\\Shield\\\\Models\\\\GroupModel\\:\\:class is discouraged\\.$#', + 'count' => 2, 'path' => __DIR__ . '/src/Entities/User.php', ]; $ignoreErrors[] = [ - 'message' => '#^Only booleans are allowed in a ternary operator condition, int\\<0, max\\> given\\.$#', - 'count' => 1, + 'message' => '#^Call to function model with CodeIgniter\\\\Shield\\\\Models\\\\LoginModel\\:\\:class is discouraged\\.$#', + 'count' => 2, + 'path' => __DIR__ . '/src/Entities/User.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Call to function model with CodeIgniter\\\\Shield\\\\Models\\\\PermissionModel\\:\\:class is discouraged\\.$#', + 'count' => 2, 'path' => __DIR__ . '/src/Entities/User.php', ]; $ignoreErrors[] = [ @@ -255,14 +275,14 @@ 'path' => __DIR__ . '/src/Entities/User.php', ]; $ignoreErrors[] = [ - 'message' => '#^Call to function model with CodeIgniter\\\\Shield\\\\Models\\\\LoginModel\\:\\:class is discouraged\\.$#', - 'count' => 2, + 'message' => '#^Construct empty\\(\\) is not allowed\\. Use more strict comparison\\.$#', + 'count' => 8, 'path' => __DIR__ . '/src/Entities/User.php', ]; $ignoreErrors[] = [ - 'message' => '#^Call to function model with CodeIgniter\\\\Shield\\\\Models\\\\UserModel\\:\\:class is discouraged\\.$#', - 'count' => 9, - 'path' => __DIR__ . '/src/Commands/User.php', + 'message' => '#^Only booleans are allowed in a ternary operator condition, int\\<0, max\\> given\\.$#', + 'count' => 1, + 'path' => __DIR__ . '/src/Entities/User.php', ]; $ignoreErrors[] = [ 'message' => '#^Construct empty\\(\\) is not allowed\\. Use more strict comparison\\.$#', @@ -289,6 +309,11 @@ 'count' => 2, 'path' => __DIR__ . '/src/Filters/TokenAuth.php', ]; +$ignoreErrors[] = [ + 'message' => '#^Property CodeIgniter\\\\Shield\\\\Models\\\\LoginModel\\:\\:\\$validationRules \\(list\\\\|string\\) does not accept default value of type array\\{ip_address\\: \'required\', id_type\\: \'required\', identifier\\: \'permit_empty\\|string\', user_agent\\: \'permit_empty\\|string\', user_id\\: \'permit_empty\', date\\: \'required\'\\}\\.$#', + 'count' => 1, + 'path' => __DIR__ . '/src/Models/LoginModel.php', +]; $ignoreErrors[] = [ 'message' => '#^Call to deprecated function random_string\\(\\)\\: The type \'basic\', \'md5\', and \'sha1\' are deprecated\\. They are not cryptographically secure\\.$#', @@ -301,19 +326,34 @@ 'count' => 1, 'path' => __DIR__ . '/src/Models/UserIdentityModel.php', ]; +$ignoreErrors[] = [ + 'message' => '#^Call to function model with CodeIgniter\\\\Shield\\\\Models\\\\UserIdentityModel\\:\\:class is discouraged\\.$#', + 'count' => 1, + 'path' => __DIR__ . '/src/Models/UserModel.php', +]; $ignoreErrors[] = [ 'message' => '#^Construct empty\\(\\) is not allowed\\. Use more strict comparison\\.$#', 'count' => 2, 'path' => __DIR__ . '/src/Models/UserModel.php', ]; $ignoreErrors[] = [ - 'message' => '#^Call to function model with CodeIgniter\\\\Shield\\\\Models\\\\UserIdentityModel\\:\\:class is discouraged\\.$#', + 'message' => '#^Parameter \\#1 \\$row \\(array\\|CodeIgniter\\\\Shield\\\\Entities\\\\User\\) of method CodeIgniter\\\\Shield\\\\Models\\\\UserModel\\:\\:insert\\(\\) should be contravariant with parameter \\$row \\(array\\\\|object\\|null\\) of method CodeIgniter\\\\Model\\:\\:insert\\(\\)$#', 'count' => 1, 'path' => __DIR__ . '/src/Models/UserModel.php', ]; $ignoreErrors[] = [ - 'message' => '#^Return type \\(int|string|true\\) of method CodeIgniter\\\\Shield\\\\Models\\\\UserModel\\:\\:insert\\(\\) should be covariant with return type \\(\\(\\$returnID is true \\? int|string|false \\: bool\\) of method CodeIgniter\\\\Model\\:\\:insert\\(\\)\\$#', - 'count' => 4, + 'message' => '#^Parameter \\#1 \\$row \\(array\\|CodeIgniter\\\\Shield\\\\Entities\\\\User\\) of method CodeIgniter\\\\Shield\\\\Models\\\\UserModel\\:\\:save\\(\\) should be contravariant with parameter \\$row \\(array\\\\|object\\) of method CodeIgniter\\\\BaseModel\\:\\:save\\(\\)$#', + 'count' => 1, + 'path' => __DIR__ . '/src/Models/UserModel.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Parameter \\#2 \\$row \\(array\\|CodeIgniter\\\\Shield\\\\Entities\\\\User\\) of method CodeIgniter\\\\Shield\\\\Models\\\\UserModel\\:\\:update\\(\\) should be contravariant with parameter \\$row \\(array\\\\|object\\|null\\) of method CodeIgniter\\\\Model\\:\\:update\\(\\)$#', + 'count' => 1, + 'path' => __DIR__ . '/src/Models/UserModel.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Return type \\(int\\|string\\|true\\) of method CodeIgniter\\\\Shield\\\\Models\\\\UserModel\\:\\:insert\\(\\) should be covariant with return type \\(\\(\\$returnID is true \\? int\\|string\\|false \\: bool\\)\\) of method CodeIgniter\\\\Model\\:\\:insert\\(\\)$#', + 'count' => 1, 'path' => __DIR__ . '/src/Models/UserModel.php', ]; $ignoreErrors[] = [ @@ -366,24 +406,5 @@ 'count' => 1, 'path' => __DIR__ . '/tests/Unit/UserTest.php', ]; -$ignoreErrors[] = [ - 'message' => '#^Call to function model with CodeIgniter\\\\Shield\\\\Models\\\\TokenLoginModel\\:\\:class is discouraged\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/src/Authentication/Authenticators/HmacSha256.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Call to function model with CodeIgniter\\\\Shield\\\\Models\\\\UserIdentityModel\\:\\:class is discouraged\\.$#', - 'count' => 1, - 'path' => __DIR__ . '/src/Authentication/Authenticators/HmacSha256.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Call to function model with CodeIgniter\\\\Shield\\\\Models\\\\GroupModel\\:\\:class is discouraged\\.$#', - 'count' => 2, - 'path' => __DIR__ . '/src/Authorization/Traits/Authorizable.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Call to function model with CodeIgniter\\\\Shield\\\\Models\\\\PermissionModel\\:\\:class is discouraged\\.$#', - 'count' => 2, - 'path' => __DIR__ . '/src/Authorization/Traits/Authorizable.php', -]; + return ['parameters' => ['ignoreErrors' => $ignoreErrors]]; diff --git a/src/Commands/User.php b/src/Commands/User.php index 1a894d7f3..0a332ffc8 100644 --- a/src/Commands/User.php +++ b/src/Commands/User.php @@ -220,7 +220,7 @@ private function setValidationRules(): void $rules = $validationRules->getRegistrationRules(); - // Remove `strong_password` because it only supports use cases + // Remove `strong_password` rule because it only supports use cases // to check the user's own password. $passwordRules = $rules['password']['rules']; if (is_string($passwordRules)) { @@ -241,11 +241,10 @@ private function setValidationRules(): void $rules['password']['rules'] = $passwordRules; - $this->validationRules = [ - 'username' => $rules['username'], - 'email' => $rules['email'], - 'password' => $rules['password'], - ]; + // Remove `password_confirm` field. + unset($rules['password_confirm']); + + $this->validationRules = $rules; } /** @@ -258,10 +257,14 @@ private function create(?string $username = null, ?string $email = null): void { $data = []; - if ($username === null) { + // If you don't use `username`, remove the validation rules for it. + if ($username === null && isset($this->validationRules['username'])) { $username = $this->prompt('Username', null, $this->validationRules['username']['rules']); } $data['username'] = $username; + if ($username === null) { + unset($data['username']); + } if ($email === null) { $email = $this->prompt('Email', null, $this->validationRules['email']['rules']); @@ -299,9 +302,14 @@ private function create(?string $username = null, ?string $email = null): void $userModel = model(UserModel::class); $user = new UserEntity($data); - $userModel->save($user); - $this->write('User "' . $username . '" created', 'green'); + if ($username === null) { + $userModel->allowEmptyInserts()->save($user); + $this->write('New User created', 'green'); + } else { + $userModel->save($user); + $this->write('User "' . $username . '" created', 'green'); + } } /**