diff --git a/.env.example b/.env.example index c0660ea..ec7f031 100644 --- a/.env.example +++ b/.env.example @@ -4,6 +4,9 @@ APP_KEY= APP_DEBUG=true APP_URL=http://localhost +# ── App Gate Password ───────────────────────────────────────────────────────── +APP_PASSWORD= + APP_LOCALE=en APP_FALLBACK_LOCALE=en APP_FAKER_LOCALE=en_US diff --git a/app/Http/Controllers/GateController.php b/app/Http/Controllers/GateController.php new file mode 100644 index 0000000..141ff07 --- /dev/null +++ b/app/Http/Controllers/GateController.php @@ -0,0 +1,44 @@ +validate([ + 'password' => 'required|string', + ]); + + $expected = config('app.password'); + + if (! $expected || $request->input('password') !== $expected) { + return back()->withErrors(['password' => 'Wrong password. Please try again.']); + } + + // Store flag in session; expires with session lifetime (24 h in .env) + $request->session()->put('gate_authenticated', true); + $request->session()->regenerate(); + + return redirect()->intended(route('dashboard')); + } + + public function logout(Request $request): RedirectResponse + { + $request->session()->forget('gate_authenticated'); + $request->session()->regenerate(); + + return redirect()->route('gate.login'); + } +} diff --git a/app/Http/Middleware/GateAuth.php b/app/Http/Middleware/GateAuth.php new file mode 100644 index 0000000..09df433 --- /dev/null +++ b/app/Http/Middleware/GateAuth.php @@ -0,0 +1,26 @@ +routeIs('gate.login', 'gate.attempt', 'gate.logout')) { + return $next($request); + } + + if (! $request->session()->get('gate_authenticated')) { + return redirect()->route('gate.login'); + } + + return $next($request); + } +} diff --git a/bootstrap/app.php b/bootstrap/app.php index c183276..232a32e 100644 --- a/bootstrap/app.php +++ b/bootstrap/app.php @@ -1,5 +1,6 @@ withMiddleware(function (Middleware $middleware): void { - // + $middleware->web(append: [ + GateAuth::class, + ]); }) ->withExceptions(function (Exceptions $exceptions): void { // diff --git a/config/app.php b/config/app.php index 423eed5..e237905 100644 --- a/config/app.php +++ b/config/app.php @@ -15,6 +15,8 @@ return [ 'name' => env('APP_NAME', 'Laravel'), + 'password' => env('APP_PASSWORD'), + /* |-------------------------------------------------------------------------- | Application Environment diff --git a/resources/views/gate/login.blade.php b/resources/views/gate/login.blade.php new file mode 100644 index 0000000..68b0d1d --- /dev/null +++ b/resources/views/gate/login.blade.php @@ -0,0 +1,111 @@ + + + + + + + KOL Manager — Login + + + @vite(['resources/css/app.css', 'resources/js/app.js']) + + + + {{-- ── Decorative blobs ───────────────────────────────────────── --}} + + + {{-- ── Login card ─────────────────────────────────────────────── --}} +
+ + {{-- Logo / header --}} +
+
🐱
+

KOL Manager

+

Your Purr-fect Assistant

+
+ + {{-- Card --}} +
+ +

Welcome back 👋

+

Enter the app password to continue.

+ + {{-- Error --}} + @error('password') +
+ 😿 + {{ $message }} +
+ @enderror + +
+ @csrf + + {{-- Password field --}} +
+ +
+ + {{-- Show/hide toggle --}} + +
+
+ + {{-- Submit --}} + +
+
+ + {{-- Footer hint --}} +

+ +

+
+ + {{-- Shake keyframe --}} + + + + diff --git a/resources/views/layouts/app.blade.php b/resources/views/layouts/app.blade.php index b4aec8b..261cda9 100644 --- a/resources/views/layouts/app.blade.php +++ b/resources/views/layouts/app.blade.php @@ -134,6 +134,15 @@ class="nav-item {{ request()->routeIs('settings.*') ? 'active' : '' }}"> 🔔 Notifications + + {{-- Logout --}} +
+ @csrf + +
diff --git a/routes/web.php b/routes/web.php index 8018327..b81bf86 100644 --- a/routes/web.php +++ b/routes/web.php @@ -3,6 +3,7 @@ declare(strict_types=1); use App\Http\Controllers\BrandContractController; +use App\Http\Controllers\GateController; use App\Http\Controllers\NoteController; use App\Http\Controllers\ClientCategoryController; use App\Http\Controllers\ClientController; @@ -18,6 +19,11 @@ use App\Http\Controllers\SearchController; use App\Http\Controllers\SocialHubController; use Illuminate\Support\Facades\Route; +// ── Gate Authentication ─────────────────────────────────────────────────────── +Route::get('/login', [GateController::class, 'login'])->name('gate.login'); +Route::post('/login', [GateController::class, 'attempt'])->name('gate.attempt'); +Route::post('/logout', [GateController::class, 'logout'])->name('gate.logout'); + Route::get('/', [DashboardController::class, 'index'])->name('dashboard'); // CRM – Clients