From 0f649ba5b22635472421c3f67f9aff3e2aa33717 Mon Sep 17 00:00:00 2001 From: Kal Marsh Date: Thu, 22 Aug 2024 14:05:18 -0700 Subject: [PATCH 1/6] updates code to L11 --- .../App/Http/Controllers/FedController.php | 2 +- .../Fed/App/Providers/FedServiceProvider.php | 2 +- .../App/Providers/RouteServiceProvider.php | 6 +- Modules/Fed/composer.json | 7 +-- Modules/Fed/module.json | 2 +- ...nController.php => InstAtteController.php} | 10 ++-- ...utionController.php => InstController.php} | 4 +- ...anceController.php => MaintController.php} | 4 +- .../{IsActive.php => InstIsActive.php} | 4 +- .../{IsAdmin.php => InstIsAdmin.php} | 4 +- .../Requests/AttestationDuplicateRequest.php | 2 +- .../Http/Requests/AttestationEditRequest.php | 2 +- .../Http/Requests/AttestationStoreRequest.php | 2 +- .../Providers/InstitutionServiceProvider.php | 2 +- .../App/Providers/RouteServiceProvider.php | 6 +- Modules/Institution/composer.json | 6 +- Modules/Institution/module.json | 2 +- Modules/Institution/routes/web.php | 22 ++++---- .../Controllers/AttestationController.php | 2 +- .../App/Http/Controllers/CapController.php | 2 +- .../App/Http/Controllers/FedCapController.php | 2 +- .../Controllers/InstitutionController.php | 2 +- .../InstitutionStaffController.php | 2 +- .../Controllers/MaintenanceController.php | 2 +- .../Http/Controllers/ProgramController.php | 2 +- .../Ministry/App/Http/Middleware/IsActive.php | 2 +- .../Ministry/App/Http/Middleware/IsAdmin.php | 2 +- .../App/Providers/MinistryServiceProvider.php | 2 +- .../App/Providers/RouteServiceProvider.php | 6 +- Modules/Ministry/composer.json | 2 +- Modules/Ministry/module.json | 2 +- Modules/Ministry/routes/web.php | 14 ++--- app/Http/Controllers/UserController.php | 24 +++++++- app/Http/Kernel.php | 8 +-- app/Http/Middleware/HandleInertiaRequests.php | 2 +- composer.json | 35 +++++++----- config/modules.php | 55 ++----------------- public/mix-manifest.json | 1 + 38 files changed, 118 insertions(+), 140 deletions(-) rename Modules/Institution/App/Http/Controllers/{AttestationController.php => InstAtteController.php} (97%) rename Modules/Institution/App/Http/Controllers/{InstitutionController.php => InstController.php} (97%) rename Modules/Institution/App/Http/Controllers/{MaintenanceController.php => MaintController.php} (79%) rename Modules/Institution/App/Http/Middleware/{IsActive.php => InstIsActive.php} (97%) rename Modules/Institution/App/Http/Middleware/{IsAdmin.php => InstIsAdmin.php} (94%) diff --git a/Modules/Fed/App/Http/Controllers/FedController.php b/Modules/Fed/App/Http/Controllers/FedController.php index 46574e2c..accc5dc8 100644 --- a/Modules/Fed/App/Http/Controllers/FedController.php +++ b/Modules/Fed/App/Http/Controllers/FedController.php @@ -1,6 +1,6 @@ namespace($this->moduleNamespace) ->group(module_path('Fed', '/routes/web.php')); } @@ -53,7 +52,6 @@ protected function mapApiRoutes(): void { Route::prefix('api') ->middleware('api') - ->namespace($this->moduleNamespace) ->group(module_path('Fed', '/routes/api.php')); } } diff --git a/Modules/Fed/composer.json b/Modules/Fed/composer.json index abc244ba..704a5c51 100644 --- a/Modules/Fed/composer.json +++ b/Modules/Fed/composer.json @@ -17,10 +17,9 @@ }, "autoload": { "psr-4": { - "Modules\\Fed\\": "", - "Modules\\Fed\\App\\": "app/", - "Modules\\Fed\\Database\\Factories\\": "database/factories/", - "Modules\\Fed\\Database\\Seeders\\": "database/seeders/" + "Modules\\Fed\\": "App/", + "Modules\\Fed\\Database\\Factories\\": "Database/factories/", + "Modules\\Fed\\Database\\Seeders\\": "Database/Seeders/" } }, "autoload-dev": { diff --git a/Modules/Fed/module.json b/Modules/Fed/module.json index 55407dc2..5ecfca46 100644 --- a/Modules/Fed/module.json +++ b/Modules/Fed/module.json @@ -5,7 +5,7 @@ "keywords": [], "priority": 0, "providers": [ - "Modules\\Fed\\App\\Providers\\FedServiceProvider" + "Modules\\Fed\\Providers\\FedServiceProvider" ], "files": [] } diff --git a/Modules/Institution/App/Http/Controllers/AttestationController.php b/Modules/Institution/App/Http/Controllers/InstAtteController.php similarity index 97% rename from Modules/Institution/App/Http/Controllers/AttestationController.php rename to Modules/Institution/App/Http/Controllers/InstAtteController.php index 5ce40c9f..a4caf9cd 100644 --- a/Modules/Institution/App/Http/Controllers/AttestationController.php +++ b/Modules/Institution/App/Http/Controllers/InstAtteController.php @@ -1,6 +1,6 @@ namespace($this->moduleNamespace) ->group(module_path('Institution', '/routes/web.php')); } @@ -53,7 +52,6 @@ protected function mapApiRoutes(): void { Route::prefix('api') ->middleware('api') - ->namespace($this->moduleNamespace) ->group(module_path('Institution', '/routes/api.php')); } } diff --git a/Modules/Institution/composer.json b/Modules/Institution/composer.json index 60649905..e8c1cd87 100644 --- a/Modules/Institution/composer.json +++ b/Modules/Institution/composer.json @@ -17,10 +17,10 @@ }, "autoload": { "psr-4": { - "Modules\\Institution\\": "", + "Modules\\Institution\\": "App/", "Modules\\Institution\\App\\": "app/", - "Modules\\Institution\\Database\\Factories\\": "database/factories/", - "Modules\\Institution\\Database\\Seeders\\": "database/seeders/" + "Modules\\Institution\\Database\\Factories\\": "Database/Factories/", + "Modules\\Institution\\Database\\Seeders\\": "Database/Seeders/" } }, "autoload-dev": { diff --git a/Modules/Institution/module.json b/Modules/Institution/module.json index 256f402f..1252f53c 100644 --- a/Modules/Institution/module.json +++ b/Modules/Institution/module.json @@ -5,7 +5,7 @@ "keywords": [], "priority": 0, "providers": [ - "Modules\\Institution\\App\\Providers\\InstitutionServiceProvider" + "Modules\\Institution\\Providers\\InstitutionServiceProvider" ], "files": [] } diff --git a/Modules/Institution/routes/web.php b/Modules/Institution/routes/web.php index 85c38330..caa2a851 100644 --- a/Modules/Institution/routes/web.php +++ b/Modules/Institution/routes/web.php @@ -2,10 +2,10 @@ use App\Http\Controllers\FaqController; use Illuminate\Support\Facades\Route; -use Modules\Institution\App\Http\Controllers\AttestationController; -use Modules\Institution\App\Http\Controllers\InstitutionController; -use Modules\Institution\App\Http\Controllers\MaintenanceController; -use Modules\Ministry\App\Http\Controllers\FedCapController; +use Modules\Institution\Http\Controllers\InstAtteController; +use Modules\Institution\Http\Controllers\InstController; +use Modules\Institution\Http\Controllers\MaintController; +use Modules\Ministry\Http\Controllers\FedCapController; /* |-------------------------------------------------------------------------- @@ -32,14 +32,14 @@ Route::get('/attestations/export', [AttestationController::class, 'exportCsv'])->name('attestations.export'); Route::post('/duplicate_attestations', [AttestationController::class, 'duplicate'])->name('attestations.duplicate'); - Route::get('/dashboard', [InstitutionController::class, 'index'])->name('dashboard'); - Route::get('/account', [InstitutionController::class, 'show'])->name('show'); + Route::get('/dashboard', [InstController::class, 'index'])->name('dashboard'); + Route::get('/account', [InstController::class, 'show'])->name('show'); - Route::get('/caps', [InstitutionController::class, 'caps'])->name('caps.index'); + Route::get('/caps', [InstController::class, 'caps'])->name('caps.index'); Route::post('/api/fetch/capStats', [AttestationController::class, 'capStat'])->name('caps.api.fetch.cap-stat'); Route::post('/api/check/duplicate_student', [AttestationController::class, 'duplicateStudent'])->name('caps.api.check.duplicate-student'); - Route::get('/faqs', [MaintenanceController::class, 'faqList'])->name('faqs.index'); + Route::get('/faqs', [MaintController::class, 'faqList'])->name('faqs.index'); Route::post('/fed_caps/default', [FedCapController::class, 'setDefault'])->name('fed_caps.set-default'); @@ -48,10 +48,10 @@ Route::group([ 'middleware' => ['institution_admin'], ], function () { - Route::get('/staff', [InstitutionController::class, 'staffList'])->name('staff.list'); + Route::get('/staff', [InstController::class, 'staffList'])->name('staff.list'); - Route::put('/staff', [InstitutionController::class, 'staffUpdate'])->name('staff.staffUpdate'); - Route::put('/roles', [InstitutionController::class, 'staffUpdateRole'])->name('roles.staffUpdateRole'); + Route::put('/staff', [InstController::class, 'staffUpdate'])->name('staff.staffUpdate'); + Route::put('/roles', [InstController::class, 'staffUpdateRole'])->name('roles.staffUpdateRole'); }); }); diff --git a/Modules/Ministry/App/Http/Controllers/AttestationController.php b/Modules/Ministry/App/Http/Controllers/AttestationController.php index c5f5d252..6c2fd3b0 100644 --- a/Modules/Ministry/App/Http/Controllers/AttestationController.php +++ b/Modules/Ministry/App/Http/Controllers/AttestationController.php @@ -1,6 +1,6 @@ namespace($this->moduleNamespace) ->group(module_path('Ministry', '/routes/web.php')); } @@ -53,7 +52,6 @@ protected function mapApiRoutes(): void { Route::prefix('api') ->middleware('api') - ->namespace($this->moduleNamespace) ->group(module_path('Ministry', '/routes/api.php')); } } diff --git a/Modules/Ministry/composer.json b/Modules/Ministry/composer.json index ccb666f6..3d58c27d 100644 --- a/Modules/Ministry/composer.json +++ b/Modules/Ministry/composer.json @@ -17,7 +17,7 @@ }, "autoload": { "psr-4": { - "Modules\\Ministry\\": "" + "Modules\\Ministry\\": "App/" } } } diff --git a/Modules/Ministry/module.json b/Modules/Ministry/module.json index c82a9745..923b02e7 100644 --- a/Modules/Ministry/module.json +++ b/Modules/Ministry/module.json @@ -5,7 +5,7 @@ "keywords": [], "priority": 0, "providers": [ - "Modules\\Ministry\\App\\Providers\\MinistryServiceProvider" + "Modules\\Ministry\\Providers\\MinistryServiceProvider" ], "files": [] } diff --git a/Modules/Ministry/routes/web.php b/Modules/Ministry/routes/web.php index 465986bf..bf1a3420 100644 --- a/Modules/Ministry/routes/web.php +++ b/Modules/Ministry/routes/web.php @@ -1,13 +1,13 @@ has('state') && empty($request->session()->get('oauth2state'))) { +// Session::regenerate(false); +// +// \Log::info('Session ID: ' . Session::getId()); +// \Log::info('A: oauth2state:' . Session::get('oauth2state')); +// \Log::info('empty oauth2state '); +// \Log::info('state:' . $request->state); +// Session::put('oauth2state', $request->state); +// \Log::info('B2: oauth2state:' . Session::get('oauth2state')); +// +// \Log::info(' '); +// Session::save(); +// +// return redirect()->to('/bceid-login?state='.Session::get('oauth2state').'&session_state='.$request->session_state. +// '&code='.$request->code); + + // Check given state against previously stored one to mitigate CSRF attack } elseif (! $request->has('state') || ($request->state !== $request->session()->get('oauth2state'))) { - $request->session()->forget('oauth2state'); \Log::info('messed up state '.$request->state.' !== '.$request->session()->get('oauth2state')); + $request->session()->forget('oauth2state'); //Invalid state, make sure HTTP sessions are enabled return Inertia::render('Auth/Login', [ @@ -77,11 +95,15 @@ private function loginUser(Request $request, $provider, $type): \Inertia\Respons 'status' => 'We could not log you in. Please contact RequestIT@gov.bc.ca', ]); } else { + \Log::info('We got State: '.$request->state . " and Code: " . $request->code); + \Log::info('Session state:' . $request->session()->get('oauth2state')); + // Try to get an access token (using the authorization coe grant) try { $token = $provider->getAccessToken('authorization_code', [ 'code' => $request->code, ]); + \Log::info('Token based on code:' . $token); } catch (\Exception $e) { return Inertia::render('Auth/Login', [ 'loginAttempt' => true, diff --git a/app/Http/Kernel.php b/app/Http/Kernel.php index 8e058433..e8fb5bd6 100644 --- a/app/Http/Kernel.php +++ b/app/Http/Kernel.php @@ -66,10 +66,10 @@ class Kernel extends HttpKernel 'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class, 'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class, - 'ministry_active' => \Modules\Ministry\App\Http\Middleware\IsActive::class, - 'ministry_admin' => \Modules\Ministry\App\Http\Middleware\IsAdmin::class, - 'institution_active' => \Modules\Institution\App\Http\Middleware\IsActive::class, - 'institution_admin' => \Modules\Institution\App\Http\Middleware\IsAdmin::class, + 'ministry_active' => \Modules\Ministry\Http\Middleware\IsActive::class, + 'ministry_admin' => \Modules\Ministry\Http\Middleware\IsAdmin::class, + 'institution_active' => \Modules\Institution\Http\Middleware\InstIsActive::class, + 'institution_admin' => \Modules\Institution\Http\Middleware\InstIsAdmin::class, 'super_admin' => \App\Http\Middleware\SuperAdmin::class, ]; diff --git a/app/Http/Middleware/HandleInertiaRequests.php b/app/Http/Middleware/HandleInertiaRequests.php index 00b04a7b..876a1047 100644 --- a/app/Http/Middleware/HandleInertiaRequests.php +++ b/app/Http/Middleware/HandleInertiaRequests.php @@ -8,7 +8,7 @@ use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; use Inertia\Middleware; -use Tightenco\Ziggy\Ziggy; +use Tighten\Ziggy\Ziggy; use Illuminate\Support\Facades\Session; use Illuminate\Support\Facades\Cache; diff --git a/composer.json b/composer.json index e1b853ed..83d81608 100644 --- a/composer.json +++ b/composer.json @@ -5,30 +5,29 @@ "keywords": ["laravel", "framework"], "license": "MIT", "require": { - "php": "^8.1", + "php": "^8.2", "barryvdh/laravel-dompdf": "^2.1", "guzzlehttp/guzzle": "^7.2", - "inertiajs/inertia-laravel": "^0.6.8", - "laravel/framework": "^10.10", - "laravel/sanctum": "^3.3", - "laravel/tinker": "^2.8", - "nwidart/laravel-modules": "^10.0", - "stevenmaguire/oauth2-keycloak": "^5.0", - "tightenco/ziggy": "^1.0" + "inertiajs/inertia-laravel": "^1.0", + "laravel/framework": "^11.9", + "laravel/sanctum": "^4.0", + "laravel/tinker": "^2.9", + "nwidart/laravel-modules": "^11.0", + "stevenmaguire/oauth2-keycloak": "^5.1", + "tightenco/ziggy": "^2.2" }, "require-dev": { "fakerphp/faker": "^1.9.1", - "laravel/pint": "^1.0", - "laravel/sail": "^1.18", - "mockery/mockery": "^1.4.4", - "nunomaduro/collision": "^7.0", - "phpunit/phpunit": "^10.1", + "laravel/pint": "^1.13", + "laravel/sail": "^1.26", + "mockery/mockery": "^1.6", + "nunomaduro/collision": "^8.0", + "phpunit/phpunit": "^11.0.1", "spatie/laravel-ignition": "^2.0" }, "autoload": { "psr-4": { "App\\": "app/", - "Modules\\": "Modules/", "Database\\Factories\\": "database/factories/", "Database\\Seeders\\": "database/seeders/" } @@ -56,6 +55,11 @@ "extra": { "laravel": { "dont-discover": [] + }, + "merge-plugin": { + "include": [ + "Modules/*/composer.json" + ] } }, "config": { @@ -64,7 +68,8 @@ "sort-packages": true, "allow-plugins": { "pestphp/pest-plugin": true, - "php-http/discovery": true + "php-http/discovery": true, + "wikimedia/composer-merge-plugin": true } }, "minimum-stability": "stable", diff --git a/config/modules.php b/config/modules.php index 32e9db76..c5c45590 100644 --- a/config/modules.php +++ b/config/modules.php @@ -1,7 +1,7 @@ [ - Commands\CommandMakeCommand::class, - Commands\ComponentClassMakeCommand::class, - Commands\ComponentViewMakeCommand::class, - Commands\ControllerMakeCommand::class, - Commands\ChannelMakeCommand::class, - Commands\DisableCommand::class, - Commands\DumpCommand::class, - Commands\EnableCommand::class, - Commands\EventMakeCommand::class, - Commands\FactoryMakeCommand::class, - Commands\JobMakeCommand::class, - Commands\ListenerMakeCommand::class, - Commands\MailMakeCommand::class, - Commands\MiddlewareMakeCommand::class, - Commands\NotificationMakeCommand::class, - Commands\ObserverMakeCommand::class, - Commands\PolicyMakeCommand::class, - Commands\ProviderMakeCommand::class, - Commands\InstallCommand::class, - Commands\LaravelModulesV6Migrator::class, - Commands\ListCommand::class, - Commands\ModuleDeleteCommand::class, - Commands\ModuleMakeCommand::class, - Commands\MigrateCommand::class, - Commands\MigrateFreshCommand::class, - Commands\MigrateRefreshCommand::class, - Commands\MigrateResetCommand::class, - Commands\MigrateRollbackCommand::class, - Commands\MigrateStatusCommand::class, - Commands\MigrationMakeCommand::class, - Commands\ModelMakeCommand::class, - Commands\ResourceMakeCommand::class, - Commands\RequestMakeCommand::class, - Commands\RuleMakeCommand::class, - Commands\RouteProviderMakeCommand::class, - Commands\PublishCommand::class, - Commands\PublishConfigurationCommand::class, - Commands\PublishMigrationCommand::class, - Commands\PublishTranslationCommand::class, - Commands\SeedCommand::class, - Commands\SeedMakeCommand::class, - Commands\SetupCommand::class, - Commands\TestMakeCommand::class, - Commands\UnUseCommand::class, - Commands\UpdateCommand::class, - Commands\UseCommand::class, - ], + 'commands' => ConsoleServiceProvider::defaultCommands() + ->merge([ + // New commands go here + ])->toArray(), + /* |-------------------------------------------------------------------------- diff --git a/public/mix-manifest.json b/public/mix-manifest.json index 2ce13dce..f02f8112 100644 --- a/public/mix-manifest.json +++ b/public/mix-manifest.json @@ -8,6 +8,7 @@ "/images/2022/BC_PSEFS_H_RGB_rev.png": "/images/2022/BC_PSEFS_H_RGB_rev.png", "/images/2022/BC_PSEFS_H_Solid_pos.png": "/images/2022/BC_PSEFS_H_Solid_pos.png", "/images/2022/BC_PSEFS_H_Solid_rev.png": "/images/2022/BC_PSEFS_H_Solid_rev.png", + "/images/attestation_sign.png": "/images/attestation_sign.png", "/images/bc-logo-grey.gif": "/images/bc-logo-grey.gif", "/images/bc_lg_logo.png": "/images/bc_lg_logo.png", "/images/bc_no_bg.png": "/images/bc_no_bg.png", From 2d435a0e3f4d5ee45d215ba1519fb236b8d228e8 Mon Sep 17 00:00:00 2001 From: Kal Marsh Date: Thu, 22 Aug 2024 15:10:01 -0700 Subject: [PATCH 2/6] updates code to L11 --- config/app.php | 18 ++++++++++++------ config/auth.php | 10 +++++----- config/session.php | 12 ++++++------ 3 files changed, 23 insertions(+), 17 deletions(-) diff --git a/config/app.php b/config/app.php index f2685900..aa4105a4 100644 --- a/config/app.php +++ b/config/app.php @@ -70,7 +70,7 @@ | */ - 'timezone' => 'America/Vancouver', + 'timezone' => env('APP_TIMEZONE', 'America/Vancouver'), /* |-------------------------------------------------------------------------- @@ -83,7 +83,7 @@ | */ - 'locale' => 'en', + 'locale' => env('APP_LOCALE', 'en'), /* |-------------------------------------------------------------------------- @@ -96,7 +96,7 @@ | */ - 'fallback_locale' => 'en', + 'fallback_locale' => env('APP_FALLBACK_LOCALE', 'en'), /* |-------------------------------------------------------------------------- @@ -109,7 +109,7 @@ | */ - 'faker_locale' => 'en_US', + 'faker_locale' => env('APP_FAKER_LOCALE', 'en_US'), /* |-------------------------------------------------------------------------- @@ -126,6 +126,12 @@ 'cipher' => 'AES-256-CBC', + 'previous_keys' => [ + ...array_filter( + explode(',', env('APP_PREVIOUS_KEYS', '')) + ), + ], + /* |-------------------------------------------------------------------------- | Maintenance Mode Driver @@ -140,8 +146,8 @@ */ 'maintenance' => [ - 'driver' => 'file', - // 'store' => 'redis', + 'driver' => env('APP_MAINTENANCE_DRIVER', 'file'), + 'store' => env('APP_MAINTENANCE_STORE', 'database'), ], /* diff --git a/config/auth.php b/config/auth.php index 9548c15d..e9741121 100644 --- a/config/auth.php +++ b/config/auth.php @@ -14,8 +14,8 @@ */ 'defaults' => [ - 'guard' => 'web', - 'passwords' => 'users', + 'guard' => env('AUTH_GUARD', 'web'), + 'passwords' => env('AUTH_PASSWORD_BROKER', 'users'), ], /* @@ -62,7 +62,7 @@ 'providers' => [ 'users' => [ 'driver' => 'eloquent', - 'model' => App\Models\User::class, + 'model' => env('AUTH_MODEL', App\Models\User::class), ], // 'users' => [ @@ -93,7 +93,7 @@ 'passwords' => [ 'users' => [ 'provider' => 'users', - 'table' => 'password_reset_tokens', + 'table' => env('AUTH_PASSWORD_RESET_TOKEN_TABLE', 'password_reset_tokens'), 'expire' => 60, 'throttle' => 60, ], @@ -110,6 +110,6 @@ | */ - 'password_timeout' => 10800, + 'password_timeout' => env('AUTH_PASSWORD_TIMEOUT', 10800), ]; diff --git a/config/session.php b/config/session.php index 5683029d..9c5b3fb8 100644 --- a/config/session.php +++ b/config/session.php @@ -18,7 +18,7 @@ | */ - 'driver' => env('SESSION_DRIVER', 'file'), + 'driver' => env('SESSION_DRIVER', 'database'), /* |-------------------------------------------------------------------------- @@ -33,7 +33,7 @@ 'lifetime' => env('SESSION_LIFETIME', 120), - 'expire_on_close' => false, + 'expire_on_close' => env('SESSION_EXPIRE_ON_CLOSE', false), /* |-------------------------------------------------------------------------- @@ -85,7 +85,7 @@ | */ - 'table' => 'sessions', + 'table' => env('SESSION_TABLE', 'sessions'), /* |-------------------------------------------------------------------------- @@ -142,7 +142,7 @@ | */ - 'path' => '/', + 'path' => env('SESSION_PATH', '/'), /* |-------------------------------------------------------------------------- @@ -181,7 +181,7 @@ | */ - 'http_only' => true, + 'http_only' => env('SESSION_HTTP_ONLY', true), /* |-------------------------------------------------------------------------- @@ -209,6 +209,6 @@ | */ - 'partitioned' => false, + 'partitioned' => env('SESSION_PARTITIONED_COOKIE', false), ]; From 3a7a27e74ebc12c3acd923b6c9697aea86bd8f1f Mon Sep 17 00:00:00 2001 From: Kal Marsh Date: Thu, 22 Aug 2024 15:28:20 -0700 Subject: [PATCH 3/6] updates code to L11 --- composer.json | 1 + 1 file changed, 1 insertion(+) diff --git a/composer.json b/composer.json index 83d81608..73b4a450 100644 --- a/composer.json +++ b/composer.json @@ -17,6 +17,7 @@ "tightenco/ziggy": "^2.2" }, "require-dev": { + "barryvdh/laravel-debugbar": "^3.13", "fakerphp/faker": "^1.9.1", "laravel/pint": "^1.13", "laravel/sail": "^1.26", From 098fa687e69a7101525303019b460e1a6f87ff34 Mon Sep 17 00:00:00 2001 From: Kal Marsh Date: Thu, 22 Aug 2024 15:46:14 -0700 Subject: [PATCH 4/6] updates code to L11 --- app/Http/Controllers/UserController.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/Http/Controllers/UserController.php b/app/Http/Controllers/UserController.php index 02636aa7..8677ac2e 100644 --- a/app/Http/Controllers/UserController.php +++ b/app/Http/Controllers/UserController.php @@ -64,6 +64,7 @@ private function loginUser(Request $request, $provider, $type): \Inertia\Respons \Log::info('$authUrl: '.$authUrl); \Log::info('$provider->getState(): '.$provider->getState()); + config(['session.same_site' => 'lax']); return Redirect::to($authUrl); // Check given state against previously stored one to mitigate CSRF attack From a7c74d0238a8ec1879b87b112d4d30a9995a47e6 Mon Sep 17 00:00:00 2001 From: Kal Marsh Date: Mon, 26 Aug 2024 13:16:51 -0700 Subject: [PATCH 5/6] fixes issue with login --- Modules/Fed/routes/web.php | 2 +- .../App/Http/Controllers/InstController.php | 3 + .../App/Http/Middleware/InstIsActive.php | 2 + .../App/Http/Middleware/InstIsAdmin.php | 1 + Modules/Institution/routes/web.php | 31 +++-- app/Http/Controllers/UserController.php | 36 +++-- app/Http/Middleware/Authenticate.php | 125 +++++++++++++++++- app/Policies/UserPolicy.php | 14 +- 8 files changed, 180 insertions(+), 34 deletions(-) diff --git a/Modules/Fed/routes/web.php b/Modules/Fed/routes/web.php index 481e0d2c..e6d0bf2b 100644 --- a/Modules/Fed/routes/web.php +++ b/Modules/Fed/routes/web.php @@ -1,7 +1,7 @@ id); $institution = $user->institution; diff --git a/Modules/Institution/App/Http/Middleware/InstIsActive.php b/Modules/Institution/App/Http/Middleware/InstIsActive.php index 4b983a65..9396b708 100644 --- a/Modules/Institution/App/Http/Middleware/InstIsActive.php +++ b/Modules/Institution/App/Http/Middleware/InstIsActive.php @@ -22,8 +22,10 @@ class InstIsActive public function handle(Request $request, Closure $next, ...$roles) { $roles = empty($roles) ? [null] : $roles; + \Log::info('InstIsActive '); if (! Auth::check()) { + \Log::info('no auth '); return redirect()->route('login'); } diff --git a/Modules/Institution/App/Http/Middleware/InstIsAdmin.php b/Modules/Institution/App/Http/Middleware/InstIsAdmin.php index ab706f90..45ad554b 100644 --- a/Modules/Institution/App/Http/Middleware/InstIsAdmin.php +++ b/Modules/Institution/App/Http/Middleware/InstIsAdmin.php @@ -20,6 +20,7 @@ class InstIsAdmin public function handle(Request $request, Closure $next, ...$roles) { $roles = empty($roles) ? [null] : $roles; + \Log::info('InstIsAdmin '); if (! Auth::check()) { return Inertia::render('Auth/Login', [ diff --git a/Modules/Institution/routes/web.php b/Modules/Institution/routes/web.php index caa2a851..7ee4f29c 100644 --- a/Modules/Institution/routes/web.php +++ b/Modules/Institution/routes/web.php @@ -1,11 +1,14 @@ group(function () { Route::group( [ - 'middleware' => ['auth', 'institution_active'], + 'middleware' => [Authenticate::class, InstIsActive::class], 'as' => 'institution.', ], function () { - Route::get('/', [AttestationController::class, 'index'])->name('home'); - Route::get('/attestations', [AttestationController::class, 'index'])->name('attestations.index'); - Route::post('/attestations', [AttestationController::class, 'store'])->name('attestations.store'); - Route::put('/attestations', [AttestationController::class, 'update'])->name('attestations.update'); - Route::get('/attestations/download/{attestation}', [AttestationController::class, 'download'])->name('attestations.download'); - Route::get('/attestations/export', [AttestationController::class, 'exportCsv'])->name('attestations.export'); - Route::post('/duplicate_attestations', [AttestationController::class, 'duplicate'])->name('attestations.duplicate'); + Route::get('/', [InstAtteController::class, 'index'])->name('home'); + Route::get('/attestations', [InstAtteController::class, 'index'])->name('attestations.index'); + Route::post('/attestations', [InstAtteController::class, 'store'])->name('attestations.store'); + Route::put('/attestations', [InstAtteController::class, 'update'])->name('attestations.update'); + Route::get('/attestations/download/{attestation}', [InstAtteController::class, 'download'])->name('attestations.download'); + Route::get('/attestations/export', [InstAtteController::class, 'exportCsv'])->name('attestations.export'); + Route::post('/duplicate_attestations', [InstAtteController::class, 'duplicate'])->name('attestations.duplicate'); - Route::get('/dashboard', [InstController::class, 'index'])->name('dashboard'); - Route::get('/account', [InstController::class, 'show'])->name('show'); + Route::get('/dashboard', [InstController::class, 'index'])->name('dashboard'); + Route::get('/account', [InstController::class, 'show'])->name('show'); - Route::get('/caps', [InstController::class, 'caps'])->name('caps.index'); - Route::post('/api/fetch/capStats', [AttestationController::class, 'capStat'])->name('caps.api.fetch.cap-stat'); - Route::post('/api/check/duplicate_student', [AttestationController::class, 'duplicateStudent'])->name('caps.api.check.duplicate-student'); + Route::get('/caps', [InstController::class, 'caps'])->name('caps.index'); + Route::post('/api/fetch/capStats', [InstAtteController::class, 'capStat'])->name('caps.api.fetch.cap-stat'); + Route::post('/api/check/duplicate_student', [InstAtteController::class, 'duplicateStudent'])->name('caps.api.check.duplicate-student'); Route::get('/faqs', [MaintController::class, 'faqList'])->name('faqs.index'); @@ -46,7 +49,7 @@ }); Route::group([ - 'middleware' => ['institution_admin'], + 'middleware' => [Authenticate::class, InstIsAdmin::class], ], function () { Route::get('/staff', [InstController::class, 'staffList'])->name('staff.list'); diff --git a/app/Http/Controllers/UserController.php b/app/Http/Controllers/UserController.php index 8677ac2e..5f9bb27e 100644 --- a/app/Http/Controllers/UserController.php +++ b/app/Http/Controllers/UserController.php @@ -10,6 +10,7 @@ use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Cache; +use Illuminate\Support\Facades\Cookie; use Illuminate\Support\Facades\Hash; use Illuminate\Support\Facades\Redirect; use Illuminate\Support\Facades\Session; @@ -60,12 +61,15 @@ private function loginUser(Request $request, $provider, $type): \Inertia\Respons if (! $request->has('code')) { // If we don't have an authorization code then get one $authUrl = $provider->getAuthorizationUrl(); - $request->session()->put('oauth2state', $provider->getState()); - \Log::info('$authUrl: '.$authUrl); - \Log::info('$provider->getState(): '.$provider->getState()); + $state = $provider->getState(); + setcookie('oauth2state', $state); +// Session::put('oauth2state', $state); + \Log::info('1 $authUrl: '.$authUrl); + \Log::info('2 $provider->getState(): '.$state); + // Store the state in a cookie with a short lifetime (e.g., 5 minutes) +// cookie()->queue(cookie('oauth2state', $state, 5)); // Store for 5 minutes - config(['session.same_site' => 'lax']); - return Redirect::to($authUrl); + return Redirect::to($authUrl.'&kc_idp_hint=usp'); // Check given state against previously stored one to mitigate CSRF attack // } elseif ($request->has('state') && empty($request->session()->get('oauth2state'))) { @@ -85,9 +89,13 @@ private function loginUser(Request $request, $provider, $type): \Inertia\Respons // '&code='.$request->code); // Check given state against previously stored one to mitigate CSRF attack - } elseif (! $request->has('state') || ($request->state !== $request->session()->get('oauth2state'))) { - \Log::info('messed up state '.$request->state.' !== '.$request->session()->get('oauth2state')); - $request->session()->forget('oauth2state'); + } elseif (! $request->has('state') || ($request->state !== $_COOKIE['oauth2state'])) { + \Log::info('messed up state '.$request->state.' !== '.Session::get('oauth2state')); + \Log::info('3 $provider->getState(): '.$_COOKIE['oauth2state']); + + //$request->session()->forget('oauth2state'); + // Clear the cookie + setcookie('oauth2state', '', -3600); //Invalid state, make sure HTTP sessions are enabled return Inertia::render('Auth/Login', [ @@ -97,7 +105,7 @@ private function loginUser(Request $request, $provider, $type): \Inertia\Respons ]); } else { \Log::info('We got State: '.$request->state . " and Code: " . $request->code); - \Log::info('Session state:' . $request->session()->get('oauth2state')); + \Log::info('Session state:' . $_COOKIE['oauth2state']); // Try to get an access token (using the authorization coe grant) try { @@ -106,6 +114,7 @@ private function loginUser(Request $request, $provider, $type): \Inertia\Respons ]); \Log::info('Token based on code:' . $token); } catch (\Exception $e) { + setcookie('oauth2state', '', -3600); return Inertia::render('Auth/Login', [ 'loginAttempt' => true, 'hasAccess' => false, @@ -121,6 +130,7 @@ private function loginUser(Request $request, $provider, $type): \Inertia\Respons \Log::info('We got a token: '.$token); \Log::info('$provider_user: '.json_encode($provider_user)); } catch (\Exception $e) { + setcookie('oauth2state', '', -3600); return Inertia::render('Auth/Login', [ 'loginAttempt' => true, 'hasAccess' => false, @@ -169,6 +179,7 @@ private function loginUser(Request $request, $provider, $type): \Inertia\Respons $user->name = $provider_user['name']; $user->save(); \Log::info('We got a name: '.$provider_user['name']); + setcookie('oauth2state', '', -3600); //else the user has access if ($type === Role::Ministry_GUEST) { @@ -183,6 +194,7 @@ private function loginUser(Request $request, $provider, $type): \Inertia\Respons } Auth::login($user); + \Log::info('User is ministry staff '); return Redirect::route('ministry.home'); } @@ -199,10 +211,14 @@ private function loginUser(Request $request, $provider, $type): \Inertia\Respons } Auth::login($user); + \Log::info('User is institution staff ' . Auth::check()); + \Log::info(Auth::check()); + \Log::info(Auth::user()->roles); return Redirect::route('institution.dashboard'); } + \Log::info('Redirect to Login '); return Redirect::route('login'); } } @@ -235,6 +251,7 @@ public function cancelledUsers(AjaxRequest $request) public function login(Request $request) { Cache::forget('global_fed_caps'); + setcookie('oauth2state', '', -3600); return Inertia::render('Auth/Login', [ 'loginAttempt' => false, 'hasAccess' => false, @@ -252,6 +269,7 @@ public function logout(Request $request) Auth::logout(); $request->session()->invalidate(); $request->session()->regenerateToken(); + setcookie('oauth2state', '', -3600); return redirect('/'); } diff --git a/app/Http/Middleware/Authenticate.php b/app/Http/Middleware/Authenticate.php index d4ef6447..0a114d98 100644 --- a/app/Http/Middleware/Authenticate.php +++ b/app/Http/Middleware/Authenticate.php @@ -3,15 +3,134 @@ namespace App\Http\Middleware; use Illuminate\Auth\Middleware\Authenticate as Middleware; +use Closure; +use Illuminate\Auth\AuthenticationException; +use Illuminate\Contracts\Auth\Factory as Auth; +use Illuminate\Contracts\Auth\Middleware\AuthenticatesRequests; use Illuminate\Http\Request; -class Authenticate extends Middleware +class Authenticate implements AuthenticatesRequests { + /** + * The authentication factory instance. + * + * @var \Illuminate\Contracts\Auth\Factory + */ + protected $auth; + + /** + * The callback that should be used to generate the authentication redirect path. + * + * @var callable + */ + protected static $redirectToCallback; + + /** + * Create a new middleware instance. + * + * @param \Illuminate\Contracts\Auth\Factory $auth + * @return void + */ + public function __construct(Auth $auth) + { + $this->auth = $auth; + } + + /** + * Specify the guards for the middleware. + * + * @param string $guard + * @param string $others + * @return string + */ + public static function using($guard, ...$others) + { + return static::class.':'.implode(',', [$guard, ...$others]); + } + + /** + * Handle an incoming request. + * + * @param \Illuminate\Http\Request $request + * @param \Closure $next + * @param string[] ...$guards + * @return mixed + * + * @throws \Illuminate\Auth\AuthenticationException + */ + public function handle($request, Closure $next, ...$guards) + { + $this->authenticate($request, $guards); + + return $next($request); + } + + /** + * Determine if the user is logged in to any of the given guards. + * + * @param \Illuminate\Http\Request $request + * @param array $guards + * @return void + * + * @throws \Illuminate\Auth\AuthenticationException + */ + protected function authenticate($request, array $guards) + { + if (empty($guards)) { + $guards = [null]; + } + + foreach ($guards as $guard) { + if ($this->auth->guard($guard)->check()) { + return $this->auth->shouldUse($guard); + } + } + + $this->unauthenticated($request, $guards); + } + + /** + * Handle an unauthenticated user. + * + * @param \Illuminate\Http\Request $request + * @param array $guards + * @return void + * + * @throws \Illuminate\Auth\AuthenticationException + */ + protected function unauthenticated($request, array $guards) + { + \Log::info('unauth'); + \Log::info(\Illuminate\Support\Facades\Auth::check()); + \Log::info($guards); + throw new AuthenticationException( + 'Unauthenticated.', + $guards, + $request->expectsJson() ? null : $this->redirectTo($request), + ); + } + /** * Get the path the user should be redirected to when they are not authenticated. + * + * @param \Illuminate\Http\Request $request + * @return string|null + */ + protected function redirectTo(Request $request) + { + if (static::$redirectToCallback) { + return call_user_func(static::$redirectToCallback, $request); + } + } + + /** + * Specify the callback that should be used to generate the redirect path. + * + * @param callable $redirectToCallback + * @return void */ - protected function redirectTo(Request $request): ?string + public static function redirectUsing(callable $redirectToCallback) { - return $request->expectsJson() ? null : route('login'); + static::$redirectToCallback = $redirectToCallback; } } diff --git a/app/Policies/UserPolicy.php b/app/Policies/UserPolicy.php index 5635260b..3e6e726a 100644 --- a/app/Policies/UserPolicy.php +++ b/app/Policies/UserPolicy.php @@ -10,13 +10,13 @@ class UserPolicy { use HandlesAuthorization; - - public function before(User $user, $ability) - { - $rolesToCheck = [Role::Ministry_USER, Role::Ministry_ADMIN, Role::SUPER_ADMIN]; - - return $user->roles()->pluck('name')->intersect($rolesToCheck)->isNotEmpty() && $user->disabled === false; - } +// +// public function before(User $user, $ability) +// { +// $rolesToCheck = [Role::Ministry_USER, Role::Ministry_ADMIN, Role::SUPER_ADMIN]; +// +// return $user->roles()->pluck('name')->intersect($rolesToCheck)->isNotEmpty() && $user->disabled === false; +// } /** * Determine whether the user can view any models. From 57533bd253fe1c80331fc8281cc9e2607f979976 Mon Sep 17 00:00:00 2001 From: Kal Marsh Date: Mon, 26 Aug 2024 13:41:17 -0700 Subject: [PATCH 6/6] reverts security updates back to lax --- .../App/Http/Controllers/FedController.php | 2 +- .../Fed/App/Providers/FedServiceProvider.php | 2 +- .../App/Providers/RouteServiceProvider.php | 6 +- Modules/Fed/composer.json | 7 +- Modules/Fed/module.json | 2 +- Modules/Fed/routes/web.php | 2 +- ...ntroller.php => AttestationController.php} | 10 +- ...ntroller.php => InstitutionController.php} | 7 +- ...ntroller.php => MaintenanceController.php} | 4 +- .../{InstIsActive.php => IsActive.php} | 6 +- .../{InstIsAdmin.php => IsAdmin.php} | 5 +- .../Requests/AttestationDuplicateRequest.php | 2 +- .../Http/Requests/AttestationEditRequest.php | 2 +- .../Http/Requests/AttestationStoreRequest.php | 2 +- .../Providers/InstitutionServiceProvider.php | 2 +- .../App/Providers/RouteServiceProvider.php | 6 +- Modules/Institution/composer.json | 6 +- Modules/Institution/module.json | 2 +- Modules/Institution/routes/web.php | 47 +++---- .../Controllers/AttestationController.php | 2 +- .../App/Http/Controllers/CapController.php | 2 +- .../App/Http/Controllers/FedCapController.php | 2 +- .../Controllers/InstitutionController.php | 2 +- .../InstitutionStaffController.php | 2 +- .../Controllers/MaintenanceController.php | 2 +- .../Http/Controllers/ProgramController.php | 2 +- .../Ministry/App/Http/Middleware/IsActive.php | 2 +- .../Ministry/App/Http/Middleware/IsAdmin.php | 2 +- .../App/Providers/MinistryServiceProvider.php | 2 +- .../App/Providers/RouteServiceProvider.php | 6 +- Modules/Ministry/composer.json | 2 +- Modules/Ministry/module.json | 2 +- Modules/Ministry/routes/web.php | 14 +- app/Http/Controllers/UserController.php | 55 +------- app/Http/Kernel.php | 8 +- app/Http/Middleware/Authenticate.php | 125 +----------------- app/Http/Middleware/HandleInertiaRequests.php | 2 +- app/Policies/UserPolicy.php | 14 +- composer.json | 33 ++--- config/app.php | 18 +-- config/auth.php | 10 +- config/modules.php | 55 +++++++- config/session.php | 14 +- public/mix-manifest.json | 1 - 44 files changed, 185 insertions(+), 316 deletions(-) rename Modules/Institution/App/Http/Controllers/{InstAtteController.php => AttestationController.php} (97%) rename Modules/Institution/App/Http/Controllers/{InstController.php => InstitutionController.php} (96%) rename Modules/Institution/App/Http/Controllers/{MaintController.php => MaintenanceController.php} (79%) rename Modules/Institution/App/Http/Middleware/{InstIsActive.php => IsActive.php} (95%) rename Modules/Institution/App/Http/Middleware/{InstIsAdmin.php => IsAdmin.php} (91%) diff --git a/Modules/Fed/App/Http/Controllers/FedController.php b/Modules/Fed/App/Http/Controllers/FedController.php index accc5dc8..46574e2c 100644 --- a/Modules/Fed/App/Http/Controllers/FedController.php +++ b/Modules/Fed/App/Http/Controllers/FedController.php @@ -1,6 +1,6 @@ namespace($this->moduleNamespace) ->group(module_path('Fed', '/routes/web.php')); } @@ -52,6 +53,7 @@ protected function mapApiRoutes(): void { Route::prefix('api') ->middleware('api') + ->namespace($this->moduleNamespace) ->group(module_path('Fed', '/routes/api.php')); } } diff --git a/Modules/Fed/composer.json b/Modules/Fed/composer.json index 704a5c51..abc244ba 100644 --- a/Modules/Fed/composer.json +++ b/Modules/Fed/composer.json @@ -17,9 +17,10 @@ }, "autoload": { "psr-4": { - "Modules\\Fed\\": "App/", - "Modules\\Fed\\Database\\Factories\\": "Database/factories/", - "Modules\\Fed\\Database\\Seeders\\": "Database/Seeders/" + "Modules\\Fed\\": "", + "Modules\\Fed\\App\\": "app/", + "Modules\\Fed\\Database\\Factories\\": "database/factories/", + "Modules\\Fed\\Database\\Seeders\\": "database/seeders/" } }, "autoload-dev": { diff --git a/Modules/Fed/module.json b/Modules/Fed/module.json index 5ecfca46..55407dc2 100644 --- a/Modules/Fed/module.json +++ b/Modules/Fed/module.json @@ -5,7 +5,7 @@ "keywords": [], "priority": 0, "providers": [ - "Modules\\Fed\\Providers\\FedServiceProvider" + "Modules\\Fed\\App\\Providers\\FedServiceProvider" ], "files": [] } diff --git a/Modules/Fed/routes/web.php b/Modules/Fed/routes/web.php index e6d0bf2b..481e0d2c 100644 --- a/Modules/Fed/routes/web.php +++ b/Modules/Fed/routes/web.php @@ -1,7 +1,7 @@ id); $institution = $user->institution; diff --git a/Modules/Institution/App/Http/Controllers/MaintController.php b/Modules/Institution/App/Http/Controllers/MaintenanceController.php similarity index 79% rename from Modules/Institution/App/Http/Controllers/MaintController.php rename to Modules/Institution/App/Http/Controllers/MaintenanceController.php index c1112e3d..28b3a15d 100644 --- a/Modules/Institution/App/Http/Controllers/MaintController.php +++ b/Modules/Institution/App/Http/Controllers/MaintenanceController.php @@ -1,13 +1,13 @@ route('login'); } diff --git a/Modules/Institution/App/Http/Middleware/InstIsAdmin.php b/Modules/Institution/App/Http/Middleware/IsAdmin.php similarity index 91% rename from Modules/Institution/App/Http/Middleware/InstIsAdmin.php rename to Modules/Institution/App/Http/Middleware/IsAdmin.php index 45ad554b..8c7cf66c 100644 --- a/Modules/Institution/App/Http/Middleware/InstIsAdmin.php +++ b/Modules/Institution/App/Http/Middleware/IsAdmin.php @@ -1,6 +1,6 @@ namespace($this->moduleNamespace) ->group(module_path('Institution', '/routes/web.php')); } @@ -52,6 +53,7 @@ protected function mapApiRoutes(): void { Route::prefix('api') ->middleware('api') + ->namespace($this->moduleNamespace) ->group(module_path('Institution', '/routes/api.php')); } } diff --git a/Modules/Institution/composer.json b/Modules/Institution/composer.json index e8c1cd87..60649905 100644 --- a/Modules/Institution/composer.json +++ b/Modules/Institution/composer.json @@ -17,10 +17,10 @@ }, "autoload": { "psr-4": { - "Modules\\Institution\\": "App/", + "Modules\\Institution\\": "", "Modules\\Institution\\App\\": "app/", - "Modules\\Institution\\Database\\Factories\\": "Database/Factories/", - "Modules\\Institution\\Database\\Seeders\\": "Database/Seeders/" + "Modules\\Institution\\Database\\Factories\\": "database/factories/", + "Modules\\Institution\\Database\\Seeders\\": "database/seeders/" } }, "autoload-dev": { diff --git a/Modules/Institution/module.json b/Modules/Institution/module.json index 1252f53c..256f402f 100644 --- a/Modules/Institution/module.json +++ b/Modules/Institution/module.json @@ -5,7 +5,7 @@ "keywords": [], "priority": 0, "providers": [ - "Modules\\Institution\\Providers\\InstitutionServiceProvider" + "Modules\\Institution\\App\\Providers\\InstitutionServiceProvider" ], "files": [] } diff --git a/Modules/Institution/routes/web.php b/Modules/Institution/routes/web.php index 7ee4f29c..85c38330 100644 --- a/Modules/Institution/routes/web.php +++ b/Modules/Institution/routes/web.php @@ -1,14 +1,11 @@ group(function () { Route::group( [ - 'middleware' => [Authenticate::class, InstIsActive::class], + 'middleware' => ['auth', 'institution_active'], 'as' => 'institution.', ], function () { - Route::get('/', [InstAtteController::class, 'index'])->name('home'); - Route::get('/attestations', [InstAtteController::class, 'index'])->name('attestations.index'); - Route::post('/attestations', [InstAtteController::class, 'store'])->name('attestations.store'); - Route::put('/attestations', [InstAtteController::class, 'update'])->name('attestations.update'); - Route::get('/attestations/download/{attestation}', [InstAtteController::class, 'download'])->name('attestations.download'); - Route::get('/attestations/export', [InstAtteController::class, 'exportCsv'])->name('attestations.export'); - Route::post('/duplicate_attestations', [InstAtteController::class, 'duplicate'])->name('attestations.duplicate'); + Route::get('/', [AttestationController::class, 'index'])->name('home'); + Route::get('/attestations', [AttestationController::class, 'index'])->name('attestations.index'); + Route::post('/attestations', [AttestationController::class, 'store'])->name('attestations.store'); + Route::put('/attestations', [AttestationController::class, 'update'])->name('attestations.update'); + Route::get('/attestations/download/{attestation}', [AttestationController::class, 'download'])->name('attestations.download'); + Route::get('/attestations/export', [AttestationController::class, 'exportCsv'])->name('attestations.export'); + Route::post('/duplicate_attestations', [AttestationController::class, 'duplicate'])->name('attestations.duplicate'); - Route::get('/dashboard', [InstController::class, 'index'])->name('dashboard'); - Route::get('/account', [InstController::class, 'show'])->name('show'); + Route::get('/dashboard', [InstitutionController::class, 'index'])->name('dashboard'); + Route::get('/account', [InstitutionController::class, 'show'])->name('show'); - Route::get('/caps', [InstController::class, 'caps'])->name('caps.index'); - Route::post('/api/fetch/capStats', [InstAtteController::class, 'capStat'])->name('caps.api.fetch.cap-stat'); - Route::post('/api/check/duplicate_student', [InstAtteController::class, 'duplicateStudent'])->name('caps.api.check.duplicate-student'); + Route::get('/caps', [InstitutionController::class, 'caps'])->name('caps.index'); + Route::post('/api/fetch/capStats', [AttestationController::class, 'capStat'])->name('caps.api.fetch.cap-stat'); + Route::post('/api/check/duplicate_student', [AttestationController::class, 'duplicateStudent'])->name('caps.api.check.duplicate-student'); - Route::get('/faqs', [MaintController::class, 'faqList'])->name('faqs.index'); + Route::get('/faqs', [MaintenanceController::class, 'faqList'])->name('faqs.index'); Route::post('/fed_caps/default', [FedCapController::class, 'setDefault'])->name('fed_caps.set-default'); }); Route::group([ - 'middleware' => [Authenticate::class, InstIsAdmin::class], + 'middleware' => ['institution_admin'], ], function () { - Route::get('/staff', [InstController::class, 'staffList'])->name('staff.list'); + Route::get('/staff', [InstitutionController::class, 'staffList'])->name('staff.list'); - Route::put('/staff', [InstController::class, 'staffUpdate'])->name('staff.staffUpdate'); - Route::put('/roles', [InstController::class, 'staffUpdateRole'])->name('roles.staffUpdateRole'); + Route::put('/staff', [InstitutionController::class, 'staffUpdate'])->name('staff.staffUpdate'); + Route::put('/roles', [InstitutionController::class, 'staffUpdateRole'])->name('roles.staffUpdateRole'); }); }); diff --git a/Modules/Ministry/App/Http/Controllers/AttestationController.php b/Modules/Ministry/App/Http/Controllers/AttestationController.php index 6c2fd3b0..c5f5d252 100644 --- a/Modules/Ministry/App/Http/Controllers/AttestationController.php +++ b/Modules/Ministry/App/Http/Controllers/AttestationController.php @@ -1,6 +1,6 @@ namespace($this->moduleNamespace) ->group(module_path('Ministry', '/routes/web.php')); } @@ -52,6 +53,7 @@ protected function mapApiRoutes(): void { Route::prefix('api') ->middleware('api') + ->namespace($this->moduleNamespace) ->group(module_path('Ministry', '/routes/api.php')); } } diff --git a/Modules/Ministry/composer.json b/Modules/Ministry/composer.json index 3d58c27d..ccb666f6 100644 --- a/Modules/Ministry/composer.json +++ b/Modules/Ministry/composer.json @@ -17,7 +17,7 @@ }, "autoload": { "psr-4": { - "Modules\\Ministry\\": "App/" + "Modules\\Ministry\\": "" } } } diff --git a/Modules/Ministry/module.json b/Modules/Ministry/module.json index 923b02e7..c82a9745 100644 --- a/Modules/Ministry/module.json +++ b/Modules/Ministry/module.json @@ -5,7 +5,7 @@ "keywords": [], "priority": 0, "providers": [ - "Modules\\Ministry\\Providers\\MinistryServiceProvider" + "Modules\\Ministry\\App\\Providers\\MinistryServiceProvider" ], "files": [] } diff --git a/Modules/Ministry/routes/web.php b/Modules/Ministry/routes/web.php index bf1a3420..465986bf 100644 --- a/Modules/Ministry/routes/web.php +++ b/Modules/Ministry/routes/web.php @@ -1,13 +1,13 @@ has('code')) { // If we don't have an authorization code then get one $authUrl = $provider->getAuthorizationUrl(); - $state = $provider->getState(); - setcookie('oauth2state', $state); -// Session::put('oauth2state', $state); - \Log::info('1 $authUrl: '.$authUrl); - \Log::info('2 $provider->getState(): '.$state); - // Store the state in a cookie with a short lifetime (e.g., 5 minutes) -// cookie()->queue(cookie('oauth2state', $state, 5)); // Store for 5 minutes + $request->session()->put('oauth2state', $provider->getState()); + \Log::info('$authUrl: '.$authUrl); + \Log::info('$provider->getState(): '.$provider->getState()); - return Redirect::to($authUrl.'&kc_idp_hint=usp'); + return Redirect::to($authUrl); // Check given state against previously stored one to mitigate CSRF attack -// } elseif ($request->has('state') && empty($request->session()->get('oauth2state'))) { -// Session::regenerate(false); -// -// \Log::info('Session ID: ' . Session::getId()); -// \Log::info('A: oauth2state:' . Session::get('oauth2state')); -// \Log::info('empty oauth2state '); -// \Log::info('state:' . $request->state); -// Session::put('oauth2state', $request->state); -// \Log::info('B2: oauth2state:' . Session::get('oauth2state')); -// -// \Log::info(' '); -// Session::save(); -// -// return redirect()->to('/bceid-login?state='.Session::get('oauth2state').'&session_state='.$request->session_state. -// '&code='.$request->code); - - // Check given state against previously stored one to mitigate CSRF attack - } elseif (! $request->has('state') || ($request->state !== $_COOKIE['oauth2state'])) { - \Log::info('messed up state '.$request->state.' !== '.Session::get('oauth2state')); - \Log::info('3 $provider->getState(): '.$_COOKIE['oauth2state']); - - //$request->session()->forget('oauth2state'); - // Clear the cookie - setcookie('oauth2state', '', -3600); + } elseif (! $request->has('state') || ($request->state !== $request->session()->get('oauth2state'))) { + $request->session()->forget('oauth2state'); + \Log::info('messed up state '.$request->state.' !== '.$request->session()->get('oauth2state')); //Invalid state, make sure HTTP sessions are enabled return Inertia::render('Auth/Login', [ @@ -104,17 +77,12 @@ private function loginUser(Request $request, $provider, $type): \Inertia\Respons 'status' => 'We could not log you in. Please contact RequestIT@gov.bc.ca', ]); } else { - \Log::info('We got State: '.$request->state . " and Code: " . $request->code); - \Log::info('Session state:' . $_COOKIE['oauth2state']); - // Try to get an access token (using the authorization coe grant) try { $token = $provider->getAccessToken('authorization_code', [ 'code' => $request->code, ]); - \Log::info('Token based on code:' . $token); } catch (\Exception $e) { - setcookie('oauth2state', '', -3600); return Inertia::render('Auth/Login', [ 'loginAttempt' => true, 'hasAccess' => false, @@ -130,7 +98,6 @@ private function loginUser(Request $request, $provider, $type): \Inertia\Respons \Log::info('We got a token: '.$token); \Log::info('$provider_user: '.json_encode($provider_user)); } catch (\Exception $e) { - setcookie('oauth2state', '', -3600); return Inertia::render('Auth/Login', [ 'loginAttempt' => true, 'hasAccess' => false, @@ -179,7 +146,6 @@ private function loginUser(Request $request, $provider, $type): \Inertia\Respons $user->name = $provider_user['name']; $user->save(); \Log::info('We got a name: '.$provider_user['name']); - setcookie('oauth2state', '', -3600); //else the user has access if ($type === Role::Ministry_GUEST) { @@ -194,7 +160,6 @@ private function loginUser(Request $request, $provider, $type): \Inertia\Respons } Auth::login($user); - \Log::info('User is ministry staff '); return Redirect::route('ministry.home'); } @@ -211,14 +176,10 @@ private function loginUser(Request $request, $provider, $type): \Inertia\Respons } Auth::login($user); - \Log::info('User is institution staff ' . Auth::check()); - \Log::info(Auth::check()); - \Log::info(Auth::user()->roles); return Redirect::route('institution.dashboard'); } - \Log::info('Redirect to Login '); return Redirect::route('login'); } } @@ -251,7 +212,6 @@ public function cancelledUsers(AjaxRequest $request) public function login(Request $request) { Cache::forget('global_fed_caps'); - setcookie('oauth2state', '', -3600); return Inertia::render('Auth/Login', [ 'loginAttempt' => false, 'hasAccess' => false, @@ -269,7 +229,6 @@ public function logout(Request $request) Auth::logout(); $request->session()->invalidate(); $request->session()->regenerateToken(); - setcookie('oauth2state', '', -3600); return redirect('/'); } diff --git a/app/Http/Kernel.php b/app/Http/Kernel.php index e8fb5bd6..8e058433 100644 --- a/app/Http/Kernel.php +++ b/app/Http/Kernel.php @@ -66,10 +66,10 @@ class Kernel extends HttpKernel 'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class, 'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class, - 'ministry_active' => \Modules\Ministry\Http\Middleware\IsActive::class, - 'ministry_admin' => \Modules\Ministry\Http\Middleware\IsAdmin::class, - 'institution_active' => \Modules\Institution\Http\Middleware\InstIsActive::class, - 'institution_admin' => \Modules\Institution\Http\Middleware\InstIsAdmin::class, + 'ministry_active' => \Modules\Ministry\App\Http\Middleware\IsActive::class, + 'ministry_admin' => \Modules\Ministry\App\Http\Middleware\IsAdmin::class, + 'institution_active' => \Modules\Institution\App\Http\Middleware\IsActive::class, + 'institution_admin' => \Modules\Institution\App\Http\Middleware\IsAdmin::class, 'super_admin' => \App\Http\Middleware\SuperAdmin::class, ]; diff --git a/app/Http/Middleware/Authenticate.php b/app/Http/Middleware/Authenticate.php index 0a114d98..d4ef6447 100644 --- a/app/Http/Middleware/Authenticate.php +++ b/app/Http/Middleware/Authenticate.php @@ -3,134 +3,15 @@ namespace App\Http\Middleware; use Illuminate\Auth\Middleware\Authenticate as Middleware; -use Closure; -use Illuminate\Auth\AuthenticationException; -use Illuminate\Contracts\Auth\Factory as Auth; -use Illuminate\Contracts\Auth\Middleware\AuthenticatesRequests; use Illuminate\Http\Request; -class Authenticate implements AuthenticatesRequests +class Authenticate extends Middleware { - /** - * The authentication factory instance. - * - * @var \Illuminate\Contracts\Auth\Factory - */ - protected $auth; - - /** - * The callback that should be used to generate the authentication redirect path. - * - * @var callable - */ - protected static $redirectToCallback; - - /** - * Create a new middleware instance. - * - * @param \Illuminate\Contracts\Auth\Factory $auth - * @return void - */ - public function __construct(Auth $auth) - { - $this->auth = $auth; - } - - /** - * Specify the guards for the middleware. - * - * @param string $guard - * @param string $others - * @return string - */ - public static function using($guard, ...$others) - { - return static::class.':'.implode(',', [$guard, ...$others]); - } - - /** - * Handle an incoming request. - * - * @param \Illuminate\Http\Request $request - * @param \Closure $next - * @param string[] ...$guards - * @return mixed - * - * @throws \Illuminate\Auth\AuthenticationException - */ - public function handle($request, Closure $next, ...$guards) - { - $this->authenticate($request, $guards); - - return $next($request); - } - - /** - * Determine if the user is logged in to any of the given guards. - * - * @param \Illuminate\Http\Request $request - * @param array $guards - * @return void - * - * @throws \Illuminate\Auth\AuthenticationException - */ - protected function authenticate($request, array $guards) - { - if (empty($guards)) { - $guards = [null]; - } - - foreach ($guards as $guard) { - if ($this->auth->guard($guard)->check()) { - return $this->auth->shouldUse($guard); - } - } - - $this->unauthenticated($request, $guards); - } - - /** - * Handle an unauthenticated user. - * - * @param \Illuminate\Http\Request $request - * @param array $guards - * @return void - * - * @throws \Illuminate\Auth\AuthenticationException - */ - protected function unauthenticated($request, array $guards) - { - \Log::info('unauth'); - \Log::info(\Illuminate\Support\Facades\Auth::check()); - \Log::info($guards); - throw new AuthenticationException( - 'Unauthenticated.', - $guards, - $request->expectsJson() ? null : $this->redirectTo($request), - ); - } - /** * Get the path the user should be redirected to when they are not authenticated. - * - * @param \Illuminate\Http\Request $request - * @return string|null - */ - protected function redirectTo(Request $request) - { - if (static::$redirectToCallback) { - return call_user_func(static::$redirectToCallback, $request); - } - } - - /** - * Specify the callback that should be used to generate the redirect path. - * - * @param callable $redirectToCallback - * @return void */ - public static function redirectUsing(callable $redirectToCallback) + protected function redirectTo(Request $request): ?string { - static::$redirectToCallback = $redirectToCallback; + return $request->expectsJson() ? null : route('login'); } } diff --git a/app/Http/Middleware/HandleInertiaRequests.php b/app/Http/Middleware/HandleInertiaRequests.php index 876a1047..00b04a7b 100644 --- a/app/Http/Middleware/HandleInertiaRequests.php +++ b/app/Http/Middleware/HandleInertiaRequests.php @@ -8,7 +8,7 @@ use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; use Inertia\Middleware; -use Tighten\Ziggy\Ziggy; +use Tightenco\Ziggy\Ziggy; use Illuminate\Support\Facades\Session; use Illuminate\Support\Facades\Cache; diff --git a/app/Policies/UserPolicy.php b/app/Policies/UserPolicy.php index 3e6e726a..5635260b 100644 --- a/app/Policies/UserPolicy.php +++ b/app/Policies/UserPolicy.php @@ -10,13 +10,13 @@ class UserPolicy { use HandlesAuthorization; -// -// public function before(User $user, $ability) -// { -// $rolesToCheck = [Role::Ministry_USER, Role::Ministry_ADMIN, Role::SUPER_ADMIN]; -// -// return $user->roles()->pluck('name')->intersect($rolesToCheck)->isNotEmpty() && $user->disabled === false; -// } + + public function before(User $user, $ability) + { + $rolesToCheck = [Role::Ministry_USER, Role::Ministry_ADMIN, Role::SUPER_ADMIN]; + + return $user->roles()->pluck('name')->intersect($rolesToCheck)->isNotEmpty() && $user->disabled === false; + } /** * Determine whether the user can view any models. diff --git a/composer.json b/composer.json index 73b4a450..e5b20ee6 100644 --- a/composer.json +++ b/composer.json @@ -5,30 +5,30 @@ "keywords": ["laravel", "framework"], "license": "MIT", "require": { - "php": "^8.2", + "php": "^8.1", "barryvdh/laravel-dompdf": "^2.1", "guzzlehttp/guzzle": "^7.2", - "inertiajs/inertia-laravel": "^1.0", - "laravel/framework": "^11.9", - "laravel/sanctum": "^4.0", - "laravel/tinker": "^2.9", - "nwidart/laravel-modules": "^11.0", - "stevenmaguire/oauth2-keycloak": "^5.1", - "tightenco/ziggy": "^2.2" + "inertiajs/inertia-laravel": "^0.6.8", + "laravel/framework": "^10.10", + "laravel/sanctum": "^3.3", + "laravel/tinker": "^2.8", + "nwidart/laravel-modules": "^10.0", + "stevenmaguire/oauth2-keycloak": "^5.0", + "tightenco/ziggy": "^1.0" }, "require-dev": { - "barryvdh/laravel-debugbar": "^3.13", "fakerphp/faker": "^1.9.1", - "laravel/pint": "^1.13", - "laravel/sail": "^1.26", - "mockery/mockery": "^1.6", - "nunomaduro/collision": "^8.0", - "phpunit/phpunit": "^11.0.1", + "laravel/pint": "^1.0", + "laravel/sail": "^1.18", + "mockery/mockery": "^1.4.4", + "nunomaduro/collision": "^7.0", + "phpunit/phpunit": "^10.1", "spatie/laravel-ignition": "^2.0" }, "autoload": { "psr-4": { "App\\": "app/", + "Modules\\": "Modules/", "Database\\Factories\\": "database/factories/", "Database\\Seeders\\": "database/seeders/" } @@ -56,11 +56,6 @@ "extra": { "laravel": { "dont-discover": [] - }, - "merge-plugin": { - "include": [ - "Modules/*/composer.json" - ] } }, "config": { diff --git a/config/app.php b/config/app.php index aa4105a4..f2685900 100644 --- a/config/app.php +++ b/config/app.php @@ -70,7 +70,7 @@ | */ - 'timezone' => env('APP_TIMEZONE', 'America/Vancouver'), + 'timezone' => 'America/Vancouver', /* |-------------------------------------------------------------------------- @@ -83,7 +83,7 @@ | */ - 'locale' => env('APP_LOCALE', 'en'), + 'locale' => 'en', /* |-------------------------------------------------------------------------- @@ -96,7 +96,7 @@ | */ - 'fallback_locale' => env('APP_FALLBACK_LOCALE', 'en'), + 'fallback_locale' => 'en', /* |-------------------------------------------------------------------------- @@ -109,7 +109,7 @@ | */ - 'faker_locale' => env('APP_FAKER_LOCALE', 'en_US'), + 'faker_locale' => 'en_US', /* |-------------------------------------------------------------------------- @@ -126,12 +126,6 @@ 'cipher' => 'AES-256-CBC', - 'previous_keys' => [ - ...array_filter( - explode(',', env('APP_PREVIOUS_KEYS', '')) - ), - ], - /* |-------------------------------------------------------------------------- | Maintenance Mode Driver @@ -146,8 +140,8 @@ */ 'maintenance' => [ - 'driver' => env('APP_MAINTENANCE_DRIVER', 'file'), - 'store' => env('APP_MAINTENANCE_STORE', 'database'), + 'driver' => 'file', + // 'store' => 'redis', ], /* diff --git a/config/auth.php b/config/auth.php index e9741121..9548c15d 100644 --- a/config/auth.php +++ b/config/auth.php @@ -14,8 +14,8 @@ */ 'defaults' => [ - 'guard' => env('AUTH_GUARD', 'web'), - 'passwords' => env('AUTH_PASSWORD_BROKER', 'users'), + 'guard' => 'web', + 'passwords' => 'users', ], /* @@ -62,7 +62,7 @@ 'providers' => [ 'users' => [ 'driver' => 'eloquent', - 'model' => env('AUTH_MODEL', App\Models\User::class), + 'model' => App\Models\User::class, ], // 'users' => [ @@ -93,7 +93,7 @@ 'passwords' => [ 'users' => [ 'provider' => 'users', - 'table' => env('AUTH_PASSWORD_RESET_TOKEN_TABLE', 'password_reset_tokens'), + 'table' => 'password_reset_tokens', 'expire' => 60, 'throttle' => 60, ], @@ -110,6 +110,6 @@ | */ - 'password_timeout' => env('AUTH_PASSWORD_TIMEOUT', 10800), + 'password_timeout' => 10800, ]; diff --git a/config/modules.php b/config/modules.php index c5c45590..32e9db76 100644 --- a/config/modules.php +++ b/config/modules.php @@ -1,7 +1,7 @@ ConsoleServiceProvider::defaultCommands() - ->merge([ - // New commands go here - ])->toArray(), - + 'commands' => [ + Commands\CommandMakeCommand::class, + Commands\ComponentClassMakeCommand::class, + Commands\ComponentViewMakeCommand::class, + Commands\ControllerMakeCommand::class, + Commands\ChannelMakeCommand::class, + Commands\DisableCommand::class, + Commands\DumpCommand::class, + Commands\EnableCommand::class, + Commands\EventMakeCommand::class, + Commands\FactoryMakeCommand::class, + Commands\JobMakeCommand::class, + Commands\ListenerMakeCommand::class, + Commands\MailMakeCommand::class, + Commands\MiddlewareMakeCommand::class, + Commands\NotificationMakeCommand::class, + Commands\ObserverMakeCommand::class, + Commands\PolicyMakeCommand::class, + Commands\ProviderMakeCommand::class, + Commands\InstallCommand::class, + Commands\LaravelModulesV6Migrator::class, + Commands\ListCommand::class, + Commands\ModuleDeleteCommand::class, + Commands\ModuleMakeCommand::class, + Commands\MigrateCommand::class, + Commands\MigrateFreshCommand::class, + Commands\MigrateRefreshCommand::class, + Commands\MigrateResetCommand::class, + Commands\MigrateRollbackCommand::class, + Commands\MigrateStatusCommand::class, + Commands\MigrationMakeCommand::class, + Commands\ModelMakeCommand::class, + Commands\ResourceMakeCommand::class, + Commands\RequestMakeCommand::class, + Commands\RuleMakeCommand::class, + Commands\RouteProviderMakeCommand::class, + Commands\PublishCommand::class, + Commands\PublishConfigurationCommand::class, + Commands\PublishMigrationCommand::class, + Commands\PublishTranslationCommand::class, + Commands\SeedCommand::class, + Commands\SeedMakeCommand::class, + Commands\SetupCommand::class, + Commands\TestMakeCommand::class, + Commands\UnUseCommand::class, + Commands\UpdateCommand::class, + Commands\UseCommand::class, + ], /* |-------------------------------------------------------------------------- diff --git a/config/session.php b/config/session.php index 9c5b3fb8..561d9085 100644 --- a/config/session.php +++ b/config/session.php @@ -18,7 +18,7 @@ | */ - 'driver' => env('SESSION_DRIVER', 'database'), + 'driver' => env('SESSION_DRIVER', 'file'), /* |-------------------------------------------------------------------------- @@ -33,7 +33,7 @@ 'lifetime' => env('SESSION_LIFETIME', 120), - 'expire_on_close' => env('SESSION_EXPIRE_ON_CLOSE', false), + 'expire_on_close' => false, /* |-------------------------------------------------------------------------- @@ -85,7 +85,7 @@ | */ - 'table' => env('SESSION_TABLE', 'sessions'), + 'table' => 'sessions', /* |-------------------------------------------------------------------------- @@ -142,7 +142,7 @@ | */ - 'path' => env('SESSION_PATH', '/'), + 'path' => '/', /* |-------------------------------------------------------------------------- @@ -181,7 +181,7 @@ | */ - 'http_only' => env('SESSION_HTTP_ONLY', true), + 'http_only' => true, /* |-------------------------------------------------------------------------- @@ -196,7 +196,7 @@ | */ - 'same_site' => env('SESSION_SAME_SITE', 'strict'), + 'same_site' => env('SESSION_SAME_SITE', 'lax'), /* |-------------------------------------------------------------------------- @@ -209,6 +209,6 @@ | */ - 'partitioned' => env('SESSION_PARTITIONED_COOKIE', false), + 'partitioned' => false, ]; diff --git a/public/mix-manifest.json b/public/mix-manifest.json index f02f8112..2ce13dce 100644 --- a/public/mix-manifest.json +++ b/public/mix-manifest.json @@ -8,7 +8,6 @@ "/images/2022/BC_PSEFS_H_RGB_rev.png": "/images/2022/BC_PSEFS_H_RGB_rev.png", "/images/2022/BC_PSEFS_H_Solid_pos.png": "/images/2022/BC_PSEFS_H_Solid_pos.png", "/images/2022/BC_PSEFS_H_Solid_rev.png": "/images/2022/BC_PSEFS_H_Solid_rev.png", - "/images/attestation_sign.png": "/images/attestation_sign.png", "/images/bc-logo-grey.gif": "/images/bc-logo-grey.gif", "/images/bc_lg_logo.png": "/images/bc_lg_logo.png", "/images/bc_no_bg.png": "/images/bc_no_bg.png",