feat(auth): func forgot password

This commit is contained in:
arieeefajar 2025-01-23 21:50:02 +07:00
parent 968a9598fb
commit 78923e7276
8 changed files with 209 additions and 56 deletions

View File

@ -3,12 +3,12 @@
namespace App\Http\Controllers\Auth; namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller; use App\Http\Controllers\Controller;
use App\Models\PasswordResetToken; use App\Mail\ResetPasswordMail;
use Illuminate\Http\RedirectResponse; use App\Models\User;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash; use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Password; use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Validator; use Illuminate\Support\Facades\Validator;
use Illuminate\View\View; use Illuminate\View\View;
@ -45,30 +45,49 @@ public function store(Request $request)
return redirect()->back()->withInput(); return redirect()->back()->withInput();
} }
DB::table('password_reset_tokens')->updateOrInsert(['email' => $request->email], [ DB::table('password_reset_tokens')->updateOrInsert(
'token' => Hash::make($request->_token), ['email' => $request->email],
'created_at' => now(), [
]); 'token' => Hash::make($request->_token),
'created_at' => now(),
]
);
$resetLink = route('auth.create_new_password_form', ['token' => $request->_token, 'email' => $request->email]);
Mail::to($request->email)->send(new ResetPasswordMail($resetLink));
alert()->success('Berhasil', 'Silahkan cek email anda untuk mereset password'); alert()->success('Berhasil', 'Silahkan cek email anda untuk mereset password');
return redirect()->back(); return redirect()->back();
} }
// public function store(Request $request): RedirectResponse
// {
// $request->validate([
// 'email' => ['required', 'email'],
// ]);
// // We will send the password reset link to this user. Once we have attempted public function createNewPasswordForm(Request $request)
// // to send the link, we will examine the response then see the message we {
// // need to show to the user. Finally, we'll send out a proper response. return view('auth.reset-password-form', ['token' => $request->token, 'email' => $request->email]);
// $status = Password::sendResetLink( }
// $request->only('email')
// );
// return $status == Password::RESET_LINK_SENT public function storeNewPasswordForm(Request $request)
// ? back()->with('status', __($status)) {
// : back()->withInput($request->only('email')) $data = DB::table('password_reset_tokens')->where('email', $request->email)->first();
// ->withErrors(['email' => __($status)]);
// } if ($data == null || !Hash::check($request->token, $data->token)) {
toast('Link reset password tidak valid atau kedaluwarsa', 'error')->position('top')->autoclose(3000);
return redirect()->back();
}
DB::beginTransaction();
$user = User::where('email', $request->email)->first();
$user->password = Hash::make($request->new_password);
try {
$user->save();
DB::table('password_reset_tokens')->where('email', $request->email)->delete();
DB::commit();
alert()->success('Berhasil', 'Password berhasil direset, silahkan login');
return redirect()->route('auth.login');
} catch (\Throwable $th) {
DB::rollBack();
toast('Terjadi kesalahan', 'error')->position('top')->autoclose(3000);
return redirect()->back();
}
}
} }

View File

