diff --git a/app/Http/Controllers/NewPasswordController.php b/app/Http/Controllers/NewPasswordController.php new file mode 100644 index 0000000..e7e01c4 --- /dev/null +++ b/app/Http/Controllers/NewPasswordController.php @@ -0,0 +1,45 @@ + $request, 'token' => $token]); + } + + public function store(Request $request) + { + $request->validate([ + 'token' => 'required', + 'email' => 'required|email', + 'password' => 'required|min:8|confirmed', + ]); + + $status = Password::reset( + $request->only('email', 'password', 'password_confirmation', 'token'), + function ($user, $password) { + $user->forceFill([ + 'password' => Hash::make($password) + ])->setRememberToken(Str::random(60)); + + $user->save(); + + event(new PasswordReset($user)); + } + ); + + if ($status == Password::PASSWORD_RESET) { + return redirect()->route('login')->with('status', __($status)); + } + + return back()->withErrors(['email' => [__($status)]]); + } +} diff --git a/app/Http/Controllers/PasswordResetLinkController.php b/app/Http/Controllers/PasswordResetLinkController.php new file mode 100644 index 0000000..cca2052 --- /dev/null +++ b/app/Http/Controllers/PasswordResetLinkController.php @@ -0,0 +1,31 @@ +validate([ + 'email' => 'required|email', + ]); + + $status = Password::sendResetLink( + $request->only('email') + ); + + if ($status == Password::RESET_LINK_SENT) { + return back()->with('status', __($status)); + } + + return back()->withErrors(['email' => __($status)]); + } +} diff --git a/app/Models/User.php b/app/Models/User.php index 5c0bb00..d806001 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -6,6 +6,7 @@ namespace App\Models; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Foundation\Auth\User as Authenticatable; use Illuminate\Notifications\Notifiable; +use App\Notifications\ResetPasswordNotification; class User extends Authenticatable { @@ -45,4 +46,15 @@ class User extends Authenticatable 'password' => 'hashed', ]; } + + /** + * Send the password reset notification. + * + * @param string $token + * @return void + */ + public function sendPasswordResetNotification($token) + { + $this->notify(new ResetPasswordNotification($token)); + } } diff --git a/app/Notifications/ResetPasswordNotification.php b/app/Notifications/ResetPasswordNotification.php new file mode 100644 index 0000000..d2bcfeb --- /dev/null +++ b/app/Notifications/ResetPasswordNotification.php @@ -0,0 +1,26 @@ + $this->token, + 'email' => $notifiable->getEmailForPasswordReset(), + ], false)); + + return (new MailMessage) + ->subject('Recuperación de Contraseña - Lauck') + ->view('emails.reset-password', [ + 'url' => $url, + ]); + } +} diff --git a/resources/views/auth/forgot-password.blade.php b/resources/views/auth/forgot-password.blade.php new file mode 100644 index 0000000..3c6e665 --- /dev/null +++ b/resources/views/auth/forgot-password.blade.php @@ -0,0 +1,51 @@ + +
+ + +
+
+ ¿Olvidaste tu contraseña? No hay problema. Simplemente déjanos saber tu dirección de correo electrónico y te enviaremos un enlace para restablecer la contraseña que te permitirá elegir una nueva. +
+ + @if (session('status')) +
+ {{ session('status') }} +
+ @endif + +
+ @csrf + + @if ($errors->any()) +
+

+ {{ $errors->first() }} +

+
+ @endif + + +
+ + +
+ +
+ + Volver a inicio de sesión + + + +
+
+
+
+
diff --git a/resources/views/auth/reset-password.blade.php b/resources/views/auth/reset-password.blade.php new file mode 100644 index 0000000..7c7eb32 --- /dev/null +++ b/resources/views/auth/reset-password.blade.php @@ -0,0 +1,56 @@ + +
+ + +
+
+ @csrf + + + + + @if ($errors->any()) +
+
    + @foreach ($errors->all() as $error) +
  • {{ $error }}
  • + @endforeach +
+
+ @endif + + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ +
+ +
+
+
+
+
diff --git a/resources/views/emails/reset-password.blade.php b/resources/views/emails/reset-password.blade.php new file mode 100644 index 0000000..c7795fa --- /dev/null +++ b/resources/views/emails/reset-password.blade.php @@ -0,0 +1,71 @@ + + + + + + Recuperar Contraseña + + + + + + +
+ + + + + + + + + + + + + + + + + +
+

+ Bicicletería Lauck +

+

Recuperación de cuenta

+
+

+ Hola, +

+

+ Estás recibiendo este correo porque recibimos una solicitud de restablecimiento de contraseña para tu cuenta en Lauck. +

+ + + + + +
+ + Restablecer Contraseña + +
+ +

+ Este enlace para restablecer la contraseña caducará en 60 minutos. +

+

+ Si no solicitaste un restablecimiento de contraseña, no es necesario realizar ninguna otra acción. +

+
+

+ Si tienes problemas para hacer clic en el botón "Restablecer Contraseña", copia y pega la siguiente URL en tu navegador web:
+ {{ $url }} +

+
+

+ © {{ date('Y') }} Bicicletería Lauck. Todos los derechos reservados. +

+
+ + diff --git a/resources/views/login.blade.php b/resources/views/login.blade.php index 9e0bc6b..ad06a6e 100644 --- a/resources/views/login.blade.php +++ b/resources/views/login.blade.php @@ -1,44 +1,65 @@ -
- -
-
+
+ + +
+ @csrf + {{-- Bloque de errores --}} @if ($errors->any()) -
+

{{ $errors->first() }}

@endif + + @if (session('status')) +
+

+ {{ session('status') }} +

+
+ @endif
- Correo electrónico - + +
- Contraseña - + + + +
- +
-

- ¿No tienes una cuenta? Regístrate acá. -

+
+

+ ¿No tienes una cuenta? Regístrate acá. +

+
+ \ No newline at end of file diff --git a/routes/web.php b/routes/web.php index e5ee711..51f733a 100644 --- a/routes/web.php +++ b/routes/web.php @@ -13,6 +13,8 @@ use App\Http\Controllers\TallerController; use App\Http\Controllers\AgendaController; use App\Http\Controllers\AppointmentController; use App\Http\Controllers\SupplierController; +use App\Http\Controllers\PasswordResetLinkController; +use App\Http\Controllers\NewPasswordController; use App\Models\Product; use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Session; @@ -25,6 +27,20 @@ Route::resource('catalogo', CatalogoController::class)->only(['index', 'show'])- Route::get('login', function(){ return view('login'); })->name('login'); Route::post('login', LoginController::class)->middleware('throttle:5,1')->name('login.attempt'); +Route::middleware('guest')->group(function () { + Route::get('forgot-password', [PasswordResetLinkController::class, 'create']) + ->name('password.request'); + + Route::post('forgot-password', [PasswordResetLinkController::class, 'store']) + ->name('password.email'); + + Route::get('reset-password/{token}', [NewPasswordController::class, 'create']) + ->name('password.reset'); + + Route::post('reset-password', [NewPasswordController::class, 'store']) + ->name('password.store'); +}); + Route::view('register', 'register')->name('register'); Route::post('register', RegisterController::class)->name('register.store');