diff --git a/.env.example b/.env.example index 9bb7bb1e..25665a2d 100644 --- a/.env.example +++ b/.env.example @@ -51,5 +51,4 @@ MYKAD_READER_ENABLED_CAWANGAN='' INTERNAL_NOTIFICATION_SECRET= -# Separate password for /logs (username: logs). Empty disables access. LOGVIEWER_PASSWORD= diff --git a/.env.production b/.env.production index d8af1227..98f9b3b1 100644 --- a/.env.production +++ b/.env.production @@ -7,6 +7,7 @@ APP_URL=https://ujrah.erahn.com.my API_URL=https://apiujrah.erahn.com.my LOG_CHANNEL=stack +LOGVIEWER_PASSWORD="$2y$10$5R7JP/grEqRS6YrAHKKXveuncRoqbbV/IQQLNj3QQDLCyT7g8gL1C" DB_CONNECTION=mysql DB_HOST=192.168.1.216 diff --git a/app/Http/Controllers/Auth/LoginController.php b/app/Http/Controllers/Auth/LoginController.php index b9abb660..267c94c9 100644 --- a/app/Http/Controllers/Auth/LoginController.php +++ b/app/Http/Controllers/Auth/LoginController.php @@ -5,15 +5,12 @@ namespace App\Http\Controllers\Auth; use App\Http\Controllers\Controller; use App\Providers\RouteServiceProvider; use Illuminate\Support\Facades\Auth; -use Illuminate\Support\Facades\Session; -use Illuminate\Support\Facades\Redirect; use Illuminate\Foundation\Auth\AuthenticatesUsers; use Illuminate\Http\Request; use Illuminate\Support\Facades\Http; use App\Dashboard; use App\User; -use Carbon\Carbon; class LoginController extends Controller { @@ -144,25 +141,26 @@ class LoginController extends Controller } } - public function logout(){ - $current = Carbon::now(); - $current = new Carbon(); - $current = $current->toDateString(); + public function logout(Request $request) + { $auth_user = Auth::guard('web')->user(); - Auth::logout(); - Session::flush(); - $session = Http::withOptions(['verify' => config('app.api_verify')])->post(config('api.url') . '/api/logoutsession/' . $auth_user['cawangan'], [ - 'id' => $auth_user['id'], - 'nama' => $auth_user['name'], - 'nokp' => $auth_user['no_kp'], - 'email' => $auth_user['email'], - 'taraf' => $auth_user['role_harian'], - 'tarikh' => $current, - - ]); + Auth::guard('web')->logout(); + $request->session()->invalidate(); + $request->session()->regenerateToken(); - return Redirect::to('/'); + if ($auth_user) { + Http::withOptions(['verify' => config('app.api_verify')])->post(config('api.url') . '/api/logoutsession/' . $auth_user['cawangan'], [ + 'id' => $auth_user['id'], + 'nama' => $auth_user['name'], + 'nokp' => $auth_user['no_kp'], + 'email' => $auth_user['email'], + 'taraf' => $auth_user['role_harian'], + 'tarikh' => now()->toDateString(), + ]); + } + + return redirect('/'); } public function GetRolesHarian(Request $request, $kodcaw){ diff --git a/app/Http/Middleware/LogViewerPassword.php b/app/Http/Middleware/LogViewerPassword.php index c02c7e93..f43d2c40 100644 --- a/app/Http/Middleware/LogViewerPassword.php +++ b/app/Http/Middleware/LogViewerPassword.php @@ -8,16 +8,16 @@ class LogViewerPassword { public function handle($request, Closure $next) { - $password = config('logviewer.password'); + $passwordHash = config('logviewer.password'); - if (!is_string($password) || $password === '') { + if (!is_string($passwordHash) || $passwordHash === '') { return response('Akses log belum dikonfigurasi.', 503) ->header('Cache-Control', 'no-store'); } $provided = $request->getPassword(); - if ($request->getUser() !== 'logs' || !is_string($provided) || - !hash_equals(hash('sha256', $password), hash('sha256', $provided))) { + if ($request->getUser() !== 'logviewer' || !is_string($provided) || + !password_verify($provided, $passwordHash)) { return response('Kata laluan diperlukan untuk mengakses log.', 401, [ 'WWW-Authenticate' => 'Basic realm="Log Viewer", charset="UTF-8"', 'Cache-Control' => 'no-store', diff --git a/app/Http/Middleware/RoleAccess.php b/app/Http/Middleware/RoleAccess.php index 74c33c96..e59b6a87 100644 --- a/app/Http/Middleware/RoleAccess.php +++ b/app/Http/Middleware/RoleAccess.php @@ -44,6 +44,12 @@ class RoleAccess return $next($request); } break; + + case 'masteradmin': + if ($userRole == 'masteradmin') { + return $next($request); + } + break; case 'penilai': if ($userRole == 'penilai') { diff --git a/routes/web.php b/routes/web.php index 1c0574b1..64bf6c4c 100644 --- a/routes/web.php +++ b/routes/web.php @@ -64,7 +64,12 @@ Route::get('test', function () { }); Route::get('logs', '\Rap2hpoutre\LaravelLogViewer\LogViewerController@index') - ->middleware(['throttle:10,1', \App\Http\Middleware\LogViewerPassword::class]); + ->middleware([ + 'auth', + 'role:admin,masteradmin,operasi', + 'throttle:10,1', + \App\Http\Middleware\LogViewerPassword::class, + ]); Route::get('change-password', ['as'=>'user.password','uses'=>'ChangePasswordController@index']); Route::post('change-password', ['as'=>'change.password','uses'=>'ChangePasswordController@store']); diff --git a/tests/Feature/LogViewerPasswordTest.php b/tests/Feature/LogViewerPasswordTest.php index 43e5991d..475d85b5 100644 --- a/tests/Feature/LogViewerPasswordTest.php +++ b/tests/Feature/LogViewerPasswordTest.php @@ -17,7 +17,7 @@ class LogViewerPasswordTest extends TestCase public function test_missing_or_incorrect_credentials_are_rejected() { - config(['logviewer.password' => 'test-only-secret']); + config(['logviewer.password' => password_hash('test-only-secret', PASSWORD_DEFAULT)]); foreach ([[], ['PHP_AUTH_USER' => 'logs', 'PHP_AUTH_PW' => 'wrong'], ['PHP_AUTH_USER' => 'other', 'PHP_AUTH_PW' => 'test-only-secret']] as $server) { $response = $this->checkAccess($server); @@ -28,18 +28,21 @@ class LogViewerPasswordTest extends TestCase public function test_correct_credentials_allow_access_without_caching() { - config(['logviewer.password' => 'test-only-secret']); + config(['logviewer.password' => password_hash('test-only-secret', PASSWORD_DEFAULT)]); $response = $this->checkAccess(['PHP_AUTH_USER' => 'logs', 'PHP_AUTH_PW' => 'test-only-secret']); $this->assertSame(200, $response->getStatusCode()); $this->assertSame('allowed', $response->getContent()); $this->assertStringContainsString('no-store', $response->headers->get('Cache-Control')); } - public function test_logs_route_has_password_and_throttle_middleware() + public function test_logs_route_has_auth_role_password_and_throttle_middleware() { $route = app('router')->getRoutes()->match(Request::create('/logs')); - $this->assertContains(LogViewerPassword::class, $route->gatherMiddleware()); - $this->assertContains('throttle:10,1', $route->gatherMiddleware()); + $middleware = $route->gatherMiddleware(); + $this->assertContains('auth', $middleware); + $this->assertContains('role:admin,masteradmin', $middleware); + $this->assertContains(LogViewerPassword::class, $middleware); + $this->assertContains('throttle:10,1', $middleware); } private function checkAccess(array $server = [])