@ -13,12 +13,14 @@ class ResetPasswordMail extends Mailable
{ {
use Queueable, SerializesModels; use Queueable, SerializesModels;
public $resetLink;
/** /**
* Create a new message instance. * Create a new message instance.
*/ */
public function __construct() public function __construct($resetLink)
{ {
// $this->resetLink = $resetLink;
} }
/** /**
@ -38,6 +40,9 @@ public function content(): Content
{ {
return new Content( return new Content(
view: 'auth.mail-reset-password', view: 'auth.mail-reset-password',
with: [
'resetLink' => $this->resetLink
]
); );
} }

View File

@ -18,7 +18,7 @@ public function run(): void
User::create([ User::create([
'username' => 'admin', 'username' => 'admin',
'name' => 'Admin Sage', 'name' => 'Admin Sage',
'email' => 'adminSage@gmail.com', 'email' => 'ariefajar739@gmail.com',
'password' => Hash::make('admin123'), 'password' => Hash::make('admin123'),
'role' => 'admin' 'role' => 'admin'
]), ]),

View File

@ -1,27 +0,0 @@
<x-guest-layout>
<div class="mb-4 text-sm text-gray-600 dark:text-gray-400">
{{ __('This is a secure area of the application. Please confirm your password before continuing.') }}
</div>
<form method="POST" action="{{ route('password.confirm') }}">
@csrf
<!-- Password -->
<div>
<x-input-label for="password" :value="__('Password')" />
<x-text-input id="password" class="block mt-1 w-full"
type="password"
name="password"
required autocomplete="current-password" />
<x-input-error :messages="$errors->get('password')" class="mt-2" />
</div>
<div class="flex justify-end mt-4">
<x-primary-button>
{{ __('Confirm') }}
</x-primary-button>
</div>
</form>
</x-guest-layout>

View File

@ -4,7 +4,7 @@
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />
<title>Reset Password | CornQuest</title> <title>Lupa Password | CornQuest</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta content="Premium Multipurpose Admin & Dashboard Template" name="description" /> <meta content="Premium Multipurpose Admin & Dashboard Template" name="description" />
<meta content="Themesbrand" name="author" /> <meta content="Themesbrand" name="author" />

View File

@ -123,6 +123,7 @@ class="fw-semibold text-primary text-decoration-underline"> Signup </a> </p>
<!-- end container --> <!-- end container -->
</div> </div>
<!-- end auth page content --> <!-- end auth page content -->
@include('sweetalert::alert')
<!-- footer --> <!-- footer -->
<footer class="footer"> <footer class="footer">

View File

@ -0,0 +1,155 @@
<!doctype html>
<html lang="en" data-layout="vertical" data-topbar="light" data-sidebar="light" data-sidebar-size="lg">
<head>
<meta charset="utf-8" />
<title>Reset Password | CornQuest</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta content="Premium Multipurpose Admin & Dashboard Template" name="description" />
<meta content="Themesbrand" name="author" />
<!-- App favicon -->
<link rel="shortcut icon" href="{{ asset('assets/images/favicon.ico') }}">
<!-- Layout config Js -->
<script src="{{ asset('assets/js/layout.js') }}"></script>
<!-- Bootstrap Css -->
<link href="{{ asset('assets/css/bootstrap.min.css') }}" rel="stylesheet" type="text/css" />
<!-- Icons Css -->
<link href="{{ asset('assets/css/icons.min.css') }}" rel="stylesheet" type="text/css" />
<!-- App Css-->
<link href="{{ asset('assets/css/app.min.css') }}" rel="stylesheet" type="text/css" />
<!-- custom Css-->
<link href="{{ asset('assets/css/custom.min.css') }}" rel="stylesheet" type="text/css" />
</head>
<body>
<div class="auth-page-wrapper pt-5">
<!-- auth page bg -->
<div class="auth-one-bg-position auth-one-bg" id="auth-particles">
<div class="bg-overlay"></div>
<div class="shape">
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink"
viewBox="0 0 1440 120">
<path d="M 0,36 C 144,53.6 432,123.2 720,124 C 1008,124.8 1296,56.8 1440,40L1440 140L0 140z"></path>
</svg>
</div>
</div>
<!-- auth page content -->
<div class="auth-page-content">
<div class="container">
<div class="row">
<div class="col-lg-12">
<div class="text-center mt-sm-5 mb-4 text-white-50">
<div>
<a href="index.html" class="d-inline-block auth-logo">
<img src="assets/images/logo-light.png" alt="" height="20">
</a>
</div>
</div>
</div>
</div>
<!-- end row -->
<div class="row justify-content-center">
<div class="col-md-8 col-lg-6 col-xl-5">
<div class="card mt-4">
<div class="card-body p-4">
<div class="text-center mt-2">
<h5 class="text-primary">Reset Password</h5>
<p class="text-muted">Silahkan password baru anda!</p>
</div>
<div class="p-2">
<form action="{{ route('auth.store_new_password_form') }}" class="needs-validation"
novalidate method="POST">
@csrf
<input type="hidden" name="token" value="{{ $token }}">
<input type="hidden" name="email" value="{{ $email }}">
<div class="mb-4">
<label class="form-label">Password Baru</label>
<input type="password" class="form-control" id="new_password"
name="new_password" placeholder="Masukan password baru" autofocus
autocomplete="off" required>
<div class="invalid-feedback">
Harap masukan password baru anda!
</div>
</div>
<div class="mb-4">
<label class="form-label">Konfirmasi Password Baru</label>
<input type="password" class="form-control" id="confirm_password"
name="confirm_password" placeholder="Masukan konfirmasi password"
autofocus required>
<div class="invalid-feedback">
Harap masukan konfirmasi password
</div>
</div>
<div class="text-center mt-4">
<button class="btn btn-success w-100" type="submit">Simpan</button>
</div>
</form><!-- end form -->
</div>
</div>
<!-- end card body -->
</div>
<!-- end card -->
<div class="mt-4 text-center">
<p class="mb-0">Tunggu, saya ingat password saya... <a href="{{ route('auth.login') }}"
class="fw-semibold text-primary text-decoration-underline"> Login </a> </p>
</div>
</div>
</div>
<!-- end row -->
</div>
<!-- end container -->
</div>
<!-- end auth page content -->
<!-- footer -->
<footer class="footer">
<div class="container">
<div class="row">
<div class="col-lg-12">
<div class="text-center">
<p class="mb-0 text-muted">&copy;
<script>
document.write(new Date().getFullYear())
</script> CornQuest. Crafted with <i
class="mdi mdi-heart text-danger"></i>
by LAB KSI Politeknik Negeri Jember
</p>
</div>
</div>
</div>
</div>
</footer>
<!-- end Footer -->
</div>
<!-- end auth-page-wrapper -->
@include('sweetalert::alert')
<!-- JAVASCRIPT -->
<script src="{{ asset('assets/libs/bootstrap/js/bootstrap.bundle.min.js') }}"></script>
<script src="{{ asset('assets/libs/simplebar/simplebar.min.js') }}"></script>
<script src="{{ asset('assets/libs/node-waves/waves.min.js') }}"></script>
<script src="{{ asset('assets/libs/feather-icons/feather.min.js') }}"></script>
<script src="{{ asset('assets/js/pages/plugins/lord-icon-2.1.0.js') }}"></script>
<script src="{{ asset('assets/js/plugins.js') }}"></script>
<!-- particles js -->
<script src="{{ asset('assets/libs/particles.js/particles.js') }}"></script>
<!-- particles app js -->
<script src="{{ asset('assets/js/pages/particles.app.js') }}"></script>
<script src="{{ asset('assets/js/pages/form-validation.init.js') }}"></script>
</body>
</html>

View File

@ -29,8 +29,8 @@
Route::get('/forgot-password', 'create')->name('forgot_password'); Route::get('/forgot-password', 'create')->name('forgot_password');
Route::post('/reset-password', 'store')->name('reset_password'); Route::post('/reset-password', 'store')->name('reset_password');
Route::get('/validasi-lupa-password/{token}', 'validation')->name('validation_forgot_password'); Route::get('/validasi-lupa-password/{token}', 'createNewPasswordForm')->name('create_new_password_form');
Route::post('/validasi-lupa-password/{token}', 'update')->name('update_forgot_password'); Route::post('/validasi-lupa-password', 'storeNewPasswordForm')->name('store_new_password_form');
}); });
}); });
}); });