implement forgot password system

This commit is contained in:
Nima8FT 2025-04-23 12:59:57 +03:30
parent 062d860c84
commit c7f24c2340
7 changed files with 213 additions and 1 deletions

View File

@ -0,0 +1,57 @@
<?php
namespace App\Http\Controllers\Auth;
use App\Models\User;
use Illuminate\Support\Str;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Password;
use Illuminate\Auth\Events\PasswordReset;
use App\Http\Requests\ResetPasswordRequest;
use App\Http\Requests\ForgotPasswordNotificationRequest;
class PasswordController extends Controller
{
public function forgotPasswordPage()
{
return view("auth.forgot-password");
}
public function forgotPasswordNotification(ForgotPasswordNotificationRequest $request)
{
$status = Password::sendResetLink(
$request->only('email')
);
return $status === Password::ResetLinkSent
? back()->with(['status' => __($status)])
: back()->withErrors(['email' => __($status)]);
}
public function resetPasswordPage(Request $request, $token)
{
$data['email'] = $request->email;
$data['token'] = $token;
return view('auth.reset-password', compact('data'));
}
public function resetPassword(ResetPasswordRequest $request)
{
$status = Password::reset(
$request->only('email', 'password', 'password_confirmation', 'token'),
function (User $user, string $password) {
$user->forceFill([
'password' => Hash::make($password)
])->setRememberToken(Str::random(60));
$user->save();
event(new PasswordReset($user));
}
);
return $status === Password::PasswordReset
? redirect()->route('login')->with('status', __($status))
: back()->withErrors(['email' => [__($status)]]);
}
}

View File

@ -0,0 +1,28 @@
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class ForgotPasswordNotificationRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
*/
public function rules(): array
{
return [
'email' => 'required|email|exists:users'
];
}
}

View File

@ -0,0 +1,29 @@
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class ResetPasswordRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
*/
public function rules(): array
{
return [
'email' => 'required|email|exists:users,email',
'password' => 'required|min:8|confirmed',
];
}
}

View File

@ -0,0 +1,36 @@
@extends('layouts.app')
@section('content')
<div class="flex justify-center items-center min-h-screen bg-gray-100 dark:bg-gray-900">
<div class="w-full max-w-md bg-white dark:bg-gray-800 shadow-md rounded-lg p-6">
<h2 class="text-2xl font-bold text-center text-gray-800 dark:text-gray-200 mb-6">Reset Password</h2>
@if (session('status'))
<div class="mb-4 text-sm text-green-600 dark:text-green-400">
{{ session('status') }}
</div>
@endif
<form method="POST" action="{{route('password.email')}}">
@csrf
<div class="mb-4">
<label for="email" class="block text-gray-700 dark:text-gray-300 font-medium mb-2">Email Address</label>
<input id="email" type="email" name="email" required autofocus autocomplete="email"
class="w-full px-4 py-2 border rounded-lg text-gray-900 dark:text-gray-100 bg-white dark:bg-gray-700 border-gray-300 dark:border-gray-600 focus:outline-none focus:ring-2 focus:ring-blue-500 @error('email') border-red-500 @enderror">
@error('email')
<p class="text-red-600 text-sm mt-2">{{ $message }}</p>
@enderror
</div>
<div class="flex justify-center">
<button type="submit"
class="bg-blue-600 hover:bg-blue-700 text-white font-semibold py-2 px-4 rounded-lg transition duration-300 cursor-pointer">
Send Password Reset Link
</button>
</div>
</form>
</div>
</div>
@endsection

View File

@ -30,7 +30,7 @@
</div> </div>
<div class="text-[#e0e1dd] flex justify-between"> <div class="text-[#e0e1dd] flex justify-between">
<a href="#ss" <a href="{{route('password.request')}}"
class="cursor-pointer font-medium underline hover:opacity-85 transition duration-300 ease-in-out">Forgot class="cursor-pointer font-medium underline hover:opacity-85 transition duration-300 ease-in-out">Forgot
Password</a> Password</a>
<a href="{{route('register.store')}}" <a href="{{route('register.store')}}"

