Browse Source

reset password

Roberto Santini 1 month ago
parent
commit
a2dbd4fbd7

+ 1
- 1
app/Actions/Fortify/CreateNewUser.php View File

@@ -24,7 +24,7 @@ class CreateNewUser implements CreatesNewUsers
24 24
             'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
25 25
             'password' => $this->passwordRules(),
26 26
             'terms' => Jetstream::hasTermsAndPrivacyPolicyFeature() ? ['accepted', 'required'] : '',
27
-        ])->validate();
27
+        ], $this->passwordValidationMessages())->validate();
28 28
 
29 29
         return User::create([
30 30
             'name' => $input['name'],

+ 10
- 2
app/Actions/Fortify/PasswordValidationRules.php View File

@@ -2,7 +2,7 @@
2 2
 
3 3
 namespace App\Actions\Fortify;
4 4
 
5
-use Illuminate\Validation\Rules\Password;
5
+use App\Support\PasswordRequirements;
6 6
 
7 7
 trait PasswordValidationRules
8 8
 {
@@ -13,6 +13,14 @@ trait PasswordValidationRules
13 13
      */
14 14
     protected function passwordRules(): array
15 15
     {
16
-        return ['required', 'string', Password::default(), 'confirmed'];
16
+        return ['required', 'string', PasswordRequirements::rule(), 'confirmed'];
17
+    }
18
+
19
+    /**
20
+     * @return array<string, string>
21
+     */
22
+    protected function passwordValidationMessages(): array
23
+    {
24
+        return PasswordRequirements::messages();
17 25
     }
18 26
 }

+ 1
- 1
app/Actions/Fortify/ResetUserPassword.php View File

@@ -20,7 +20,7 @@ class ResetUserPassword implements ResetsUserPasswords
20 20
     {
21 21
         Validator::make($input, [
22 22
             'password' => $this->passwordRules(),
23
-        ])->validate();
23
+        ], $this->passwordValidationMessages())->validate();
24 24
 
25 25
         $user->forceFill([
26 26
             'password' => Hash::make($input['password']),

+ 2
- 2
app/Actions/Fortify/UpdateUserPassword.php View File

@@ -21,9 +21,9 @@ class UpdateUserPassword implements UpdatesUserPasswords
21 21
         Validator::make($input, [
22 22
             'current_password' => ['required', 'string', 'current_password:web'],
23 23
             'password' => $this->passwordRules(),
24
-        ], [
24
+        ], array_merge($this->passwordValidationMessages(), [
25 25
             'current_password.current_password' => __('The provided password does not match your current password.'),
26
-        ])->validateWithBag('updatePassword');
26
+        ]))->validateWithBag('updatePassword');
27 27
 
28 28
         $user->forceFill([
29 29
             'password' => Hash::make($input['password']),

+ 4
- 4
app/Http/Controllers/UserController.php View File

@@ -26,6 +26,7 @@ use Intervention\Image\ImageManager;
26 26
 use Intervention\Image\Drivers\Gd\Driver;
27 27
 use Illuminate\Support\Facades\Validator;
28 28
 use App\Models\Role;
29
+use App\Support\PasswordRequirements;
29 30
 
30 31
 class UserController extends Controller implements HasMiddleware
31 32
 {
@@ -252,11 +253,10 @@ class UserController extends Controller implements HasMiddleware
252 253
 
253 254
           $validated = $request->validate([
254 255
             'current_password' => ['required', 'string', 'current_password:web'],
255
-            'password' => ['required', 'string', 'confirmed', \Illuminate\Validation\Rules\Password::default()],
256
-          ], [
256
+            'password' => ['required', 'string', 'confirmed', PasswordRequirements::rule()],
257
+          ], array_merge(PasswordRequirements::messages(), [
257 258
             'current_password.current_password' => 'La password attuale non è corretta.',
258
-            'password.confirmed' => 'La conferma password non coincide.',
259
-          ]);
259
+          ]));
260 260
 
261 261
           $user->forceFill([
262 262
             'password' => Hash::make($validated['password']),

+ 6
- 0
app/Models/User.php View File

@@ -1,6 +1,7 @@
1 1
 <?php
2 2
 namespace App\Models;
3 3
 
4
+use App\Notifications\ResetPasswordNotification;
4 5
 use Illuminate\Database\Eloquent\Factories\HasFactory;
5 6
 use Illuminate\Foundation\Auth\User as Authenticatable;
6 7
 use Illuminate\Notifications\Notifiable;
@@ -156,4 +157,9 @@ class User extends \App\Models\AbstractModels\AbstractUser
156 157
       ->whereNotNull('email')
157 158
       ->get();
158 159
   }
160
+
161
+  public function sendPasswordResetNotification($token): void
162
+  {
163
+    $this->notify(new ResetPasswordNotification($token));
164
+  }
159 165
 }

+ 14
- 47
app/Notifications/ResetPasswordNotification.php View File

@@ -2,63 +2,30 @@
2 2
 
3 3
 namespace App\Notifications;
4 4
 
5
+use Illuminate\Auth\Notifications\ResetPassword;
5 6
 use Illuminate\Bus\Queueable;
6 7
 use Illuminate\Contracts\Queue\ShouldQueue;
7 8
 use Illuminate\Notifications\Messages\MailMessage;
8
-use Illuminate\Notifications\Notification;
9 9
 
10
-class ResetPasswordNotification extends Notification implements ShouldQueue
10
+class ResetPasswordNotification extends ResetPassword implements ShouldQueue
11 11
 {
12 12
   use Queueable;
13
-  public $url = "";
14 13
 
15 14
   /**
16
-  * Create a new notification instance.
17
-  *
18
-  * @return void
19
-  */
20
-  public function __construct($url)
21
-  {
22
-    $this->url = $url;
23
-  }
24
-
25
-  /**
26
-  * Get the notification's delivery channels.
27
-  *
28
-  * @param  mixed  $notifiable
29
-  * @return array
30
-  */
31
-  public function via($notifiable)
32
-  {
33
-    return ['mail'];
34
-  }
35
-
36
-  /**
37
-  * Get the mail representation of the notification.
38
-  *
39
-  * @param  mixed  $notifiable
40
-  * @return \Illuminate\Notifications\Messages\MailMessage
41
-  */
15
+   * Get the mail representation of the notification.
16
+   *
17
+   * @param  mixed  $notifiable
18
+   * @return \Illuminate\Notifications\Messages\MailMessage
19
+   */
42 20
   public function toMail($notifiable)
43 21
   {
44
-    return (new MailMessage)
45
-    ->subject('Reset password')
46
-    ->line('Hai ricevuto questa email perché abbiamo ricevuto una richiesta di reimpostazione della password per il tuo account.')
47
-    ->action('Reset Password', $this->url)
48
-    ->line('Questo link per la reimpostazione della password scadrà tra 60 minuti.')
49
-    ->line('Se non hai richiesto la reimpostazione della password, non sono necessarie ulteriori azioni.');
50
-  }
22
+    $expire = (int) config('auth.passwords.users.expire', 60);
51 23
 
52
-  /**
53
-  * Get the array representation of the notification.
54
-  *
55
-  * @param  mixed  $notifiable
56
-  * @return array
57
-  */
58
-  public function toArray($notifiable)
59
-  {
60
-    return [
61
-      //
62
-    ];
24
+    return (new MailMessage)
25
+      ->subject('Reimposta la password')
26
+      ->line('Hai ricevuto questa email perché abbiamo ricevuto una richiesta di reimpostazione della password per il tuo account.')
27
+      ->action('Reimposta la password', $this->resetUrl($notifiable))
28
+      ->line("Questo link per la reimpostazione della password scadrà tra {$expire} minuti.")
29
+      ->line('Se non hai richiesto la reimpostazione della password, non sono necessarie ulteriori azioni.');
63 30
   }
64 31
 }

+ 28
- 0
app/Support/PasswordRequirements.php View File

@@ -0,0 +1,28 @@
1
+<?php
2
+
3
+namespace App\Support;
4
+
5
+use Illuminate\Validation\Rules\Password;
6
+
7
+class PasswordRequirements
8
+{
9
+    public const HINT = 'La password deve contenere almeno 6 caratteri, un numero e un simbolo.';
10
+
11
+    public static function rule(): Password
12
+    {
13
+        return Password::min(6)->numbers()->symbols();
14
+    }
15
+
16
+    /**
17
+     * @return array<string, string>
18
+     */
19
+    public static function messages(): array
20
+    {
21
+        return [
22
+            'password.min' => 'La password deve contenere almeno 6 caratteri.',
23
+            'password.numbers' => 'La password deve contenere almeno un numero.',
24
+            'password.symbols' => 'La password deve contenere almeno un simbolo.',
25
+            'password.confirmed' => 'La conferma della password non corrisponde.',
26
+        ];
27
+    }
28
+}

+ 6
- 0
lang/it.json View File

@@ -89,6 +89,12 @@
89 89
   "Resend Verification Email": "Invia nuovamente email di verifica",
90 90
   "Reset Content": "Resetta il contenuto",
91 91
   "Reset Password": "Resetta la password",
92
+  "Reset Password Notification": "Reimposta la password",
93
+  "You are receiving this email because we received a password reset request for your account.": "Hai ricevuto questa email perché abbiamo ricevuto una richiesta di reimpostazione della password per il tuo account.",
94
+  "This password reset link will expire in :count minutes.": "Questo link per la reimpostazione della password scadrà tra :count minuti.",
95
+  "If you did not request a password reset, no further action is required.": "Se non hai richiesto la reimpostazione della password, non sono necessarie ulteriori azioni.",
96
+  "Hello!": "Ciao!",
97
+  "Regards": "Cordiali saluti",
92 98
   "Retry With": "Riprova con",
93 99
   "Save": "Salva",
94 100
   "Saved.": "Salvato.",

+ 1
- 0
resources/views/profile/edit_profile.blade.php View File

@@ -260,6 +260,7 @@
260 260
           <div class="mb-3">
261 261
             <label class="form-label" for="password">Nuova password</label>
262 262
             <input type="password" class="form-control @error('password') is-invalid @enderror" id="password" name="password" autocomplete="new-password" required>
263
+            <div class="form-text">{{ \App\Support\PasswordRequirements::HINT }}</div>
263 264
             @error('password')
264 265
             <div class="invalid-feedback">{{ $message }}</div>
265 266
             @enderror

+ 6
- 6
tests/Feature/PasswordResetTest.php View File

@@ -3,7 +3,7 @@
3 3
 namespace Tests\Feature;
4 4
 
5 5
 use App\Models\User;
6
-use Illuminate\Auth\Notifications\ResetPassword;
6
+use App\Notifications\ResetPasswordNotification;
7 7
 use Illuminate\Foundation\Testing\RefreshDatabase;
8 8
 use Illuminate\Support\Facades\Notification;
9 9
 use Laravel\Fortify\Features;
@@ -38,7 +38,7 @@ class PasswordResetTest extends TestCase
38 38
             'email' => $user->email,
39 39
         ]);
