Fungsi lupa password bisa coy
This commit is contained in:
parent
7c7c6f9238
commit
b44ecf544f
|
@ -39,7 +39,8 @@ public function __construct()
|
|||
*/
|
||||
public function showLinkRequestForm()
|
||||
{
|
||||
return view('auth.passwords.email');
|
||||
// Redirect to home page with forgot_password modal flag
|
||||
return redirect()->route('home')->with('status', 'Silahkan masukkan email Anda untuk mereset password.');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -73,8 +74,10 @@ public function sendResetLinkEmail(Request $request)
|
|||
*/
|
||||
protected function sendResetLinkResponse(Request $request, $response)
|
||||
{
|
||||
session()->flash('success', trans($response));
|
||||
return back();
|
||||
// Return to home page with success message and keep the forgot_password modal open
|
||||
return redirect()->route('home')
|
||||
->with('status', trans($response))
|
||||
->with('success', 'Link reset password telah dikirim ke email Anda.');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -86,8 +89,10 @@ protected function sendResetLinkResponse(Request $request, $response)
|
|||
*/
|
||||
protected function sendResetLinkFailedResponse(Request $request, $response)
|
||||
{
|
||||
session()->flash('error', trans($response));
|
||||
return back()
|
||||
->withInput($request->only('email'));
|
||||
// Return to home page with error and keep the forgot_password modal open
|
||||
return redirect()->route('home')
|
||||
->withInput($request->only('email'))
|
||||
->with('error', trans($response))
|
||||
->with('status', 'Terjadi kesalahan. Silakan coba lagi.');
|
||||
}
|
||||
}
|
|
@ -88,12 +88,12 @@ protected function sendFailedLoginResponse(Request $request)
|
|||
|
||||
if ($user && !$user->hasVerifiedEmail()) {
|
||||
return redirect()->route('home')
|
||||
->with('login_error', 'Email belum diverifikasi. Silakan periksa email Anda untuk link verifikasi atau klik resend untuk mengirim ulang.')
|
||||
->with('login_error', 'Email belum diverifikasi. Silakan periksa email Anda untuk link verifikasi.')
|
||||
->withInput($request->only('email'));
|
||||
}
|
||||
|
||||
return redirect()->route('home')
|
||||
->with('login_error', 'Kredensial yang Anda masukkan tidak valid.')
|
||||
->with('login_error', 'Email atau password yang anda masukkan salah.')
|
||||
->withInput($request->only('email'));
|
||||
}
|
||||
|
||||
|
|
|
@ -6,6 +6,10 @@
|
|||
use App\Providers\RouteServiceProvider;
|
||||
use Illuminate\Foundation\Auth\ResetsPasswords;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Password;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Auth\Events\PasswordReset;
|
||||
|
||||
class ResetPasswordController extends Controller
|
||||
{
|
||||
|
@ -20,7 +24,9 @@ class ResetPasswordController extends Controller
|
|||
|
|
||||
*/
|
||||
|
||||
use ResetsPasswords;
|
||||
use ResetsPasswords {
|
||||
reset as protected traitReset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Where to redirect users after resetting their password.
|
||||
|
@ -39,6 +45,71 @@ public function __construct()
|
|||
$this->middleware('guest');
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the password reset view for the given token.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param string|null $token
|
||||
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
|
||||
*/
|
||||
public function showResetForm(Request $request, $token = null)
|
||||
{
|
||||
// Pass token directly as a query parameter instead of route parameter
|
||||
return redirect()->route('home', [
|
||||
'token' => $token,
|
||||
'email' => $request->email,
|
||||
'reset' => 'true' // Add explicit reset parameter for more compatibility
|
||||
])->with('reset', true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Override the reset method from the trait to prevent auto-login
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function reset(Request $request)
|
||||
{
|
||||
$request->validate($this->rules(), $this->validationErrorMessages());
|
||||
|
||||
// Here's the main change - instead of using the trait reset method,
|
||||
// we implement a custom reset logic without the auto-login
|
||||
$response = $this->broker()->reset(
|
||||
$this->credentials($request),
|
||||
function ($user, $password) {
|
||||
$this->resetPassword($user, $password);
|
||||
|
||||
// Don't login the user automatically
|
||||
// Auth::guard()->login($user); <-- This line is removed
|
||||
}
|
||||
);
|
||||
|
||||
// If the password was successfully reset, we will redirect the user back to
|
||||
// the application's home authenticated view with a success message.
|
||||
return $response == Password::PASSWORD_RESET
|
||||
? $this->sendResetResponse($request, $response)
|
||||
: $this->sendResetFailedResponse($request, $response);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the given user's password.
|
||||
*
|
||||
* @param \Illuminate\Contracts\Auth\CanResetPassword $user
|
||||
* @param string $password
|
||||
* @return void
|
||||
*/
|
||||
protected function resetPassword($user, $password)
|
||||
{
|
||||
$user->password = bcrypt($password);
|
||||
$user->setRememberToken(Str::random(60));
|
||||
$user->save();
|
||||
|
||||
event(new PasswordReset($user));
|
||||
|
||||
// Don't login automatically
|
||||
// $this->guard()->login($user); <-- This line is removed
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the response for a successful password reset.
|
||||
*
|
||||
|
@ -48,8 +119,10 @@ public function __construct()
|
|||
*/
|
||||
protected function sendResetResponse(Request $request, $response)
|
||||
{
|
||||
session()->flash('success', trans($response));
|
||||
return redirect($this->redirectPath());
|
||||
// Redirect to home with success message and open login modal
|
||||
return redirect()->route('home')
|
||||
->with('success', 'Password berhasil direset.')
|
||||
->with('login_error', 'Silakan login dengan password baru Anda.');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -61,9 +134,14 @@ protected function sendResetResponse(Request $request, $response)
|
|||
*/
|
||||
protected function sendResetFailedResponse(Request $request, $response)
|
||||
{
|
||||
session()->flash('error', trans($response));
|
||||
return redirect()->back()
|
||||
->withInput($request->only('email'))
|
||||
// Return to home with reset modal open showing the error
|
||||
return redirect()->route('home', [
|
||||
'token' => $request->token,
|
||||
'email' => $request->email,
|
||||
'reset' => 'true' // Add explicit reset parameter for more compatibility
|
||||
])
|
||||
->with('reset', true)
|
||||
->with('error', trans($response))
|
||||
->withErrors(['email' => trans($response)]);
|
||||
}
|
||||
}
|
|
@ -6,7 +6,6 @@
|
|||
use App\Providers\RouteServiceProvider;
|
||||
use Illuminate\Foundation\Auth\VerifiesEmails;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Auth\Events\Verified;
|
||||
|
||||
class VerificationController extends Controller
|
||||
{
|
||||
|
@ -37,77 +36,31 @@ class VerificationController extends Controller
|
|||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware('auth')->except(['verify']);
|
||||
$this->middleware('auth');
|
||||
$this->middleware('signed')->only('verify');
|
||||
$this->middleware('throttle:6,1')->only('verify', 'resend');
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark the authenticated user's email address as verified.
|
||||
* Custom handler for successful verification
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function verify(Request $request)
|
||||
public function verified(Request $request)
|
||||
{
|
||||
$user = \App\Models\User::find($request->route('id'));
|
||||
|
||||
if (!hash_equals((string) $request->route('hash'), sha1($user->getEmailForVerification()))) {
|
||||
return redirect()->route('home')
|
||||
->with('error', 'Link verifikasi tidak valid.');
|
||||
}
|
||||
|
||||
if ($user->hasVerifiedEmail()) {
|
||||
return redirect()->route('home')
|
||||
->with('verified', 'Email sudah terverifikasi sebelumnya. Silakan login.');
|
||||
}
|
||||
|
||||
if ($user->markEmailAsVerified()) {
|
||||
event(new Verified($user));
|
||||
}
|
||||
|
||||
if ($request->user()) {
|
||||
auth()->logout();
|
||||
}
|
||||
|
||||
return redirect()->route('home')
|
||||
->with('verified', 'Email berhasil diverifikasi. Silakan login.');
|
||||
->with('verified', 'Email Anda berhasil diverifikasi. Silakan login untuk melanjutkan.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Resend the email verification notification.
|
||||
* The user has been verified.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
* @return mixed
|
||||
*/
|
||||
public function resend(Request $request)
|
||||
protected function verified(Request $request)
|
||||
{
|
||||
if ($request->user()->hasVerifiedEmail()) {
|
||||
return redirect()->route('home');
|
||||
}
|
||||
|
||||
$request->user()->sendEmailVerificationNotification();
|
||||
|
||||
return back()->with('resent', true)
|
||||
->with('success', 'Link verifikasi telah dikirim ulang ke alamat email Anda.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the email verification notice.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\RedirectResponse|\Illuminate\View\View
|
||||
*/
|
||||
public function show(Request $request)
|
||||
{
|
||||
if ($request->user()->hasVerifiedEmail()) {
|
||||
return redirect($this->redirectPath());
|
||||
}
|
||||
|
||||
// Redirect to homepage with message instead of showing verification.notice view
|
||||
return redirect()->route('home')
|
||||
->with('error', 'Silakan verifikasi email Anda terlebih dahulu.
|
||||
Link verifikasi telah dikirim ke alamat email Anda.')
|
||||
->with('resend_link', true);
|
||||
return redirect($this->redirectPath())
|
||||
->with('verified', 'Email Anda berhasil diverifikasi!');
|
||||
}
|
||||
}
|
|
@ -22,8 +22,8 @@
|
|||
|
||||
<body class="font-poppins">
|
||||
<header class="fixed top-0 w-full bg-white shadow-sm z-50" x-data="{
|
||||
showModal: {{ $errors->any() || session('login_error') || session('register_error') || session('verified') ? 'true' : 'false' }},
|
||||
modalType: '{{ session('login_error') || session('verified') ? 'login' : (session('register_error') ? 'register' : ($errors->any() ? (old('email') && !old('name') ? 'login' : 'register') : '')) }}'
|
||||
showModal: {{ $errors->any() || session('login_error') || session('register_error') || session('verified') || session('status') || session('reset') || request()->has('token') ? 'true' : 'false' }},
|
||||
modalType: '{{ session('reset') || request()->has('token') ? 'reset_password' : (session('status') ? 'forgot_password' : (session('login_error') || session('verified') ? 'login' : (session('register_error') ? 'register' : ($errors->any() ? (old('email') && !old('name') && !isset($request) ? 'login' : (request()->is('password/reset*') ? 'reset_password' : 'register')) : '')))) }}'
|
||||
}">
|
||||
<nav x-data="{ isMobileMenuOpen: false }" class="relative py-4 px-4 lg:px-44 flex items-center justify-between">
|
||||
<a href="/">
|
||||
|
@ -134,6 +134,7 @@ class="absolute top-3 right-4 text-gray-500 hover:text-gray-700 text-xl">
|
|||
×
|
||||
</button>
|
||||
|
||||
<!-- Login Modal -->
|
||||
<template x-if="modalType === 'login'">
|
||||
<div>
|
||||
<h2 class="text-xl font-semibold mb-4">Masuk</h2>
|
||||
|
@ -168,9 +169,10 @@ class="w-full border px-4 py-2 rounded" required>
|
|||
<div class="flex items-center justify-between">
|
||||
<div class="flex items-center">
|
||||
</div>
|
||||
<a href="{{ route('password.request') }}" class="text-sm text-primary hover:underline">
|
||||
<button type="button" @click="modalType = 'forgot_password'"
|
||||
class="text-sm text-primary hover:underline">
|
||||
Lupa Password?
|
||||
</a>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<button type="submit"
|
||||
|
@ -183,6 +185,7 @@ class="w-full bg-blue-600 hover:bg-blue-700 text-white py-2 rounded">Masuk</butt
|
|||
</div>
|
||||
</template>
|
||||
|
||||
<!-- Register Modal -->
|
||||
<template x-if="modalType === 'register'">
|
||||
<div>
|
||||
<h2 class="text-xl font-semibold mb-4">Daftar</h2>
|
||||
|
@ -210,6 +213,7 @@ class="w-full border px-4 py-2 rounded" required>
|
|||
class="w-full border px-4 py-2 rounded" required>
|
||||
<input type="password" name="password" placeholder="Password"
|
||||
class="w-full border px-4 py-2 rounded" required>
|
||||
<small class="px-4 text-gray-500">Password harus terdiri dari minimal 8 karakter.</small>
|
||||
<input type="password" name="password_confirmation" placeholder="Konfirmasi Password"
|
||||
class="w-full border px-4 py-2 rounded" required>
|
||||
<button type="submit"
|
||||
|
@ -221,28 +225,95 @@ class="w-full bg-blue-600 hover:bg-blue-700 text-white py-2 rounded">Daftar</but
|
|||
</p>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- Forgot Password Modal -->
|
||||
<template x-if="modalType === 'forgot_password'">
|
||||
<div>
|
||||
<h2 class="text-xl font-semibold mb-4">Lupa Password</h2>
|
||||
|
||||
<!-- Success message -->
|
||||
@if(session('status'))
|
||||
<div class="bg-green-100 border-l-4 border-green-500 text-green-700 p-4 mb-4" role="alert">
|
||||
<p>{{ session('status') }}</p>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<!-- Error messages -->
|
||||
@if($errors->has('email'))
|
||||
<div class="bg-red-100 border-l-4 border-red-500 text-red-700 p-4 mb-4" role="alert">
|
||||
<ul>
|
||||
@foreach($errors->get('email') as $error)
|
||||
<li>{{ $error }}</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<p class="text-sm mb-4">Masukkan alamat email Anda dan kami akan mengirimkan link untuk atur
|
||||
ulang password.</p>
|
||||
|
||||
<form method="POST" action="{{ route('password.email') }}" class="space-y-4">
|
||||
@csrf
|
||||
<input type="email" name="email" value="{{ old('email') }}" placeholder="Email"
|
||||
class="w-full border px-4 py-2 rounded" required>
|
||||
|
||||
<button type="submit"
|
||||
class="w-full bg-blue-600 hover:bg-blue-700 text-white py-2 rounded">Kirim Link Reset
|
||||
Password</button>
|
||||
</form>
|
||||
|
||||
<p class="text-sm mt-4 text-center">
|
||||
<button @click="modalType = 'login'" class="text-primary hover:underline">Kembali ke Halaman
|
||||
Login</button>
|
||||
</p>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- Reset Password Modal -->
|
||||
<template x-if="modalType === 'reset_password'">
|
||||
<div>
|
||||
<h2 class="text-xl font-semibold mb-4">Reset Password</h2>
|
||||
|
||||
<!-- Error messages -->
|
||||
@if($errors->any())
|
||||
<div class="bg-red-100 border-l-4 border-red-500 text-red-700 p-4 mb-4" role="alert">
|
||||
<ul>
|
||||
@foreach($errors->all() as $error)
|
||||
<li>{{ $error }}</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<form method="POST" action="{{ route('password.update') }}" class="space-y-4">
|
||||
@csrf
|
||||
<input type="hidden" name="token"
|
||||
value="{{ request()->query('token') ?? request()->input('token') ?? old('token') }}">
|
||||
|
||||
<input type="email" name="email" value="{{ request()->query('email') ?? old('email') }}"
|
||||
placeholder="Email" class="w-full border px-4 py-2 rounded" required>
|
||||
|
||||
<input type="password" name="password" placeholder="Password Baru"
|
||||
class="w-full border px-4 py-2 rounded" required>
|
||||
<small class="px-4 text-gray-500">Password harus terdiri dari minimal 8 karakter.</small>
|
||||
|
||||
<input type="password" name="password_confirmation" placeholder="Konfirmasi Password Baru"
|
||||
class="w-full border px-4 py-2 rounded" required>
|
||||
|
||||
<button type="submit"
|
||||
class="w-full bg-blue-600 hover:bg-blue-700 text-white py-2 rounded">Reset
|
||||
Password</button>
|
||||
</form>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main class="pt-20">
|
||||
@if (session('success') || session('error') || session('verified'))
|
||||
<div id="floating-alert" style="
|
||||
position: fixed;
|
||||
top: 30px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
background-color: {{ session('success') || session('verified') ? '#d1e7dd' : '#f8d7da' }};
|
||||
color: {{ session('success') || session('verified') ? '#0f5132' : '#842029' }};
|
||||
padding: 10px 20px;
|
||||
border-radius: 6px;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
box-shadow: 0 3px 10px rgba(0,0,0,0.15);
|
||||
z-index: 9999;
|
||||
max-width: 300px;
|
||||
text-align: center;
|
||||
">
|
||||
<div id="floating-alert"
|
||||
style="position: fixed;top: 30px;left: 50%;transform: translateX(-50%);background-color: {{ session('success') || session('verified') ? '#d1e7dd' : '#f8d7da' }};color: {{ session('success') || session('verified') ? '#0f5132' : '#842029' }};padding: 10px 20px;border-radius: 6px;font-size: 14px;font-weight: 500;box-shadow: 0 3px 10px rgba(0,0,0,0.15);z-index: 9999;max-width: 300px;text-align: center">
|
||||
{{ session('success') ?? session('error') ?? session('verified') }}
|
||||
</div>
|
||||
|
||||
|
@ -283,4 +354,36 @@ class="w-full bg-blue-600 hover:bg-blue-700 text-white py-2 rounded">Daftar</but
|
|||
</footer>
|
||||
</body>
|
||||
|
||||
<script>
|
||||
// Function to get URL parameters
|
||||
function getUrlParameter(name) {
|
||||
name = name.replace(/[\[]/, '\\[').replace(/[\]]/, '\\]');
|
||||
var regex = new RegExp('[\\?&]' + name + '=([^&#]*)');
|
||||
var results = regex.exec(location.search);
|
||||
return results === null ? '' : decodeURIComponent(results[1].replace(/\+/g, ' '));
|
||||
}
|
||||
|
||||
// When the page loads, check for token and email in URL parameters
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
const token = getUrlParameter('token');
|
||||
const email = getUrlParameter('email');
|
||||
|
||||
if (token && email) {
|
||||
// Set the form values
|
||||
setTimeout(() => {
|
||||
const tokenInput = document.querySelector('input[name="token"]');
|
||||
const emailInput = document.querySelector('input[name="email"]');
|
||||
|
||||
if (tokenInput) tokenInput.value = token;
|
||||
if (emailInput) emailInput.value = email;
|
||||
|
||||
// Open the reset password modal
|
||||
const alpineData = document.querySelector('header').__x.$data;
|
||||
alpineData.showModal = true;
|
||||
alpineData.modalType = 'reset_password';
|
||||
}, 100);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
</html>
|
Loading…
Reference in New Issue