View File

@ -0,0 +1,51 @@
@extends('layouts.app')
@section('content')
<div class="flex items-center justify-center min-h-screen bg-gray-100 dark:bg-gray-900">
<div class="w-full max-w-md bg-white dark:bg-gray-800 shadow-md rounded-lg p-6">
<h2 class="text-2xl font-bold text-center text-gray-800 dark:text-gray-100 mb-6">
Reset Password
</h2>
@if (session()->has('status'))
<div class="mb-4 text-green-600 dark:text-green-400">
{{ session('status') }}
</div>
@endif
<form method="POST" action="{{route('password.update')}}">
@csrf
<input type="hidden" name="token" value="{{ $data['token']}}">
<div class="mb-4">
<label for="email" class="block text-gray-700 dark:text-gray-300 font-medium mb-2">Email</label>
<input type="email" id="email" name="email" value="{{$data['email']}}"
class="w-full px-4 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 dark:bg-gray-700 dark:text-white @error('email') border-red-500 @enderror">
@error('email') <span class="text-red-500 text-sm">{{ $message }}</span> @enderror
</div>
{{-- Password --}}
<div class="mb-4">
<label for="password" class="block text-gray-700 dark:text-gray-300 font-medium mb-2">New
Password</label>
<input type="password" id="password" name="password"
class="w-full px-4 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 dark:bg-gray-700 dark:text-white @error('password') border-red-500 @enderror">
@error('password') <span class="text-red-500 text-sm">{{ $message }}</span> @enderror
</div>
{{-- Password Confirmation --}}
<div class="mb-6">
<label for="password_confirmation"
class="block text-gray-700 dark:text-gray-300 font-medium mb-2">Confirm Password</label>
<input type="password" id="password_confirmation" name="password_confirmation"
class="w-full px-4 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 dark:bg-gray-700 dark:text-white">
</div>
<button type="submit"
class="w-full bg-blue-600 hover:bg-blue-700 text-white font-semibold py-2 rounded-lg transition duration-300 cursor-pointer">
Reset Password
</button>
</form>
</div>
</div>
@endsection

View File

@ -3,6 +3,7 @@
use App\Http\Controllers\Auth\LoginController; use App\Http\Controllers\Auth\LoginController;
use App\Http\Controllers\Auth\LogoutController; use App\Http\Controllers\Auth\LogoutController;
use App\Http\Controllers\Auth\MailController; use App\Http\Controllers\Auth\MailController;
use App\Http\Controllers\Auth\PasswordController;
use App\Http\Controllers\Auth\RegisterController; use App\Http\Controllers\Auth\RegisterController;
use App\Http\Controllers\DashboardController; use App\Http\Controllers\DashboardController;
use Illuminate\Support\Facades\Route; use Illuminate\Support\Facades\Route;
@ -27,3 +28,13 @@ Route::group(['middleware' => 'auth'], function () {
Route::post('email/verification-notification', [MailController::class, 'notification'])->name('verification.send'); Route::post('email/verification-notification', [MailController::class, 'notification'])->name('verification.send');
Route::get('email/verify/{id}/{hash}', [MailController::class, 'verify'])->name('verification.verify'); Route::get('email/verify/{id}/{hash}', [MailController::class, 'verify'])->name('verification.verify');
}); });
Route::group(['middleware' => 'guest'], function () {
//forgot password
// Route::get('forgot-password', [PasswordController::class, 'forgotPasswordPage'])->name('password.request');
Route::get('forgot-password-page', [PasswordController::class, 'forgotPasswordPage'])->name('password.request');
Route::post('forgot-password', [PasswordController::class, 'forgotPasswordNotification'])->name('password.email');
Route::get('reset-password/{token}', [PasswordController::class, 'resetPasswordPage'])->name('password.reset');
Route::post('reset-password', [PasswordController::class, 'resetPassword'])->name('password.update');
});