40 40
 
41
-        Notification::assertSentTo($user, ResetPassword::class);
41
+        Notification::assertSentTo($user, ResetPasswordNotification::class);
42 42
     }
43 43
 
44 44
     public function test_reset_password_screen_can_be_rendered(): void
@@ -55,7 +55,7 @@ class PasswordResetTest extends TestCase
55 55
             'email' => $user->email,
56 56
         ]);
57 57
 
58
-        Notification::assertSentTo($user, ResetPassword::class, function (object $notification) {
58
+        Notification::assertSentTo($user, ResetPasswordNotification::class, function (object $notification) {
59 59
             $response = $this->get('/reset-password/'.$notification->token);
60 60
 
61 61
             $response->assertStatus(200);
@@ -78,12 +78,12 @@ class PasswordResetTest extends TestCase
78 78
             'email' => $user->email,
79 79
         ]);
80 80
 
81
-        Notification::assertSentTo($user, ResetPassword::class, function (object $notification) use ($user) {
81
+        Notification::assertSentTo($user, ResetPasswordNotification::class, function (object $notification) use ($user) {
82 82
             $response = $this->post('/reset-password', [
83 83
                 'token' => $notification->token,
84 84
                 'email' => $user->email,
85
-                'password' => 'password',
86
-                'password_confirmation' => 'password',
85
+                'password' => 'Password1!',
86
+                'password_confirmation' => 'Password1!',
87 87
             ]);
88 88
 
89 89
             $response->assertSessionHasNoErrors();

+ 2
- 2
tests/Feature/RegistrationTest.php View File

@@ -42,8 +42,8 @@ class RegistrationTest extends TestCase
42 42
         $response = $this->post('/register', [
43 43
             'name' => 'Test User',
44 44
             'email' => 'test@example.com',
45
-            'password' => 'password',
46
-            'password_confirmation' => 'password',
45
+            'password' => 'Password1!',
46
+            'password_confirmation' => 'Password1!',
47 47
             'terms' => Jetstream::hasTermsAndPrivacyPolicyFeature(),
48 48
         ]);
49 49
 

+ 6
- 6
tests/Feature/UpdatePasswordTest.php View File

@@ -20,12 +20,12 @@ class UpdatePasswordTest extends TestCase
20 20
         Livewire::test(UpdatePasswordForm::class)
21 21
             ->set('state', [
22 22
                 'current_password' => 'password',
23
-                'password' => 'new-password',
24
-                'password_confirmation' => 'new-password',
23
+                'password' => 'Password1!',
24
+                'password_confirmation' => 'Password1!',
25 25
             ])
26 26
             ->call('updatePassword');
27 27
 
28
-        $this->assertTrue(Hash::check('new-password', $user->fresh()->password));
28
+        $this->assertTrue(Hash::check('Password1!', $user->fresh()->password));
29 29
     }
30 30
 
31 31
     public function test_current_password_must_be_correct(): void
@@ -35,8 +35,8 @@ class UpdatePasswordTest extends TestCase
35 35
         Livewire::test(UpdatePasswordForm::class)
36 36
             ->set('state', [
37 37
                 'current_password' => 'wrong-password',
38
-                'password' => 'new-password',
39
-                'password_confirmation' => 'new-password',
38
+                'password' => 'Password1!',
39
+                'password_confirmation' => 'Password1!',
40 40
             ])
41 41
             ->call('updatePassword')
42 42
             ->assertHasErrors(['current_password']);
@@ -51,7 +51,7 @@ class UpdatePasswordTest extends TestCase
51 51
         Livewire::test(UpdatePasswordForm::class)
52 52
             ->set('state', [
53 53
                 'current_password' => 'password',
54
-                'password' => 'new-password',
54
+                'password' => 'Password1!',
55 55
                 'password_confirmation' => 'wrong-password',
56 56
             ])
57 57
             ->call('updatePassword')

+ 15
- 0
tests/Unit/PasswordRequirementsTest.php View File

@@ -0,0 +1,15 @@
1
+<?php
2
+
3
+namespace Tests\Unit;
4
+
5
+use App\Support\PasswordRequirements;
6
+use Tests\TestCase;
7
+
8
+class PasswordRequirementsTest extends TestCase
9
+{
10
+    public function test_hint_is_defined(): void
11
+    {
12
+        $this->assertNotEmpty(PasswordRequirements::HINT);
13
+        $this->assertStringContainsString('6 caratteri', PasswordRequirements::HINT);
14
+    }
15
+}

Loading…
Cancel
Save