From c726c40e8c8038e8163cd8fdafe2fc1158c453a9 Mon Sep 17 00:00:00 2001 From: Isaac Hatilima Date: Wed, 9 Oct 2024 22:28:07 +0200 Subject: [PATCH] Validation refactoring --- .github/workflows/laravel.yml | 2 - app/Http/Requests/ConfirmPasswordRequest.php | 5 +-- app/Http/Requests/PasswordUpdateRequest.php | 20 +++------ app/Http/Requests/ProfileUpdateRequest.php | 23 +++++++--- app/Http/Requests/RegisterRequest.php | 43 ++++++++----------- app/Validations/ConfirmPasswordValidation.php | 8 ++++ app/Validations/NewEmailValidation.php | 18 ++++++-- app/Validations/NewPasswordValidation.php | 14 ++++++ app/Validations/RequiredInputValidation.php | 21 ++++++++- app/Validations/UpdateWithEmailValidation.php | 18 +++++++- resources/js/Pages/Auth/Login.vue | 2 +- .../Partials/UpdateProfileInformationForm.vue | 6 ++- 12 files changed, 123 insertions(+), 57 deletions(-) diff --git a/.github/workflows/laravel.yml b/.github/workflows/laravel.yml index bd83c84..2197774 100644 --- a/.github/workflows/laravel.yml +++ b/.github/workflows/laravel.yml @@ -1,8 +1,6 @@ name: Laravel on: - push: - branches: [ "master" ] pull_request: branches: [ "master" ] diff --git a/app/Http/Requests/ConfirmPasswordRequest.php b/app/Http/Requests/ConfirmPasswordRequest.php index 149f5b9..1ec8e03 100644 --- a/app/Http/Requests/ConfirmPasswordRequest.php +++ b/app/Http/Requests/ConfirmPasswordRequest.php @@ -28,9 +28,6 @@ public function rules(): array public function messages(): array { - return [ - 'required' => 'Password is required.', - 'current_password' => 'Password is incorrect.', - ]; + return ConfirmPasswordValidation::messages(); } } diff --git a/app/Http/Requests/PasswordUpdateRequest.php b/app/Http/Requests/PasswordUpdateRequest.php index a2adfdb..18b2cea 100644 --- a/app/Http/Requests/PasswordUpdateRequest.php +++ b/app/Http/Requests/PasswordUpdateRequest.php @@ -37,18 +37,12 @@ public function rules(): array public function messages(): array { - return [ - 'current_password.required' => 'Current password is required.', - 'current_password.current_password' => 'Your current password is incorrect.', - - 'password.required' => 'New password is required.', - 'password.regex' => 'New password must contain at least one upper and lower case letter, one number, and one special character (!, $, #, %, @, ?).', - 'password.min' => 'New password must be at least 8 characters long.', - 'password.required_with' => 'New password confirmation is required.', - 'password.same' => 'Password and confirmation must match.', - - 'password_confirmation.required' => 'Please confirm your new password.', - 'password_confirmation.same' => 'Password confirmation does not match the new password.', - ]; + return array_merge( + NewPasswordValidation::messages(), + [ + 'current_password.required' => 'Current password is required.', + 'current_password.current_password' => 'Your current password is incorrect.', + ] + ); } } diff --git a/app/Http/Requests/ProfileUpdateRequest.php b/app/Http/Requests/ProfileUpdateRequest.php index c27a1f9..7902e30 100644 --- a/app/Http/Requests/ProfileUpdateRequest.php +++ b/app/Http/Requests/ProfileUpdateRequest.php @@ -2,7 +2,6 @@ namespace App\Http\Requests; -use App\Validations\NewEmailValidation; use App\Validations\RequiredInputValidation; use App\Validations\UpdateWithEmailValidation; use Illuminate\Contracts\Validation\Rule; @@ -18,13 +17,27 @@ class ProfileUpdateRequest extends FormRequest public function rules(): array { return array_merge( - NewEmailValidation::rules(), - RequiredInputValidation::rules('first_name'), - RequiredInputValidation::rules('last_name'), + (new RequiredInputValidation('first_name'))->rules(), + (new RequiredInputValidation('last_name'))->rules(), UpdateWithEmailValidation::rules($this->user()->id), [ 'date_of_birth' => ['nullable', 'date', 'date_format:Y-m-d'], - 'gender' => ['nullable', 'in:male,female'], + 'gender' => ['nullable', 'in:male,female, diverse'], + ] + ); + } + + public function messages(): array + { + return array_merge( + (new RequiredInputValidation('first_name'))->messages(), + (new RequiredInputValidation('last_name'))->messages(), + [ + 'date_of_birth.date' => 'Value must be a valid date.', + 'date_of_birth.regex' => 'Invalid date format.', + + 'gender.in' => 'Invalid gender.', + ] ); } diff --git a/app/Http/Requests/RegisterRequest.php b/app/Http/Requests/RegisterRequest.php index 99708b3..b42ad8b 100644 --- a/app/Http/Requests/RegisterRequest.php +++ b/app/Http/Requests/RegisterRequest.php @@ -28,35 +28,28 @@ public function rules(): array return array_merge( NewEmailValidation::rules(), NewPasswordValidation::rules(), - RequiredInputValidation::rules('first_name'), - RequiredInputValidation::rules('last_name'), + (new RequiredInputValidation('first_name'))->rules(), + (new RequiredInputValidation('last_name'))->rules() ); } public function messages(): array { - return [ - 'email.required' => 'Email is required.', - 'email.string' => 'Email MUST be a string.', - 'email.lowercase' => 'Email MUST be lowercase letters.', - 'email.email' => 'Invalid email format.', - 'email.max' => 'Email is too long.', - 'email.unique' => 'Email is already in use.', - - - 'password.required' => 'Password is required.', - 'password.regex' => 'Password must contain at least one upper and lower case letter, one number, and one special character (!, $, #, %, @, ?).', - 'password.min' => 'Password must be at least 8 characters long.', - 'password.required_with' => 'Password confirmation is required.', - 'password.same' => 'Password and confirmation must match.', - - 'password_confirmation.required' => 'Please confirm your password.', - 'password_confirmation.same' => 'Password confirmation does not match the new password.', - - 'first_name.required' => 'First Name is required.', - 'first_name.string' => 'First Name MUST be a string.', - 'last_name.required' => 'Last Name is required.', - 'last_name.string' => 'Last Name MUST be a string.', - ]; + return array_merge( + NewEmailValidation::messages(), + (new RequiredInputValidation('first_name'))->messages(), + (new RequiredInputValidation('last_name'))->messages(), + [ + 'password.required' => 'Password is required.', + 'password.regex' => 'Password must contain at least one upper and lower case letter, one number, and one special character (!, $, #, %, @, ?).', + 'password.min' => 'Password must be at least 8 characters long.', + 'password.required_with' => 'Password confirmation is required.', + 'password.same' => 'Password and confirmation must match.', + + 'password_confirmation.required' => 'Please confirm your password.', + 'password_confirmation.same' => 'Password confirmation does not match the new password.', + + ] + ); } } diff --git a/app/Validations/ConfirmPasswordValidation.php b/app/Validations/ConfirmPasswordValidation.php index f0c501c..89befde 100644 --- a/app/Validations/ConfirmPasswordValidation.php +++ b/app/Validations/ConfirmPasswordValidation.php @@ -13,4 +13,12 @@ public static function rules(): array ] ]; } + + public static function messages(): array + { + return [ + 'password.required' => 'Password is required.', + 'password.current_password' => 'Password is not correct.' + ]; + } } diff --git a/app/Validations/NewEmailValidation.php b/app/Validations/NewEmailValidation.php index 405c0de..5c251b3 100644 --- a/app/Validations/NewEmailValidation.php +++ b/app/Validations/NewEmailValidation.php @@ -13,10 +13,22 @@ public static function rules(): array 'required', 'string', 'lowercase', - 'email:rfc,dns', - 'max:255', - 'unique:'.User::class + 'email:rfc' . (!app()->environment('production') ? '' : ',dns'), + 'max:50', + 'unique:' . User::class, ] ]; } + + public static function messages(): array + { + return [ + 'email.required' => 'Email is required.', + 'email.string' => 'Email MUST be a string.', + 'email.lowercase' => 'Email MUST be lowercase letters.', + 'email.email' => 'Invalid email format.', + 'email.max' => 'Email is too long.', + 'email.unique' => 'Email is already in use.', + ]; + } } diff --git a/app/Validations/NewPasswordValidation.php b/app/Validations/NewPasswordValidation.php index 8b7f5f1..5433e05 100644 --- a/app/Validations/NewPasswordValidation.php +++ b/app/Validations/NewPasswordValidation.php @@ -20,4 +20,18 @@ public static function rules(): array ] ]; } + + public static function messages(): array + { + return [ + 'password.required' => 'New password is required.', + 'password.regex' => 'New password must contain at least one upper and lower case letter, one number, and one special character (!, $, #, %, @, ?).', + 'password.min' => 'New password must be at least 8 characters long.', + 'password.required_with' => 'New password confirmation is required.', + 'password.same' => 'Password and confirmation must match.', + + 'password_confirmation.required' => 'Please confirm your new password.', + 'password_confirmation.same' => 'Password confirmation does not match the new password.', + ]; + } } diff --git a/app/Validations/RequiredInputValidation.php b/app/Validations/RequiredInputValidation.php index 2ea6e40..0d6b3fb 100644 --- a/app/Validations/RequiredInputValidation.php +++ b/app/Validations/RequiredInputValidation.php @@ -4,14 +4,31 @@ class RequiredInputValidation { - public static function rules(string $attribute): array + private string $attribute; + + public function __construct(string $attribute) + { + $this->attribute = $attribute; + } + + public function rules(): array { return [ - $attribute => [ + $this->attribute => [ 'required', 'string', 'min:2' ] ]; } + + public function messages(): array + { + $formattedAttribute = ucwords(str_replace('_', ' ', $this->attribute)); + + return [ + $this->attribute.'.required' => $formattedAttribute.' is required.', + $this->attribute.'.string' => $formattedAttribute.' MUST be a string.', + ]; + } } diff --git a/app/Validations/UpdateWithEmailValidation.php b/app/Validations/UpdateWithEmailValidation.php index 25d8448..4c7afbb 100644 --- a/app/Validations/UpdateWithEmailValidation.php +++ b/app/Validations/UpdateWithEmailValidation.php @@ -11,9 +11,25 @@ public static function rules(int $userId): array { return [ 'email' => [ - 'required', 'string', 'lowercase', 'email:rfc,dns', 'max:255', + 'required', + 'string', + 'lowercase', + 'email:rfc' . (!app()->environment('production') ? '' : ',dns'), + 'max:50', Rule::unique(User::class)->ignore($userId) ] ]; } + + public static function messages(): array + { + return [ + 'email.required' => 'Email is required.', + 'email.string' => 'Email MUST be a string.', + 'email.lowercase' => 'Email MUST be lowercase letters.', + 'email.email' => 'Invalid email format.', + 'email.max' => 'Email is too long.', + 'email.unique' => 'Email is already in use.', + ]; + } } diff --git a/resources/js/Pages/Auth/Login.vue b/resources/js/Pages/Auth/Login.vue index 3a0b2a9..d005567 100644 --- a/resources/js/Pages/Auth/Login.vue +++ b/resources/js/Pages/Auth/Login.vue @@ -52,7 +52,7 @@ function handleGoogleLogin() :class="{ 'border-red-500': form.errors.email }" v-model="form.email" autofocus - autocomplete="username"/> + autocomplete="email"/> diff --git a/resources/js/Pages/Profile/Partials/UpdateProfileInformationForm.vue b/resources/js/Pages/Profile/Partials/UpdateProfileInformationForm.vue index 7bd5a1a..0e603a3 100644 --- a/resources/js/Pages/Profile/Partials/UpdateProfileInformationForm.vue +++ b/resources/js/Pages/Profile/Partials/UpdateProfileInformationForm.vue @@ -132,10 +132,14 @@ function submitForm() { +
+ + +
-
+

Your email address is unverified.