diff --git a/app/Http/Controllers/Auth/LoginController.php b/app/Http/Controllers/Auth/LoginController.php index bf0064a..2f7bdbc 100644 --- a/app/Http/Controllers/Auth/LoginController.php +++ b/app/Http/Controllers/Auth/LoginController.php @@ -6,6 +6,7 @@ use Illuminate\Foundation\Auth\AuthenticatesUsers; use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; +use Illuminate\Validation\ValidationException; class LoginController extends Controller { @@ -40,6 +41,40 @@ public function __construct() $this->middleware('auth')->only('logout'); } + /** + * The user has been authenticated. + * + * @param \Illuminate\Http\Request $request + * @param mixed $user + * @return mixed + */ + protected function authenticated(Request $request, $user) + { + // Cek jika email belum terverifikasi + if (!$user->hasVerifiedEmail()) { + Auth::logout(); + + $request->session()->invalidate(); + $request->session()->regenerateToken(); + + throw ValidationException::withMessages([ + 'email' => [__('Akun Anda belum diverifikasi. Silakan periksa email Anda untuk link verifikasi.')], + ])->redirectTo(route('verification.notice')); + } + + session()->flash('success', 'Login berhasil!'); + if ($user->role === 'admin') { + return redirect('/admin'); + } + return redirect()->intended($this->redirectTo); + } + + /** + * Log the user out of the application. + * + * @param \Illuminate\Http\Request $request + * @return \Illuminate\Http\RedirectResponse + */ public function logout(Request $request) { Auth::logout(); @@ -50,14 +85,4 @@ public function logout(Request $request) session()->flash('error', 'Berhasil logout!'); return redirect('/'); } - - protected function authenticated(Request $request, $user) - { - session()->flash('success', 'Login berhasil!'); - if ($user->role === 'admin') { - return redirect('/admin'); - } - return redirect()->intended($this->redirectTo); - } - -} +} \ No newline at end of file diff --git a/app/Http/Controllers/Auth/RegisterController.php b/app/Http/Controllers/Auth/RegisterController.php index ab7ef63..d95c0c8 100644 --- a/app/Http/Controllers/Auth/RegisterController.php +++ b/app/Http/Controllers/Auth/RegisterController.php @@ -7,6 +7,8 @@ use Illuminate\Foundation\Auth\RegistersUsers; use Illuminate\Support\Facades\Hash; use Illuminate\Support\Facades\Validator; +use Illuminate\Http\Request; +use Illuminate\Auth\Events\Registered; class RegisterController extends Controller { @@ -69,4 +71,25 @@ protected function create(array $data) 'password' => Hash::make($data['password']), ]); } -} + + /** + * Override the registration method to prevent auto-login after registration + * and show a verification email message. + * + * @param \Illuminate\Http\Request $request + * @return \Illuminate\Http\RedirectResponse + */ + public function register(Request $request) + { + $this->validator($request->all())->validate(); + + event(new Registered($user = $this->create($request->all()))); + + // Don't automatically login the user + // $this->guard()->login($user); + + return $this->registered($request, $user) + ?: redirect($this->redirectPath()) + ->with('success', 'Pendaftaran berhasil! Silahkan periksa email Anda untuk verifikasi akun.'); + } +} \ No newline at end of file diff --git a/app/Http/Controllers/Auth/VerificationController.php b/app/Http/Controllers/Auth/VerificationController.php index 4b23c59..72c89db 100644 --- a/app/Http/Controllers/Auth/VerificationController.php +++ b/app/Http/Controllers/Auth/VerificationController.php @@ -6,6 +6,7 @@ use App\Providers\RouteServiceProvider; use Illuminate\Foundation\Auth\VerifiesEmails; use Illuminate\Http\Request; +use Illuminate\Auth\Events\Verified; class VerificationController extends Controller { @@ -36,59 +37,52 @@ class VerificationController extends Controller */ public function __construct() { - $this->middleware('auth'); + $this->middleware('auth')->except(['verify']); $this->middleware('signed')->only('verify'); $this->middleware('throttle:6,1')->only('verify', 'resend'); } /** - * Show the email verification notice. - * - * @param \Illuminate\Http\Request $request - * @return \Illuminate\Http\RedirectResponse|\Illuminate\View\View - */ - public function show(Request $request) - { - // Jika user sudah terverifikasi, redirect ke halaman utama - if ($request->user()->hasVerifiedEmail()) { - return redirect($this->redirectPath()) - ->with('success', 'Email anda sudah terverifikasi.'); - } - - // Jika user belum terverifikasi dan baru register (email_verified_at adalah null), - // tampilkan halaman verifikasi - return view('auth.verify'); - } - - /** - * The user has been verified. - * - * @param \Illuminate\Http\Request $request - * @return mixed - */ - protected function verified(Request $request) - { - session()->flash('success', 'Email berhasil diverifikasi! Selamat datang di Ayo Venue.'); - return redirect($this->redirectPath()); - } - - /** - * Resend the email verification notification. + * Mark the authenticated user's email address as verified. * * @param \Illuminate\Http\Request $request * @return \Illuminate\Http\RedirectResponse */ - public function resend(Request $request) + public function verify(Request $request) { - // Jika user sudah terverifikasi, tidak perlu kirim ulang - if ($request->user()->hasVerifiedEmail()) { - return redirect($this->redirectPath()) - ->with('success', 'Email anda sudah terverifikasi.'); + $user = \App\Models\User::find($request->route('id')); + + if (!hash_equals((string) $request->route('hash'), sha1($user->getEmailForVerification()))) { + return redirect()->route('verification.notice') + ->with('error', 'Link verifikasi tidak valid.'); } - // Kirim email verifikasi baru - $request->user()->sendEmailVerificationNotification(); + if ($user->hasVerifiedEmail()) { + return redirect()->route('login') + ->with('verified', true) + ->with('success', 'Email sudah terverifikasi sebelumnya. Silakan login.'); + } - return back()->with('success', 'Link verifikasi baru telah dikirim ke email anda.'); + if ($user->markEmailAsVerified()) { + event(new Verified($user)); + } + + if ($request->user()) { + auth()->logout(); + } + + return redirect()->route('login') + ->with('verified', true) + ->with('success', 'Email berhasil diverifikasi. Silakan login.'); + } + + /** + * Show the verification success page. + * + * @return \Illuminate\Contracts\View\View + */ + public function verified() + { + return view('auth.verified'); } } \ No newline at end of file diff --git a/resources/views/auth/verified.blade.php b/resources/views/auth/verified.blade.php new file mode 100644 index 0000000..cf4530f --- /dev/null +++ b/resources/views/auth/verified.blade.php @@ -0,0 +1,37 @@ +@extends('layouts.app') + +@section('content') +
+
+
+

{{ __('Email Berhasil Diverifikasi!') }}

+
+ +
+
+
+ +
+

{{ __('Verifikasi Berhasil') }}

+

+ {{ __('Selamat! Email Anda telah berhasil diverifikasi.') }} +

+
+ +
+

+ + {{ __('Anda sekarang memiliki akses penuh ke semua fitur Ayo Venue.') }} +

+
+ + +
+
+
+@endsection \ No newline at end of file diff --git a/resources/views/auth/verify.blade.php b/resources/views/auth/verify.blade.php index d336085..d40447f 100644 --- a/resources/views/auth/verify.blade.php +++ b/resources/views/auth/verify.blade.php @@ -14,21 +14,29 @@ @endif + @if (session('verified')) + + @endif +

- {{ __('Sebelum melanjutkan, silakan periksa email Anda untuk link verifikasi.') }}

+ {{ __('Sebelum melanjutkan, silakan periksa email Anda untuk link verifikasi.') }} +

- {{ __('Email verifikasi biasanya dikirim dalam beberapa menit.') }}

+ {{ __('Email verifikasi biasanya dikirim dalam beberapa menit.') }} +

- {{ __('Tidak perlu khawatir. Anda sudah dapat login dan menggunakan fitur dasar Ayo Venue. Verifikasi email ini hanya diperlukan untuk fitur tertentu dan keamanan akun Anda.') }} + {{ __('Verifikasi email diperlukan untuk menggunakan fitur aplikasi Ayo Venue. Pastikan Anda memverifikasi email Anda untuk akses penuh ke platform kami.') }}

diff --git a/resources/views/layouts/main.blade.php b/resources/views/layouts/main.blade.php index e62527e..1d0bc34 100644 --- a/resources/views/layouts/main.blade.php +++ b/resources/views/layouts/main.blade.php @@ -122,96 +122,120 @@ class="block w-full text-left px-4 py-2 text-sm text-gray-700 hover:bg-gray-100
+ x-transition:enter-start="opacity-0" x-transition:enter-end="opacity-100" + x-transition:leave="transition ease-in duration-200" x-transition:leave-start="opacity-100" + x-transition:leave-end="opacity-0" + class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50"> - -
+ +
- + - + + +
+
@if (session('success') || session('error'))
+ position: fixed; + top: 30px; + left: 50%; + transform: translateX(-50%); + background-color: {{ session('success') ? '#d1e7dd' : '#f8d7da' }}; + color: {{ session('success') ? '#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') }}
diff --git a/resources/views/pages/booking-history.blade.php b/resources/views/pages/booking-history.blade.php index 1bad4fb..91eca17 100644 --- a/resources/views/pages/booking-history.blade.php +++ b/resources/views/pages/booking-history.blade.php @@ -6,7 +6,7 @@ @if($bookings->isEmpty())

