diff --git a/app/Http/Controllers/AuthController.php b/app/Http/Controllers/AuthController.php new file mode 100644 index 0000000..6499b11 --- /dev/null +++ b/app/Http/Controllers/AuthController.php @@ -0,0 +1,73 @@ +validate([ + 'login' => 'required', + 'password' => 'required' + ]); + + $loginType = filter_var($request->login, FILTER_VALIDATE_EMAIL) ? 'email' : 'employee_id'; + + $credentials = [ + $loginType => $request->login, + 'password' => $request->password + ]; + + if (Auth::attempt($credentials)) { + + $request->session()->regenerate(); + + session(['token_version' => Auth::user()->token_version]); + + Redis::lpush('login_logs', json_encode([ + 'user_id' => Auth::id(), + 'event' => 'login', + 'ip' => request()->ip(), + 'time' => now() + ])); + + return redirect('/dashboard'); + } + + return back()->withErrors([ + 'login' => 'ID Pekerja / Email atau Password salah.' + ]); + } + + public function logout(Request $request) + { + $userId = Auth::id(); // ambil dulu sebelum logout + + Redis::lpush('login_logs', json_encode([ + 'user_id' => $userId, + 'event' => 'logout', + 'ip' => request()->ip(), + 'time' => now() + ])); + + Auth::logout(); + + $request->session()->invalidate(); + $request->session()->regenerateToken(); + + return redirect('/login'); + } +} diff --git a/app/Http/Middleware/CheckTokenVersion.php b/app/Http/Middleware/CheckTokenVersion.php new file mode 100644 index 0000000..8952c84 --- /dev/null +++ b/app/Http/Middleware/CheckTokenVersion.php @@ -0,0 +1,33 @@ +token_version) { + + Auth::logout(); + $request->session()->invalidate(); + $request->session()->regenerateToken(); + + return redirect('/login')->with('message', 'Session expired. Please login again.'); + } + } + + return $next($request); + } +} diff --git a/app/Http/Middleware/IdleTimeout.php b/app/Http/Middleware/IdleTimeout.php new file mode 100644 index 0000000..85ffa18 --- /dev/null +++ b/app/Http/Middleware/IdleTimeout.php @@ -0,0 +1,37 @@ +has('last_activity')) { + + if (time() - session('last_activity') > $timeout) { + Auth::logout(); + session()->invalidate(); + return redirect('/login')->with('message', 'Session expired.'); + } + } + + session(['last_activity' => time()]); + } + + return $next($request); + } +} diff --git a/app/Models/User.php b/app/Models/User.php index 749c7b7..f645f04 100755 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -19,6 +19,7 @@ class User extends Authenticatable */ protected $fillable = [ 'name', + 'employee_id', 'email', 'password', ]; diff --git a/bootstrap/app.php b/bootstrap/app.php index c183276..c913618 100755 --- a/bootstrap/app.php +++ b/bootstrap/app.php @@ -11,7 +11,10 @@ health: '/up', ) ->withMiddleware(function (Middleware $middleware): void { - // + $middleware->alias([ + 'auth.idle' => \App\Http\Middleware\IdleTimeout::class, + 'auth.token' => \App\Http\Middleware\CheckTokenVersion::class, + ]); }) ->withExceptions(function (Exceptions $exceptions): void { // diff --git a/config/session.php b/config/session.php index 5b541b7..64fcc94 100755 --- a/config/session.php +++ b/config/session.php @@ -18,7 +18,7 @@ | */ - 'driver' => env('SESSION_DRIVER', 'database'), + 'driver' => env('SESSION_DRIVER', 'redis'), /* |-------------------------------------------------------------------------- @@ -32,7 +32,7 @@ | */ - 'lifetime' => (int) env('SESSION_LIFETIME', 120), + 'lifetime' => (int) env('SESSION_LIFETIME', 30), 'expire_on_close' => env('SESSION_EXPIRE_ON_CLOSE', false), diff --git a/database/migrations/2026_02_19_150107_add_employee_id_to_users_table.php b/database/migrations/2026_02_19_150107_add_employee_id_to_users_table.php new file mode 100644 index 0000000..bafcbac --- /dev/null +++ b/database/migrations/2026_02_19_150107_add_employee_id_to_users_table.php @@ -0,0 +1,28 @@ +string('employee_id')->unique()->after('id'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('users', function (Blueprint $table) { + // + }); + } +}; diff --git a/database/migrations/2026_02_19_154552_add_token_version_to_users.php b/database/migrations/2026_02_19_154552_add_token_version_to_users.php new file mode 100644 index 0000000..79ab118 --- /dev/null +++ b/database/migrations/2026_02_19_154552_add_token_version_to_users.php @@ -0,0 +1,28 @@ +integer('token_version')->default(1); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('users', function (Blueprint $table) { + // + }); + } +}; diff --git a/database/migrations/2026_02_19_161052_add_token_version_to_users.php b/database/migrations/2026_02_19_161052_add_token_version_to_users.php new file mode 100644 index 0000000..5773e07 --- /dev/null +++ b/database/migrations/2026_02_19_161052_add_token_version_to_users.php @@ -0,0 +1,28 @@ +create(); - - User::factory()->create([ - 'name' => 'Test User', - 'email' => 'test@example.com', - ]); + $this->call(UserSeeder::class); } } diff --git a/database/seeders/UserSeeder.php b/database/seeders/UserSeeder.php new file mode 100644 index 0000000..1a2b973 --- /dev/null +++ b/database/seeders/UserSeeder.php @@ -0,0 +1,24 @@ + 'Admin', + 'employee_id' => 'ADMIN001', + 'email' => 'admin@company.com', + 'password' => Hash::make('admin123') + ]); + } +} diff --git a/resources/views/auth/login.blade.php b/resources/views/auth/login.blade.php new file mode 100644 index 0000000..7f4e55a --- /dev/null +++ b/resources/views/auth/login.blade.php @@ -0,0 +1,152 @@ + + + +
+ +Let’s get you signed in. Enter your email and password to continue.
+ + ++ New here? Create an account +
+ ++ © + UBold — by Coderthemes +
+Total Sales
+Orders Placed
+Active Customers
+Refund Requests
++ You have 21 pending orders awaiting fulfillment. +
+ +|
+
+
+
+ Audio
+
+ Wireless Earbuds+ |
+
+ Stock
+ 180 units+ |
+
+ Price
+ $59.90+ |
+
+ Ratings
+ + + + + + + + + (52) ++ |
+
+ Status
+ Active+ |
+
+
+
+
+
+
+
+ |
+
|
+
+
+
+ Accessories
+
+ Laptop Stand+ |
+
+ Stock
+ 45 units+ |
+
+ Price
+ $29.00+ |
+
+ Ratings
+ + + + + + + + + (11) ++ |
+
+ Status
+ Low Stock+ |
+
+
+
+
+
+
+
+ |
+
|
+
+
+
+ Gadgets
+
+ Drone Camera+ |
+
+ Stock
+ 0 units+ |
+
+ Price
+ $199.99+ |
+
+ Ratings
+ + + + + + + + + (8) ++ |
+
+ Status
+ Out of Stock+ |
+
+
+
+
+
+
+
+ |
+
|
+
+
+
+ Electronics
+
+ Portable Projector+ |
+
+ Stock
+ 32 units+ |
+
+ Price
+ $120.00+ |
+
+ Ratings
+ + + + + + + + + (16) ++ |
+
+ Status
+ Limited+ |
+
+
+
+
+
+
+
+ |
+
|
+
+
+
+ Mobiles
+
+ Smartphone G12+ |
+
+ Stock
+ 85 units+ |
+
+ Price
+ $499.00+ |
+
+ Ratings
+ + + + + + + + + (112) ++ |
+
+ Status
+ Active+ |
+
+
+
+
+
+
+
+ |
+
|
+
+
+
+ Audio
+
+ Noise Cancelling Headphones+ |
+
+ Stock
+ 25 units+ |
+
+ Price
+ $129.99+ |
+
+ Ratings
+ + + + + + + + + (78) ++ |
+
+ Status
+ Low Stock+ |
+
+
+
+
+
+
+
+ |
+
|
+
+
+
+ Home Tech
+
+ Mini Air Purifier+ |
+
+ Stock
+ 0 units+ |
+
+ Price
+ $49.99+ |
+
+ Ratings
+ + + + + + + + + (34) ++ |
+
+ Status
+ Out of Stock+ |
+
+
+
+
+
+
+
+ |
+
|
+
+
+
+ Accessories
+
+ USB-C Docking Station+ |
+
+ Stock
+ 142 units+ |
+
+ Price
+ $89.00+ |
+
+ Ratings
+ + + + + + + + + (64) ++ |
+
+ Status
+ Active+ |
+
+
+
+
+
+
+
+ |
+
|
+
+
+
+ Gadgets
+
+ Digital Photo Frame+ |
+
+ Stock
+ 58 units+ |
+
+ Price
+ $74.95+ |
+
+ Ratings
+ + + + + + + + + (40) ++ |
+
+ Status
+ Active+ |
+
+
+
+
+
+
+
+ |
+
|
+
+
+
+ Alice Cooper
+
+ #ORD-2001+ |
+
+ Product
+ Noise Cancelling Headphones+ |
+
+ Date
+ 2025-05-01+ |
+
+ Amount
+ $199.99+ |
+
+ Status
+ Delivered+ |
+
+
+
+
+
+
+
+ |
+
|
+
+
+
+ David Lee
+
+ #ORD-2002+ |
+
+ Product
+ 4K Monitor+ |
+
+ Date
+ 2025-04-30+ |
+
+ Amount
+ $349.00+ |
+
+ Status
+ Pending+ |
+
+
+
+
+
+
+
+ |
+
|
+
+
+
+ Sophia Turner
+
+ #ORD-2003+ |
+
+ Product
+ Mechanical Keyboard+ |
+
+ Date
+ 2025-04-29+ |
+
+ Amount
+ $89.49+ |
+
+ Status
+ Completed+ |
+
+
+
+
+
+
+
+ |
+
|
+
+
+
+ James Wilson
+
+ #ORD-2004+ |
+
+ Product
+ Drone Camera+ |
+
+ Date
+ 2025-04-28+ |
+
+ Amount
+ $450.00+ |
+
+ Status
+ Cancelled+ |
+
+
+
+
+
+
+
+ |
+
|
+
+
+
+ Ava Carter
+
+ #ORD-2005+ |
+
+ Product
+ Wireless Earbuds+ |
+
+ Date
+ 2025-04-27+ |
+
+ Amount
+ $129.99+ |
+
+ Status
+ Completed+ |
+
+
+
+
+
+
+
+ |
+
|
+
+
+
+ Ethan Brooks
+
+ #ORD-2011+ |
+
+ Product
+ VR Headset+ |
+
+ Date
+ 2025-05-02+ |
+
+ Amount
+ $299.00+ |
+
+ Status
+ Completed+ |
+
+
+
+
+
+
+
+ |
+
|
+
+
+
+ Mia Clarke
+
+ #ORD-2012+ |
+
+ Product
+ Portable Charger+ |
+
+ Date
+ 2025-05-01+ |
+
+ Amount
+ $59.99+ |
+
+ Status
+ Completed+ |
+
+
+
+
+
+
+
+ |
+
|
+
+
+
+ Lucas Perry
+
+ #ORD-2013+ |
+
+ Product
+ Smartphone Gimbal+ |
+
+ Date
+ 2025-04-30+ |
+
+ Amount
+ $149.99+ |
+
+ Status
+ Pending+ |
+
+
+
+
+
+
+
+ |
+
|
+
+
+
+ Chloe Adams
+
+ #ORD-2014+ |
+
+ Product
+ LED Desk Lamp+ |
+
+ Date
+ 2025-04-29+ |
+
+ Amount
+ $45.00+ |
+
+ Status
+ Delivered+ |
+
+
+
+
+
+
+
+ |
+
|
+
+
+
+ Benjamin Gray
+
+ #ORD-2015+ |
+
+ Product
+ Noise Meter+ |
+
+ Date
+ 2025-04-28+ |
+
+ Amount
+ $75.49+ |
+
+ Status
+ Delivered+ |
+
+
+
+
+
+
+
+ |
+
Easily configure layout, styles, and preferences for your admin interface.
+