Anda belum memiliki riwayat booking.

- Cari + Cari Venue
@else diff --git a/routes/web.php b/routes/web.php index acf0aa3..bfa162e 100644 --- a/routes/web.php +++ b/routes/web.php @@ -8,12 +8,16 @@ use App\Http\Controllers\admin\BookingsController; use App\Http\Controllers\admin\TableController; use App\Http\Controllers\admin\AdminController; +use App\Http\Controllers\Auth\VerificationController; use Illuminate\Support\Facades\Route; use Illuminate\Support\Facades\Auth; // Authentication Routes (dengan verifikasi email aktif) Auth::routes(['verify' => true]); +// Rute custom untuk verifikasi email +Route::get('/email/verified', [VerificationController::class, 'verified'])->name('verification.verified'); + Route::get('/', [HomeController::class, "index"])->name('index'); Route::get('/venue/{venueName}', [VenueController::class, "venue"])->name('venue'); @@ -23,8 +27,22 @@ Route::get('/booking/schedules', [BookingController::class, 'getBookedSchedules'])->name('booking.schedules'); Route::post('/payment/notification', [BookingController::class, 'handleNotification'])->name('payment.notification'); -// Booking history routes (authenticated only, tidak perlu verified) +// Routes that require authentication but not email verification Route::middleware(['auth'])->group(function () { + // Route untuk melihat halaman verifikasi email dan kirim ulang email verifikasi + // sudah ditangani oleh Auth::routes(['verify' => true]) + + // Profile route access without verification + Route::get('/profile', [AccountController::class, 'settings'])->name('profile'); + + // Account settings routes - moved from password confirmation middleware + Route::get('/account/settings', [AccountController::class, 'settings'])->name('account.settings'); + Route::put('/account/update', [AccountController::class, 'update'])->name('account.update'); +}); + +// Routes that require both authentication and email verification +Route::middleware(['auth', 'verified'])->group(function () { + // Booking history routes Route::get('/booking/history', [BookingHistoryController::class, 'index'])->name('booking.history'); // Pending bookings routes @@ -32,20 +50,14 @@ Route::get('/booking/pending/{id}/resume', [BookingController::class, 'resumeBooking'])->name('booking.resume'); Route::delete('/booking/pending/{id}', [BookingController::class, 'deletePendingBooking'])->name('booking.pending.delete'); - // Profile route definition - use the existing account settings as the profile page - Route::get('/profile', [AccountController::class, 'settings'])->name('profile'); - - // Routes that require password confirmation + // Routes that require password confirmation - moved account settings out of this group Route::middleware(['password.confirm'])->group(function () { - // Add routes that require password confirmation here - // For example, account settings, deleting accounts, etc. - Route::get('/account/settings', [AccountController::class, 'settings'])->name('account.settings'); - Route::put('/account/update', [AccountController::class, 'update'])->name('account.update'); + // Any sensitive operations that should still require password confirmation can go here }); }); // Admin routes (admin tetap perlu verified untuk keamanan) -Route::middleware(['auth', 'is_admin'])->prefix('admin')->group(function () { +Route::middleware(['auth', 'verified', 'is_admin'])->prefix('admin')->group(function () { Route::get('/', [AdminController::class, 'index'])->name('admin.dashboard'); Route::get('/bookings', [BookingsController::class, 'index'])->name('admin.bookings.index'); Route::get('/bookings/export', [BookingsController::class, 'export'])->name('admin.bookings.export');