From 73ae27039cbbecd1cecc2c0c9661334dd5441aad Mon Sep 17 00:00:00 2001 From: Habu Date: Wed, 6 Nov 2024 19:53:32 +0100 Subject: [PATCH 1/3] Added pint job in Laravel github actions workflow --- .github/workflows/bump.yml | 3 --- .github/workflows/laravel.yml | 12 ++++++++++-- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/.github/workflows/bump.yml b/.github/workflows/bump.yml index 3e058cf..e2674ba 100644 --- a/.github/workflows/bump.yml +++ b/.github/workflows/bump.yml @@ -41,6 +41,3 @@ jobs: command: diff env: GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} - - - diff --git a/.github/workflows/laravel.yml b/.github/workflows/laravel.yml index 6027678..11f9c0d 100644 --- a/.github/workflows/laravel.yml +++ b/.github/workflows/laravel.yml @@ -8,9 +8,7 @@ on: jobs: laravel-tests: - runs-on: ubuntu-latest - steps: - uses: shivammathur/setup-php@15c43e89cdef867065b0213be354c2841860869e with: @@ -44,3 +42,13 @@ jobs: DB_USERNAME: root DB_PASSWORD: "" run: vendor/bin/pest + + laravel-pint: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: "laravel-pint" + uses: aglipanci/laravel-pint-action@latest + with: + testMode: true + pintVersion: 1.18.1 From 06bb291d6de8088f8f3f1873a9e89196d9090ff0 Mon Sep 17 00:00:00 2001 From: Habu Date: Wed, 6 Nov 2024 20:03:57 +0100 Subject: [PATCH 2/3] Added pint config --- composer.json | 2 +- composer.lock | 24 ++++++++++++------------ pint.json | 13 +++++++++++++ 3 files changed, 26 insertions(+), 13 deletions(-) create mode 100644 pint.json diff --git a/composer.json b/composer.json index 7918851..816f361 100644 --- a/composer.json +++ b/composer.json @@ -45,7 +45,7 @@ "require-dev": { "fakerphp/faker": "^1.9.1", "itsgoingd/clockwork": "^5.1", - "laravel/pint": "^1.0", + "laravel/pint": "^1.18", "laravel/sail": "^1.26", "mockery/mockery": "^1.4.4", "nunomaduro/collision": "^8.1", diff --git a/composer.lock b/composer.lock index ba9f4d1..58afbbc 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "b3022e257da6a4c45b71440a037be096", + "content-hash": "e24b7d12aa30f1bd6a16f694984eb912", "packages": [ { "name": "anourvalar/eloquent-serialize", @@ -10953,16 +10953,16 @@ }, { "name": "laravel/pint", - "version": "v1.16.2", + "version": "v1.18.1", "source": { "type": "git", "url": "https://github.com/laravel/pint.git", - "reference": "51f1ba679a6afe0315621ad143d788bd7ded0eca" + "reference": "35c00c05ec43e6b46d295efc0f4386ceb30d50d9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/pint/zipball/51f1ba679a6afe0315621ad143d788bd7ded0eca", - "reference": "51f1ba679a6afe0315621ad143d788bd7ded0eca", + "url": "https://api.github.com/repos/laravel/pint/zipball/35c00c05ec43e6b46d295efc0f4386ceb30d50d9", + "reference": "35c00c05ec43e6b46d295efc0f4386ceb30d50d9", "shasum": "" }, "require": { @@ -10973,13 +10973,13 @@ "php": "^8.1.0" }, "require-dev": { - "friendsofphp/php-cs-fixer": "^3.59.3", - "illuminate/view": "^10.48.12", - "larastan/larastan": "^2.9.7", + "friendsofphp/php-cs-fixer": "^3.64.0", + "illuminate/view": "^10.48.20", + "larastan/larastan": "^2.9.8", "laravel-zero/framework": "^10.4.0", "mockery/mockery": "^1.6.12", "nunomaduro/termwind": "^1.15.1", - "pestphp/pest": "^2.34.8" + "pestphp/pest": "^2.35.1" }, "bin": [ "builds/pint" @@ -11015,7 +11015,7 @@ "issues": "https://github.com/laravel/pint/issues", "source": "https://github.com/laravel/pint" }, - "time": "2024-07-09T15:58:08+00:00" + "time": "2024-09-24T17:22:50+00:00" }, { "name": "laravel/sail", @@ -13884,7 +13884,7 @@ ], "aliases": [], "minimum-stability": "stable", - "stability-flags": [], + "stability-flags": {}, "prefer-stable": true, "prefer-lowest": false, "platform": { @@ -13893,6 +13893,6 @@ "ext-json": "*", "ext-simplexml": "*" }, - "platform-dev": [], + "platform-dev": {}, "plugin-api-version": "2.6.0" } diff --git a/pint.json b/pint.json new file mode 100644 index 0000000..73df0a4 --- /dev/null +++ b/pint.json @@ -0,0 +1,13 @@ +{ + "preset": "laravel", + "rules": { + "concat_space": { + "spacing": "one" + }, + "new_with_parentheses": { + "named_class": true, + "anonymous_class": true + }, + "no_superfluous_phpdoc_tags": false + } +} From b36979e47ce3c22f77071ae828fccab4f63c976a Mon Sep 17 00:00:00 2001 From: Habu Date: Wed, 6 Nov 2024 20:04:18 +0100 Subject: [PATCH 3/3] Fixed pint errors --- .../User/UserChangePasswordCommand.php | 3 +- app/Console/Kernel.php | 3 +- app/Events/AppLoginEvent.php | 5 +- app/Events/NewProfilePhotoEvent.php | 1 + app/Exceptions/Handler.php | 3 +- app/Filament/Resources/ActivityResource.php | 11 +- app/Filament/Resources/AppResource.php | 54 +- .../GroupsRelationManager.php | 2 +- app/Filament/Resources/GroupResource.php | 27 +- .../GroupResource/Pages/CreateGroup.php | 2 - .../GroupResource/Pages/EditGroup.php | 2 - .../RelationManagers/UsersRelationManager.php | 4 +- app/Filament/Resources/UserResource.php | 7 +- .../Resources/UserResource/Pages/EditUser.php | 6 +- .../ActionsRelationManager.php | 12 +- .../GroupsRelationManager.php | 30 +- .../TokensRelationManager.php | 8 +- .../Auth/FrontChannelLogoutController.php | 3 +- .../Controllers/Api/v1/GroupController.php | 18 +- .../Api/v1/GroupUserController.php | 5 +- .../Api/v1/IntrospectionController.php | 3 +- app/Http/Controllers/AppsController.php | 28 +- .../Controllers/Auth/ConsentController.php | 8 +- .../Auth/ForgotPasswordController.php | 2 +- .../Auth/FrontChannelLogoutController.php | 1 + app/Http/Controllers/Auth/LoginController.php | 10 +- .../Controllers/Auth/LogoutController.php | 9 +- .../Auth/PasswordResetController.php | 2 +- .../Controllers/Auth/RegisterController.php | 7 +- .../Auth/VerifyEmailController.php | 9 +- app/Http/Controllers/AuthController.php | 13 +- .../TwoFactor/TotpSetupController.php | 18 +- .../TwoFactor/TwoFactorController.php | 4 +- .../TwoFactor/YubikeySetupController.php | 9 +- .../Settings/UpdatePasswordController.php | 3 +- .../Profile/StoreAvatarController.php | 5 +- .../Profile/UpdateProfileController.php | 7 +- .../Profile/UserinfoController.php | 2 +- .../Staff/GroupMemberController.php | 57 +- .../Controllers/Staff/GroupTeamController.php | 8 +- .../Controllers/Staff/GroupsController.php | 17 +- app/Http/Controllers/TwoFactorController.php | 11 +- .../Controllers/UpdateEmailController.php | 9 +- .../AccessTokenValidationMiddleware.php | 4 +- app/Http/Middleware/Authenticate.php | 6 +- app/Http/Middleware/CheckIfAdmin.php | 4 +- app/Http/Middleware/GroupMember.php | 1 + app/Http/Middleware/GuardSwitcher.php | 5 +- app/Http/Middleware/HandleInertiaRequests.php | 22 +- .../TokenIntrospectionCheckMiddleware.php | 4 +- app/Http/Requests/Auth/GroupRequest.php | 3 +- app/Http/Requests/Auth/LoginRequest.php | 2 +- app/Http/Requests/Auth/RegisterRequest.php | 21 +- app/Http/Requests/Auth/UserRequest.php | 1 + .../Requests/EmailVerificationRequest.php | 3 +- app/Http/Requests/ForgotPasswordRequest.php | 2 +- app/Http/Requests/GroupStoreRequest.php | 8 +- app/Http/Requests/GroupUpdateRequest.php | 6 +- app/Http/Requests/GroupUserStoreRequest.php | 10 +- .../Requests/Groups/GroupUpdateRequest.php | 4 +- app/Http/Requests/IntrospectionRequest.php | 12 +- app/Http/Requests/PasswordResetRequest.php | 2 +- .../Requests/Profile/UpdateProfileRequest.php | 20 +- app/Http/Requests/UpdatePasswordRequest.php | 12 +- app/Http/Requests/UserinfoRequest.php | 4 +- app/Http/Resources/V1/GroupCollection.php | 2 +- app/Http/Resources/V1/GroupResource.php | 2 +- app/Http/Resources/V1/GroupUserCollection.php | 2 +- app/Http/Resources/V1/LoginResource.php | 2 +- app/Http/Resources/V1/TokenResource.php | 2 +- app/Http/Resources/V1/UserinfoResource.php | 2 +- app/Jobs/CheckStaffGroupMembershipJob.php | 4 +- app/Listeners/LogFailedLoginListener.php | 4 +- app/Listeners/LogUserAppLoginListener.php | 4 +- app/Listeners/LogUserLockoutListener.php | 4 +- app/Listeners/LogUserLoginListener.php | 4 +- app/Listeners/LogUserLogoutListener.php | 4 +- .../LogUserPasswordResetListener.php | 4 +- app/Listeners/LogUserRegisteredListener.php | 4 +- app/Listeners/LogUserVerifiedListener.php | 4 +- app/Models/App.php | 5 +- app/Models/Group.php | 17 +- app/Models/GroupUser.php | 10 +- app/Models/Permission.php | 4 +- app/Models/Role.php | 4 +- app/Models/User.php | 19 +- .../PasswordResetQueuedNotification.php | 1 - app/Notifications/UpdateEmailNotification.php | 5 +- .../VerifyEmailQueuedNotification.php | 1 - app/Observers/AppObserver.php | 2 +- app/Observers/GroupObserver.php | 17 +- app/Observers/GroupUserObserver.php | 6 +- app/Policies/GroupPolicy.php | 23 +- app/Policies/GroupUserPolicy.php | 4 +- app/Providers/AppServiceProvider.php | 8 +- app/Providers/AuthServiceProvider.php | 3 +- app/Providers/RouteServiceProvider.php | 2 +- .../Socialite/SocialiteIdentityProvider.php | 33 +- app/Services/Auth/AdminAuth.php | 15 +- app/Services/Auth/ApiGuard.php | 27 +- app/Services/Hydra/Admin.php | 5 +- app/Services/Hydra/Client.php | 37 +- app/Services/Hydra/Models/App.php | 275 ++++--- app/Services/NextcloudService.php | 32 +- app/Services/OpenIDService.php | 3 +- app/Services/YubicoService.php | 25 +- app/helpers.php | 4 +- config/cache.php | 2 +- config/clockwork.php | 768 +++++++++--------- config/database.php | 2 +- config/filament.php | 2 +- config/filesystems.php | 2 +- config/groups.php | 2 +- config/horizon.php | 2 +- config/image.php | 2 +- config/mail.php | 1 - config/sentry.php | 2 +- config/services.php | 6 +- config/session.php | 2 +- config/translatable.php | 2 +- database/factories/UserFactory.php | 6 +- ..._add_two_factor_columns_to_users_table.php | 8 +- ...01_create_personal_access_tokens_table.php | 2 +- .../2022_11_04_215854_create_apps_table.php | 3 +- ...3225_update_group_and_group_user_table.php | 9 +- ...34133_make_slug_unique_on_groups_table.php | 3 +- ..._02_12_114846_add_fields_to_apps_table.php | 25 +- ...60150_add_title_field_group_user_table.php | 3 +- ...02_20_160405_add_types_to_groups_table.php | 5 +- ..._03_13_001722_add_secret_to_apps_table.php | 3 +- ...d_description_in_groups_table_not_json.php | 3 +- ...40_remove_two_factor_secret_from_users.php | 3 +- ..._01_21_235202_create_two_factors_table.php | 3 +- ...6_142612_add_system_name_to_apps_table.php | 3 +- ...212812_add_system_name_to_groups_table.php | 3 +- ..._01_28_224525_add_unique_to_group_user.php | 3 +- ..._nextcloud_folder_name_to_groups_table.php | 3 +- ...dd_nextcloud_folder_id_to_groups_table.php | 3 +- ...614_update_description_in_groups_table.php | 3 +- ...4_000454_add_parent_id_to_groups_table.php | 3 +- database/seeders/AppSeeder.php | 24 +- database/seeders/UserSeeder.php | 12 +- public/index.php | 8 +- resources/lang/en/activity.php | 19 +- routes/api.php | 6 +- routes/apps/portal.php | 1 - routes/apps/staff.php | 8 +- server.php | 6 +- tests/Browser/ExampleTest.php | 3 +- tests/Browser/LoginTest.php | 3 +- tests/CreatesApplication.php | 2 +- tests/DuskTestCase.php | 4 +- tests/Feature/Api/v1/GroupsTest.php | 174 ++-- tests/Feature/Api/v1/UserinfoTest.php | 16 +- tests/Feature/Auth/CreateNewAccountTest.php | 11 +- tests/Feature/Auth/LoginTest.php | 52 +- tests/Feature/ErrorUserDeletedTest.php | 33 +- tests/Feature/Profile/UpdateEmailTest.php | 14 +- tests/Feature/Staff/GroupMemberTest.php | 7 +- tests/TestCase.php | 1 + tests/Unit/HydraAppTest.php | 336 ++++---- 161 files changed, 1479 insertions(+), 1392 deletions(-) diff --git a/app/Console/Commands/User/UserChangePasswordCommand.php b/app/Console/Commands/User/UserChangePasswordCommand.php index 3b0dc4c..45506a9 100644 --- a/app/Console/Commands/User/UserChangePasswordCommand.php +++ b/app/Console/Commands/User/UserChangePasswordCommand.php @@ -16,8 +16,9 @@ public function handle(): void { $email = $this->argument('email'); $user = User::where('email', $email)->first(); - if (!$user) { + if (! $user) { $this->error('User not found'); + return; } $password = $this->secret('New Password'); diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php index e3624a5..bd49205 100644 --- a/app/Console/Kernel.php +++ b/app/Console/Kernel.php @@ -4,7 +4,6 @@ use App\Console\Commands\appsSyncCommand; use App\Console\Commands\ClearUnverifiedCommand; -use App\Console\Commands\GenerateRulesCommand; use App\Console\Commands\User\UserChangePasswordCommand; use Illuminate\Console\Scheduling\Schedule; use Illuminate\Foundation\Console\Kernel as ConsoleKernel; @@ -42,7 +41,7 @@ protected function schedule(Schedule $schedule) */ protected function commands() { - $this->load(__DIR__.'/Commands'); + $this->load(__DIR__ . '/Commands'); require base_path('routes/console.php'); } diff --git a/app/Events/AppLoginEvent.php b/app/Events/AppLoginEvent.php index f5f48ce..68c6314 100644 --- a/app/Events/AppLoginEvent.php +++ b/app/Events/AppLoginEvent.php @@ -8,8 +8,5 @@ class AppLoginEvent { use Dispatchable; - public function __construct(readonly public string $clientId, readonly public string $userId) - { - - } + public function __construct(readonly public string $clientId, readonly public string $userId) {} } diff --git a/app/Events/NewProfilePhotoEvent.php b/app/Events/NewProfilePhotoEvent.php index 91223d0..ce8f720 100644 --- a/app/Events/NewProfilePhotoEvent.php +++ b/app/Events/NewProfilePhotoEvent.php @@ -10,6 +10,7 @@ class NewProfilePhotoEvent use Dispatchable; public User $user; + public string $path; public function __construct(User $user, string $path) diff --git a/app/Exceptions/Handler.php b/app/Exceptions/Handler.php index 2b74f5b..adf07ae 100644 --- a/app/Exceptions/Handler.php +++ b/app/Exceptions/Handler.php @@ -66,8 +66,7 @@ public function render( return $response; } - - if (!in_array($status, [401, 402, 403, 404, 405, 500, 503])) { + if (! in_array($status, [401, 402, 403, 404, 405, 500, 503])) { return $response; } diff --git a/app/Filament/Resources/ActivityResource.php b/app/Filament/Resources/ActivityResource.php index f4310d9..2dd2da3 100644 --- a/app/Filament/Resources/ActivityResource.php +++ b/app/Filament/Resources/ActivityResource.php @@ -4,9 +4,9 @@ use App\Filament\Resources\ActivityResource\Pages; use Filament\Resources\Resource; -use Filament\Tables\Table; use Filament\Tables\Columns\Column; use Filament\Tables\Columns\TextColumn; +use Filament\Tables\Table; use Illuminate\Database\Eloquent\Model; use Spatie\Activitylog\Models\Activity; @@ -24,15 +24,16 @@ public static function table(Table $table): Table { return $table ->columns([ - TextColumn::make('description')->formatStateUsing(fn(string $state) => __("activity." . $state)), - TextColumn::make('causer.name')->description(fn(Activity $record): string => ($record->causer_type ?? "")), + TextColumn::make('description')->formatStateUsing(fn (string $state) => __('activity.' . $state)), + TextColumn::make('causer.name')->description(fn (Activity $record): string => ($record->causer_type ?? '')), TextColumn::make('subject.name') ->formatStateUsing(static function (Column $column, $state): ?string { $record = $column->getRecord(); $record->load('subject', 'causer'); - return $record->subject->name ?? $record->subject->data['client_name'] ?? $record->subject->id ?? ""; + + return $record->subject->name ?? $record->subject->data['client_name'] ?? $record->subject->id ?? ''; }) - ->description(fn(Activity $record): string => ($record->subject_type ?? "")), + ->description(fn (Activity $record): string => ($record->subject_type ?? '')), // TextColumn::make('changes'), TextColumn::make('created_at')->label('Date')->dateTime()->description(function (Activity $record) { diff --git a/app/Filament/Resources/AppResource.php b/app/Filament/Resources/AppResource.php index ae1e009..779f786 100644 --- a/app/Filament/Resources/AppResource.php +++ b/app/Filament/Resources/AppResource.php @@ -60,37 +60,37 @@ public static function form(Form $form): Form Tabs\Tab::make('Login')->icon('heroicon-o-arrow-left-on-rectangle')->schema([ TagsInput::make('data.redirect_uris')->columnSpan(2), Select::make('data.subject_type')->options([ - "public" => "public", - "pairwise" => "pairwise", + 'public' => 'public', + 'pairwise' => 'pairwise', ])->columnSpan(2), Select::make('data.grant_types')->multiple()->options([ - "authorization_code" => "authorization_code", - "refresh_token" => "refresh_token", - "implicit" => "implicit", - "client_credentials" => "client_credentials", + 'authorization_code' => 'authorization_code', + 'refresh_token' => 'refresh_token', + 'implicit' => 'implicit', + 'client_credentials' => 'client_credentials', ])->columnSpan(2), Select::make('data.response_types')->multiple()->options([ - "code" => "code", - "id_token" => "id_token", - "token" => "token", + 'code' => 'code', + 'id_token' => 'id_token', + 'token' => 'token', ])->columnSpan(2), ]), Tabs\Tab::make('Token')->icon('heroicon-o-lock-closed')->schema([ Select::make('data.token_endpoint_auth_method')->options([ - "client_secret_post" => "client_secret_post", - "client_secret_basic" => "client_secret_basic", - "private_key_jwt" => "private_key_jwt", - "none" => "none", + 'client_secret_post' => 'client_secret_post', + 'client_secret_basic' => 'client_secret_basic', + 'private_key_jwt' => 'private_key_jwt', + 'none' => 'none', ]), TextInput::make('data.jwks_uri') ->helperText('When authenticating with a signed jwks key against the token endpoint, you may enter a path to a keys.json containing the public keys of your app here.') ->url(), CheckboxList::make('data.scope')->options(static function () { - return collect((new Client())->getScopes())->mapWithKeys(fn($v) => [$v => $v]); + return collect((new Client())->getScopes())->mapWithKeys(fn ($v) => [$v => $v]); })->afterStateHydrated(function (CheckboxList $component, $state) { - if (!is_array($state)) { - $state = explode(" ", $state); + if (! is_array($state)) { + $state = explode(' ', $state); } $component->state($state); }), @@ -122,9 +122,9 @@ public static function form(Form $form): Form Tabs\Tab::make('Request')->icon('heroicon-o-signal')->schema([ TagsInput::make('data.request_uris')->columnSpan(2), Select::make('data.request_object_signing_alg')->options([ - "none" => "none", - "RS256" => "RS256", - "ES256" => "ES256", + 'none' => 'none', + 'RS256' => 'RS256', + 'ES256' => 'ES256', ])->columnSpan(2), ]), @@ -160,22 +160,22 @@ public static function form(Form $form): Form TextInput::make('description')->required(), Select::make('icon')->options(function () { return collect(scandir(resource_path('js/Components/Icons'))) - ->filter(fn($icon) => !in_array($icon, ['.', '..'])) - ->map(fn($icon) => str_replace('.vue', '', $icon)) + ->filter(fn ($icon) => ! in_array($icon, ['.', '..'])) + ->map(fn ($icon) => str_replace('.vue', '', $icon)) ->values() - ->keyBy(fn($icon) => $icon) + ->keyBy(fn ($icon) => $icon) ->toArray(); })->hint('Request new Icons @ Thiritin')->required(), TextInput::make('url')->url(), ]), Card::make()->schema([ Placeholder::make('created_at') - ->label("Created At") - ->content(fn(?App $record): string => $record?->created_at?->diffForHumans() ?? '-'), + ->label('Created At') + ->content(fn (?App $record): string => $record?->created_at?->diffForHumans() ?? '-'), Placeholder::make('updated_at') - ->label("Updated At") - ->content(fn(?App $record): string => $record?->updated_at?->diffForHumans() ?? '-'), + ->label('Updated At') + ->content(fn (?App $record): string => $record?->updated_at?->diffForHumans() ?? '-'), ]), ]), @@ -211,7 +211,7 @@ public static function getRelations(): array public static function getGloballySearchableAttributes(): array { return [ - "name", + 'name', ]; } } diff --git a/app/Filament/Resources/AppResource/RelationManagers/GroupsRelationManager.php b/app/Filament/Resources/AppResource/RelationManagers/GroupsRelationManager.php index 000e3ce..3ec4b68 100644 --- a/app/Filament/Resources/AppResource/RelationManagers/GroupsRelationManager.php +++ b/app/Filament/Resources/AppResource/RelationManagers/GroupsRelationManager.php @@ -5,8 +5,8 @@ use Filament\Forms; use Filament\Forms\Form; use Filament\Resources\RelationManagers\RelationManager; -use Filament\Tables\Table; use Filament\Tables; +use Filament\Tables\Table; class GroupsRelationManager extends RelationManager { diff --git a/app/Filament/Resources/GroupResource.php b/app/Filament/Resources/GroupResource.php index 9b9d354..fa3bcc9 100644 --- a/app/Filament/Resources/GroupResource.php +++ b/app/Filament/Resources/GroupResource.php @@ -13,7 +13,6 @@ use Filament\Forms\Components\Textarea; use Filament\Forms\Components\TextInput; use Filament\Forms\Form; -use Filament\Resources\Concerns\Translatable; use Filament\Resources\Resource; use Filament\Tables\Actions\EditAction; use Filament\Tables\Columns\TextColumn; @@ -21,13 +20,13 @@ class GroupResource extends Resource { - protected static ?string $model = Group::class; protected static ?string $slug = 'groups'; + protected static ?string $recordTitleAttribute = 'name'; - protected static ?string $navigationIcon = "heroicon-o-users"; + protected static ?string $navigationIcon = 'heroicon-o-users'; public static function form(Form $form): Form { @@ -38,23 +37,23 @@ public static function form(Form $form): Form FilamentGroup::make()->columns()->schema([ Placeholder::make('id') ->label('Internal ID') - ->content(fn(?Group $record): string => $record?->id ?? '-'), + ->content(fn (?Group $record): string => $record?->id ?? '-'), Placeholder::make('hashid') ->label('Public ID') - ->content(fn(?Group $record): string => $record?->hashid() ?? '-'), + ->content(fn (?Group $record): string => $record?->hashid() ?? '-'), ]), TextInput::make('system_name') ->label('System Name') ->hint('Unique system name, should be left empty in most cases.') ->unique('groups', 'system_name', ignoreRecord: true) - ->disabled(fn(?Group $record) => $record?->exists), + ->disabled(fn (?Group $record) => $record?->exists), TextInput::make('name') ->required(), TextInput::make('nextcloud_folder_name') ->label('Nextcloud Folder Name') ->hiddenOn('create') - ->required(fn(Group|null $record - ) => $record !== null && !empty($record->nextcloud_folder_id)) + ->required(fn (?Group $record + ) => $record !== null && ! empty($record->nextcloud_folder_id)) ->hint('Leave empty if the group should not be allowed to access Nextcloud.') ->unique('groups', 'nextcloud_folder_name', ignoreRecord: true), Textarea::make('description')->rows(5), @@ -65,19 +64,19 @@ public static function form(Form $form): Form Section::make()->schema([ Select::make('type')->options([ - GroupTypeEnum::Default->value => "Default", - GroupTypeEnum::Automated->value => "Automated", - GroupTypeEnum::Department->value => "Department", + GroupTypeEnum::Default->value => 'Default', + GroupTypeEnum::Automated->value => 'Automated', + GroupTypeEnum::Department->value => 'Department', ])->required(), ]), Placeholder::make('created_at') ->label('Created Date') - ->content(fn(?Group $record): string => $record?->created_at?->diffForHumans() ?? '-'), + ->content(fn (?Group $record): string => $record?->created_at?->diffForHumans() ?? '-'), Placeholder::make('updated_at') ->label('Last Modified Date') - ->content(fn(?Group $record): string => $record?->updated_at?->diffForHumans() ?? '-'), + ->content(fn (?Group $record): string => $record?->updated_at?->diffForHumans() ?? '-'), ]), ])->columns(3); } @@ -91,7 +90,7 @@ public static function table(Table $table): Table ->sortable(), TextColumn::make('type') ->sortable() - ->formatStateUsing(fn($state) => ucfirst($state->value)), + ->formatStateUsing(fn ($state) => ucfirst($state->value)), ]) ->actions([ EditAction::make(), diff --git a/app/Filament/Resources/GroupResource/Pages/CreateGroup.php b/app/Filament/Resources/GroupResource/Pages/CreateGroup.php index b6c0ab0..0de1e59 100644 --- a/app/Filament/Resources/GroupResource/Pages/CreateGroup.php +++ b/app/Filament/Resources/GroupResource/Pages/CreateGroup.php @@ -3,9 +3,7 @@ namespace App\Filament\Resources\GroupResource\Pages; use App\Filament\Resources\GroupResource; -use Filament\Pages\Actions\LocaleSwitcher; use Filament\Resources\Pages\CreateRecord; -use Filament\Resources\Pages\CreateRecord\Concerns\Translatable; class CreateGroup extends CreateRecord { diff --git a/app/Filament/Resources/GroupResource/Pages/EditGroup.php b/app/Filament/Resources/GroupResource/Pages/EditGroup.php index 759447f..e7d9d15 100644 --- a/app/Filament/Resources/GroupResource/Pages/EditGroup.php +++ b/app/Filament/Resources/GroupResource/Pages/EditGroup.php @@ -4,9 +4,7 @@ use App\Filament\Resources\GroupResource; use Filament\Pages\Actions\DeleteAction; -use Filament\Pages\Actions\LocaleSwitcher; use Filament\Resources\Pages\EditRecord; -use Filament\Resources\Pages\EditRecord\Concerns\Translatable; class EditGroup extends EditRecord { diff --git a/app/Filament/Resources/GroupResource/RelationManagers/UsersRelationManager.php b/app/Filament/Resources/GroupResource/RelationManagers/UsersRelationManager.php index 50f6fd1..f6d2a9b 100644 --- a/app/Filament/Resources/GroupResource/RelationManagers/UsersRelationManager.php +++ b/app/Filament/Resources/GroupResource/RelationManagers/UsersRelationManager.php @@ -6,9 +6,9 @@ use Filament\Forms; use Filament\Forms\Form; use Filament\Resources\RelationManagers\RelationManager; -use Filament\Tables\Table; use Filament\Tables; use Filament\Tables\Actions\AttachAction; +use Filament\Tables\Table; class UsersRelationManager extends RelationManager { @@ -30,7 +30,7 @@ public function table(Table $table): Table // ]) ->headerActions([ - AttachAction::make()->form(fn(AttachAction $action): array => [ + AttachAction::make()->form(fn (AttachAction $action): array => [ $action->getRecordSelect(), Forms\Components\Select::make('level')->required() ->options(GroupUserLevel::class), diff --git a/app/Filament/Resources/UserResource.php b/app/Filament/Resources/UserResource.php index fd02a45..1cb4706 100644 --- a/app/Filament/Resources/UserResource.php +++ b/app/Filament/Resources/UserResource.php @@ -23,7 +23,8 @@ class UserResource extends Resource protected static ?string $slug = 'users'; protected static ?string $recordTitleAttribute = 'name'; - protected static ?string $navigationIcon = "heroicon-o-user"; + + protected static ?string $navigationIcon = 'heroicon-o-user'; public static function form(Form $form): Form { @@ -50,11 +51,11 @@ public static function form(Form $form): Form Placeholder::make('created_at') ->label('Created Date') - ->content(fn(?User $record): string => $record?->created_at?->diffForHumans() ?? '-'), + ->content(fn (?User $record): string => $record?->created_at?->diffForHumans() ?? '-'), Placeholder::make('updated_at') ->label('Last Modified Date') - ->content(fn(?User $record): string => $record?->updated_at?->diffForHumans() ?? '-'), + ->content(fn (?User $record): string => $record?->updated_at?->diffForHumans() ?? '-'), ]); } diff --git a/app/Filament/Resources/UserResource/Pages/EditUser.php b/app/Filament/Resources/UserResource/Pages/EditUser.php index f009928..1f6ce1f 100644 --- a/app/Filament/Resources/UserResource/Pages/EditUser.php +++ b/app/Filament/Resources/UserResource/Pages/EditUser.php @@ -23,10 +23,10 @@ protected function getHeaderActions(): array ->label('Reset 2FA') ->requiresConfirmation() ->color('danger') - ->visible(fn(User $record) => $record->twoFactors()->exists()) + ->visible(fn (User $record) => $record->twoFactors()->exists()) ->action(function () { - $this->record->resetTwoFactorAuth(); - }), + $this->record->resetTwoFactorAuth(); + }), ]; } } diff --git a/app/Filament/Resources/UserResource/RelationManagers/ActionsRelationManager.php b/app/Filament/Resources/UserResource/RelationManagers/ActionsRelationManager.php index 55221cd..6b19400 100644 --- a/app/Filament/Resources/UserResource/RelationManagers/ActionsRelationManager.php +++ b/app/Filament/Resources/UserResource/RelationManagers/ActionsRelationManager.php @@ -15,21 +15,23 @@ class ActionsRelationManager extends RelationManager { protected static string $relationship = 'actions'; + protected static ?string $recordTitleAttribute = 'description'; public function table(Table $table): Table { return $table ->columns([ - Tables\Columns\TextColumn::make('description')->formatStateUsing(fn(string $state - ) => __("activity.".$state)), + Tables\Columns\TextColumn::make('description')->formatStateUsing(fn (string $state + ) => __('activity.' . $state)), Tables\Columns\TextColumn::make('subject.name') ->formatStateUsing(static function (Column $column, $state): ?string { $record = $column->getRecord(); $record->load('subject', 'causer'); + return $record->subject->name ?? $record->subject->data['client_name'] ?? $record->subject->id ?? $record->causer->name ?? $record->causer->id; }) - ->description(fn(Activity $record): string => ($record->subject_type ?? $record->causer_type)), + ->description(fn (Activity $record): string => ($record->subject_type ?? $record->causer_type)), // TextColumn::make('changes'), Tables\Columns\TextColumn::make('created_at')->label('Date')->dateTime()->description(function ( @@ -49,11 +51,11 @@ public function table(Table $table): Table $indicators = []; if ($data['from'] ?? null) { - $indicators['from'] = 'Created from '.Carbon::parse($data['from'])->toFormattedDateString(); + $indicators['from'] = 'Created from ' . Carbon::parse($data['from'])->toFormattedDateString(); } if ($data['until'] ?? null) { - $indicators['until'] = 'Created until '.Carbon::parse($data['until'])->toFormattedDateString(); + $indicators['until'] = 'Created until ' . Carbon::parse($data['until'])->toFormattedDateString(); } return $indicators; diff --git a/app/Filament/Resources/UserResource/RelationManagers/GroupsRelationManager.php b/app/Filament/Resources/UserResource/RelationManagers/GroupsRelationManager.php index 2752553..2a0451e 100644 --- a/app/Filament/Resources/UserResource/RelationManagers/GroupsRelationManager.php +++ b/app/Filament/Resources/UserResource/RelationManagers/GroupsRelationManager.php @@ -8,8 +8,8 @@ use Filament\Forms\Components\TextInput; use Filament\Forms\Form; use Filament\Resources\RelationManagers\RelationManager; -use Filament\Tables\Table; use Filament\Tables\Columns\TextColumn; +use Filament\Tables\Table; class GroupsRelationManager extends RelationManager { @@ -22,26 +22,26 @@ public function form(Form $form): Form return $form ->schema([ TextInput::make('type') - ->required(), + ->required(), FileUpload::make('logo') - ->image() - ->disk('avatars') - ->label('Group Photo') - ->imageResizeTargetWidth('512') - ->imageResizeTargetHeight('512') - ->imagePreviewHeight('256'), + ->image() + ->disk('avatars') + ->label('Group Photo') + ->imageResizeTargetWidth('512') + ->imageResizeTargetHeight('512') + ->imagePreviewHeight('256'), Placeholder::make('created_at') - ->label('Created Date') - ->content(fn(?Group $record): string => $record?->created_at?->diffForHumans() ?? '-'), + ->label('Created Date') + ->content(fn (?Group $record): string => $record?->created_at?->diffForHumans() ?? '-'), Placeholder::make('updated_at') - ->label('Last Modified Date') - ->content(fn(?Group $record): string => $record?->updated_at?->diffForHumans() ?? '-'), + ->label('Last Modified Date') + ->content(fn (?Group $record): string => $record?->updated_at?->diffForHumans() ?? '-'), TextInput::make('internal_name') - ->required(), + ->required(), ]); } @@ -52,8 +52,8 @@ public function table(Table $table): Table TextColumn::make('type'), TextColumn::make('name') - ->searchable() - ->sortable(), + ->searchable() + ->sortable(), TextColumn::make('description'), ]); diff --git a/app/Filament/Resources/UserResource/RelationManagers/TokensRelationManager.php b/app/Filament/Resources/UserResource/RelationManagers/TokensRelationManager.php index 2fcb8e0..4ac1687 100644 --- a/app/Filament/Resources/UserResource/RelationManagers/TokensRelationManager.php +++ b/app/Filament/Resources/UserResource/RelationManagers/TokensRelationManager.php @@ -7,8 +7,8 @@ use Filament\Forms; use Filament\Forms\Form; use Filament\Resources\RelationManagers\RelationManager; -use Filament\Tables\Table; use Filament\Tables; +use Filament\Tables\Table; use Illuminate\Support\Facades\Cache; use Laravel\Sanctum\PersonalAccessToken; @@ -35,7 +35,7 @@ public function table(Table $table): Table })->form([ Forms\Components\TextInput::make('name'), Forms\Components\Select::make('abilities')->options(static function () { - return collect((new Client())->getScopes())->mapWithKeys(fn($v) => [$v => $v]); + return collect((new Client())->getScopes())->mapWithKeys(fn ($v) => [$v => $v]); })->multiple(), Forms\Components\DateTimePicker::make('expires_at'), ]), @@ -57,11 +57,11 @@ public function form(Form $form): Form ->required() ->maxLength(255), Forms\Components\Select::make('abilities')->options(static function () { - return collect((new Client())->getScopes())->mapWithKeys(fn($v) => [$v => $v]); + return collect((new Client())->getScopes())->mapWithKeys(fn ($v) => [$v => $v]); })->multiple(), Forms\Components\TextInput::make('token') ->disabled() - ->visible(fn(PersonalAccessToken $record) => Cache::has('admin.accessKeyTmp.' . $record->id)) + ->visible(fn (PersonalAccessToken $record) => Cache::has('admin.accessKeyTmp.' . $record->id)) ->hint('Will be hidden 3 minutes after access token creation.') ->formatStateUsing(function (PersonalAccessToken $record) { return Cache::get('admin.accessKeyTmp.' . $record->id); diff --git a/app/Http/Controllers/Admin/Auth/FrontChannelLogoutController.php b/app/Http/Controllers/Admin/Auth/FrontChannelLogoutController.php index c351c05..764a47f 100644 --- a/app/Http/Controllers/Admin/Auth/FrontChannelLogoutController.php +++ b/app/Http/Controllers/Admin/Auth/FrontChannelLogoutController.php @@ -11,6 +11,7 @@ class FrontChannelLogoutController extends Controller public function __invoke(Request $request) { Auth::guard('admin')->logout(); - return "Logout successful."; + + return 'Logout successful.'; } } diff --git a/app/Http/Controllers/Api/v1/GroupController.php b/app/Http/Controllers/Api/v1/GroupController.php index 414a50d..91290c1 100644 --- a/app/Http/Controllers/Api/v1/GroupController.php +++ b/app/Http/Controllers/Api/v1/GroupController.php @@ -15,15 +15,15 @@ class GroupController extends Controller { public function index(Request $request) { - $this->authorize("viewAny", Group::class); + $this->authorize('viewAny', Group::class); $groups = Group::query(); if ($request->user()->isStaff()) { $groups = $groups->where('type', GroupTypeEnum::Department) - ->orWhereHas('users', fn($q) => $q->where('user_id', $request->user()->id)); + ->orWhereHas('users', fn ($q) => $q->where('user_id', $request->user()->id)); } else { - $groups = $groups->whereHas('users', fn($q) => $q->where('user_id', $request->user()->id)); + $groups = $groups->whereHas('users', fn ($q) => $q->where('user_id', $request->user()->id)); } $groups = $groups->simplePaginate(25); @@ -33,29 +33,33 @@ public function index(Request $request) public function store(GroupStoreRequest $request) { - $this->authorize("create", Group::class); + $this->authorize('create', Group::class); $group = Group::create($request->validationData()); + return new GroupResource($group); } public function show(Group $group, Request $request) { - $this->authorize("view", [$group, $request->user()]); + $this->authorize('view', [$group, $request->user()]); + return new GroupResource($group); } public function update(GroupUpdateRequest $request, Group $group) { - $this->authorize("update", [$group, $request->user()]); + $this->authorize('update', [$group, $request->user()]); $group->fill($request->validationData()); $group->save(); + return new GroupResource($group); } public function destroy(Group $group, Request $request) { - $this->authorize("delete", [$group, $request->user()]); + $this->authorize('delete', [$group, $request->user()]); $group->delete(); + return response(null, 204); } } diff --git a/app/Http/Controllers/Api/v1/GroupUserController.php b/app/Http/Controllers/Api/v1/GroupUserController.php index 9ecb3e9..9a0579c 100644 --- a/app/Http/Controllers/Api/v1/GroupUserController.php +++ b/app/Http/Controllers/Api/v1/GroupUserController.php @@ -18,6 +18,7 @@ class GroupUserController extends Controller public function index(Group $group, Request $request) { $this->authorize('view', [$group->users()->find($request->user()->id)->pivot]); + return new GroupUserCollection(QueryBuilder::for($group->users()) ->allowedFilters(AllowedFilter::exact('level', 'group_user.level')) ->simplePaginate(100)); @@ -35,7 +36,7 @@ public function store(GroupUserStoreRequest $request, Group $group) }; // validated email - if (!$user->hasVerifiedEmail()) { + if (! $user->hasVerifiedEmail()) { throw ValidationException::withMessages(['email' => 'User has not verified their email']); } @@ -45,6 +46,7 @@ public function store(GroupUserStoreRequest $request, Group $group) } $group->users()->attach($user, ['level' => $request->validationData()['level']]); + return new GroupUserResource($group->users()->find($user->id)); } @@ -53,6 +55,7 @@ public function destroy(Group $group, User $user, Request $request) $pivot = $group->users()->find($request->user()->id)->pivot; $this->authorize('delete', [$pivot]); $group->users()->detach($user); + return response(null, 204); } } diff --git a/app/Http/Controllers/Api/v1/IntrospectionController.php b/app/Http/Controllers/Api/v1/IntrospectionController.php index 268b15f..851891e 100644 --- a/app/Http/Controllers/Api/v1/IntrospectionController.php +++ b/app/Http/Controllers/Api/v1/IntrospectionController.php @@ -11,7 +11,8 @@ class IntrospectionController extends Controller { public function __invoke(IntrospectionRequest $request, Client $client) { - $data = $client->getToken($request->post('token'), explode(" ", $request->post('scope'))); + $data = $client->getToken($request->post('token'), explode(' ', $request->post('scope'))); + return new TokenResource($data); } } diff --git a/app/Http/Controllers/AppsController.php b/app/Http/Controllers/AppsController.php index ab04f70..910eb3e 100644 --- a/app/Http/Controllers/AppsController.php +++ b/app/Http/Controllers/AppsController.php @@ -9,32 +9,18 @@ class AppsController extends Controller { public function index() { - return inertia("Apps/Index"); + return inertia('Apps/Index'); } - public function create() - { - } - - public function store(Request $request) - { - } - - public function show(App $app) - { + public function create() {} - } + public function store(Request $request) {} - public function edit(App $app) - { - } + public function show(App $app) {} - public function update(Request $request) - { + public function edit(App $app) {} - } + public function update(Request $request) {} - public function destroy(App $app) - { - } + public function destroy(App $app) {} } diff --git a/app/Http/Controllers/Auth/ConsentController.php b/app/Http/Controllers/Auth/ConsentController.php index af8f2d8..4b34a0c 100644 --- a/app/Http/Controllers/Auth/ConsentController.php +++ b/app/Http/Controllers/Auth/ConsentController.php @@ -6,8 +6,6 @@ use App\Http\Requests\Auth\ConsentRequest; use App\Models\User; use App\Services\Hydra\Client; -use Illuminate\Support\Facades\Cookie; -use Vinkla\Hashids\Facades\Hashids; class ConsentController extends Controller { @@ -18,12 +16,14 @@ public function __invoke(ConsentRequest $request) if (isset($consentRequest['redirect_to'])) { return redirect($consentRequest['redirect_to']); } - $user = User::findByHashid($consentRequest["subject"]); + $user = User::findByHashid($consentRequest['subject']); if ($user === null) { - $response = $hydra->rejectConsentRequest($consentRequest, "login_required", "The account of the user does not exist.", "Your user account does not exist anymore. It may have been deleted due to not being verified for over 24 hours.", "The account of the user does not exist.", "401"); + $response = $hydra->rejectConsentRequest($consentRequest, 'login_required', 'The account of the user does not exist.', 'Your user account does not exist anymore. It may have been deleted due to not being verified for over 24 hours.', 'The account of the user does not exist.', '401'); + return redirect($response['redirect_to']); } $response = $hydra->acceptConsentRequest($consentRequest, $user); + return redirect($response['redirect_to']); } } diff --git a/app/Http/Controllers/Auth/ForgotPasswordController.php b/app/Http/Controllers/Auth/ForgotPasswordController.php index 0e56dbc..a5ba93c 100644 --- a/app/Http/Controllers/Auth/ForgotPasswordController.php +++ b/app/Http/Controllers/Auth/ForgotPasswordController.php @@ -14,7 +14,7 @@ class ForgotPasswordController extends Controller { public function __invoke(ForgotPasswordRequest $request) { - $key = 'reset-passwords:'.$request->ip(); + $key = 'reset-passwords:' . $request->ip(); // Throttle requests if (RateLimiter::tooManyAttempts($key, 5)) { throw ValidationException::withMessages(['email' => 'Too many attempts.']); diff --git a/app/Http/Controllers/Auth/FrontChannelLogoutController.php b/app/Http/Controllers/Auth/FrontChannelLogoutController.php index b7e6a97..aff3cff 100644 --- a/app/Http/Controllers/Auth/FrontChannelLogoutController.php +++ b/app/Http/Controllers/Auth/FrontChannelLogoutController.php @@ -12,6 +12,7 @@ class FrontChannelLogoutController extends Controller public function __invoke(Request $request) { Auth::guard('web')->logout(); + return Redirect::route('auth.choose'); } } diff --git a/app/Http/Controllers/Auth/LoginController.php b/app/Http/Controllers/Auth/LoginController.php index 4e5426e..c5f61b2 100644 --- a/app/Http/Controllers/Auth/LoginController.php +++ b/app/Http/Controllers/Auth/LoginController.php @@ -40,7 +40,7 @@ public function view(Request $request) } if ($subject !== null) { - return Redirect::to($hydra->acceptLogin($subject, $loginRequest["challenge"], null, $loginRequest)); + return Redirect::to($hydra->acceptLogin($subject, $loginRequest['challenge'], null, $loginRequest)); } return Inertia::render('Auth/Login'); @@ -78,7 +78,7 @@ public function submit(LoginRequest $request) } $url = (new Client())->acceptLogin($user->hashId(), $request->get('login_challenge'), - $request->get('remember') ? "2592000" : "3600"); + $request->get('remember') ? '2592000' : '3600'); return Inertia::location($url); } @@ -92,14 +92,15 @@ public function submit(LoginRequest $request) */ private function shouldSkipLogin(mixed $loginRequest): ?string { - if (isset($loginRequest["skip"]) && $loginRequest["skip"] === true) { + if (isset($loginRequest['skip']) && $loginRequest['skip'] === true) { return $loginRequest['subject']; } $registerLoginSkipOnceUserId = Session::get('justRegisteredSkipLogin.user_id'); - if (!is_null($registerLoginSkipOnceUserId)) { + if (! is_null($registerLoginSkipOnceUserId)) { $subject = $registerLoginSkipOnceUserId; Session::forget('justRegisteredSkipLogin.user_id'); + return User::findOrFail($subject)->hashid; } @@ -122,6 +123,7 @@ private function checkEmailVerification($loginRequest, User|string $user) if ($clientModel->system_name === 'portal') { return true; } + return false; } } diff --git a/app/Http/Controllers/Auth/LogoutController.php b/app/Http/Controllers/Auth/LogoutController.php index a92b545..16907af 100644 --- a/app/Http/Controllers/Auth/LogoutController.php +++ b/app/Http/Controllers/Auth/LogoutController.php @@ -15,19 +15,22 @@ public function __invoke(Request $request) { if ($request->session()->get('web.token') !== null) { Session::flush(); - return Redirect::to(config('app.url').'/oauth2/sessions/logout'); + + return Redirect::to(config('app.url') . '/oauth2/sessions/logout'); } if ($request->missing('logout_challenge')) { Auth::logout(); Session::flush(); - return Redirect::to(config('app.url').'/oauth2/sessions/logout'); + + return Redirect::to(config('app.url') . '/oauth2/sessions/logout'); } $request->validate(['logout_challenge' => 'required|string']); $hydra = new Client(); $hydraResponse = $hydra->acceptLogoutRequest($request->get('logout_challenge')); - return redirect($hydraResponse["redirect_to"]); + + return redirect($hydraResponse['redirect_to']); } } diff --git a/app/Http/Controllers/Auth/PasswordResetController.php b/app/Http/Controllers/Auth/PasswordResetController.php index 32ca634..4774fd6 100644 --- a/app/Http/Controllers/Auth/PasswordResetController.php +++ b/app/Http/Controllers/Auth/PasswordResetController.php @@ -24,7 +24,7 @@ public function store(PasswordResetRequest $request) $request->only('email', 'password', 'password_confirmation', 'token'), function ($user, $password) { $user->forceFill([ - 'password' => Hash::make($password) + 'password' => Hash::make($password), ])->setRememberToken(Str::random(60)); $user->save(); diff --git a/app/Http/Controllers/Auth/RegisterController.php b/app/Http/Controllers/Auth/RegisterController.php index 6e71803..1392445 100644 --- a/app/Http/Controllers/Auth/RegisterController.php +++ b/app/Http/Controllers/Auth/RegisterController.php @@ -14,12 +14,13 @@ class RegisterController extends Controller public function __invoke(RegisterRequest $request) { $user = User::create([ - "name" => $request->username, - "email" => $request->email, - "password" => Hash::make($request->password) + 'name' => $request->username, + 'email' => $request->email, + 'password' => Hash::make($request->password), ]); event(new Registered($user)); Session::put('justRegisteredSkipLogin.user_id', $user->id); + return redirect()->route('login.apps.redirect', ['app' => 'portal']); } } diff --git a/app/Http/Controllers/Auth/VerifyEmailController.php b/app/Http/Controllers/Auth/VerifyEmailController.php index 4d392c1..6c4fbcd 100644 --- a/app/Http/Controllers/Auth/VerifyEmailController.php +++ b/app/Http/Controllers/Auth/VerifyEmailController.php @@ -16,33 +16,36 @@ public function view(Request $request) if ($request->user()->hasVerifiedEmail()) { return Redirect::route('auth.choose'); } + return Inertia::render('Auth/VerifyEmail'); } public function verify(EmailVerificationRequest $request) { $user = $request->verifyUser(); - if (!$user->hasVerifiedEmail()) { + if (! $user->hasVerifiedEmail()) { $user->markEmailAsVerified(); event(new Verified($user)); } + // No login session? The user gets redirected to the success page. return Inertia::render('Auth/VerifyEmailSuccess', ['user' => $user->only('name', 'email')]); } public function resend(Request $request) { - $success = \Illuminate\Support\Facades\RateLimiter::attempt($request->user()->id.':resend-verification-email', + $success = \Illuminate\Support\Facades\RateLimiter::attempt($request->user()->id . ':resend-verification-email', 1, function () use ($request) { if ($request->user()->hasVerifiedEmail()) { return Redirect::route('dashboard'); } $request->user()->sendEmailVerificationNotification(); + return true; }, 30); - if (!$success) { + if (! $success) { return Inertia::render('Auth/VerifyEmail')->with('status', 'throttled'); } diff --git a/app/Http/Controllers/AuthController.php b/app/Http/Controllers/AuthController.php index a83d0bd..41d8c77 100644 --- a/app/Http/Controllers/AuthController.php +++ b/app/Http/Controllers/AuthController.php @@ -19,9 +19,10 @@ public function login($app) return redirect()->route(config('services.apps')[$app]['home_route']); } - $url = Socialite::driver('idp-'.$app) + $url = Socialite::driver('idp-' . $app) ->scopes(config('services.apps')[$app]['scopes']) ->redirect(); + return Inertia::location($url->getTargetUrl()); } @@ -29,31 +30,33 @@ public function loginCallback($app) { $this->checkApp($app); try { - $userInfo = Socialite::driver('idp-'.$app)->user(); + $userInfo = Socialite::driver('idp-' . $app)->user(); } catch (InvalidStateException $e) { return redirect()->route('login.apps.redirect', ['app' => $app]); } $userid = Hashids::connection('user')->decode($userInfo->id)[0]; Auth::guard($this->getGuard($app))->loginUsingId($userid); - Socialite::driver('idp-'.$app)->putToken( + Socialite::driver('idp-' . $app)->putToken( token: $userInfo->token, refreshToken: $userInfo->refreshToken, expiresIn: now()->addSeconds($userInfo->expiresIn), ); + return redirect()->route(config('services.apps')[$app]['home_route']); } public function logout($app) { $this->checkApp($app); - return Socialite::driver('idp-'.$app)->logoutAll(); + + return Socialite::driver('idp-' . $app)->logoutAll(); } public function frontchannelLogout($app) { $this->checkApp($app); Auth::guard($this->getGuard($app))->logout(); - Socialite::driver('idp-'.$app)->clearToken(); + Socialite::driver('idp-' . $app)->clearToken(); } private function checkApp($app) diff --git a/app/Http/Controllers/Profile/Settings/TwoFactor/TotpSetupController.php b/app/Http/Controllers/Profile/Settings/TwoFactor/TotpSetupController.php index cd39e0f..0b146eb 100644 --- a/app/Http/Controllers/Profile/Settings/TwoFactor/TotpSetupController.php +++ b/app/Http/Controllers/Profile/Settings/TwoFactor/TotpSetupController.php @@ -22,15 +22,17 @@ public function show() // Determine if Two Factor is enabled for the person $twoFactorEnabled = auth()->user()->twoFactors()->whereType(TwoFactorTypeEnum::TOTP)->exists(); if ($twoFactorEnabled === false) { - $secret = Cache::remember('user-'.auth()->user()->id.'-two-factor-user-cache', now()->addHour(), + $secret = Cache::remember('user-' . auth()->user()->id . '-two-factor-user-cache', now()->addHour(), function () use ($tfa) { $secret = $tfa->createSecret(); + return [ 'secret' => $secret, - 'qrCode' => $tfa->getQRCodeImageAsDataUri(config('app.name')."-".auth()->user()->name, $secret), + 'qrCode' => $tfa->getQRCodeImageAsDataUri(config('app.name') . '-' . auth()->user()->name, $secret), ]; }); } + return Inertia::render('Settings/TwoFactor/AuthenticatorApp', [ 'secret' => $secret['secret'] ?? null, 'qrCode' => $secret['qrCode'] ?? null, @@ -44,15 +46,15 @@ public function store(TotpStoreRequest $request) $tfa = $this->createTwoFactorAuth(); $data = $request->validated(); // Verify that data->code is equal to cached value - $cachedValue = Cache::get('user-'.auth()->user()->id.'-two-factor-user-cache'); - if (!isset($cachedValue['secret'])) { + $cachedValue = Cache::get('user-' . auth()->user()->id . '-two-factor-user-cache'); + if (! isset($cachedValue['secret'])) { throw ValidationException::withMessages(['code' => 'Your secret expired, please try again.']); } if ($cachedValue['secret'] !== $data['secret']) { throw ValidationException::withMessages(['code' => 'Invalid code']); } // Verify that code is valid - if (!$tfa->verifyCode($data['secret'], $data['code'])) { + if (! $tfa->verifyCode($data['secret'], $data['code'])) { throw ValidationException::withMessages(['code' => 'Invalid code']); } // Add totp device to user @@ -61,7 +63,8 @@ public function store(TotpStoreRequest $request) 'secret' => $data['secret'], ]); // Clear cache - Cache::forget('user-'.auth()->user()->id.'-two-factor-user-cache'); + Cache::forget('user-' . auth()->user()->id . '-two-factor-user-cache'); + return redirect()->route('settings.two-factor'); } @@ -71,11 +74,12 @@ public function destroy(TotpDestroyRequest $request) $data = $request->validated(); // Verify that password is correct $userPassword = auth()->user()->password; - if (!Hash::check($data['password'], $userPassword)) { + if (! Hash::check($data['password'], $userPassword)) { throw ValidationException::withMessages(['password' => 'Invalid password']); } // Delete totp device auth()->user()->twoFactors()->whereType(TwoFactorTypeEnum::TOTP)->delete(); + return redirect()->route('settings.two-factor'); } diff --git a/app/Http/Controllers/Profile/Settings/TwoFactor/TwoFactorController.php b/app/Http/Controllers/Profile/Settings/TwoFactor/TwoFactorController.php index 0389de0..3b359f5 100644 --- a/app/Http/Controllers/Profile/Settings/TwoFactor/TwoFactorController.php +++ b/app/Http/Controllers/Profile/Settings/TwoFactor/TwoFactorController.php @@ -24,8 +24,8 @@ public function __invoke() 'description' => 'Use a Yubikey device to sign in to your account.', 'url' => route('settings.two-factor.yubikey'), 'active' => Auth::user()->twoFactors()->whereType(TwoFactorTypeEnum::YUBIKEY)->exists(), - ] - ] + ], + ], ]); } } diff --git a/app/Http/Controllers/Profile/Settings/TwoFactor/YubikeySetupController.php b/app/Http/Controllers/Profile/Settings/TwoFactor/YubikeySetupController.php index 94ccff9..bdbae37 100644 --- a/app/Http/Controllers/Profile/Settings/TwoFactor/YubikeySetupController.php +++ b/app/Http/Controllers/Profile/Settings/TwoFactor/YubikeySetupController.php @@ -25,7 +25,7 @@ public function index() { return Inertia::render('Settings/TwoFactor/YubikeySetup', [ 'keys' => auth()->user()->twoFactors()->where('type', 'yubikey')->get([ - 'id', 'name', 'last_used_at' + 'id', 'name', 'last_used_at', ]), ]); } @@ -33,7 +33,7 @@ public function index() // Add new Yubikey public function store(YubikeyStoreRequest $request) { - $limitKey = 'yubikey-setup-'.$request->user()->id; + $limitKey = 'yubikey-setup-' . $request->user()->id; // Rate limit this endpoint if (RateLimiter::tooManyAttempts($limitKey, 10)) { throw ValidationException::withMessages(['code' => 'Too many attempts. Please try again later.']); @@ -52,6 +52,7 @@ public function store(YubikeyStoreRequest $request) 'identifier' => $yubico->identifier, 'type' => 'yubikey', ]); + return redirect()->route('settings.two-factor.yubikey'); } @@ -61,11 +62,12 @@ public function destroy(YubikeyDestroyRequest $request) $data = $request->validated(); // Verify that password is correct $userPassword = auth()->user()->password; - if (!Hash::check($data['password'], $userPassword)) { + if (! Hash::check($data['password'], $userPassword)) { throw ValidationException::withMessages(['password' => 'Invalid password']); } // Delete totp device auth()->user()->twoFactors()->where('id', $request->input('keyId'))->delete(); + return redirect()->route('settings.two-factor'); } @@ -81,7 +83,6 @@ private function verifyResponseSignature(array $response): bool return $this->yubicoService->verifyResponseSignature($response); } - private function convertResponseToArray(string $response): array { return $this->yubicoService->convertResponseToArray($response); diff --git a/app/Http/Controllers/Profile/Settings/UpdatePasswordController.php b/app/Http/Controllers/Profile/Settings/UpdatePasswordController.php index f39420f..a310195 100644 --- a/app/Http/Controllers/Profile/Settings/UpdatePasswordController.php +++ b/app/Http/Controllers/Profile/Settings/UpdatePasswordController.php @@ -14,6 +14,7 @@ public function __invoke(UpdatePasswordRequest $request) $data = $request->validated(); $request->user()->update(['password' => Hash::make($data['password'])]); - return Inertia::render("Settings/UpdatePassword", ["success" => true]); + + return Inertia::render('Settings/UpdatePassword', ['success' => true]); } } diff --git a/app/Http/Controllers/Profile/StoreAvatarController.php b/app/Http/Controllers/Profile/StoreAvatarController.php index dfa1331..c83382b 100644 --- a/app/Http/Controllers/Profile/StoreAvatarController.php +++ b/app/Http/Controllers/Profile/StoreAvatarController.php @@ -29,15 +29,16 @@ public function __invoke(Request $request) $image = $request->file('image'); $image = Image::make($image)->crop($data['crop']['width'], $data['crop']['height'], $data['crop']['x'], $data['crop']['y'])->encode('webp', '100'); - $path = Str::random(40).".webp"; + $path = Str::random(40) . '.webp'; Storage::disk('s3-avatars')->put($path, $image); NewProfilePhotoEvent::dispatch(Auth::user(), $path); - if (!is_null(Auth::user()->profile_photo_path)) { + if (! is_null(Auth::user()->profile_photo_path)) { if (Storage::disk('s3-avatars')->exists(Auth::user()->profile_photo_path)) { Storage::disk('s3-avatars')->delete(Auth::user()->profile_photo_path); } } $request->user()->update(['profile_photo_path' => $path]); + return Redirect::route('settings.profile'); } } diff --git a/app/Http/Controllers/Profile/UpdateProfileController.php b/app/Http/Controllers/Profile/UpdateProfileController.php index d4c23f7..830c940 100644 --- a/app/Http/Controllers/Profile/UpdateProfileController.php +++ b/app/Http/Controllers/Profile/UpdateProfileController.php @@ -21,17 +21,18 @@ public function __invoke(UpdateProfileRequest $request) if ($user->email !== $request->get('email')) { $done = RateLimiter::attempt( - 'emailVerify:'.$user->id, + 'emailVerify:' . $user->id, 5, function () use ($user, $request) { - $this->validate($request, ["unique:users,email"]); + $this->validate($request, ['unique:users,email']); activity()->by($user)->log('mail.change-email'); $user->changeMail($request->get('email')); + return Redirect::route('settings.profile')->with('message', 'emailVerify'); }, 900 ); - if (!$done) { + if (! $done) { return Redirect::route('settings.profile')->with('message', 'emailTooMany'); } } diff --git a/app/Http/Controllers/Profile/UserinfoController.php b/app/Http/Controllers/Profile/UserinfoController.php index 8917aec..c1fcded 100644 --- a/app/Http/Controllers/Profile/UserinfoController.php +++ b/app/Http/Controllers/Profile/UserinfoController.php @@ -11,7 +11,7 @@ class UserinfoController extends Controller public function __invoke(Request $request) { $data = $request->validate([ - 'token' => 'string|required' + 'token' => 'string|required', ]); $hydra = new Client(); $hydra->getToken($data['token'], ['openid', 'profile']); diff --git a/app/Http/Controllers/Staff/GroupMemberController.php b/app/Http/Controllers/Staff/GroupMemberController.php index 3f80fbe..6d48fe2 100644 --- a/app/Http/Controllers/Staff/GroupMemberController.php +++ b/app/Http/Controllers/Staff/GroupMemberController.php @@ -18,30 +18,30 @@ class GroupMemberController extends Controller public function index(Group $group, Request $request) { return Inertia::render('Staff/Groups/Tabs/MemberTab', [ - 'group' => $group->loadCount('users')->only(['hashid', 'name', 'users_count','parent_id']), + 'group' => $group->loadCount('users')->only(['hashid', 'name', 'users_count', 'parent_id']), 'parent' => $group->parent?->only(['hashid', 'name']), // Sort Owner, Admin, Moderator, Member and then by name 'users' => $group->users() ->with([ - 'groups' => fn($q) => $q->where('type', 'team')->where('parent_id', $group->id)->get(['id', 'name']) + 'groups' => fn ($q) => $q->where('type', 'team')->where('parent_id', $group->id)->get(['id', 'name']), ]) - ->withPivot('level')->get(['id', 'name', 'profile_photo_path'])->map(fn($user - ) => [ - 'id' => $user->hashid, - 'name' => $user->name, - 'profile_photo_path' => (is_null($user->profile_photo_path)) ? null : Storage::drive('s3-avatars')->url($user->profile_photo_path), - 'level' => $user->pivot->level, - 'teams' => $user->groups->map(fn($group) => [ - 'id' => $group->hashid, - 'name' => $group->name, + ->withPivot('level')->get(['id', 'name', 'profile_photo_path'])->map(fn ($user + ) => [ + 'id' => $user->hashid, + 'name' => $user->name, + 'profile_photo_path' => (is_null($user->profile_photo_path)) ? null : Storage::drive('s3-avatars')->url($user->profile_photo_path), + 'level' => $user->pivot->level, + 'teams' => $user->groups->map(fn ($group) => [ + 'id' => $group->hashid, + 'name' => $group->name, + ]), + 'title' => $user->pivot->title, + ])->sortBy(fn ($user) => [ + $user['level'] === 'owner' ? 0 : 1, + $user['level'] === 'admin' ? 1 : 2, + $user['level'] === 'moderator' ? 2 : 3, + $user['name'], ]), - 'title' => $user->pivot->title, - ])->sortBy(fn($user) => [ - $user['level'] === 'owner' ? 0 : 1, - $user['level'] === 'admin' ? 1 : 2, - $user['level'] === 'moderator' ? 2 : 3, - $user['name'] - ]), 'canEdit' => $request->user()->can('update', $group), ]); } @@ -65,7 +65,7 @@ public function store(Group $group, Request $request) throw ValidationException::withMessages([$field => 'User not found']); } // If email not verified throw validationexception - if (!$user->hasVerifiedEmail()) { + if (! $user->hasVerifiedEmail()) { throw ValidationException::withMessages([$field => 'User has not verified their email']); } // If user is already in the department throw validationexception @@ -75,9 +75,10 @@ public function store(Group $group, Request $request) // Attach user to department $group->users()->attach($user, ['level' => GroupUserLevel::Member]); // If group has a parent, add them to the parent group - if ($group->parent && !$group->parent->users->contains($user)) { + if ($group->parent && ! $group->parent->users->contains($user)) { $group->parent->users()->syncWithoutDetaching([$user->id => ['level' => GroupUserLevel::Member]]); } + return redirect()->route('staff.groups.members.index', $group); } @@ -86,7 +87,7 @@ public function edit(Group $group, User $member) return Inertia::render('Staff/GroupMember/GroupMemberEdit', [ 'group' => $group, // Load pivot data - 'member' => $group->users()->where('user_id', $member->id)->select(['id', 'name'])->first() + 'member' => $group->users()->where('user_id', $member->id)->select(['id', 'name'])->first(), ]); } @@ -97,8 +98,8 @@ public function edit(Group $group, User $member) public function update(Group $group, User $member, Request $request) { $isAdminOfParentGroup = $group->parent?->isAdmin($request->user()); - if ($member->id == $request->user()->id && !$isAdminOfParentGroup) { - throw ValidationException::withMessages(["You cannot update your own level."]); + if ($member->id == $request->user()->id && ! $isAdminOfParentGroup) { + throw ValidationException::withMessages(['You cannot update your own level.']); } $data = $request->validate([ @@ -106,12 +107,12 @@ public function update(Group $group, User $member, Request $request) ]); $requestMember = $group->users()->find($member->id)->pivot; - $this->authorize("update", $requestMember); + $this->authorize('update', $requestMember); $pivot = $group->users()->find($member->id)->pivot; $pivot->update($data); - return to_route("staff.groups.members.index", ['group' => $group->hashid()]); + return to_route('staff.groups.members.index', ['group' => $group->hashid()]); } /** @@ -120,8 +121,8 @@ public function update(Group $group, User $member, Request $request) */ public function destroy(Group $group, User $member, Request $request) { - if ($member->id === $request->user()->id && !$group->parent?->isAdmin($request->user())) { - throw ValidationException::withMessages(["You cannot remove yourself."]); + if ($member->id === $request->user()->id && ! $group->parent?->isAdmin($request->user())) { + throw ValidationException::withMessages(['You cannot remove yourself.']); } $requestMember = $group->users()->find($member)->pivot; @@ -129,7 +130,7 @@ public function destroy(Group $group, User $member, Request $request) $group->users()->detach($member); // If group has children, remove them from the children if ($group->children()->exists()) { - $group->children->each(fn($child) => $child->users()->detach($member)); + $group->children->each(fn ($child) => $child->users()->detach($member)); } } } diff --git a/app/Http/Controllers/Staff/GroupTeamController.php b/app/Http/Controllers/Staff/GroupTeamController.php index d2b243e..67c06bc 100644 --- a/app/Http/Controllers/Staff/GroupTeamController.php +++ b/app/Http/Controllers/Staff/GroupTeamController.php @@ -16,16 +16,17 @@ public function index(Group $group, Request $request) Gate::authorize('view', $group); $myDepartments = $request->user()->groups() ->where('type', GroupTypeEnum::Department)->select('id', 'level')->get() - ->mapWithKeys(fn($role) => [$role->id => ucwords($role->level)]); + ->mapWithKeys(fn ($role) => [$role->id => ucwords($role->level)]); + return Inertia::render('Staff/Groups/Tabs/TeamTab', [ - 'group' => $group->loadCount('users')->only(['hashid', 'name', 'users_count','parent_id']), + 'group' => $group->loadCount('users')->only(['hashid', 'name', 'users_count', 'parent_id']), 'parent' => $group->parent?->only(['hashid', 'name']), 'teams' => $group->children() ->where('type', GroupTypeEnum::Team) ->withCount('users') ->get(['hashid', 'name', 'users_count']), 'myGroups' => $myDepartments->values(), - 'canEdit' => $group->isAdmin($request->user()) + 'canEdit' => $group->isAdmin($request->user()), ]); } @@ -39,6 +40,7 @@ public function store(Group $group, Request $request) 'name' => $validated['name'], 'type' => GroupTypeEnum::Team, ]); + return redirect()->back(); } } diff --git a/app/Http/Controllers/Staff/GroupsController.php b/app/Http/Controllers/Staff/GroupsController.php index 4710f27..2043c28 100644 --- a/app/Http/Controllers/Staff/GroupsController.php +++ b/app/Http/Controllers/Staff/GroupsController.php @@ -10,7 +10,6 @@ use Illuminate\Support\Facades\Gate; use Inertia\Inertia; use Parsedown; -use Spatie\LaravelMarkdown\MarkdownRenderer; use Stevebauman\Purify\Facades\Purify; class GroupsController extends Controller @@ -19,14 +18,14 @@ public function index(Request $request) { $myDepartments = $request->user()->groups() ->where('type', GroupTypeEnum::Department)->select('id', 'level')->get() - ->mapWithKeys(fn($role) => [$role->id => ucwords($role->level)]); + ->mapWithKeys(fn ($role) => [$role->id => ucwords($role->level)]); $departments = Group::where('type', GroupTypeEnum::Department) ->withCount('users')->get(); - $departmentsSortedByMembershipAndUserCount = $departments->sortByDesc(fn($department) => [ + $departmentsSortedByMembershipAndUserCount = $departments->sortByDesc(fn ($department) => [ $myDepartments->contains($department->id), - $department->users_count + $department->users_count, ]); return Inertia::render('Staff/Groups/GroupsIndex', [ @@ -39,10 +38,11 @@ public function show(Group $group, Request $request) { $Parsedown = new Parsedown(); $Parsedown->setSafeMode(true); + return Inertia::render('Staff/Groups/Tabs/GroupInfoTab', [ 'group' => $group ->loadCount('users') - ->only(['hashid', 'name', 'users_count', 'description','parent_id']), + ->only(['hashid', 'name', 'users_count', 'description', 'parent_id']), 'parent' => $group->parent?->only(['hashid', 'name']), 'descriptionHtml' => $Parsedown->parse($group->description), 'canEdit' => $request->user()->can('update', $group), @@ -59,13 +59,15 @@ public function update(GroupUpdateRequest $request, Group $group) ]); } $group->update($request->validated()); + return redirect()->back(); $group->update([ 'description' => Purify::clean($request->validated()['description'], [ - 'HTML.Allowed' => 'div,p,span,ul,ol,li,strong,em,br,a[href],img[src],h1,h2,h3,h4,h5,h6' - ]) + 'HTML.Allowed' => 'div,p,span,ul,ol,li,strong,em,br,a[href],img[src],h1,h2,h3,h4,h5,h6', + ]), ]); + return redirect()->back(); } @@ -74,6 +76,7 @@ public function destroy(Group $group) Gate::authorize('delete', $group); $parent = $group->parent; $group->delete(); + return redirect()->route('staff.groups.show', $parent); } diff --git a/app/Http/Controllers/TwoFactorController.php b/app/Http/Controllers/TwoFactorController.php index d95e771..b991c0c 100644 --- a/app/Http/Controllers/TwoFactorController.php +++ b/app/Http/Controllers/TwoFactorController.php @@ -25,6 +25,7 @@ public function show(Request $request) } // Get last used two factor method $lastUsed = $twoFactors->firstWhere('last_used_at', '!=', null)->type ?? $twoFactors->first()->type ?? null; + return Inertia::render('Auth/TwoFactor', [ 'twoFactors' => $twoFactors, 'lastUsedMethod' => $lastUsed, @@ -54,18 +55,18 @@ public function submit(Request $request) } if ($data['method'] === 'yubikey') { - if (!$this->verifyYubikey($data, $twoFactors, $user)) { + if (! $this->verifyYubikey($data, $twoFactors, $user)) { throw ValidationException::withMessages(['code' => 'Invalid Yubikey code.']); } } elseif ($data['method'] === 'totp') { - if (!$this->verifyTOTP($data, $twoFactors)) { + if (! $this->verifyTOTP($data, $twoFactors)) { throw ValidationException::withMessages(['code' => 'Invalid TOTP code.']); } } else { throw ValidationException::withMessages(['code' => 'Invalid two factor method.']); } $url = (new Client())->acceptLogin($user->hashId(), $request->get('login_challenge'), - $request->get('remember') ? "2592000" : "3600"); + $request->get('remember') ? '2592000' : '3600'); return Inertia::location($url); } @@ -80,7 +81,7 @@ public function verifyYubikey($data, Collection $twoFactors, $user): bool throw ValidationException::withMessages(['code' => 'This Yubikey is not known.']); } - $limitKey = 'yubikey-setup-'.$user->id; + $limitKey = 'yubikey-setup-' . $user->id; // Rate limit this endpoint if (RateLimiter::tooManyAttempts($limitKey, 10)) { throw ValidationException::withMessages(['code' => 'Too many attempts. Please try again later.']); @@ -91,6 +92,7 @@ public function verifyYubikey($data, Collection $twoFactors, $user): bool // Update last used at $twoFactor->update(['last_used_at' => now()]); } + return $success; } @@ -102,6 +104,7 @@ public function verifyTOTP($data, Collection $twoFactors): bool // Update last used at $factorModel->update(['last_used_at' => now()]); } + return $success; } } diff --git a/app/Http/Controllers/UpdateEmailController.php b/app/Http/Controllers/UpdateEmailController.php index 9e2bdf1..7e40320 100644 --- a/app/Http/Controllers/UpdateEmailController.php +++ b/app/Http/Controllers/UpdateEmailController.php @@ -14,14 +14,14 @@ public function __invoke(Request $request) { $data = $request->validate([ 'id' => [ - "required", + 'required', ], 'newEmail' => [ - "required", + 'required', ], ]); $user = User::findByHashidOrFail($data['id']); - $newMailFromCache = Cache::get('user:'.$data['id'].':newEmail'); + $newMailFromCache = Cache::get('user:' . $data['id'] . ':newEmail'); if (sha1($user->email) === $data['newEmail']) { return Inertia::render('Auth/VerifyEmailSuccess', [ 'user' => $user->only('name', 'email'), @@ -36,8 +36,9 @@ public function __invoke(Request $request) ]); } - Log::info($user->id." has changed his E-Mail from ".$user->email." to ".$newMailFromCache); + Log::info($user->id . ' has changed his E-Mail from ' . $user->email . ' to ' . $newMailFromCache); $user->update(['email' => $newMailFromCache]); + return Inertia::render('Auth/VerifyEmailSuccess', [ 'user' => $user->only('name', 'email'), 'hideUserInfo' => true, diff --git a/app/Http/Middleware/AccessTokenValidationMiddleware.php b/app/Http/Middleware/AccessTokenValidationMiddleware.php index 0e07a41..4511c72 100644 --- a/app/Http/Middleware/AccessTokenValidationMiddleware.php +++ b/app/Http/Middleware/AccessTokenValidationMiddleware.php @@ -35,7 +35,7 @@ public function handle(Request $request, Closure $next) } /* @var SocialiteIdentityProvider $provider */ - $provider = Socialite::driver('idp-'.$systemName); + $provider = Socialite::driver('idp-' . $systemName); $token = $provider->getToken(); $refreshToken = $provider->getRefreshToken(); $tokenExpiresAt = $provider->getExpiresIn(); @@ -45,6 +45,7 @@ public function handle(Request $request, Closure $next) */ if ($token === null || $refreshToken === null || $tokenExpiresAt === null) { Auth::logout(); + return Redirect::route('auth.choose'); } @@ -60,6 +61,7 @@ public function handle(Request $request, Closure $next) } catch (IdentityProviderException|UnexpectedValueException $exception) { // If refresh fails, try to reauth user. Auth::logout(); + return Redirect::route('login.apps.redirect', ['app' => $systemName]); } /* @var SocialiteIdentityProvider $provider */ diff --git a/app/Http/Middleware/Authenticate.php b/app/Http/Middleware/Authenticate.php index bd7329b..40e6b57 100644 --- a/app/Http/Middleware/Authenticate.php +++ b/app/Http/Middleware/Authenticate.php @@ -16,12 +16,12 @@ class Authenticate extends Middleware */ protected function redirectTo($request) { - if (!$request->expectsJson()) { - if (Route::is("staff.*")) { + if (! $request->expectsJson()) { + if (Route::is('staff.*')) { return route('login.apps.redirect', ['app' => 'staff']); } + return route('login.apps.redirect', ['app' => 'portal']); } } - } diff --git a/app/Http/Middleware/CheckIfAdmin.php b/app/Http/Middleware/CheckIfAdmin.php index d241c63..dcace23 100644 --- a/app/Http/Middleware/CheckIfAdmin.php +++ b/app/Http/Middleware/CheckIfAdmin.php @@ -30,7 +30,6 @@ public function handle($request, Closure $next) * Answer to unauthorized access request. * * @param [type] $request [description] - * * @return [type] [description] */ private function respondToUnauthorizedRequest($request) @@ -59,11 +58,10 @@ private function respondToUnauthorizedRequest($request) * (again - users, not admins). * * @param [type] $user [description] - * * @return bool [description] */ private function checkIfUserIsAdmin(User $user) { - return ($user->hasRole('superadmin') === true); + return $user->hasRole('superadmin') === true; } } diff --git a/app/Http/Middleware/GroupMember.php b/app/Http/Middleware/GroupMember.php index 5cfc5ec..1330e0d 100644 --- a/app/Http/Middleware/GroupMember.php +++ b/app/Http/Middleware/GroupMember.php @@ -12,6 +12,7 @@ public function handle(Request $request, Closure $next, $groupSystemName) if ($request->user()->groups()->where('system_name', $groupSystemName)->doesntExist()) { abort(403); } + return $next($request); } } diff --git a/app/Http/Middleware/GuardSwitcher.php b/app/Http/Middleware/GuardSwitcher.php index e064f17..982bed5 100644 --- a/app/Http/Middleware/GuardSwitcher.php +++ b/app/Http/Middleware/GuardSwitcher.php @@ -9,9 +9,10 @@ class GuardSwitcher { public function handle(Request $request, Closure $next, $defaultGuard = null) { - if (array_key_exists($defaultGuard, config("auth.guards"))) { - config(["auth.defaults.guard" => $defaultGuard]); + if (array_key_exists($defaultGuard, config('auth.guards'))) { + config(['auth.defaults.guard' => $defaultGuard]); } + return $next($request); } } diff --git a/app/Http/Middleware/HandleInertiaRequests.php b/app/Http/Middleware/HandleInertiaRequests.php index 839db12..7703641 100644 --- a/app/Http/Middleware/HandleInertiaRequests.php +++ b/app/Http/Middleware/HandleInertiaRequests.php @@ -14,6 +14,7 @@ class HandleInertiaRequests extends Middleware * The root template that's loaded on the first page visit. * * @see https://inertiajs.com/server-side-setup#root-template + * * @var string */ protected $rootView = 'app'; @@ -22,6 +23,7 @@ class HandleInertiaRequests extends Middleware * Determines the current asset version. * * @see https://inertiajs.com/asset-versioning + * * @param Request $request * @return string|null */ @@ -34,6 +36,7 @@ public function version(Request $request) * Defines the props that are shared by default. * * @see https://inertiajs.com/shared-data + * * @param Request $request * @return array */ @@ -42,11 +45,11 @@ public function share(Request $request) $user = null; if ($request->user()) { $user = array_merge([ - "id" => $request->user()->hashId(), - "avatar" => ($request->user()->profile_photo_path) ? Storage::disk('s3-avatars')->url($request->user()->profile_photo_path) : null, - "isAdmin" => $request->user()->hasRole(['admin', 'superadmin']), - "roles" => $request->user()->getRoleNames(), - "language" => "en", + 'id' => $request->user()->hashId(), + 'avatar' => ($request->user()->profile_photo_path) ? Storage::disk('s3-avatars')->url($request->user()->profile_photo_path) : null, + 'isAdmin' => $request->user()->hasRole(['admin', 'superadmin']), + 'roles' => $request->user()->getRoleNames(), + 'language' => 'en', 'departments' => $request->user()->groups() ->where('type', 'department') ->limit(10) @@ -57,19 +60,18 @@ public function share(Request $request) $staffMembers = null; // If user has departments - if($user && $user['departments']->count() > 0) { - $staffMembers = User::whereHas('groups', fn($q) => $q->where('type', 'department')) + if ($user && $user['departments']->count() > 0) { + $staffMembers = User::whereHas('groups', fn ($q) => $q->where('type', 'department')) ->orderBy('name') - ->get(['id','name']); + ->get(['id', 'name']); } - return array_merge(parent::share($request), [ 'user' => Route::is(['auth.login.view']) ? null : $user, 'hideUserInfo' => Route::is(['auth.login.view', 'verification.notice']), 'staffMemberList' => $staffMembers, 'flash' => [ - 'message' => fn() => $request->session()->get('message') + 'message' => fn () => $request->session()->get('message'), ], ]); } diff --git a/app/Http/Middleware/TokenIntrospectionCheckMiddleware.php b/app/Http/Middleware/TokenIntrospectionCheckMiddleware.php index c192e13..ee42cb3 100644 --- a/app/Http/Middleware/TokenIntrospectionCheckMiddleware.php +++ b/app/Http/Middleware/TokenIntrospectionCheckMiddleware.php @@ -17,12 +17,13 @@ class TokenIntrospectionCheckMiddleware public function handle(Request $request, Closure $next) { $isAdmin = $request->routeIs('filament.*'); - $prefix = ($isAdmin) ? "admin" : "web"; + $prefix = ($isAdmin) ? 'admin' : 'web'; // Get Token that is saved in session. $token = $request->session()->get($prefix . '.token'); $response = Cache::remember('introspected-token-' . hash('xxh3', $token->getToken()), now()->addSeconds(60), function () use ($token) { $hydra = new Client(); + return $hydra->getToken($token, ['openid']); }); @@ -32,6 +33,7 @@ public function handle(Request $request, Closure $next) * Logout user and reauthenticate. */ Auth::logout(); + return Redirect::route('auth.oidc.login'); } diff --git a/app/Http/Requests/Auth/GroupRequest.php b/app/Http/Requests/Auth/GroupRequest.php index 77b7f7e..c5f1507 100644 --- a/app/Http/Requests/Auth/GroupRequest.php +++ b/app/Http/Requests/Auth/GroupRequest.php @@ -5,6 +5,7 @@ use App\Http\Requests\Request; use Illuminate\Foundation\Http\FormRequest; use Illuminate\Validation\Rules\In; + use function backpack_auth; class GroupRequest extends FormRequest @@ -32,7 +33,7 @@ public function rules() 'name' => 'required|min:5|max:255', 'type' => [ new In(['default', 'department', 'system']), - 'required' + 'required', ], 'description' => 'nullable', 'logo' => 'nullable|image|mimes:jpeg,png,jpg,gif,svg|max:10240', diff --git a/app/Http/Requests/Auth/LoginRequest.php b/app/Http/Requests/Auth/LoginRequest.php index e4afe07..c0fdeb2 100644 --- a/app/Http/Requests/Auth/LoginRequest.php +++ b/app/Http/Requests/Auth/LoginRequest.php @@ -12,7 +12,7 @@ public function rules() 'email' => 'required|email', 'password' => 'required', 'login_challenge' => 'required|string', - 'remember' => 'required|bool' + 'remember' => 'required|bool', ]; } } diff --git a/app/Http/Requests/Auth/RegisterRequest.php b/app/Http/Requests/Auth/RegisterRequest.php index b886a2c..7e0d19b 100644 --- a/app/Http/Requests/Auth/RegisterRequest.php +++ b/app/Http/Requests/Auth/RegisterRequest.php @@ -9,22 +9,21 @@ class RegisterRequest extends FormRequest /** * @var mixed */ - public function rules() { return [ - "username" => [ - "min:3", - "max:25", - "required", - "alpha_dash", - "unique:users,name", + 'username' => [ + 'min:3', + 'max:25', + 'required', + 'alpha_dash', + 'unique:users,name', ], - "email" => [ - "email", - "required", + 'email' => [ + 'email', + 'required', 'max:255', - "unique:users,email", + 'unique:users,email', ], 'password' => [ 'required', diff --git a/app/Http/Requests/Auth/UserRequest.php b/app/Http/Requests/Auth/UserRequest.php index 0a363f7..d909cf3 100644 --- a/app/Http/Requests/Auth/UserRequest.php +++ b/app/Http/Requests/Auth/UserRequest.php @@ -4,6 +4,7 @@ use App\Http\Requests\Request; use Illuminate\Foundation\Http\FormRequest; + use function backpack_auth; class UserRequest extends FormRequest diff --git a/app/Http/Requests/EmailVerificationRequest.php b/app/Http/Requests/EmailVerificationRequest.php index c3f58b8..90a557a 100644 --- a/app/Http/Requests/EmailVerificationRequest.php +++ b/app/Http/Requests/EmailVerificationRequest.php @@ -22,9 +22,10 @@ public function authorize(): bool if ($this->user === null) { return false; } - if (!hash_equals(sha1($this->user->getEmailForVerification()), (string) $this->route('hash'))) { + if (! hash_equals(sha1($this->user->getEmailForVerification()), (string) $this->route('hash'))) { return false; } + return true; } diff --git a/app/Http/Requests/ForgotPasswordRequest.php b/app/Http/Requests/ForgotPasswordRequest.php index e4c1cdf..789872f 100644 --- a/app/Http/Requests/ForgotPasswordRequest.php +++ b/app/Http/Requests/ForgotPasswordRequest.php @@ -9,7 +9,7 @@ class ForgotPasswordRequest extends FormRequest public function rules(): array { return [ - "email" => "email|required|exists:users,email" + 'email' => 'email|required|exists:users,email', ]; } } diff --git a/app/Http/Requests/GroupStoreRequest.php b/app/Http/Requests/GroupStoreRequest.php index 6f9bee5..a448d26 100644 --- a/app/Http/Requests/GroupStoreRequest.php +++ b/app/Http/Requests/GroupStoreRequest.php @@ -11,10 +11,10 @@ class GroupStoreRequest extends FormRequest public function rules(): array { return [ - "type" => [Rule::enum(GroupTypeEnum::class)], - "name" => "string|required|max:255", - "description" => "string|nullable", - "logo" => "string|nullable", + 'type' => [Rule::enum(GroupTypeEnum::class)], + 'name' => 'string|required|max:255', + 'description' => 'string|nullable', + 'logo' => 'string|nullable', ]; } } diff --git a/app/Http/Requests/GroupUpdateRequest.php b/app/Http/Requests/GroupUpdateRequest.php index c4057a4..7a45899 100644 --- a/app/Http/Requests/GroupUpdateRequest.php +++ b/app/Http/Requests/GroupUpdateRequest.php @@ -9,9 +9,9 @@ class GroupUpdateRequest extends FormRequest public function rules(): array { return [ - "name.*" => "string|required|max:255", - "description.*" => "string|nullable", - "logo" => "file|image|nullable|mimes:jpeg,png,jpg|max:2048", + 'name.*' => 'string|required|max:255', + 'description.*' => 'string|nullable', + 'logo' => 'file|image|nullable|mimes:jpeg,png,jpg|max:2048', ]; } } diff --git a/app/Http/Requests/GroupUserStoreRequest.php b/app/Http/Requests/GroupUserStoreRequest.php index f9566c4..986e42c 100644 --- a/app/Http/Requests/GroupUserStoreRequest.php +++ b/app/Http/Requests/GroupUserStoreRequest.php @@ -11,11 +11,11 @@ class GroupUserStoreRequest extends FormRequest public function rules(): array { return [ - "id" => "required_without:email|prohibits:email", - "email" => "email|required_without:id|exists:users,email|prohibits:id", - "level" => [ - Rule::enum(GroupUserLevel::class) - ] + 'id' => 'required_without:email|prohibits:email', + 'email' => 'email|required_without:id|exists:users,email|prohibits:id', + 'level' => [ + Rule::enum(GroupUserLevel::class), + ], ]; } } diff --git a/app/Http/Requests/Groups/GroupUpdateRequest.php b/app/Http/Requests/Groups/GroupUpdateRequest.php index 7e012ba..3466428 100644 --- a/app/Http/Requests/Groups/GroupUpdateRequest.php +++ b/app/Http/Requests/Groups/GroupUpdateRequest.php @@ -9,8 +9,8 @@ class GroupUpdateRequest extends FormRequest public function rules(): array { return [ - 'description' => ['nullable','string','max:10000'], - 'name' => ['nullable','string','max:255'], + 'description' => ['nullable', 'string', 'max:10000'], + 'name' => ['nullable', 'string', 'max:255'], ]; } diff --git a/app/Http/Requests/IntrospectionRequest.php b/app/Http/Requests/IntrospectionRequest.php index 0643233..453ce79 100644 --- a/app/Http/Requests/IntrospectionRequest.php +++ b/app/Http/Requests/IntrospectionRequest.php @@ -9,14 +9,14 @@ class IntrospectionRequest extends FormRequest { - private App|null $client = null; + private ?App $client = null; public function rules(): array { return [ - "client_id" => "required|string", - "scope" => "nullable|string", - "token" => "required|string", + 'client_id' => 'required|string', + 'scope' => 'nullable|string', + 'token' => 'required|string', ]; } @@ -34,6 +34,7 @@ public function authorize(): bool if (Hash::check($this->bearerToken(), $client->client_secret)) { return true; } + return false; } @@ -43,7 +44,8 @@ public function getApp() return $this->client; } - $this->client = App::firstWhere('client_id', "=", $this->post('client_id')); + $this->client = App::firstWhere('client_id', '=', $this->post('client_id')); + return $this->client; } } diff --git a/app/Http/Requests/PasswordResetRequest.php b/app/Http/Requests/PasswordResetRequest.php index 91d35d5..427bff4 100644 --- a/app/Http/Requests/PasswordResetRequest.php +++ b/app/Http/Requests/PasswordResetRequest.php @@ -14,7 +14,7 @@ public function rules(): array 'password' => [ 'required', 'confirmed', - \Illuminate\Validation\Rules\Password::min(8)->mixedCase()->numbers() + \Illuminate\Validation\Rules\Password::min(8)->mixedCase()->numbers(), ], ]; } diff --git a/app/Http/Requests/Profile/UpdateProfileRequest.php b/app/Http/Requests/Profile/UpdateProfileRequest.php index 11b8768..4a6bb45 100644 --- a/app/Http/Requests/Profile/UpdateProfileRequest.php +++ b/app/Http/Requests/Profile/UpdateProfileRequest.php @@ -10,17 +10,17 @@ class UpdateProfileRequest extends FormRequest public function rules(): array { return [ - "name" => [ - "min:3", - "max:25", - "required", - "alpha_dash", - "unique:users,name,".Auth::id(), + 'name' => [ + 'min:3', + 'max:25', + 'required', + 'alpha_dash', + 'unique:users,name,' . Auth::id(), ], - "email" => [ - "email", - "required", - "unique:users,email,".Auth::id(), + 'email' => [ + 'email', + 'required', + 'unique:users,email,' . Auth::id(), ], ]; } diff --git a/app/Http/Requests/UpdatePasswordRequest.php b/app/Http/Requests/UpdatePasswordRequest.php index dc678cf..add9901 100644 --- a/app/Http/Requests/UpdatePasswordRequest.php +++ b/app/Http/Requests/UpdatePasswordRequest.php @@ -9,13 +9,13 @@ class UpdatePasswordRequest extends FormRequest public function rules(): array { return [ - "current_password" => [ - "required", - "current_password", + 'current_password' => [ + 'required', + 'current_password', ], - "password" => [ - "required", - "confirmed", + 'password' => [ + 'required', + 'confirmed', \Illuminate\Validation\Rules\Password::min(8)->mixedCase()->numbers(), ], ]; diff --git a/app/Http/Requests/UserinfoRequest.php b/app/Http/Requests/UserinfoRequest.php index cba6055..1cc6e63 100644 --- a/app/Http/Requests/UserinfoRequest.php +++ b/app/Http/Requests/UserinfoRequest.php @@ -6,7 +6,5 @@ class UserinfoRequest extends FormRequest { - public function rules(): array - { - } + public function rules(): array {} } diff --git a/app/Http/Resources/V1/GroupCollection.php b/app/Http/Resources/V1/GroupCollection.php index d4f1a44..92b376e 100644 --- a/app/Http/Resources/V1/GroupCollection.php +++ b/app/Http/Resources/V1/GroupCollection.php @@ -9,7 +9,7 @@ class GroupCollection extends ResourceCollection { /** - * @param Request $request + * @param Request $request * @return array */ public function toArray($request) diff --git a/app/Http/Resources/V1/GroupResource.php b/app/Http/Resources/V1/GroupResource.php index f8fcc2b..e295656 100644 --- a/app/Http/Resources/V1/GroupResource.php +++ b/app/Http/Resources/V1/GroupResource.php @@ -10,7 +10,7 @@ class GroupResource extends JsonResource { /** - * @param Request $request + * @param Request $request * @return array */ public function toArray($request) diff --git a/app/Http/Resources/V1/GroupUserCollection.php b/app/Http/Resources/V1/GroupUserCollection.php index e92dd5a..139fa15 100644 --- a/app/Http/Resources/V1/GroupUserCollection.php +++ b/app/Http/Resources/V1/GroupUserCollection.php @@ -9,7 +9,7 @@ class GroupUserCollection extends ResourceCollection { /** - * @param Request $request + * @param Request $request * @return array */ public function toArray($request) diff --git a/app/Http/Resources/V1/LoginResource.php b/app/Http/Resources/V1/LoginResource.php index 810a94e..ded8820 100644 --- a/app/Http/Resources/V1/LoginResource.php +++ b/app/Http/Resources/V1/LoginResource.php @@ -15,7 +15,7 @@ public function __construct($link) } /** - * @param Request $request + * @param Request $request * @return array */ public function toArray($request) diff --git a/app/Http/Resources/V1/TokenResource.php b/app/Http/Resources/V1/TokenResource.php index 1a15434..5e79712 100644 --- a/app/Http/Resources/V1/TokenResource.php +++ b/app/Http/Resources/V1/TokenResource.php @@ -17,7 +17,7 @@ public function __construct($resource) } /** - * @param Request $request + * @param Request $request * @return array */ public function toArray($request) diff --git a/app/Http/Resources/V1/UserinfoResource.php b/app/Http/Resources/V1/UserinfoResource.php index dee500d..226d29e 100644 --- a/app/Http/Resources/V1/UserinfoResource.php +++ b/app/Http/Resources/V1/UserinfoResource.php @@ -32,7 +32,7 @@ public function toArray($request) if ($this->scopeCheck('email')) { $data['email'] = $this->email; - $data['email_verified'] = !is_null($this->email_verified_at); + $data['email_verified'] = ! is_null($this->email_verified_at); } if ($this->scopeCheck('profile')) { diff --git a/app/Jobs/CheckStaffGroupMembershipJob.php b/app/Jobs/CheckStaffGroupMembershipJob.php index fcb69b9..729a8b4 100644 --- a/app/Jobs/CheckStaffGroupMembershipJob.php +++ b/app/Jobs/CheckStaffGroupMembershipJob.php @@ -24,9 +24,7 @@ class CheckStaffGroupMembershipJob implements ShouldQueue use Queueable; use SerializesModels; - public function __construct(private User $user) - { - } + public function __construct(private User $user) {} public function handle(): void { diff --git a/app/Listeners/LogFailedLoginListener.php b/app/Listeners/LogFailedLoginListener.php index 514b697..0071f27 100644 --- a/app/Listeners/LogFailedLoginListener.php +++ b/app/Listeners/LogFailedLoginListener.php @@ -6,9 +6,7 @@ class LogFailedLoginListener { - public function __construct() - { - } + public function __construct() {} public function handle(Failed $event) { diff --git a/app/Listeners/LogUserAppLoginListener.php b/app/Listeners/LogUserAppLoginListener.php index 0aa921d..2ef5cfa 100644 --- a/app/Listeners/LogUserAppLoginListener.php +++ b/app/Listeners/LogUserAppLoginListener.php @@ -8,9 +8,7 @@ class LogUserAppLoginListener { - public function __construct() - { - } + public function __construct() {} public function handle(AppLoginEvent $event) { diff --git a/app/Listeners/LogUserLockoutListener.php b/app/Listeners/LogUserLockoutListener.php index 9be1bec..7a84b1b 100644 --- a/app/Listeners/LogUserLockoutListener.php +++ b/app/Listeners/LogUserLockoutListener.php @@ -6,9 +6,7 @@ class LogUserLockoutListener { - public function __construct() - { - } + public function __construct() {} public function handle(Lockout $event) { diff --git a/app/Listeners/LogUserLoginListener.php b/app/Listeners/LogUserLoginListener.php index 603e0ab..3fcace4 100644 --- a/app/Listeners/LogUserLoginListener.php +++ b/app/Listeners/LogUserLoginListener.php @@ -4,9 +4,7 @@ class LogUserLoginListener { - public function __construct() - { - } + public function __construct() {} public function handle($event) { diff --git a/app/Listeners/LogUserLogoutListener.php b/app/Listeners/LogUserLogoutListener.php index 3dbba18..623027f 100644 --- a/app/Listeners/LogUserLogoutListener.php +++ b/app/Listeners/LogUserLogoutListener.php @@ -6,9 +6,7 @@ class LogUserLogoutListener { - public function __construct() - { - } + public function __construct() {} public function handle(Logout $event) { diff --git a/app/Listeners/LogUserPasswordResetListener.php b/app/Listeners/LogUserPasswordResetListener.php index 37a9da9..ab26bc3 100644 --- a/app/Listeners/LogUserPasswordResetListener.php +++ b/app/Listeners/LogUserPasswordResetListener.php @@ -6,9 +6,7 @@ class LogUserPasswordResetListener { - public function __construct() - { - } + public function __construct() {} public function handle(PasswordReset $event) { diff --git a/app/Listeners/LogUserRegisteredListener.php b/app/Listeners/LogUserRegisteredListener.php index af1558a..00f087e 100644 --- a/app/Listeners/LogUserRegisteredListener.php +++ b/app/Listeners/LogUserRegisteredListener.php @@ -6,9 +6,7 @@ class LogUserRegisteredListener { - public function __construct() - { - } + public function __construct() {} public function handle(Registered $event) { diff --git a/app/Listeners/LogUserVerifiedListener.php b/app/Listeners/LogUserVerifiedListener.php index f1fdc15..e0fa139 100644 --- a/app/Listeners/LogUserVerifiedListener.php +++ b/app/Listeners/LogUserVerifiedListener.php @@ -6,9 +6,7 @@ class LogUserVerifiedListener { - public function __construct() - { - } + public function __construct() {} public function handle(Verified $event) { diff --git a/app/Models/App.php b/app/Models/App.php index 36b6bc5..226053c 100644 --- a/app/Models/App.php +++ b/app/Models/App.php @@ -7,9 +7,10 @@ class App extends Model { - protected $guarded = ["client_secret"]; + protected $guarded = ['client_secret']; + protected $casts = [ - "data" => "array", + 'data' => 'array', ]; public function owner(): BelongsTo diff --git a/app/Models/Group.php b/app/Models/Group.php index 8169401..e66ed79 100644 --- a/app/Models/Group.php +++ b/app/Models/Group.php @@ -25,6 +25,7 @@ * @property Carbon $updated_at * @property-read Collection|User[] $users * @property-read int|null $users_count + * * @method static Builder|Group newModelQuery() * @method static Builder|Group newQuery() * @method static Builder|Group query() @@ -33,6 +34,7 @@ * @method static Builder|Group whereLogo($value) * @method static Builder|Group whereName($value) * @method static Builder|Group whereUpdatedAt($value) + * * @mixin Eloquent */ class Group extends Model @@ -46,7 +48,7 @@ class Group extends Model protected $guarded = []; protected $casts = [ - "type" => GroupTypeEnum::class, + 'type' => GroupTypeEnum::class, ]; public function users() @@ -63,9 +65,9 @@ public function users() public function owner() { - return $this->hasOneThrough(User::class, GroupUser::class, "group_id", "id", "id", "user_id") + return $this->hasOneThrough(User::class, GroupUser::class, 'group_id', 'id', 'id', 'user_id') ->where('level', GroupUserLevel::Owner) - ->select(["name"]); + ->select(['name']); } public function apps() @@ -83,14 +85,14 @@ public function setNameAttribute($value) $this->attributes['name'] = $value; $prefix = ''; if ($this->parent) { - $prefix = $this->parent->name.' / '; + $prefix = $this->parent->name . ' / '; } - $this->attributes['slug'] = $prefix.Str::slug($value); + $this->attributes['slug'] = $prefix . Str::slug($value); } public function getLogoUrlAttribute() { - return (is_null($this->logo)) ? null : Storage::url('avatars/'.$this->logo); + return (is_null($this->logo)) ? null : Storage::url('avatars/' . $this->logo); } public function isMember(User $user): bool @@ -101,9 +103,10 @@ public function isMember(User $user): bool public function isAdmin(User $user) { $member = $this->users->find($user); - if (!$member) { + if (! $member) { return false; } + return $member->pivot->level == GroupUserLevel::Admin || $member->pivot->level == GroupUserLevel::Owner; } diff --git a/app/Models/GroupUser.php b/app/Models/GroupUser.php index 17748f6..21ce7c7 100644 --- a/app/Models/GroupUser.php +++ b/app/Models/GroupUser.php @@ -8,11 +8,13 @@ class GroupUser extends Pivot { public $incrementing = false; + protected $primaryKey = null; + public $timestamps = false; protected $casts = [ - 'level' => GroupUserLevel::class + 'level' => GroupUserLevel::class, ]; public function user() @@ -32,16 +34,16 @@ public function isOwner(): bool public function isAdmin(): bool { - return ($this->isOwner() || $this->level === GroupUserLevel::Admin); + return $this->isOwner() || $this->level === GroupUserLevel::Admin; } public function isModerator(): bool { - return ($this->isAdmin() || $this->level === GroupUserLevel::Moderator); + return $this->isAdmin() || $this->level === GroupUserLevel::Moderator; } public function isMember(): bool { - return ($this->isModerator() || $this->level === GroupUserLevel::Member); + return $this->isModerator() || $this->level === GroupUserLevel::Member; } } diff --git a/app/Models/Permission.php b/app/Models/Permission.php index f31050c..8e93140 100644 --- a/app/Models/Permission.php +++ b/app/Models/Permission.php @@ -2,6 +2,4 @@ namespace App\Models; -class Permission extends \Spatie\Permission\Models\Permission -{ -} +class Permission extends \Spatie\Permission\Models\Permission {} diff --git a/app/Models/Role.php b/app/Models/Role.php index 4d2355d..17ff0c2 100644 --- a/app/Models/Role.php +++ b/app/Models/Role.php @@ -2,6 +2,4 @@ namespace App\Models; -class Role extends \Spatie\Permission\Models\Role -{ -} +class Role extends \Spatie\Permission\Models\Role {} diff --git a/app/Models/User.php b/app/Models/User.php index ab33584..ee84cb7 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -24,16 +24,16 @@ use Spatie\Activitylog\Traits\LogsActivity; use Spatie\Permission\Traits\HasRoles; -class User extends Authenticatable implements MustVerifyEmail, FilamentUser +class User extends Authenticatable implements FilamentUser, MustVerifyEmail { - use HasFactory; - use Notifiable; - use HasRoles; + use CausesActivity; use HasApiTokens; + use HasFactory; use HasHashid; use HashidRouting; - use CausesActivity; + use HasRoles; use LogsActivity; + use Notifiable; /** * The attributes that are mass assignable. @@ -115,7 +115,7 @@ public function changeMail(string $newEmail) ->log('mail-change-mail'); Cache::put( - 'user:'.$this->hashid.':newEmail', + 'user:' . $this->hashid . ':newEmail', $newEmail, Carbon::now()->addMinutes(Config::get('auth.verification.expire', 60))); Notification::route('mail', $newEmail) @@ -146,12 +146,14 @@ public function resetTwoFactorAuth() public function appCan(string $scope) { $auth = Auth::guard('api'); + return in_array($scope, $auth->getScopes(), true); } public function permCheck(string $ability) { - $adminCheck = $this->can('admin.'.$ability); + $adminCheck = $this->can('admin.' . $ability); + return $adminCheck || $this->scopeCheck($ability); } @@ -162,7 +164,8 @@ public function scopeCheck(string $ability) } $sanctumCheck = $this->tokenCan($ability); $appCheck = $this->appCan($ability); - return ($sanctumCheck || $appCheck); + + return $sanctumCheck || $appCheck; } public function canAccessPanel($panel): bool diff --git a/app/Notifications/PasswordResetQueuedNotification.php b/app/Notifications/PasswordResetQueuedNotification.php index b96edbc..4db8e47 100644 --- a/app/Notifications/PasswordResetQueuedNotification.php +++ b/app/Notifications/PasswordResetQueuedNotification.php @@ -2,7 +2,6 @@ namespace App\Notifications; -use App\Models\User; use Illuminate\Auth\Notifications\ResetPassword; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; diff --git a/app/Notifications/UpdateEmailNotification.php b/app/Notifications/UpdateEmailNotification.php index 437c896..50074f5 100644 --- a/app/Notifications/UpdateEmailNotification.php +++ b/app/Notifications/UpdateEmailNotification.php @@ -15,9 +15,7 @@ class UpdateEmailNotification extends Notification implements ShouldQueue { use Queueable; - public function __construct(public $newEmail, public $hashId) - { - } + public function __construct(public $newEmail, public $hashId) {} public function via($notifiable): array { @@ -44,5 +42,4 @@ protected function verificationUrl(): string ] ); } - } diff --git a/app/Notifications/VerifyEmailQueuedNotification.php b/app/Notifications/VerifyEmailQueuedNotification.php index 75b81fd..ba049bb 100644 --- a/app/Notifications/VerifyEmailQueuedNotification.php +++ b/app/Notifications/VerifyEmailQueuedNotification.php @@ -2,7 +2,6 @@ namespace App\Notifications; -use App\Models\User; use Illuminate\Auth\Notifications\VerifyEmail; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; diff --git a/app/Observers/AppObserver.php b/app/Observers/AppObserver.php index 43f59f5..2f5fb9a 100644 --- a/app/Observers/AppObserver.php +++ b/app/Observers/AppObserver.php @@ -20,7 +20,7 @@ public function updated(App $app) { $app->data = \App\Services\Hydra\Models\App::find($app->client_id)->update($app->data); $app->client_id = $app->data['client_id']; - if (!empty($app->data['client_secret'])) { + if (! empty($app->data['client_secret'])) { $app->client_secret = Hash::make($app->data['client_secret']); } $app->saveQuietly(); diff --git a/app/Observers/GroupObserver.php b/app/Observers/GroupObserver.php index d417cdf..78fe9a6 100644 --- a/app/Observers/GroupObserver.php +++ b/app/Observers/GroupObserver.php @@ -20,14 +20,15 @@ public function created(Group $group) if ($group->type === GroupTypeEnum::Team && $group->parent->nextcloud_folder_id) { NextcloudService::createGroup($group->hashid); // Parent->name / Group->name - NextcloudService::setDisplayName($group->hashid, $group->parent->name.' / '.$group->name); + NextcloudService::setDisplayName($group->hashid, $group->parent->name . ' / ' . $group->name); // Add to parent group folder NextcloudService::addGroupToFolder($group->parent->nextcloud_folder_id, $group->hashid); + return; } if (Auth::user()) { $group->users()->attach(Auth::user(), [ - "level" => GroupUserLevel::Owner + 'level' => GroupUserLevel::Owner, ]); } } @@ -38,7 +39,7 @@ public function updated(Group $group): void return; } - if ($group->isDirty('nextcloud_folder_name') && !app()->runningUnitTests()) { + if ($group->isDirty('nextcloud_folder_name') && ! app()->runningUnitTests()) { // Update or create the folder via nextcloud if ($group->nextcloud_folder_id) { NextcloudService::renameFolder($group->nextcloud_folder_id, $group->nextcloud_folder_name); @@ -49,22 +50,22 @@ public function updated(Group $group): void $group->save(); NextcloudService::setDisplayName($group->hashid, $group->name); // Add all users to the group - $group->users->each(fn($user) => NextcloudService::addUserToGroup($group, $user)); + $group->users->each(fn ($user) => NextcloudService::addUserToGroup($group, $user)); // Set Admin & Owner to aclmanagers - $group->users->filter(fn($user) => in_array($user->pivot->level, + $group->users->filter(fn ($user) => in_array($user->pivot->level, [GroupUserLevel::Admin, GroupUserLevel::Owner])) - ->each(fn($user) => NextcloudService::setManageAcl($group, $user, true)); + ->each(fn ($user) => NextcloudService::setManageAcl($group, $user, true)); } } - if ($group->nextcloud_folder_id && $group->isDirty('name') && !app()->runningUnitTests()) { + if ($group->nextcloud_folder_id && $group->isDirty('name') && ! app()->runningUnitTests()) { // Update the display name of the group NextcloudService::setDisplayName($group->hashid, $group->name); } // Team update nextcloud dipslay name if ($group->type === GroupTypeEnum::Team && $group->isDirty('name') && $group->parent->nextcloud_folder_id) { - NextcloudService::setDisplayName($group->hashid, $group->parent->name.' / '.$group->name); + NextcloudService::setDisplayName($group->hashid, $group->parent->name . ' / ' . $group->name); } } diff --git a/app/Observers/GroupUserObserver.php b/app/Observers/GroupUserObserver.php index 1bfb27f..4f9800b 100644 --- a/app/Observers/GroupUserObserver.php +++ b/app/Observers/GroupUserObserver.php @@ -19,7 +19,7 @@ public function created(GroupUser $groupUser): void if (App::isLocal()) { return; } - if (($groupUser->group->nextcloud_folder_name || $groupUser->group->parent?->nextcloud_folder_name) && !app()->runningUnitTests()) { + if (($groupUser->group->nextcloud_folder_name || $groupUser->group->parent?->nextcloud_folder_name) && ! app()->runningUnitTests()) { NextcloudService::addUserToGroup($groupUser->group, $groupUser->user); $allowAclManagement = in_array($groupUser->level, [GroupUserLevel::Admin, GroupUserLevel::Owner]); if ($allowAclManagement && $groupUser->group->type !== GroupTypeEnum::Team) { @@ -33,7 +33,7 @@ public function updated(GroupUser $groupUser): void if (App::isLocal()) { return; } - if ($groupUser->group->nextcloud_folder_name && !app()->runningUnitTests()) { + if ($groupUser->group->nextcloud_folder_name && ! app()->runningUnitTests()) { if ($groupUser->isDirty('level')) { $allowAclManagement = in_array($groupUser->level, [GroupUserLevel::Admin, GroupUserLevel::Owner]); NextcloudService::setManageAcl($groupUser->group, $groupUser->user, $allowAclManagement); @@ -49,7 +49,7 @@ public function deleted(GroupUser $groupUser): void if (App::isLocal()) { return; } - if ($groupUser->group->nextcloud_folder_name && !app()->runningUnitTests()) { + if ($groupUser->group->nextcloud_folder_name && ! app()->runningUnitTests()) { NextcloudService::removeUserFromGroup($groupUser->group, $groupUser->user); if ($groupUser->group->type !== GroupTypeEnum::Team) { NextcloudService::setManageAcl($groupUser->group, $groupUser->user, false); diff --git a/app/Policies/GroupPolicy.php b/app/Policies/GroupPolicy.php index a6db896..c7b0043 100644 --- a/app/Policies/GroupPolicy.php +++ b/app/Policies/GroupPolicy.php @@ -20,15 +20,16 @@ class GroupPolicy */ public function viewAny(User $user): bool { - if (Auth::guard("admin")->check()) { + if (Auth::guard('admin')->check()) { return $user->can('admin.groups.view'); } - if (Auth::guard("web")->check()) { + if (Auth::guard('web')->check()) { return true; } - if (Auth::guard("api")->check()) { + if (Auth::guard('api')->check()) { return $user->scopeCheck('groups.read'); } + return true; } @@ -42,9 +43,11 @@ public function view(User $user, Group $group): Response if ($userPermission === false) { return Response::deny('Insufficient permissions, groups.read is missing'); } + return Response::allow(); } - return Response::deny("User is not a member of the group"); + + return Response::deny('User is not a member of the group'); } public function create(User $user): bool @@ -59,22 +62,24 @@ public function update(User $user, Group $group): bool } $userAdminInGroup = GroupUser::whereUserId($user->id) ->whereGroupId($group->id) - ->where(fn($q) => $q->whereLevel(GroupUserLevel::Admin)->orWhere('level', GroupUserLevel::Owner)) + ->where(fn ($q) => $q->whereLevel(GroupUserLevel::Admin)->orWhere('level', GroupUserLevel::Owner)) ->exists(); $userAdminInParentGroup = GroupUser::whereUserId($user->id) ->whereGroupId($group->parent_id) - ->where(fn($q) => $q->whereLevel(GroupUserLevel::Admin)->orWhere('level', GroupUserLevel::Owner)) + ->where(fn ($q) => $q->whereLevel(GroupUserLevel::Admin)->orWhere('level', GroupUserLevel::Owner)) ->exists(); - return ((Auth::guard("admin")->check() && $user->can('admin.groups.update')) || (($userAdminInGroup || $userAdminInParentGroup) && $user->scopeCheck('groups.update'))); + + return (Auth::guard('admin')->check() && $user->can('admin.groups.update')) || (($userAdminInGroup || $userAdminInParentGroup) && $user->scopeCheck('groups.update')); } public function delete(User $user, Group $group): bool { - if($group->type !== GroupTypeEnum::Team) { + if ($group->type !== GroupTypeEnum::Team) { return false; } $userOwnerInGroup = GroupUser::whereUserId($user->id)->whereGroupId($group->id)->whereLevel(GroupUserLevel::Owner)->exists(); $userOwnerInParentGroup = GroupUser::whereUserId($user->id)->whereGroupId($group->parent_id)->whereLevel(GroupUserLevel::Owner)->exists(); - return ((Auth::guard("admin")->check() && $user->can('admin.groups.delete')) || (($userOwnerInGroup || $userOwnerInParentGroup) && $user->scopeCheck('groups.delete'))); + + return (Auth::guard('admin')->check() && $user->can('admin.groups.delete')) || (($userOwnerInGroup || $userOwnerInParentGroup) && $user->scopeCheck('groups.delete')); } } diff --git a/app/Policies/GroupUserPolicy.php b/app/Policies/GroupUserPolicy.php index 6fef3cf..d1edc58 100644 --- a/app/Policies/GroupUserPolicy.php +++ b/app/Policies/GroupUserPolicy.php @@ -14,7 +14,7 @@ class GroupUserPolicy public function view(User $user, GroupUser $groupUser): bool { - return ($user->scopeCheck('groups.read') && ($groupUser->isMember() || $groupUser->group->parent?->isMember($user))); + return $user->scopeCheck('groups.read') && ($groupUser->isMember() || $groupUser->group->parent?->isMember($user)); } public function update(User $user, GroupUser $groupUser): bool @@ -30,7 +30,7 @@ public function create(User $user, GroupUser $groupUser): bool public function delete(User $user, GroupUser $groupUser): Response { if ($groupUser->level === GroupUserLevel::Owner) { - return Response::deny("Owners cannot be removed from group."); + return Response::deny('Owners cannot be removed from group.'); } if ($user->scopeCheck('groups.update') && $groupUser->isAdmin()) { return Response::allow(); diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index 03cd304..8e82069 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -21,9 +21,7 @@ class AppServiceProvider extends ServiceProvider * * @return void */ - public function register() - { - } + public function register() {} /** * Bootstrap any application services. @@ -33,7 +31,7 @@ public function register() public function boot() { RateLimiter::for('login', function (Request $request) { - return Limit::perMinute(5)->by($request->email.$request->ip()); + return Limit::perMinute(5)->by($request->email . $request->ip()); }); RateLimiter::for('register', function (Request $request) { @@ -54,7 +52,7 @@ public function boot() Http::macro('nextcloud', function () { return Http::baseUrl(config('services.nextcloud.baseUrl')) - ->withHeader('OCS-APIRequest', "true") + ->withHeader('OCS-APIRequest', 'true') ->withBasicAuth(config('services.nextcloud.username'), config('services.nextcloud.password')); }); diff --git a/app/Providers/AuthServiceProvider.php b/app/Providers/AuthServiceProvider.php index 46cf3e6..8183f85 100644 --- a/app/Providers/AuthServiceProvider.php +++ b/app/Providers/AuthServiceProvider.php @@ -8,7 +8,6 @@ use App\Policies\GroupUserPolicy; use App\Services\Auth\AdminAuth; use App\Services\Auth\ApiGuard; -use App\Services\Auth\TokenAuth; use Illuminate\Auth\Notifications\ResetPassword; use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider; use Illuminate\Support\Facades\Auth; @@ -38,7 +37,7 @@ public function boot() $this->registerPolicies(); Gate::before(function ($user, $ability) { - return ($user->hasRole('superadmin') && Str::startsWith($ability, "admin.")) ? true : null; + return ($user->hasRole('superadmin') && Str::startsWith($ability, 'admin.')) ? true : null; }); Auth::extend('admin', function ($app, $name, array $config) { diff --git a/app/Providers/RouteServiceProvider.php b/app/Providers/RouteServiceProvider.php index f12c8a6..e6c8a37 100644 --- a/app/Providers/RouteServiceProvider.php +++ b/app/Providers/RouteServiceProvider.php @@ -52,7 +52,7 @@ public function boot() ->group(base_path('routes/apps/portal.php')); Route::middleware([ - 'web', 'auth:staff', 'verified', 'auth.oidc', 'guardswitcher:staff', 'groupmember:staff' + 'web', 'auth:staff', 'verified', 'auth.oidc', 'guardswitcher:staff', 'groupmember:staff', ]) ->namespace($this->namespace) ->name('staff.') diff --git a/app/Providers/Socialite/SocialiteIdentityProvider.php b/app/Providers/Socialite/SocialiteIdentityProvider.php index 1912951..ab54ddd 100644 --- a/app/Providers/Socialite/SocialiteIdentityProvider.php +++ b/app/Providers/Socialite/SocialiteIdentityProvider.php @@ -13,11 +13,17 @@ class SocialiteIdentityProvider extends AbstractProvider { private mixed $issuer; + private mixed $userinfoEndpoint; + private mixed $tokenEndpoint; + private mixed $authorizationEndpoint; + private mixed $jwksUri; + private mixed $endSessionEndpoint; + private mixed $revocationEndpoint; /** @@ -51,6 +57,7 @@ public function getIdentityConfig() $this->jwksUri = $config['jwks_uri']; $this->endSessionEndpoint = $config['end_session_endpoint']; $this->revocationEndpoint = $config['revocation_endpoint']; + return $this; } @@ -69,7 +76,7 @@ protected function getUserByToken($token) $response = $this->getHttpClient()->get($this->getIdentityConfig()->userinfoEndpoint, [ 'headers' => [ 'cache-control' => 'no-cache', - 'Authorization' => 'Bearer '.$token, + 'Authorization' => 'Bearer ' . $token, 'Content-Type' => 'application/x-www-form-urlencoded', ], ]); @@ -99,31 +106,31 @@ public function putToken( ?Carbon $expiresIn ) { if ($token) { - Session::put($this->clientId.'.token.value', $token); - Session::put($this->clientId.'.token.expiry', $expiresIn); - Session::put($this->clientId.'.refreshToken', $refreshToken); + Session::put($this->clientId . '.token.value', $token); + Session::put($this->clientId . '.token.expiry', $expiresIn); + Session::put($this->clientId . '.refreshToken', $refreshToken); } } public function clearToken(): void { - Session::forget($this->clientId.'.token.value'); - Session::forget($this->clientId.'.token.expiry'); - Session::forget($this->clientId.'.refreshToken'); + Session::forget($this->clientId . '.token.value'); + Session::forget($this->clientId . '.token.expiry'); + Session::forget($this->clientId . '.refreshToken'); } - public function getToken(): string|null + public function getToken(): ?string { - return Session::get($this->clientId.'.token.value'); + return Session::get($this->clientId . '.token.value'); } - public function getRefreshToken(): string|null + public function getRefreshToken(): ?string { - return Session::get($this->clientId.'.refreshToken'); + return Session::get($this->clientId . '.refreshToken'); } - public function getExpiresIn(): Carbon|null + public function getExpiresIn(): ?Carbon { - return Session::get($this->clientId.'.token.expiry'); + return Session::get($this->clientId . '.token.expiry'); } } diff --git a/app/Services/Auth/AdminAuth.php b/app/Services/Auth/AdminAuth.php index 59b1714..c3cd017 100644 --- a/app/Services/Auth/AdminAuth.php +++ b/app/Services/Auth/AdminAuth.php @@ -28,7 +28,7 @@ public function __construct(UserProvider $provider) public function guest() { - return !$this->check(); + return ! $this->check(); } public function check() @@ -52,7 +52,7 @@ public function user() public function validate(array $credentials = []): bool { - if (!$cookie = Cookie::get('jwt')) { + if (! $cookie = Cookie::get('jwt')) { return false; } $signingKey = $this->getSigningKey(); @@ -65,20 +65,21 @@ protected function getSigningKey() } $response = Http::get(config('services.hydra.public.url')); - if($response->failed()) { - Log::error('Hydra\'s JWK Endpoint is not reachable Response Code: '.$response->status()); + if ($response->failed()) { + Log::error('Hydra\'s JWK Endpoint is not reachable Response Code: ' . $response->status()); abort('500', 'We\'re unable to reach the Authentication Server. Please try again later.'); } - if (!$body = json_decode($response->body())) { - Log::error('Unable to decode body of jwt update response'.$response->body()); + if (! $body = json_decode($response->body())) { + Log::error('Unable to decode body of jwt update response' . $response->body()); abort('500', 'We\'re unable to reach the Authentication Server. Please try again later.'); } - if (!$key = $body->keys[0]) { + if (! $key = $body->keys[0]) { abort('500', 'No keys available to verify your session.'); } if (Cache::set('jwt_publickey', $key, '1d')) { Log::info('Updated id_token jwt public key successfully.'); } + return $key; } diff --git a/app/Services/Auth/ApiGuard.php b/app/Services/Auth/ApiGuard.php index b82873a..b391d1b 100644 --- a/app/Services/Auth/ApiGuard.php +++ b/app/Services/Auth/ApiGuard.php @@ -9,32 +9,36 @@ class ApiGuard extends TokenGuard { private array $scopes = []; + private array $audiences = []; - private string $client_id = ""; + private string $client_id = ''; + + private string $exp = ''; + + private string $iat = ''; - private string $exp = ""; + private string $nbf = ''; - private string $iat = ""; + private string $iss = ''; - private string $nbf = ""; - private string $iss = ""; - private string $token_type = ""; - private string $token_use = ""; + private string $token_type = ''; + + private string $token_use = ''; public function user() { // If we've already retrieved the user for the current request we can just // return it back immediately. We do not want to fetch the user data on // every call to this method because that would be tremendously slow. - if (!is_null($this->user)) { + if (! is_null($this->user)) { return $this->user; } $user = null; $token = $this->getTokenForRequest(); - if (!empty($token)) { + if (! empty($token)) { $hydra = new Client(); $response = $hydra->getToken($token); @@ -47,7 +51,7 @@ public function user() $this->iss = $response['iss']; $this->token_type = $response['token_type']; $this->token_use = $response['token_use']; - $this->scopes = explode(" ", $response['scope']); + $this->scopes = explode(' ', $response['scope']); $user = $this->provider->retrieveByCredentials([ 'id' => Hashids::connection('user')->decode($response['sub']), ]); @@ -65,7 +69,8 @@ public function validate(array $credentials = []) $hydra = new Client(); $response = $hydra->getToken($credentials[$this->inputKey]); - return $response["active"] === true; + + return $response['active'] === true; } public function getScopes() diff --git a/app/Services/Hydra/Admin.php b/app/Services/Hydra/Admin.php index b2d33e3..853d68e 100644 --- a/app/Services/Hydra/Admin.php +++ b/app/Services/Hydra/Admin.php @@ -7,12 +7,13 @@ class Admin { private $url; + protected $http; public function __construct() { $this->url = config('services.hydra.admin'); - $this->http = Http::baseUrl($this->url."/admin")->acceptJson(); + $this->http = Http::baseUrl($this->url . '/admin')->acceptJson(); } public function apps() @@ -30,7 +31,7 @@ public function getRequest(string $path, array $query = []): array public function postRequest(string $path, array $body): array { - return $this->http->post($path,$body)->json(); + return $this->http->post($path, $body)->json(); } public function deleteRequest(string $path, array $body = []): bool diff --git a/app/Services/Hydra/Client.php b/app/Services/Hydra/Client.php index d439415..3d4570c 100644 --- a/app/Services/Hydra/Client.php +++ b/app/Services/Hydra/Client.php @@ -32,7 +32,7 @@ public function getLoginRequest(string $loginChallenge) public function getScopes() { - return Http::hydraPublic()->get("/.well-known/openid-configuration")->json('scopes_supported'); + return Http::hydraPublic()->get('/.well-known/openid-configuration')->json('scopes_supported'); } /** @@ -40,13 +40,14 @@ public function getScopes() * * @param string $login_challenge * @return Response + * * @throws JsonException */ public function acceptLogin( string $subject, string $login_challenge, - int|null $remember_seconds = 0, - array|null $loginRequest = null + ?int $remember_seconds = 0, + ?array $loginRequest = null ): string { $hydra = new Client(); // If $loginRequest is not supplied, refetch. @@ -66,15 +67,15 @@ public function acceptLogin( event(new AppLoginEvent($loginRequest['client']['client_id'], $subject)); // Throw error on missing redirect - if (!isset($hydraResponse["redirect_to"])) { - throw ValidationException::withMessages(['general' => $hydraResponse['error_description'] ?? "Unknown error"]); + if (! isset($hydraResponse['redirect_to'])) { + throw ValidationException::withMessages(['general' => $hydraResponse['error_description'] ?? 'Unknown error']); } // Return redirect url given in response return $hydraResponse['redirect_to']; } - public function acceptLoginRequest(string $userId, string $loginChallenge, int|null $remember = 0) + public function acceptLoginRequest(string $userId, string $loginChallenge, ?int $remember = 0) { try { $loginRequestBody = ['subject' => $userId]; @@ -82,7 +83,8 @@ public function acceptLoginRequest(string $userId, string $loginChallenge, int|n $loginRequestBody['remember'] = ($remember !== 0); $loginRequestBody['remember_for'] = $remember; } - return Http::hydraAdmin()->put('/admin/oauth2/auth/requests/login/accept?challenge='.$loginChallenge, $loginRequestBody)->json(); + + return Http::hydraAdmin()->put('/admin/oauth2/auth/requests/login/accept?challenge=' . $loginChallenge, $loginRequestBody)->json(); } catch (Exception $e) { if ($e->getCode() === 404) { @@ -104,7 +106,7 @@ public function acceptConsentRequest(array $consentChallenge, User $user) if (in_array('email', $consentChallenge['requested_scope'])) { $requestData['session']['id_token']['email'] = $user->email; - $requestData['session']['id_token']['email_verified'] = !is_null($user->email_verified_at); + $requestData['session']['id_token']['email_verified'] = ! is_null($user->email_verified_at); } if (in_array('profile', $consentChallenge['requested_scope'])) { $requestData['session']['id_token']['name'] = $user->name; @@ -114,7 +116,7 @@ public function acceptConsentRequest(array $consentChallenge, User $user) $requestData['session']['id_token']['groups'] = $user->groups->pluck('hashid'); } - return Http::hydraAdmin()->put('/admin/oauth2/auth/requests/consent/accept?challenge='.$consentChallenge['challenge'], + return Http::hydraAdmin()->put('/admin/oauth2/auth/requests/consent/accept?challenge=' . $consentChallenge['challenge'], $requestData)->json(); } catch (Exception $e) { if ($e->getCode() === 404) { @@ -134,13 +136,14 @@ public function rejectConsentRequest( ) { try { $requestData = [ - "error" => $errorCode, - "error_description" => $errorDescription, - "error_hint" => $errorHint, - "error_debug" => $errorDebug, - "status_code" => $statusCode, + 'error' => $errorCode, + 'error_description' => $errorDescription, + 'error_hint' => $errorHint, + 'error_debug' => $errorDebug, + 'status_code' => $statusCode, ]; - return Http::hydraAdmin()->put('/admin/oauth2/auth/requests/consent/reject?challenge='.$consentChallenge['challenge'], + + return Http::hydraAdmin()->put('/admin/oauth2/auth/requests/consent/reject?challenge=' . $consentChallenge['challenge'], $requestData)->json(); } catch (Exception $e) { if ($e->getCode() === 404) { @@ -184,7 +187,7 @@ public function acceptLogoutRequest(string $logoutChallenge) { try { return Http::hydraAdmin()->put( - '/admin/oauth2/auth/requests/logout/accept?challenge='.$logoutChallenge + '/admin/oauth2/auth/requests/logout/accept?challenge=' . $logoutChallenge )->json(); } catch (Exception $e) { if ($e->getCode() === 404) { @@ -200,7 +203,7 @@ public function invalidateAllSessions(string $subject) try { return Http::hydraAdmin()->delete('/admin/oauth2/auth/sessions/login', [ 'query' => [ - "subject" => $subject, + 'subject' => $subject, ], ])->successful(); } catch (Exception $e) { diff --git a/app/Services/Hydra/Models/App.php b/app/Services/Hydra/Models/App.php index 1109698..2b2b3ba 100644 --- a/app/Services/Hydra/Models/App.php +++ b/app/Services/Hydra/Models/App.php @@ -6,45 +6,83 @@ class App extends Admin { - public string $client_name = ""; - public string $client_id = ""; - public string|null $client_secret = null; + public string $client_name = ''; + + public string $client_id = ''; + + public ?string $client_secret = null; + public array $allowed_cors_origins = []; + public array $audience = []; + public bool $backchannel_logout_session_required = false; - public string $backchannel_logout_uri = ""; - public string $client_uri = ""; + + public string $backchannel_logout_uri = ''; + + public string $client_uri = ''; + public array $contacts = []; + public bool $frontchannel_logout_session_required = false; - public string $frontchannel_logout_uri = ""; - public array $grant_types = ["authorization_code", "refresh_token"]; - public string $jwks_uri = ""; - public string $logo_uri = ""; + + public string $frontchannel_logout_uri = ''; + + public array $grant_types = ['authorization_code', 'refresh_token']; + + public string $jwks_uri = ''; + + public string $logo_uri = ''; + public array $metadata = []; - public string $owner = ""; - public string $policy_uri = ""; + + public string $owner = ''; + + public string $policy_uri = ''; + public array $post_logout_redirect_uris = []; + public array $redirect_uris = []; - public string $request_object_signing_alg = "RS256"; + + public string $request_object_signing_alg = 'RS256'; + public array $request_uris = []; - public array $response_types = ["code"]; + + public array $response_types = ['code']; + public array $scope = ['openid']; - public string $sector_identifier_uri = ""; - public string $subject_type = "public"; - public string $token_endpoint_auth_method = "none"; - public string $token_endpoint_auth_signing_alg = ""; - public string $tos_uri = ""; - public string $userinfo_signed_response_alg = ""; - public string $authorization_code_grant_access_token_lifespan = ""; - public string $authorization_code_grant_id_token_lifespan = ""; - public string $authorization_code_grant_refresh_token_lifespan = ""; - public string $client_credentials_grant_access_token_lifespan = ""; - public string $implicit_grant_access_token_lifespan = ""; - public string $implicit_grant_id_token_lifespan = ""; - public string $jwt_bearer_grant_access_token_lifespan = ""; - public string $refresh_token_grant_access_token_lifespan = ""; - public string $refresh_token_grant_id_token_lifespan = ""; - public string $refresh_token_grant_refresh_token_lifespan = ""; + + public string $sector_identifier_uri = ''; + + public string $subject_type = 'public'; + + public string $token_endpoint_auth_method = 'none'; + + public string $token_endpoint_auth_signing_alg = ''; + + public string $tos_uri = ''; + + public string $userinfo_signed_response_alg = ''; + + public string $authorization_code_grant_access_token_lifespan = ''; + + public string $authorization_code_grant_id_token_lifespan = ''; + + public string $authorization_code_grant_refresh_token_lifespan = ''; + + public string $client_credentials_grant_access_token_lifespan = ''; + + public string $implicit_grant_access_token_lifespan = ''; + + public string $implicit_grant_id_token_lifespan = ''; + + public string $jwt_bearer_grant_access_token_lifespan = ''; + + public string $refresh_token_grant_access_token_lifespan = ''; + + public string $refresh_token_grant_id_token_lifespan = ''; + + public string $refresh_token_grant_refresh_token_lifespan = ''; public static function find(string $id) { @@ -53,101 +91,104 @@ public static function find(string $id) private function load(string $id): App { - $data = $this->getRequest("/clients/".$id); + $data = $this->getRequest('/clients/' . $id); $this->fill($data); + return $this; } public function create(array $attributes = []) { $this->fill($attributes); - $data = $this->postRequest("/clients", $this->formPayload()); + $data = $this->postRequest('/clients', $this->formPayload()); $this->fill($data); + return $this; } public function delete(): bool { - return $this->deleteRequest("/clients/" . $this->client_id); + return $this->deleteRequest('/clients/' . $this->client_id); } public function get(): array { - $data = $this->getRequest("/clients/" . $this->client_id); + $data = $this->getRequest('/clients/' . $this->client_id); $this->fill($data); + return $data; } public function update(array $attributes = []): array { $this->fill($attributes); - $data = $this->putRequest("/clients/" . $this->client_id, $this->formPayload()); + $data = $this->putRequest('/clients/' . $this->client_id, $this->formPayload()); $this->fill($data); + return $data; } public function payload(): array { return [ - "client_name" => $this->client_name, - "client_secret" => $this->client_secret, - "allowed_cors_origins" => $this->allowed_cors_origins, - "audience" => $this->audience, - "backchannel_logout_session_required" => $this->backchannel_logout_session_required, - "backchannel_logout_uri" => $this->backchannel_logout_uri, - "client_uri" => $this->client_uri, - "contacts" => $this->contacts, - "frontchannel_logout_session_required" => $this->frontchannel_logout_session_required, - "frontchannel_logout_uri" => $this->frontchannel_logout_uri, - "grant_types" => $this->grant_types, - "jwks_uri" => $this->jwks_uri, - "logo_uri" => $this->logo_uri, - "owner" => $this->owner, - "policy_uri" => $this->policy_uri, - "post_logout_redirect_uris" => $this->post_logout_redirect_uris, - "redirect_uris" => $this->redirect_uris, - "request_object_signing_alg" => $this->request_object_signing_alg, - "request_uris" => $this->request_uris, - "response_types" => $this->response_types, - "scope" => implode(" ", $this->scope), - "sector_identifier_uri" => $this->sector_identifier_uri, - "subject_type" => $this->subject_type, - "token_endpoint_auth_method" => $this->token_endpoint_auth_method, - "token_endpoint_auth_signing_alg" => $this->token_endpoint_auth_signing_alg, - "tos_uri" => $this->tos_uri, - "userinfo_signed_response_alg" => $this->userinfo_signed_response_alg, + 'client_name' => $this->client_name, + 'client_secret' => $this->client_secret, + 'allowed_cors_origins' => $this->allowed_cors_origins, + 'audience' => $this->audience, + 'backchannel_logout_session_required' => $this->backchannel_logout_session_required, + 'backchannel_logout_uri' => $this->backchannel_logout_uri, + 'client_uri' => $this->client_uri, + 'contacts' => $this->contacts, + 'frontchannel_logout_session_required' => $this->frontchannel_logout_session_required, + 'frontchannel_logout_uri' => $this->frontchannel_logout_uri, + 'grant_types' => $this->grant_types, + 'jwks_uri' => $this->jwks_uri, + 'logo_uri' => $this->logo_uri, + 'owner' => $this->owner, + 'policy_uri' => $this->policy_uri, + 'post_logout_redirect_uris' => $this->post_logout_redirect_uris, + 'redirect_uris' => $this->redirect_uris, + 'request_object_signing_alg' => $this->request_object_signing_alg, + 'request_uris' => $this->request_uris, + 'response_types' => $this->response_types, + 'scope' => implode(' ', $this->scope), + 'sector_identifier_uri' => $this->sector_identifier_uri, + 'subject_type' => $this->subject_type, + 'token_endpoint_auth_method' => $this->token_endpoint_auth_method, + 'token_endpoint_auth_signing_alg' => $this->token_endpoint_auth_signing_alg, + 'tos_uri' => $this->tos_uri, + 'userinfo_signed_response_alg' => $this->userinfo_signed_response_alg, // Lifespans - "authorization_code_grant_access_token_lifespan" => $this->authorization_code_grant_access_token_lifespan, - "authorization_code_grant_id_token_lifespan" => $this->authorization_code_grant_id_token_lifespan, - "authorization_code_grant_refresh_token_lifespan" => $this->authorization_code_grant_refresh_token_lifespan, - "client_credentials_grant_access_token_lifespan" => $this->client_credentials_grant_access_token_lifespan, - "implicit_grant_access_token_lifespan" => $this->implicit_grant_access_token_lifespan, - "implicit_grant_id_token_lifespan" => $this->implicit_grant_id_token_lifespan, - "jwt_bearer_grant_access_token_lifespan" => $this->jwt_bearer_grant_access_token_lifespan, - "refresh_token_grant_access_token_lifespan" => $this->refresh_token_grant_access_token_lifespan, - "refresh_token_grant_id_token_lifespan" => $this->refresh_token_grant_id_token_lifespan, - "refresh_token_grant_refresh_token_lifespan" => $this->refresh_token_grant_refresh_token_lifespan, + 'authorization_code_grant_access_token_lifespan' => $this->authorization_code_grant_access_token_lifespan, + 'authorization_code_grant_id_token_lifespan' => $this->authorization_code_grant_id_token_lifespan, + 'authorization_code_grant_refresh_token_lifespan' => $this->authorization_code_grant_refresh_token_lifespan, + 'client_credentials_grant_access_token_lifespan' => $this->client_credentials_grant_access_token_lifespan, + 'implicit_grant_access_token_lifespan' => $this->implicit_grant_access_token_lifespan, + 'implicit_grant_id_token_lifespan' => $this->implicit_grant_id_token_lifespan, + 'jwt_bearer_grant_access_token_lifespan' => $this->jwt_bearer_grant_access_token_lifespan, + 'refresh_token_grant_access_token_lifespan' => $this->refresh_token_grant_access_token_lifespan, + 'refresh_token_grant_id_token_lifespan' => $this->refresh_token_grant_id_token_lifespan, + 'refresh_token_grant_refresh_token_lifespan' => $this->refresh_token_grant_refresh_token_lifespan, ]; } public function formPayload() { - return collect($this->payload())->reject(fn($v) => empty($v))->toArray(); + return collect($this->payload())->reject(fn ($v) => empty($v))->toArray(); } - public function fill(array $attributes): void { collect($attributes)->each(function ($value, $key) { if ($value !== null) { - if ($key === "scope") { - if (!is_array($value)) { - $this->$key = explode(" ", $value); + if ($key === 'scope') { + if (! is_array($value)) { + $this->$key = explode(' ', $value); } else { $this->$key = $value; } - } elseif ($key === "metadata") { - if (!is_array($value)) { + } elseif ($key === 'metadata') { + if (! is_array($value)) { $this->$key = json_decode($value, true, 512, JSON_THROW_ON_ERROR); } else { $this->$key = $value; @@ -162,46 +203,46 @@ public function fill(array $attributes): void public function toArray(): array { return [ - "client_id" => $this->client_id, - "client_name" => $this->client_name, - "client_secret" => $this->client_secret, - "allowed_cors_origins" => $this->allowed_cors_origins, - "audience" => $this->audience, - "backchannel_logout_session_required" => $this->backchannel_logout_session_required, - "backchannel_logout_uri" => $this->backchannel_logout_uri, - "client_uri" => $this->client_uri, - "contacts" => $this->contacts, - "frontchannel_logout_session_required" => $this->frontchannel_logout_session_required, - "frontchannel_logout_uri" => $this->frontchannel_logout_uri, - "grant_types" => $this->grant_types, - "jwks_uri" => $this->jwks_uri, - "logo_uri" => $this->logo_uri, - "metadata" => $this->metadata, - "owner" => $this->owner, - "policy_uri" => $this->policy_uri, - "post_logout_redirect_uris" => $this->post_logout_redirect_uris, - "redirect_uris" => $this->redirect_uris, - "request_object_signing_alg" => $this->request_object_signing_alg, - "request_uris" => $this->request_uris, - "response_types" => $this->response_types, - "scope" => $this->scope, - "sector_identifier_uri" => $this->sector_identifier_uri, - "subject_type" => $this->subject_type, - "token_endpoint_auth_method" => $this->token_endpoint_auth_method, - "token_endpoint_auth_signing_alg" => $this->token_endpoint_auth_signing_alg, - "tos_uri" => $this->tos_uri, - "userinfo_signed_response_alg" => $this->userinfo_signed_response_alg, + 'client_id' => $this->client_id, + 'client_name' => $this->client_name, + 'client_secret' => $this->client_secret, + 'allowed_cors_origins' => $this->allowed_cors_origins, + 'audience' => $this->audience, + 'backchannel_logout_session_required' => $this->backchannel_logout_session_required, + 'backchannel_logout_uri' => $this->backchannel_logout_uri, + 'client_uri' => $this->client_uri, + 'contacts' => $this->contacts, + 'frontchannel_logout_session_required' => $this->frontchannel_logout_session_required, + 'frontchannel_logout_uri' => $this->frontchannel_logout_uri, + 'grant_types' => $this->grant_types, + 'jwks_uri' => $this->jwks_uri, + 'logo_uri' => $this->logo_uri, + 'metadata' => $this->metadata, + 'owner' => $this->owner, + 'policy_uri' => $this->policy_uri, + 'post_logout_redirect_uris' => $this->post_logout_redirect_uris, + 'redirect_uris' => $this->redirect_uris, + 'request_object_signing_alg' => $this->request_object_signing_alg, + 'request_uris' => $this->request_uris, + 'response_types' => $this->response_types, + 'scope' => $this->scope, + 'sector_identifier_uri' => $this->sector_identifier_uri, + 'subject_type' => $this->subject_type, + 'token_endpoint_auth_method' => $this->token_endpoint_auth_method, + 'token_endpoint_auth_signing_alg' => $this->token_endpoint_auth_signing_alg, + 'tos_uri' => $this->tos_uri, + 'userinfo_signed_response_alg' => $this->userinfo_signed_response_alg, // Lifespans - "authorization_code_grant_access_token_lifespan" => $this->authorization_code_grant_access_token_lifespan, - "authorization_code_grant_id_token_lifespan" => $this->authorization_code_grant_id_token_lifespan, - "authorization_code_grant_refresh_token_lifespan" => $this->authorization_code_grant_refresh_token_lifespan, - "client_credentials_grant_access_token_lifespan" => $this->client_credentials_grant_access_token_lifespan, - "implicit_grant_access_token_lifespan" => $this->implicit_grant_access_token_lifespan, - "implicit_grant_id_token_lifespan" => $this->implicit_grant_id_token_lifespan, - "jwt_bearer_grant_access_token_lifespan" => $this->jwt_bearer_grant_access_token_lifespan, - "refresh_token_grant_access_token_lifespan" => $this->refresh_token_grant_access_token_lifespan, - "refresh_token_grant_id_token_lifespan" => $this->refresh_token_grant_id_token_lifespan, - "refresh_token_grant_refresh_token_lifespan" => $this->refresh_token_grant_refresh_token_lifespan, + 'authorization_code_grant_access_token_lifespan' => $this->authorization_code_grant_access_token_lifespan, + 'authorization_code_grant_id_token_lifespan' => $this->authorization_code_grant_id_token_lifespan, + 'authorization_code_grant_refresh_token_lifespan' => $this->authorization_code_grant_refresh_token_lifespan, + 'client_credentials_grant_access_token_lifespan' => $this->client_credentials_grant_access_token_lifespan, + 'implicit_grant_access_token_lifespan' => $this->implicit_grant_access_token_lifespan, + 'implicit_grant_id_token_lifespan' => $this->implicit_grant_id_token_lifespan, + 'jwt_bearer_grant_access_token_lifespan' => $this->jwt_bearer_grant_access_token_lifespan, + 'refresh_token_grant_access_token_lifespan' => $this->refresh_token_grant_access_token_lifespan, + 'refresh_token_grant_id_token_lifespan' => $this->refresh_token_grant_id_token_lifespan, + 'refresh_token_grant_refresh_token_lifespan' => $this->refresh_token_grant_refresh_token_lifespan, ]; } } diff --git a/app/Services/NextcloudService.php b/app/Services/NextcloudService.php index 7635ce2..a5e01bd 100644 --- a/app/Services/NextcloudService.php +++ b/app/Services/NextcloudService.php @@ -10,9 +10,10 @@ class NextcloudService { public static function createGroup($groupId) { - Http::nextcloud()->post("/ocs/v1.php/cloud/groups", [ - "groupid" => $groupId, + Http::nextcloud()->post('/ocs/v1.php/cloud/groups', [ + 'groupid' => $groupId, ])->throw(); + return $groupId; } @@ -32,7 +33,7 @@ public static function setDisplayName($groupId, $displayName) public static function checkUserExists($userId): bool { - $res = Http::nextcloud()->get("ocs/v2.php/cloud/users/".$userId)->throwIfServerError(); + $res = Http::nextcloud()->get('ocs/v2.php/cloud/users/' . $userId)->throwIfServerError(); if ($res->notFound()) { return false; } @@ -45,17 +46,17 @@ public static function checkUserExists($userId): bool public static function addUserToGroup(Group $group, User $user) { // Check user - if (!self::checkUserExists($user->hashid)) { + if (! self::checkUserExists($user->hashid)) { self::createUser($user); // Create user also adds groups so we don't need to add them here } Http::nextcloud()->post("ocs/v2.php/cloud/users/{$user->hashid}/groups", [ - "groupid" => $group->hashid, + 'groupid' => $group->hashid, ])->throw(); } public static function removeUserFromGroup(Group $group, User $user) { - if (!self::checkUserExists($user->hashid)) { + if (! self::checkUserExists($user->hashid)) { return; } Http::nextcloud()->delete("ocs/v2.php/cloud/users/{$user->hashid}/groups?groupid={$group->hashid}")->throw(); @@ -72,18 +73,19 @@ public static function setManageAcl(Group $group, User $user, bool $allow): void public static function getUsers() { - $res = Http::nextcloud()->get("ocs/v2.php/cloud/users", [ + $res = Http::nextcloud()->get('ocs/v2.php/cloud/users', [ 'offset' => 0, 'limit' => 1000, ])->throw(); // Parse xml $xml = simplexml_load_string($res->body()); + return (array) $xml->data->users->element; } public static function createUser(User $user) { - Http::nextcloud()->post("ocs/v2.php/cloud/users", [ + Http::nextcloud()->post('ocs/v2.php/cloud/users', [ 'displayName' => $user->name, 'email' => $user->email, 'groups' => $user->groups()->whereNotNull('nextcloud_folder_name')->get()->pluck('hashid')->toArray(), @@ -97,19 +99,20 @@ public static function createUser(User $user) public static function createFolder(string $folderName, string $groupId): int { - $response = Http::nextcloud()->post("apps/groupfolders/folders", [ - "mountpoint" => $folderName, + $response = Http::nextcloud()->post('apps/groupfolders/folders', [ + 'mountpoint' => $folderName, ])->throw(); $xml = simplexml_load_string($response->body()); // enable acl for group (we have that enabled for all groups) Http::nextcloud()->post("apps/groupfolders/folders/{$xml->data->id}/acl", [ - "acl" => 1, + 'acl' => 1, ])->throw(); // add group to folder apps/groupfolders/folders/$folderId/groups/$groupId Http::nextcloud()->post("apps/groupfolders/folders/{$xml->data->id}/groups", [ - "group" => $groupId, + 'group' => $groupId, ])->throw(); + return (int) $xml->data->id; } @@ -117,15 +120,14 @@ public static function createFolder(string $folderName, string $groupId): int public static function addGroupToFolder($folderId, $groupId) { Http::nextcloud()->post("apps/groupfolders/folders/{$folderId}/groups", [ - "group" => $groupId, + 'group' => $groupId, ])->throw(); } public static function renameFolder(int $folderId, string $folderName): void { Http::nextcloud()->post("apps/groupfolders/folders/{$folderId}/mountpoint", [ - "mountpoint" => $folderName, + 'mountpoint' => $folderName, ])->throw(); } - } diff --git a/app/Services/OpenIDService.php b/app/Services/OpenIDService.php index eb6f1bc..a218a49 100644 --- a/app/Services/OpenIDService.php +++ b/app/Services/OpenIDService.php @@ -10,7 +10,6 @@ class OpenIDService { - public function setupOIDC(Request $request, $systemName): GenericProvider { $config = Cache::remember('identity_config', now()->addDay(), function () { @@ -30,7 +29,7 @@ public function setupOIDC(Request $request, $systemName): GenericProvider 'urlResourceOwnerDetails' => $config['userinfo_endpoint'], 'accessTokenMethod' => AbstractProvider::METHOD_POST, 'scopeSeparator' => ' ', - 'scopes' => explode(" ", config('services.apps')[$systemName]['scopes']) + 'scopes' => explode(' ', config('services.apps')[$systemName]['scopes']), ]); } } diff --git a/app/Services/YubicoService.php b/app/Services/YubicoService.php index 638307e..732308e 100644 --- a/app/Services/YubicoService.php +++ b/app/Services/YubicoService.php @@ -7,6 +7,7 @@ class YubicoService { public string $identifier; + public string $nonce; public function verify(string $otp): bool @@ -27,19 +28,19 @@ public function verify(string $otp): bool $errorMessage = match ($responseData['status']) { 'OK' => ($responseData['nonce'] === $this->nonce) ? null : 'Nonce mismatch.', - 'BAD_OTP' => "The OTP is invalid format.", - 'REPLAYED_OTP' => "The OTP has already been used.", - 'BAD_SIGNATURE' => "The HMAC signature verification failed.", - 'MISSING_PARAMETER' => "The request lacks a parameter.", - 'NO_SUCH_CLIENT' => "The request id does not exist.", - 'OPERATION_NOT_ALLOWED' => "The request id is not allowed to verify OTPs.", - 'BACKEND_ERROR' => "Unexpected error in Yubico server.", - 'NOT_ENOUGH_ANSWERS' => "Server could not get requested number of syncs during before timeout.", - 'REPLAYED_REQUEST' => "Server has seen the OTP/Nonce combination before.", - default => "Unknown error.", + 'BAD_OTP' => 'The OTP is invalid format.', + 'REPLAYED_OTP' => 'The OTP has already been used.', + 'BAD_SIGNATURE' => 'The HMAC signature verification failed.', + 'MISSING_PARAMETER' => 'The request lacks a parameter.', + 'NO_SUCH_CLIENT' => 'The request id does not exist.', + 'OPERATION_NOT_ALLOWED' => 'The request id is not allowed to verify OTPs.', + 'BACKEND_ERROR' => 'Unexpected error in Yubico server.', + 'NOT_ENOUGH_ANSWERS' => 'Server could not get requested number of syncs during before timeout.', + 'REPLAYED_REQUEST' => 'Server has seen the OTP/Nonce combination before.', + default => 'Unknown error.', }; // Check if the signature is valid - if (!$this->verifyResponseSignature($responseData)) { + if (! $this->verifyResponseSignature($responseData)) { $errorMessage = 'Signature mismatch.'; } if ($errorMessage) { @@ -47,6 +48,7 @@ public function verify(string $otp): bool } // Get the first 12 characters of the OTP $this->identifier = substr($responseData['otp'], 0, 12); + return true; } @@ -105,6 +107,7 @@ public function convertResponseToArray(string $response): array $parts = explode('=', $line, 2); $arrayData[$parts[0]] = $parts[1]; } + return $arrayData; } } diff --git a/app/helpers.php b/app/helpers.php index 5ad67a3..5f1e47f 100644 --- a/app/helpers.php +++ b/app/helpers.php @@ -2,11 +2,11 @@ /** * File for Helper functions */ - function translations($json) { - if(!file_exists($json)) { + if (! file_exists($json)) { return []; } + return json_decode(file_get_contents($json), true); } diff --git a/config/cache.php b/config/cache.php index 8736c7a..e9eb649 100644 --- a/config/cache.php +++ b/config/cache.php @@ -105,6 +105,6 @@ | */ - 'prefix' => env('CACHE_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_').'_cache'), + 'prefix' => env('CACHE_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_') . '_cache'), ]; diff --git a/config/clockwork.php b/config/clockwork.php index ce77f7d..81f4528 100644 --- a/config/clockwork.php +++ b/config/clockwork.php @@ -15,135 +15,135 @@ | */ - 'enable' => env('CLOCKWORK_ENABLE', null), - - /* - |------------------------------------------------------------------------------------------------------------------ - | Features - |------------------------------------------------------------------------------------------------------------------ - | - | You can enable or disable various Clockwork features here. Some features have additional settings (eg. slow query - | threshold for database queries). - | - */ - - 'features' => [ - - // Cache usage stats and cache queries including results - 'cache' => [ - 'enabled' => env('CLOCKWORK_CACHE_ENABLED', true), - - // Collect cache queries - 'collect_queries' => env('CLOCKWORK_CACHE_QUERIES', true), - - // Collect values from cache queries (high performance impact with a very high number of queries) - 'collect_values' => env('CLOCKWORK_CACHE_COLLECT_VALUES', false) - ], - - // Database usage stats and queries - 'database' => [ - 'enabled' => env('CLOCKWORK_DATABASE_ENABLED', true), - - // Collect database queries (high performance impact with a very high number of queries) - 'collect_queries' => env('CLOCKWORK_DATABASE_COLLECT_QUERIES', true), - - // Collect details of models updates (high performance impact with a lot of model updates) - 'collect_models_actions' => env('CLOCKWORK_DATABASE_COLLECT_MODELS_ACTIONS', true), - - // Collect details of retrieved models (very high performance impact with a lot of models retrieved) - 'collect_models_retrieved' => env('CLOCKWORK_DATABASE_COLLECT_MODELS_RETRIEVED', false), - - // Query execution time threshold in milliseconds after which the query will be marked as slow - 'slow_threshold' => env('CLOCKWORK_DATABASE_SLOW_THRESHOLD'), - - // Collect only slow database queries - 'slow_only' => env('CLOCKWORK_DATABASE_SLOW_ONLY', false), - - // Detect and report duplicate queries - 'detect_duplicate_queries' => env('CLOCKWORK_DATABASE_DETECT_DUPLICATE_QUERIES', false) - ], - - // Dispatched events - 'events' => [ - 'enabled' => env('CLOCKWORK_EVENTS_ENABLED', true), - - // Ignored events (framework events are ignored by default) - 'ignored_events' => [ - // App\Events\UserRegistered::class, - // 'user.registered' - ], - ], - - // Laravel log (you can still log directly to Clockwork with laravel log disabled) - 'log' => [ - 'enabled' => env('CLOCKWORK_LOG_ENABLED', true) - ], - - // Sent notifications - 'notifications' => [ - 'enabled' => env('CLOCKWORK_NOTIFICATIONS_ENABLED', true), - ], - - // Performance metrics - 'performance' => [ - // Allow collecting of client metrics. Requires separate clockwork-browser npm package. - 'client_metrics' => env('CLOCKWORK_PERFORMANCE_CLIENT_METRICS', true) - ], - - // Dispatched queue jobs - 'queue' => [ - 'enabled' => env('CLOCKWORK_QUEUE_ENABLED', true) - ], - - // Redis commands - 'redis' => [ - 'enabled' => env('CLOCKWORK_REDIS_ENABLED', true) - ], - - // Routes list - 'routes' => [ - 'enabled' => env('CLOCKWORK_ROUTES_ENABLED', false), - - // Collect only routes from particular namespaces (only application routes by default) - 'only_namespaces' => [ 'App' ] - ], - - // Rendered views - 'views' => [ - 'enabled' => env('CLOCKWORK_VIEWS_ENABLED', true), - - // Collect views including view data (high performance impact with a high number of views) - 'collect_data' => env('CLOCKWORK_VIEWS_COLLECT_DATA', false), - - // Use Twig profiler instead of Laravel events for apps using laravel-twigbridge (more precise, but does - // not support collecting view data) - 'use_twig_profiler' => env('CLOCKWORK_VIEWS_USE_TWIG_PROFILER', false) - ] - - ], - - /* - |------------------------------------------------------------------------------------------------------------------ - | Enable web UI - |------------------------------------------------------------------------------------------------------------------ - | - | Clockwork comes with a web UI accessible via http://your.app/clockwork. Here you can enable or disable this - | feature. You can also set a custom path for the web UI. - | - */ - - 'web' => env('CLOCKWORK_WEB', true), - - /* - |------------------------------------------------------------------------------------------------------------------ - | Enable toolbar - |------------------------------------------------------------------------------------------------------------------ - | - | Clockwork can show a toolbar with basic metrics on all responses. Here you can enable or disable this feature. - | Requires a separate clockwork-browser npm library. - | For installation instructions see https://underground.works/clockwork/#docs-viewing-data - | - */ + 'enable' => env('CLOCKWORK_ENABLE', null), + + /* + |------------------------------------------------------------------------------------------------------------------ + | Features + |------------------------------------------------------------------------------------------------------------------ + | + | You can enable or disable various Clockwork features here. Some features have additional settings (eg. slow query + | threshold for database queries). + | + */ + + 'features' => [ + + // Cache usage stats and cache queries including results + 'cache' => [ + 'enabled' => env('CLOCKWORK_CACHE_ENABLED', true), + + // Collect cache queries + 'collect_queries' => env('CLOCKWORK_CACHE_QUERIES', true), + + // Collect values from cache queries (high performance impact with a very high number of queries) + 'collect_values' => env('CLOCKWORK_CACHE_COLLECT_VALUES', false), + ], + + // Database usage stats and queries + 'database' => [ + 'enabled' => env('CLOCKWORK_DATABASE_ENABLED', true), + + // Collect database queries (high performance impact with a very high number of queries) + 'collect_queries' => env('CLOCKWORK_DATABASE_COLLECT_QUERIES', true), + + // Collect details of models updates (high performance impact with a lot of model updates) + 'collect_models_actions' => env('CLOCKWORK_DATABASE_COLLECT_MODELS_ACTIONS', true), + + // Collect details of retrieved models (very high performance impact with a lot of models retrieved) + 'collect_models_retrieved' => env('CLOCKWORK_DATABASE_COLLECT_MODELS_RETRIEVED', false), + + // Query execution time threshold in milliseconds after which the query will be marked as slow + 'slow_threshold' => env('CLOCKWORK_DATABASE_SLOW_THRESHOLD'), + + // Collect only slow database queries + 'slow_only' => env('CLOCKWORK_DATABASE_SLOW_ONLY', false), + + // Detect and report duplicate queries + 'detect_duplicate_queries' => env('CLOCKWORK_DATABASE_DETECT_DUPLICATE_QUERIES', false), + ], + + // Dispatched events + 'events' => [ + 'enabled' => env('CLOCKWORK_EVENTS_ENABLED', true), + + // Ignored events (framework events are ignored by default) + 'ignored_events' => [ + // App\Events\UserRegistered::class, + // 'user.registered' + ], + ], + + // Laravel log (you can still log directly to Clockwork with laravel log disabled) + 'log' => [ + 'enabled' => env('CLOCKWORK_LOG_ENABLED', true), + ], + + // Sent notifications + 'notifications' => [ + 'enabled' => env('CLOCKWORK_NOTIFICATIONS_ENABLED', true), + ], + + // Performance metrics + 'performance' => [ + // Allow collecting of client metrics. Requires separate clockwork-browser npm package. + 'client_metrics' => env('CLOCKWORK_PERFORMANCE_CLIENT_METRICS', true), + ], + + // Dispatched queue jobs + 'queue' => [ + 'enabled' => env('CLOCKWORK_QUEUE_ENABLED', true), + ], + + // Redis commands + 'redis' => [ + 'enabled' => env('CLOCKWORK_REDIS_ENABLED', true), + ], + + // Routes list + 'routes' => [ + 'enabled' => env('CLOCKWORK_ROUTES_ENABLED', false), + + // Collect only routes from particular namespaces (only application routes by default) + 'only_namespaces' => ['App'], + ], + + // Rendered views + 'views' => [ + 'enabled' => env('CLOCKWORK_VIEWS_ENABLED', true), + + // Collect views including view data (high performance impact with a high number of views) + 'collect_data' => env('CLOCKWORK_VIEWS_COLLECT_DATA', false), + + // Use Twig profiler instead of Laravel events for apps using laravel-twigbridge (more precise, but does + // not support collecting view data) + 'use_twig_profiler' => env('CLOCKWORK_VIEWS_USE_TWIG_PROFILER', false), + ], + + ], + + /* + |------------------------------------------------------------------------------------------------------------------ + | Enable web UI + |------------------------------------------------------------------------------------------------------------------ + | + | Clockwork comes with a web UI accessible via http://your.app/clockwork. Here you can enable or disable this + | feature. You can also set a custom path for the web UI. + | + */ + + 'web' => env('CLOCKWORK_WEB', true), + + /* + |------------------------------------------------------------------------------------------------------------------ + | Enable toolbar + |------------------------------------------------------------------------------------------------------------------ + | + | Clockwork can show a toolbar with basic metrics on all responses. Here you can enable or disable this feature. + | Requires a separate clockwork-browser npm library. + | For installation instructions see https://underground.works/clockwork/#docs-viewing-data + | + */ 'toolbar' => env('CLOCKWORK_TOOLBAR', false), @@ -156,264 +156,264 @@ | */ - 'requests' => [ - // With on-demand mode enabled, Clockwork will only profile requests when the browser extension is open or you - // manually pass a "clockwork-profile" cookie or get/post data key. - // Optionally you can specify a "secret" that has to be passed as the value to enable profiling. - 'on_demand' => env('CLOCKWORK_REQUESTS_ON_DEMAND', false), - - // Collect only errors (requests with HTTP 4xx and 5xx responses) - 'errors_only' => env('CLOCKWORK_REQUESTS_ERRORS_ONLY', false), - - // Response time threshold in milliseconds after which the request will be marked as slow - 'slow_threshold' => env('CLOCKWORK_REQUESTS_SLOW_THRESHOLD'), - - // Collect only slow requests - 'slow_only' => env('CLOCKWORK_REQUESTS_SLOW_ONLY', false), - - // Sample the collected requests (e.g. set to 100 to collect only 1 in 100 requests) - 'sample' => env('CLOCKWORK_REQUESTS_SAMPLE', false), - - // List of URIs that should not be collected - 'except' => [ - '/horizon/.*', // Laravel Horizon requests - '/telescope/.*', // Laravel Telescope requests - '/_debugbar/.*', // Laravel DebugBar requests - ], - - // List of URIs that should be collected, any other URI will not be collected if not empty - 'only' => [ - // '/api/.*' - ], - - // Don't collect OPTIONS requests, mostly used in the CSRF pre-flight requests and are rarely of interest - 'except_preflight' => env('CLOCKWORK_REQUESTS_EXCEPT_PREFLIGHT', true) - ], - - /* - |------------------------------------------------------------------------------------------------------------------ - | Artisan commands collection - |------------------------------------------------------------------------------------------------------------------ - | - | Clockwork can collect data about executed artisan commands. Here you can enable and configure which commands - | should be collected. - | - */ - - 'artisan' => [ - // Enable or disable collection of executed Artisan commands - 'collect' => env('CLOCKWORK_ARTISAN_COLLECT', false), - - // List of commands that should not be collected (built-in commands are not collected by default) - 'except' => [ - // 'inspire' - ], - - // List of commands that should be collected, any other command will not be collected if not empty - 'only' => [ - // 'inspire' - ], - - // Enable or disable collection of command output - 'collect_output' => env('CLOCKWORK_ARTISAN_COLLECT_OUTPUT', false), - - // Enable or disable collection of built-in Laravel commands - 'except_laravel_commands' => env('CLOCKWORK_ARTISAN_EXCEPT_LARAVEL_COMMANDS', true) - ], - - /* - |------------------------------------------------------------------------------------------------------------------ - | Queue jobs collection - |------------------------------------------------------------------------------------------------------------------ - | - | Clockwork can collect data about executed queue jobs. Here you can enable and configure which queue jobs should - | be collected. - | - */ - - 'queue' => [ - // Enable or disable collection of executed queue jobs - 'collect' => env('CLOCKWORK_QUEUE_COLLECT', false), - - // List of queue jobs that should not be collected - 'except' => [ - // App\Jobs\ExpensiveJob::class - ], - - // List of queue jobs that should be collected, any other queue job will not be collected if not empty - 'only' => [ - // App\Jobs\BuggyJob::class - ] - ], - - /* - |------------------------------------------------------------------------------------------------------------------ - | Tests collection - |------------------------------------------------------------------------------------------------------------------ - | - | Clockwork can collect data about executed tests. Here you can enable and configure which tests should be - | collected. - | - */ - - 'tests' => [ - // Enable or disable collection of ran tests - 'collect' => env('CLOCKWORK_TESTS_COLLECT', false), - - // List of tests that should not be collected - 'except' => [ - // Tests\Unit\ExampleTest::class - ] - ], - - /* - |------------------------------------------------------------------------------------------------------------------ - | Enable data collection when Clockwork is disabled - |------------------------------------------------------------------------------------------------------------------ - | - | You can enable this setting to collect data even when Clockwork is disabled, e.g. for future analysis. - | - */ - - 'collect_data_always' => env('CLOCKWORK_COLLECT_DATA_ALWAYS', false), - - /* - |------------------------------------------------------------------------------------------------------------------ - | Metadata storage - |------------------------------------------------------------------------------------------------------------------ - | - | Configure how is the metadata collected by Clockwork stored. Two options are available: - | - files - A simple fast storage implementation storing data in one-per-request files. - | - sql - Stores requests in a sql database. Supports MySQL, PostgreSQL and SQLite. Requires PDO. - | - */ - - 'storage' => env('CLOCKWORK_STORAGE', 'files'), - - // Path where the Clockwork metadata is stored - 'storage_files_path' => env('CLOCKWORK_STORAGE_FILES_PATH', storage_path('clockwork')), - - // Compress the metadata files using gzip, trading a little bit of performance for lower disk usage - 'storage_files_compress' => env('CLOCKWORK_STORAGE_FILES_COMPRESS', false), - - // SQL database to use, can be a name of database configured in database.php or a path to a SQLite file - 'storage_sql_database' => env('CLOCKWORK_STORAGE_SQL_DATABASE', storage_path('clockwork.sqlite')), - - // SQL table name to use, the table is automatically created and udpated when needed - 'storage_sql_table' => env('CLOCKWORK_STORAGE_SQL_TABLE', 'clockwork'), - - // Maximum lifetime of collected metadata in minutes, older requests will automatically be deleted, false to disable - 'storage_expiration' => env('CLOCKWORK_STORAGE_EXPIRATION', 60 * 24 * 7), - - /* - |------------------------------------------------------------------------------------------------------------------ - | Authentication - |------------------------------------------------------------------------------------------------------------------ - | - | Clockwork can be configured to require authentication before allowing access to the collected data. This might be - | useful when the application is publicly accessible. Setting to true will enable a simple authentication with a - | pre-configured password. You can also pass a class name of a custom implementation. - | - */ - - 'authentication' => env('CLOCKWORK_AUTHENTICATION', false), - - // Password for the simple authentication - 'authentication_password' => env('CLOCKWORK_AUTHENTICATION_PASSWORD', 'VerySecretPassword'), - - /* - |------------------------------------------------------------------------------------------------------------------ - | Stack traces collection - |------------------------------------------------------------------------------------------------------------------ - | - | Clockwork can collect stack traces for log messages and certain data like database queries. Here you can set - | whether to collect stack traces, limit the number of collected frames and set further configuration. Collecting - | long stack traces considerably increases metadata size. - | - */ - - 'stack_traces' => [ - // Enable or disable collecting of stack traces - 'enabled' => env('CLOCKWORK_STACK_TRACES_ENABLED', true), - - // Limit the number of frames to be collected - 'limit' => env('CLOCKWORK_STACK_TRACES_LIMIT', 10), - - // List of vendor names to skip when determining caller, common vendors are automatically added - 'skip_vendors' => [ - // 'phpunit' - ], - - // List of namespaces to skip when determining caller - 'skip_namespaces' => [ - // 'Laravel' - ], - - // List of class names to skip when determining caller - 'skip_classes' => [ - // App\CustomLog::class - ] - - ], - - /* - |------------------------------------------------------------------------------------------------------------------ - | Serialization - |------------------------------------------------------------------------------------------------------------------ - | - | Clockwork serializes the collected data to json for storage and transfer. Here you can configure certain aspects - | of serialization. Serialization has a large effect on the cpu time and memory usage. - | - */ - - // Maximum depth of serialized multi-level arrays and objects - 'serialization_depth' => env('CLOCKWORK_SERIALIZATION_DEPTH', 10), - - // A list of classes that will never be serialized (e.g. a common service container class) - 'serialization_blackbox' => [ + 'requests' => [ + // With on-demand mode enabled, Clockwork will only profile requests when the browser extension is open or you + // manually pass a "clockwork-profile" cookie or get/post data key. + // Optionally you can specify a "secret" that has to be passed as the value to enable profiling. + 'on_demand' => env('CLOCKWORK_REQUESTS_ON_DEMAND', false), + + // Collect only errors (requests with HTTP 4xx and 5xx responses) + 'errors_only' => env('CLOCKWORK_REQUESTS_ERRORS_ONLY', false), + + // Response time threshold in milliseconds after which the request will be marked as slow + 'slow_threshold' => env('CLOCKWORK_REQUESTS_SLOW_THRESHOLD'), + + // Collect only slow requests + 'slow_only' => env('CLOCKWORK_REQUESTS_SLOW_ONLY', false), + + // Sample the collected requests (e.g. set to 100 to collect only 1 in 100 requests) + 'sample' => env('CLOCKWORK_REQUESTS_SAMPLE', false), + + // List of URIs that should not be collected + 'except' => [ + '/horizon/.*', // Laravel Horizon requests + '/telescope/.*', // Laravel Telescope requests + '/_debugbar/.*', // Laravel DebugBar requests + ], + + // List of URIs that should be collected, any other URI will not be collected if not empty + 'only' => [ + // '/api/.*' + ], + + // Don't collect OPTIONS requests, mostly used in the CSRF pre-flight requests and are rarely of interest + 'except_preflight' => env('CLOCKWORK_REQUESTS_EXCEPT_PREFLIGHT', true), + ], + + /* + |------------------------------------------------------------------------------------------------------------------ + | Artisan commands collection + |------------------------------------------------------------------------------------------------------------------ + | + | Clockwork can collect data about executed artisan commands. Here you can enable and configure which commands + | should be collected. + | + */ + + 'artisan' => [ + // Enable or disable collection of executed Artisan commands + 'collect' => env('CLOCKWORK_ARTISAN_COLLECT', false), + + // List of commands that should not be collected (built-in commands are not collected by default) + 'except' => [ + // 'inspire' + ], + + // List of commands that should be collected, any other command will not be collected if not empty + 'only' => [ + // 'inspire' + ], + + // Enable or disable collection of command output + 'collect_output' => env('CLOCKWORK_ARTISAN_COLLECT_OUTPUT', false), + + // Enable or disable collection of built-in Laravel commands + 'except_laravel_commands' => env('CLOCKWORK_ARTISAN_EXCEPT_LARAVEL_COMMANDS', true), + ], + + /* + |------------------------------------------------------------------------------------------------------------------ + | Queue jobs collection + |------------------------------------------------------------------------------------------------------------------ + | + | Clockwork can collect data about executed queue jobs. Here you can enable and configure which queue jobs should + | be collected. + | + */ + + 'queue' => [ + // Enable or disable collection of executed queue jobs + 'collect' => env('CLOCKWORK_QUEUE_COLLECT', false), + + // List of queue jobs that should not be collected + 'except' => [ + // App\Jobs\ExpensiveJob::class + ], + + // List of queue jobs that should be collected, any other queue job will not be collected if not empty + 'only' => [ + // App\Jobs\BuggyJob::class + ], + ], + + /* + |------------------------------------------------------------------------------------------------------------------ + | Tests collection + |------------------------------------------------------------------------------------------------------------------ + | + | Clockwork can collect data about executed tests. Here you can enable and configure which tests should be + | collected. + | + */ + + 'tests' => [ + // Enable or disable collection of ran tests + 'collect' => env('CLOCKWORK_TESTS_COLLECT', false), + + // List of tests that should not be collected + 'except' => [ + // Tests\Unit\ExampleTest::class + ], + ], + + /* + |------------------------------------------------------------------------------------------------------------------ + | Enable data collection when Clockwork is disabled + |------------------------------------------------------------------------------------------------------------------ + | + | You can enable this setting to collect data even when Clockwork is disabled, e.g. for future analysis. + | + */ + + 'collect_data_always' => env('CLOCKWORK_COLLECT_DATA_ALWAYS', false), + + /* + |------------------------------------------------------------------------------------------------------------------ + | Metadata storage + |------------------------------------------------------------------------------------------------------------------ + | + | Configure how is the metadata collected by Clockwork stored. Two options are available: + | - files - A simple fast storage implementation storing data in one-per-request files. + | - sql - Stores requests in a sql database. Supports MySQL, PostgreSQL and SQLite. Requires PDO. + | + */ + + 'storage' => env('CLOCKWORK_STORAGE', 'files'), + + // Path where the Clockwork metadata is stored + 'storage_files_path' => env('CLOCKWORK_STORAGE_FILES_PATH', storage_path('clockwork')), + + // Compress the metadata files using gzip, trading a little bit of performance for lower disk usage + 'storage_files_compress' => env('CLOCKWORK_STORAGE_FILES_COMPRESS', false), + + // SQL database to use, can be a name of database configured in database.php or a path to a SQLite file + 'storage_sql_database' => env('CLOCKWORK_STORAGE_SQL_DATABASE', storage_path('clockwork.sqlite')), + + // SQL table name to use, the table is automatically created and udpated when needed + 'storage_sql_table' => env('CLOCKWORK_STORAGE_SQL_TABLE', 'clockwork'), + + // Maximum lifetime of collected metadata in minutes, older requests will automatically be deleted, false to disable + 'storage_expiration' => env('CLOCKWORK_STORAGE_EXPIRATION', 60 * 24 * 7), + + /* + |------------------------------------------------------------------------------------------------------------------ + | Authentication + |------------------------------------------------------------------------------------------------------------------ + | + | Clockwork can be configured to require authentication before allowing access to the collected data. This might be + | useful when the application is publicly accessible. Setting to true will enable a simple authentication with a + | pre-configured password. You can also pass a class name of a custom implementation. + | + */ + + 'authentication' => env('CLOCKWORK_AUTHENTICATION', false), + + // Password for the simple authentication + 'authentication_password' => env('CLOCKWORK_AUTHENTICATION_PASSWORD', 'VerySecretPassword'), + + /* + |------------------------------------------------------------------------------------------------------------------ + | Stack traces collection + |------------------------------------------------------------------------------------------------------------------ + | + | Clockwork can collect stack traces for log messages and certain data like database queries. Here you can set + | whether to collect stack traces, limit the number of collected frames and set further configuration. Collecting + | long stack traces considerably increases metadata size. + | + */ + + 'stack_traces' => [ + // Enable or disable collecting of stack traces + 'enabled' => env('CLOCKWORK_STACK_TRACES_ENABLED', true), + + // Limit the number of frames to be collected + 'limit' => env('CLOCKWORK_STACK_TRACES_LIMIT', 10), + + // List of vendor names to skip when determining caller, common vendors are automatically added + 'skip_vendors' => [ + // 'phpunit' + ], + + // List of namespaces to skip when determining caller + 'skip_namespaces' => [ + // 'Laravel' + ], + + // List of class names to skip when determining caller + 'skip_classes' => [ + // App\CustomLog::class + ], + + ], + + /* + |------------------------------------------------------------------------------------------------------------------ + | Serialization + |------------------------------------------------------------------------------------------------------------------ + | + | Clockwork serializes the collected data to json for storage and transfer. Here you can configure certain aspects + | of serialization. Serialization has a large effect on the cpu time and memory usage. + | + */ + + // Maximum depth of serialized multi-level arrays and objects + 'serialization_depth' => env('CLOCKWORK_SERIALIZATION_DEPTH', 10), + + // A list of classes that will never be serialized (e.g. a common service container class) + 'serialization_blackbox' => [ Container::class, \Illuminate\Foundation\Application::class, - Application::class + Application::class, ], - /* - |------------------------------------------------------------------------------------------------------------------ - | Register helpers - |------------------------------------------------------------------------------------------------------------------ - | - | Clockwork comes with a "clock" global helper function. You can use this helper to quickly log something and to - | access the Clockwork instance. - | - */ - - 'register_helpers' => env('CLOCKWORK_REGISTER_HELPERS', true), - - /* - |------------------------------------------------------------------------------------------------------------------ - | Send headers for AJAX request - |------------------------------------------------------------------------------------------------------------------ - | - | When trying to collect data, the AJAX method can sometimes fail if it is missing required headers. For example, an - | API might require a version number using Accept headers to route the HTTP request to the correct codebase. - | - */ - - 'headers' => [ - // 'Accept' => 'application/vnd.com.whatever.v1+json', - ], - - /* - |------------------------------------------------------------------------------------------------------------------ - | Server timing - |------------------------------------------------------------------------------------------------------------------ - | - | Clockwork supports the W3C Server Timing specification, which allows for collecting a simple performance metrics - | in a cross-browser way. E.g. in Chrome, your app, database and timeline event timings will be shown in the Dev - | Tools network tab. This setting specifies the max number of timeline events that will be sent. Setting to false - | will disable the feature. - | - */ - - 'server_timing' => env('CLOCKWORK_SERVER_TIMING', 10) + /* + |------------------------------------------------------------------------------------------------------------------ + | Register helpers + |------------------------------------------------------------------------------------------------------------------ + | + | Clockwork comes with a "clock" global helper function. You can use this helper to quickly log something and to + | access the Clockwork instance. + | + */ + + 'register_helpers' => env('CLOCKWORK_REGISTER_HELPERS', true), + + /* + |------------------------------------------------------------------------------------------------------------------ + | Send headers for AJAX request + |------------------------------------------------------------------------------------------------------------------ + | + | When trying to collect data, the AJAX method can sometimes fail if it is missing required headers. For example, an + | API might require a version number using Accept headers to route the HTTP request to the correct codebase. + | + */ + + 'headers' => [ + // 'Accept' => 'application/vnd.com.whatever.v1+json', + ], + + /* + |------------------------------------------------------------------------------------------------------------------ + | Server timing + |------------------------------------------------------------------------------------------------------------------ + | + | Clockwork supports the W3C Server Timing specification, which allows for collecting a simple performance metrics + | in a cross-browser way. E.g. in Chrome, your app, database and timeline event timings will be shown in the Dev + | Tools network tab. This setting specifies the max number of timeline events that will be sent. Setting to false + | will disable the feature. + | + */ + + 'server_timing' => env('CLOCKWORK_SERVER_TIMING', 10), ]; diff --git a/config/database.php b/config/database.php index b42d9b3..3bfc47a 100644 --- a/config/database.php +++ b/config/database.php @@ -123,7 +123,7 @@ 'options' => [ 'cluster' => env('REDIS_CLUSTER', 'redis'), - 'prefix' => env('REDIS_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_').'_database_'), + 'prefix' => env('REDIS_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_') . '_database_'), ], 'default' => [ diff --git a/config/filament.php b/config/filament.php index eed9158..b687973 100644 --- a/config/filament.php +++ b/config/filament.php @@ -37,4 +37,4 @@ 'default_filesystem_disk' => env('FILAMENT_FILESYSTEM_DISK', 'public'), -]; \ No newline at end of file +]; diff --git a/config/filesystems.php b/config/filesystems.php index ac3ff58..b12fc01 100644 --- a/config/filesystems.php +++ b/config/filesystems.php @@ -38,7 +38,7 @@ 'public' => [ 'driver' => 'local', 'root' => storage_path('app/public'), - 'url' => env('APP_URL').'/storage', + 'url' => env('APP_URL') . '/storage', 'visibility' => 'public', ], diff --git a/config/groups.php b/config/groups.php index bffe1ac..c5a3371 100644 --- a/config/groups.php +++ b/config/groups.php @@ -1,4 +1,5 @@ env('GROUP_ATTENDEES_ID'), ]; diff --git a/config/horizon.php b/config/horizon.php index 15c05cf..3a186ed 100644 --- a/config/horizon.php +++ b/config/horizon.php @@ -56,7 +56,7 @@ 'prefix' => env( 'HORIZON_PREFIX', - Str::slug(env('APP_NAME', 'laravel'), '_').'_horizon:' + Str::slug(env('APP_NAME', 'laravel'), '_') . '_horizon:' ), /* diff --git a/config/image.php b/config/image.php index 2b1d2c3..6798381 100644 --- a/config/image.php +++ b/config/image.php @@ -15,6 +15,6 @@ | */ - 'driver' => 'gd' + 'driver' => 'gd', ]; diff --git a/config/mail.php b/config/mail.php index 5931a15..4c66d91 100644 --- a/config/mail.php +++ b/config/mail.php @@ -91,7 +91,6 @@ /** * Global Reply To Address */ - 'reply_to' => [ 'address' => env('MAIL_REPLY_TO_ADDRESS', 'identity@eurofurence.org'), 'name' => env('MAIL_REPLY_TO_NAME', 'Eurofurence Identity'), diff --git a/config/sentry.php b/config/sentry.php index 0f2c2e1..d9975e6 100644 --- a/config/sentry.php +++ b/config/sentry.php @@ -50,7 +50,7 @@ // @see: https://docs.sentry.io/platforms/php/configuration/options/#send-default-pii 'send_default_pii' => false, - 'traces_sample_rate' => (float)(env('SENTRY_TRACES_SAMPLE_RATE', 0.0)), + 'traces_sample_rate' => (float) (env('SENTRY_TRACES_SAMPLE_RATE', 0.0)), 'controllers_base_namespace' => env('SENTRY_CONTROLLERS_BASE_NAMESPACE', 'App\\Http\\Controllers'), diff --git a/config/services.php b/config/services.php index 3986eb1..d552375 100644 --- a/config/services.php +++ b/config/services.php @@ -62,8 +62,8 @@ ], 'hydra' => [ 'public' => env('HYDRA_PUBLIC_URL'), - 'local_public' => env('HYDRA_LOCAL_PUBLIC'), # For Dev purposes - 'admin' => env('HYDRA_ADMIN_URL') + 'local_public' => env('HYDRA_LOCAL_PUBLIC'), // For Dev purposes + 'admin' => env('HYDRA_ADMIN_URL'), ], // Yubikey 'yubikey' => [ @@ -74,5 +74,5 @@ 'baseUrl' => env('NEXTCLOUD_BASE_URL'), 'username' => env('NEXTCLOUD_USERNAME'), 'password' => env('NEXTCLOUD_PASSWORD'), - ] + ], ]; diff --git a/config/session.php b/config/session.php index ce60ae0..1f2645c 100644 --- a/config/session.php +++ b/config/session.php @@ -128,7 +128,7 @@ 'cookie' => env( 'SESSION_COOKIE', - Str::slug(env('APP_NAME', 'laravel'), '_').'_session' + Str::slug(env('APP_NAME', 'laravel'), '_') . '_session' ), /* diff --git a/config/translatable.php b/config/translatable.php index 145b559..839f563 100644 --- a/config/translatable.php +++ b/config/translatable.php @@ -5,7 +5,7 @@ /* * If a translation has not been set for a given locale, use this locale instead. */ - 'fallback_locale' => "en", + 'fallback_locale' => 'en', /* * If a translation has not been set for a given locale and the fallback locale, diff --git a/database/factories/UserFactory.php b/database/factories/UserFactory.php index 917e4e8..888619c 100644 --- a/database/factories/UserFactory.php +++ b/database/factories/UserFactory.php @@ -23,10 +23,10 @@ class UserFactory extends Factory public function definition() { return [ - 'name' => $this->faker->name, - 'email' => $this->faker->safeEmail, + 'name' => $this->faker->name, + 'email' => $this->faker->safeEmail, 'email_verified_at' => $this->faker->dateTime(), - 'password' => Hash::make($this->faker->password), + 'password' => Hash::make($this->faker->password), ]; } } diff --git a/database/migrations/2014_10_12_200000_add_two_factor_columns_to_users_table.php b/database/migrations/2014_10_12_200000_add_two_factor_columns_to_users_table.php index f4500c9..8e291ca 100644 --- a/database/migrations/2014_10_12_200000_add_two_factor_columns_to_users_table.php +++ b/database/migrations/2014_10_12_200000_add_two_factor_columns_to_users_table.php @@ -15,12 +15,12 @@ public function up() { Schema::table('users', function (Blueprint $table) { $table->text('two_factor_secret') - ->after('password') - ->nullable(); + ->after('password') + ->nullable(); $table->text('two_factor_recovery_codes') - ->after('two_factor_secret') - ->nullable(); + ->after('two_factor_secret') + ->nullable(); }); } diff --git a/database/migrations/2019_12_14_000001_create_personal_access_tokens_table.php b/database/migrations/2019_12_14_000001_create_personal_access_tokens_table.php index 6c81fd2..fa2845f 100644 --- a/database/migrations/2019_12_14_000001_create_personal_access_tokens_table.php +++ b/database/migrations/2019_12_14_000001_create_personal_access_tokens_table.php @@ -4,7 +4,7 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class extends Migration +return new class() extends Migration { /** * Run the migrations. diff --git a/database/migrations/2022_11_04_215854_create_apps_table.php b/database/migrations/2022_11_04_215854_create_apps_table.php index 9798c8e..4442004 100644 --- a/database/migrations/2022_11_04_215854_create_apps_table.php +++ b/database/migrations/2022_11_04_215854_create_apps_table.php @@ -4,7 +4,8 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class extends Migration { +return new class() extends Migration +{ public function up() { Schema::create('apps', function (Blueprint $table) { diff --git a/database/migrations/2022_12_11_033225_update_group_and_group_user_table.php b/database/migrations/2022_12_11_033225_update_group_and_group_user_table.php index e517163..7dfe68a 100644 --- a/database/migrations/2022_12_11_033225_update_group_and_group_user_table.php +++ b/database/migrations/2022_12_11_033225_update_group_and_group_user_table.php @@ -4,7 +4,8 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class extends Migration { +return new class() extends Migration +{ public function up() { Schema::table('groups', function (Blueprint $table) { @@ -17,9 +18,9 @@ public function up() Schema::table('group_user', function (Blueprint $table) { $table->dropColumn(['authorization_level', 'is_director', 'title']); $table->enum('level', ['invited', 'banned', 'member', 'moderator', 'admin', 'owner']) - ->index() - ->default('invited') - ->after('user_id'); + ->index() + ->default('invited') + ->after('user_id'); }); } }; diff --git a/database/migrations/2022_12_11_034133_make_slug_unique_on_groups_table.php b/database/migrations/2022_12_11_034133_make_slug_unique_on_groups_table.php index 3652c38..5728dcc 100644 --- a/database/migrations/2022_12_11_034133_make_slug_unique_on_groups_table.php +++ b/database/migrations/2022_12_11_034133_make_slug_unique_on_groups_table.php @@ -4,7 +4,8 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class extends Migration { +return new class() extends Migration +{ public function up() { Schema::table('groups', function (Blueprint $table) { diff --git a/database/migrations/2023_02_12_114846_add_fields_to_apps_table.php b/database/migrations/2023_02_12_114846_add_fields_to_apps_table.php index d0beecc..75dd973 100644 --- a/database/migrations/2023_02_12_114846_add_fields_to_apps_table.php +++ b/database/migrations/2023_02_12_114846_add_fields_to_apps_table.php @@ -4,12 +4,13 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class extends Migration { +return new class() extends Migration +{ public function up() { Schema::table('apps', function (Blueprint $table) { - $table->timestamp("starts_at")->nullable()->after('client_id'); - $table->timestamp("ends_at")->nullable()->after('starts_at'); + $table->timestamp('starts_at')->nullable()->after('client_id'); + $table->timestamp('ends_at')->nullable()->after('starts_at'); $table->boolean('public')->default(false)->after('ends_at'); $table->boolean('featured')->default(false)->after('ends_at'); $table->integer('priority')->unsigned()->default(1000)->after('public'); @@ -24,15 +25,15 @@ public function down() { Schema::table('apps', function (Blueprint $table) { $table->dropColumn([ - "starts_at", - "ends_at", - "public", - "featured", - "priority", - "name", - "description", - "icon", - "url", + 'starts_at', + 'ends_at', + 'public', + 'featured', + 'priority', + 'name', + 'description', + 'icon', + 'url', ]); }); } diff --git a/database/migrations/2023_02_20_160150_add_title_field_group_user_table.php b/database/migrations/2023_02_20_160150_add_title_field_group_user_table.php index a946e4f..f5a18c3 100644 --- a/database/migrations/2023_02_20_160150_add_title_field_group_user_table.php +++ b/database/migrations/2023_02_20_160150_add_title_field_group_user_table.php @@ -4,7 +4,8 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class extends Migration { +return new class() extends Migration +{ public function up(): void { Schema::table('group_user', function (Blueprint $table) { diff --git a/database/migrations/2023_02_20_160405_add_types_to_groups_table.php b/database/migrations/2023_02_20_160405_add_types_to_groups_table.php index 32dfd5e..6f8d116 100644 --- a/database/migrations/2023_02_20_160405_add_types_to_groups_table.php +++ b/database/migrations/2023_02_20_160405_add_types_to_groups_table.php @@ -4,7 +4,8 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class extends Migration { +return new class() extends Migration +{ public function up(): void { Schema::table('groups', function (Blueprint $table) { @@ -19,7 +20,7 @@ public function up(): void public function down(): void { Schema::table('groups', function (Blueprint $table) { - $table->enum('type', ['none','department'])->default('none')->change(); + $table->enum('type', ['none', 'department'])->default('none')->change(); }); } diff --git a/database/migrations/2023_03_13_001722_add_secret_to_apps_table.php b/database/migrations/2023_03_13_001722_add_secret_to_apps_table.php index 3ce8d55..ab240f9 100644 --- a/database/migrations/2023_03_13_001722_add_secret_to_apps_table.php +++ b/database/migrations/2023_03_13_001722_add_secret_to_apps_table.php @@ -4,7 +4,8 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class extends Migration { +return new class() extends Migration +{ public function up() { Schema::table('apps', function (Blueprint $table) { diff --git a/database/migrations/2023_12_22_001949_make_name_and_description_in_groups_table_not_json.php b/database/migrations/2023_12_22_001949_make_name_and_description_in_groups_table_not_json.php index 4fcb0d5..d4ce6d9 100644 --- a/database/migrations/2023_12_22_001949_make_name_and_description_in_groups_table_not_json.php +++ b/database/migrations/2023_12_22_001949_make_name_and_description_in_groups_table_not_json.php @@ -4,7 +4,8 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class extends Migration { +return new class() extends Migration +{ public function up(): void { Schema::table('groups', function (Blueprint $table) { diff --git a/database/migrations/2024_01_21_233240_remove_two_factor_secret_from_users.php b/database/migrations/2024_01_21_233240_remove_two_factor_secret_from_users.php index 5d80391..af9bdac 100644 --- a/database/migrations/2024_01_21_233240_remove_two_factor_secret_from_users.php +++ b/database/migrations/2024_01_21_233240_remove_two_factor_secret_from_users.php @@ -4,7 +4,8 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class extends Migration { +return new class() extends Migration +{ public function up(): void { Schema::table('users', function (Blueprint $table) { diff --git a/database/migrations/2024_01_21_235202_create_two_factors_table.php b/database/migrations/2024_01_21_235202_create_two_factors_table.php index 259d294..f25e561 100644 --- a/database/migrations/2024_01_21_235202_create_two_factors_table.php +++ b/database/migrations/2024_01_21_235202_create_two_factors_table.php @@ -4,7 +4,8 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class extends Migration { +return new class() extends Migration +{ public function up(): void { Schema::create('two_factors', function (Blueprint $table) { diff --git a/database/migrations/2024_01_26_142612_add_system_name_to_apps_table.php b/database/migrations/2024_01_26_142612_add_system_name_to_apps_table.php index 99612d8..64f6e71 100644 --- a/database/migrations/2024_01_26_142612_add_system_name_to_apps_table.php +++ b/database/migrations/2024_01_26_142612_add_system_name_to_apps_table.php @@ -4,7 +4,8 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class extends Migration { +return new class() extends Migration +{ public function up(): void { Schema::table('apps', function (Blueprint $table) { diff --git a/database/migrations/2024_01_28_212812_add_system_name_to_groups_table.php b/database/migrations/2024_01_28_212812_add_system_name_to_groups_table.php index efd7b7b..19e0fcc 100644 --- a/database/migrations/2024_01_28_212812_add_system_name_to_groups_table.php +++ b/database/migrations/2024_01_28_212812_add_system_name_to_groups_table.php @@ -4,7 +4,8 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class extends Migration { +return new class() extends Migration +{ public function up(): void { Schema::table('groups', function (Blueprint $table) { diff --git a/database/migrations/2024_01_28_224525_add_unique_to_group_user.php b/database/migrations/2024_01_28_224525_add_unique_to_group_user.php index 146ff8e..d83375c 100644 --- a/database/migrations/2024_01_28_224525_add_unique_to_group_user.php +++ b/database/migrations/2024_01_28_224525_add_unique_to_group_user.php @@ -4,7 +4,8 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class extends Migration { +return new class() extends Migration +{ public function up(): void { Schema::table('group_user', function (Blueprint $table) { diff --git a/database/migrations/2024_05_26_152355_add_nextcloud_folder_name_to_groups_table.php b/database/migrations/2024_05_26_152355_add_nextcloud_folder_name_to_groups_table.php index 681ae74..037254a 100644 --- a/database/migrations/2024_05_26_152355_add_nextcloud_folder_name_to_groups_table.php +++ b/database/migrations/2024_05_26_152355_add_nextcloud_folder_name_to_groups_table.php @@ -4,7 +4,8 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class extends Migration { +return new class() extends Migration +{ public function up(): void { Schema::table('groups', function (Blueprint $table) { diff --git a/database/migrations/2024_05_26_214441_add_nextcloud_folder_id_to_groups_table.php b/database/migrations/2024_05_26_214441_add_nextcloud_folder_id_to_groups_table.php index 4ee7471..6185ccb 100644 --- a/database/migrations/2024_05_26_214441_add_nextcloud_folder_id_to_groups_table.php +++ b/database/migrations/2024_05_26_214441_add_nextcloud_folder_id_to_groups_table.php @@ -4,7 +4,8 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class extends Migration { +return new class() extends Migration +{ public function up(): void { Schema::table('groups', function (Blueprint $table) { diff --git a/database/migrations/2024_07_14_214614_update_description_in_groups_table.php b/database/migrations/2024_07_14_214614_update_description_in_groups_table.php index ea7f88e..a428402 100644 --- a/database/migrations/2024_07_14_214614_update_description_in_groups_table.php +++ b/database/migrations/2024_07_14_214614_update_description_in_groups_table.php @@ -4,7 +4,8 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class extends Migration { +return new class() extends Migration +{ public function up(): void { Schema::table('groups', function (Blueprint $table) { diff --git a/database/migrations/2024_08_14_000454_add_parent_id_to_groups_table.php b/database/migrations/2024_08_14_000454_add_parent_id_to_groups_table.php index 66c8e48..1bef98a 100644 --- a/database/migrations/2024_08_14_000454_add_parent_id_to_groups_table.php +++ b/database/migrations/2024_08_14_000454_add_parent_id_to_groups_table.php @@ -5,7 +5,8 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class extends Migration { +return new class() extends Migration +{ public function up(): void { Schema::table('groups', function (Blueprint $table) { diff --git a/database/seeders/AppSeeder.php b/database/seeders/AppSeeder.php index 40121a4..57cf370 100644 --- a/database/seeders/AppSeeder.php +++ b/database/seeders/AppSeeder.php @@ -25,23 +25,23 @@ public function createApp( string $clientName ) { $app = App::firstOrCreate([ - "system_name" => $systemName, + 'system_name' => $systemName, ], [ - "name" => $clientName, + 'name' => $clientName, 'public' => false, - 'description' => 'This is the official '.$clientName.'.', + 'description' => 'This is the official ' . $clientName . '.', 'icon' => 'CogsDuotone', - "system_name" => $systemName, + 'system_name' => $systemName, 'user_id' => User::first()->id, 'data' => [ - "client_name" => $clientName, - "redirect_uris" => [ + 'client_name' => $clientName, + 'redirect_uris' => [ route('login.apps.callback', ['app' => $systemName]), ], - "scope" => explode(" ", config('services.apps')[$systemName]['scopes']), - "token_endpoint_auth_method" => "client_secret_post", - "frontchannel_logout_uri" => route('login.apps.frontchannel-logout', ['app' => $systemName]), - ] + 'scope' => explode(' ', config('services.apps')[$systemName]['scopes']), + 'token_endpoint_auth_method' => 'client_secret_post', + 'frontchannel_logout_uri' => route('login.apps.frontchannel-logout', ['app' => $systemName]), + ], ]); // Check if App was just created if ($app->wasRecentlyCreated && app()->isLocal()) { @@ -50,8 +50,8 @@ public function createApp( $client_secret = $app->data['client_secret']; $envName = Str::upper($systemName); - shell_exec("sed -i \"s/.*IDENTITY_".$envName."_ID=.*/IDENTITY_".$envName."_ID=$client_id/\" .env"); - shell_exec("sed -i \"s/.*IDENTITY_".$envName."_SECRET=.*/IDENTITY_".$envName."_SECRET=$client_secret/\" .env"); + shell_exec('sed -i "s/.*IDENTITY_' . $envName . '_ID=.*/IDENTITY_' . $envName . "_ID=$client_id/\" .env"); + shell_exec('sed -i "s/.*IDENTITY_' . $envName . '_SECRET=.*/IDENTITY_' . $envName . "_SECRET=$client_secret/\" .env"); } } } diff --git a/database/seeders/UserSeeder.php b/database/seeders/UserSeeder.php index 700e31a..e15b7e2 100644 --- a/database/seeders/UserSeeder.php +++ b/database/seeders/UserSeeder.php @@ -22,14 +22,14 @@ public function run() } $user = User::firstOrCreate([ - "id" => 1 + 'id' => 1, ], [ - "name" => "Admin", - "email" => "identity@eurofurence.localhost", - "email_verified_at" => now(), - "password" => \Hash::make(random_bytes(32)) + 'name' => 'Admin', + 'email' => 'identity@eurofurence.localhost', + 'email_verified_at' => now(), + 'password' => \Hash::make(random_bytes(32)), ]); // Warning this user will be made admin! - $user->roles()->attach(Role::where('name','superadmin')->firstOrFail()); + $user->roles()->attach(Role::where('name', 'superadmin')->firstOrFail()); } } diff --git a/public/index.php b/public/index.php index 66ea93c..79f02c5 100644 --- a/public/index.php +++ b/public/index.php @@ -16,8 +16,8 @@ | */ -if (file_exists(__DIR__.'/../storage/framework/maintenance.php')) { - require __DIR__.'/../storage/framework/maintenance.php'; +if (file_exists(__DIR__ . '/../storage/framework/maintenance.php')) { + require __DIR__ . '/../storage/framework/maintenance.php'; } /* @@ -31,7 +31,7 @@ | */ -require __DIR__.'/../vendor/autoload.php'; +require __DIR__ . '/../vendor/autoload.php'; /* |-------------------------------------------------------------------------- @@ -44,7 +44,7 @@ | */ -$app = require_once __DIR__.'/../bootstrap/app.php'; +$app = require_once __DIR__ . '/../bootstrap/app.php'; $kernel = $app->make(Kernel::class); diff --git a/resources/lang/en/activity.php b/resources/lang/en/activity.php index fc8bd3b..1fb6edf 100644 --- a/resources/lang/en/activity.php +++ b/resources/lang/en/activity.php @@ -1,13 +1,14 @@ "Updated Resource", - "login" => "Successful login", - "login-app" => "Accessed App", - "login-failed" => "Failed login", - "lockout" => "Lockout", - "logout" => "Logout", - "password-reset" => "Password reset", - "verified" => "Verified email", - "registered" => "User created his account", + 'updated' => 'Updated Resource', + 'login' => 'Successful login', + 'login-app' => 'Accessed App', + 'login-failed' => 'Failed login', + 'lockout' => 'Lockout', + 'logout' => 'Logout', + 'password-reset' => 'Password reset', + 'verified' => 'Verified email', + 'registered' => 'User created his account', ]; diff --git a/routes/api.php b/routes/api.php index 22d9150..3884b8d 100644 --- a/routes/api.php +++ b/routes/api.php @@ -23,9 +23,9 @@ */ Route::middleware('auth:sanctum')->group(function () { Route::get('userinfo', UserinfoController::class)->name('userinfo'); - Route::apiResource("groups", GroupController::class); - Route::apiResource("groups.users", GroupUserController::class, [ - "only" => ["index", "store", "destroy"], + Route::apiResource('groups', GroupController::class); + Route::apiResource('groups.users', GroupUserController::class, [ + 'only' => ['index', 'store', 'destroy'], ]); }); /** diff --git a/routes/apps/portal.php b/routes/apps/portal.php index 463bfab..3cf9617 100644 --- a/routes/apps/portal.php +++ b/routes/apps/portal.php @@ -46,4 +46,3 @@ Route::post('/profile/avatar/store', StoreAvatarController::class) ->name('profile.avatar.store'); - diff --git a/routes/apps/staff.php b/routes/apps/staff.php index bc284af..ba2c995 100644 --- a/routes/apps/staff.php +++ b/routes/apps/staff.php @@ -8,9 +8,9 @@ // Forward / to /dashboard Route::redirect('/', '/dashboard'); Route::get('/dashboard', DashboardController::class)->name('dashboard'); -Route::resource('groups', GroupsController::class)->only(['index','show','update','destroy']); +Route::resource('groups', GroupsController::class)->only(['index', 'show', 'update', 'destroy']); Route::resource('groups.members', GroupMemberController::class); -Route::resource('groups.teams', GroupTeamController::class)->only(['index','store']); +Route::resource('groups.teams', GroupTeamController::class)->only(['index', 'store']); // rewrite /departments to /groups -Route::get('/departments', fn() => redirect()->route('groups.index')); -Route::get('/departments/{department}', fn($department) => redirect()->route('staff.groups.show', $department)); +Route::get('/departments', fn () => redirect()->route('groups.index')); +Route::get('/departments/{department}', fn ($department) => redirect()->route('staff.groups.show', $department)); diff --git a/server.php b/server.php index 5fb6379..24c8411 100644 --- a/server.php +++ b/server.php @@ -3,10 +3,8 @@ /** * Laravel - A PHP Framework For Web Artisans * - * @package Laravel * @author Taylor Otwell */ - $uri = urldecode( parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH) ); @@ -14,8 +12,8 @@ // This file allows us to emulate Apache's "mod_rewrite" functionality from the // built-in PHP web server. This provides a convenient way to test a Laravel // application without having installed a "real" web server software here. -if ($uri !== '/' && file_exists(__DIR__.'/public'.$uri)) { +if ($uri !== '/' && file_exists(__DIR__ . '/public' . $uri)) { return false; } -require_once __DIR__.'/public/index.php'; +require_once __DIR__ . '/public/index.php'; diff --git a/tests/Browser/ExampleTest.php b/tests/Browser/ExampleTest.php index d5ad6b6..15dc8f5 100644 --- a/tests/Browser/ExampleTest.php +++ b/tests/Browser/ExampleTest.php @@ -2,7 +2,6 @@ namespace Tests\Browser; -use Illuminate\Foundation\Testing\DatabaseMigrations; use Laravel\Dusk\Browser; use Tests\DuskTestCase; @@ -15,7 +14,7 @@ public function testBasicExample(): void { $this->browse(function (Browser $browser) { $browser->visit('/') - ->assertSee('Laravel'); + ->assertSee('Laravel'); }); } } diff --git a/tests/Browser/LoginTest.php b/tests/Browser/LoginTest.php index 5da36b0..9bfe565 100644 --- a/tests/Browser/LoginTest.php +++ b/tests/Browser/LoginTest.php @@ -2,7 +2,6 @@ namespace Tests\Browser; -use Illuminate\Foundation\Testing\DatabaseMigrations; use Laravel\Dusk\Browser; use Tests\DuskTestCase; @@ -15,7 +14,7 @@ public function testExample(): void { $this->browse(function (Browser $browser) { $browser->visit('/') - ->assertSee('Laravel'); + ->assertSee('Laravel'); }); } } diff --git a/tests/CreatesApplication.php b/tests/CreatesApplication.php index 547152f..ab92402 100644 --- a/tests/CreatesApplication.php +++ b/tests/CreatesApplication.php @@ -13,7 +13,7 @@ trait CreatesApplication */ public function createApplication() { - $app = require __DIR__.'/../bootstrap/app.php'; + $app = require __DIR__ . '/../bootstrap/app.php'; $app->make(Kernel::class)->bootstrap(); diff --git a/tests/DuskTestCase.php b/tests/DuskTestCase.php index 3dfbbe3..b550606 100644 --- a/tests/DuskTestCase.php +++ b/tests/DuskTestCase.php @@ -2,10 +2,10 @@ namespace Tests; -use Illuminate\Support\Collection; use Facebook\WebDriver\Chrome\ChromeOptions; use Facebook\WebDriver\Remote\DesiredCapabilities; use Facebook\WebDriver\Remote\RemoteWebDriver; +use Illuminate\Support\Collection; use Laravel\Dusk\TestCase as BaseTestCase; abstract class DuskTestCase extends BaseTestCase @@ -29,7 +29,7 @@ public static function prepare(): void */ protected function driver(): RemoteWebDriver { - $options = (new ChromeOptions)->addArguments(collect([ + $options = (new ChromeOptions())->addArguments(collect([ $this->shouldStartMaximized() ? '--start-maximized' : '--window-size=1920,1080', ])->unless($this->hasHeadlessDisabled(), function (Collection $items) { return $items->merge([ diff --git a/tests/Feature/Api/v1/GroupsTest.php b/tests/Feature/Api/v1/GroupsTest.php index af0c5d0..d6f8415 100644 --- a/tests/Feature/Api/v1/GroupsTest.php +++ b/tests/Feature/Api/v1/GroupsTest.php @@ -7,6 +7,7 @@ use App\Models\User; use Illuminate\Foundation\Testing\RefreshDatabase; use Laravel\Sanctum\Sanctum; + use function Pest\Laravel\assertDatabaseHas; use function Pest\Laravel\assertDatabaseMissing; use function Pest\Laravel\delete; @@ -30,13 +31,13 @@ $group->users()->sync([$user->id => ['level' => GroupUserLevel::Owner]]); $data = [ - "type" => "none", - "name" => "Testgroup", + 'type' => 'none', + 'name' => 'Testgroup', ]; $request = postJson(route('api.v1.groups.store'), $data); $request->assertSuccessful(); assertDatabaseHas('groups', [ - "type" => "none", + 'type' => 'none', ]); }); @@ -50,15 +51,15 @@ $user->assignRole('superadmin'); $data = [ - "type" => "none", - "name" => "Testgroup", + 'type' => 'none', + 'name' => 'Testgroup', ]; $request = postJson(route('api.v1.groups.store'), $data); $request->assertSuccessful(); assertDatabaseHas('group_user', [ - "level" => "owner", - "group_id" => Hashids::connection('group')->decode($request->json('data')['id'])[0], - "user_id" => $user->id, + 'level' => 'owner', + 'group_id' => Hashids::connection('group')->decode($request->json('data')['id'])[0], + 'user_id' => $user->id, ]); }); @@ -72,14 +73,14 @@ $group->users()->sync([$user->id => ['level' => GroupUserLevel::Owner]]); $data = [ - "type" => "none", - "name" => "Testgroup", + 'type' => 'none', + 'name' => 'Testgroup', ]; $request = postJson(route('api.v1.groups.store'), $data); $request->assertForbidden(); assertDatabaseMissing('groups', [ - "type" => "none", - "name" => "Testgroup", + 'type' => 'none', + 'name' => 'Testgroup', ]); }); @@ -93,20 +94,20 @@ $group->users()->sync([$user->id => ['level' => GroupUserLevel::Owner]]); $data = [ - "type" => "none", - "name" => "Testgroup", + 'type' => 'none', + 'name' => 'Testgroup', ]; // Assert $user is level owner in group assertDatabaseHas('group_user', [ - "level" => "owner", - "group_id" => $group->id, - "user_id" => $user->id, + 'level' => 'owner', + 'group_id' => $group->id, + 'user_id' => $user->id, ]); $request = putJson(route('api.v1.groups.update', $group), $data); $request->assertSuccessful(); assertDatabaseHas('groups', [ - "type" => "none", + 'type' => 'none', ]); }); @@ -120,14 +121,14 @@ $group->users()->sync([$user->id => ['level' => GroupUserLevel::Member]]); $data = [ - "type" => "none", - "name" => "Testgroup", + 'type' => 'none', + 'name' => 'Testgroup', ]; $request = put(route('api.v1.groups.update', $group), $data); $request->assertForbidden(); assertDatabaseMissing('groups', [ - "type" => "none", - "name" => "Testgroup", + 'type' => 'none', + 'name' => 'Testgroup', ]); }); @@ -141,14 +142,14 @@ $group->users()->sync([$user->id => ['level' => GroupUserLevel::Moderator]]); $data = [ - "type" => "none", - "name" => "Testgroup", + 'type' => 'none', + 'name' => 'Testgroup', ]; $request = put(route('api.v1.groups.update', $group), $data); $request->assertForbidden(); assertDatabaseMissing('groups', [ - "type" => "none", - "name" => "Testgroup", + 'type' => 'none', + 'name' => 'Testgroup', ]); }); @@ -162,14 +163,14 @@ $group->users()->sync([$user->id => ['level' => GroupUserLevel::Owner]]); $data = [ - "type" => "none", - "name" => "Testgroup", + 'type' => 'none', + 'name' => 'Testgroup', ]; $request = put(route('api.v1.groups.update', $group), $data); $request->assertSuccessful(); assertDatabaseHas('groups', [ - "type" => "none", - "name" => "Testgroup", + 'type' => 'none', + 'name' => 'Testgroup', ]); }); @@ -182,17 +183,16 @@ ); assertDatabaseHas('groups', [ - "logo" => $group->logo, + 'logo' => $group->logo, ]); $group->users()->sync([$user->id => ['level' => GroupUserLevel::Owner]]); $request = delete(route('api.v1.groups.destroy', $group)); $request->assertSuccessful(); assertDatabaseMissing('groups', [ - "logo" => $group->logo, + 'logo' => $group->logo, ]); }); - test('Delete Group success as non-owner', function () { $group = Group::factory()->create(); @@ -205,7 +205,6 @@ $request->assertForbidden(); }); - test('Get single group', function () { $group = Group::factory()->create(); @@ -217,8 +216,8 @@ $request = get(route('api.v1.groups.show', $group)); $request->assertSuccessful(); $request->assertJson([ - "data" => [ - "name" => $group->name, + 'data' => [ + 'name' => $group->name, ], ]); }); @@ -233,7 +232,7 @@ $request = get(route('api.v1.groups.index', $group)); $request->assertSuccessful(); $request->assertJsonFragment([ - "name" => $group->name, + 'name' => $group->name, ]); }); @@ -246,8 +245,8 @@ ); $userToBeInvited = User::factory()->create(); $data = [ - "email" => $userToBeInvited->email, - "level" => "member", + 'email' => $userToBeInvited->email, + 'level' => 'member', ]; $group->users()->sync([$user->id => ['level' => GroupUserLevel::Admin]]); @@ -255,14 +254,14 @@ $request->assertSuccessful(); // verify response contains user_id, group_id and level $request->assertJsonFragment([ - "user_id" => $userToBeInvited->hashid, - "group_id" => $group->hashid, - "level" => "member", + 'user_id' => $userToBeInvited->hashid, + 'group_id' => $group->hashid, + 'level' => 'member', ]); assertDatabaseHas('group_user', [ - "user_id" => $userToBeInvited->id, - "group_id" => $group->id, - "level" => "member", + 'user_id' => $userToBeInvited->id, + 'group_id' => $group->id, + 'level' => 'member', ]); }); @@ -276,8 +275,8 @@ ); $userToBeInvited = User::factory()->create(); $data = [ - "email" => $userToBeInvited->email, - "level" => "member", + 'email' => $userToBeInvited->email, + 'level' => 'member', ]; $group->users()->sync([$user->id => ['level' => GroupUserLevel::Admin]]); @@ -285,14 +284,14 @@ $request->assertSuccessful(); // verify response contains user_id, group_id and level $request->assertJsonFragment([ - "user_id" => $userToBeInvited->hashid, - "group_id" => $group->hashid, - "level" => "member", + 'user_id' => $userToBeInvited->hashid, + 'group_id' => $group->hashid, + 'level' => 'member', ]); assertDatabaseHas('group_user', [ - "user_id" => $userToBeInvited->id, - "group_id" => $group->id, - "level" => "member", + 'user_id' => $userToBeInvited->id, + 'group_id' => $group->id, + 'level' => 'member', ]); $request = postJson(route('api.v1.groups.users.store', $group), $data, ['Accept' => 'application/json']); @@ -308,8 +307,8 @@ ); $userToBeInvited = User::factory()->create(); $data = [ - "id" => $userToBeInvited->hashid, - "level" => "member", + 'id' => $userToBeInvited->hashid, + 'level' => 'member', ]; $group->users()->sync([$user->id => ['level' => GroupUserLevel::Admin]]); @@ -318,14 +317,14 @@ $request->assertSuccessful(); // verify response contains user_id, group_id and level $request->assertJsonFragment([ - "user_id" => $userToBeInvited->hashid, - "group_id" => $group->hashid, - "level" => "member", + 'user_id' => $userToBeInvited->hashid, + 'group_id' => $group->hashid, + 'level' => 'member', ]); assertDatabaseHas('group_user', [ - "user_id" => $userToBeInvited->id, - "group_id" => $group->id, - "level" => "member", + 'user_id' => $userToBeInvited->id, + 'group_id' => $group->id, + 'level' => 'member', ]); }); @@ -338,9 +337,9 @@ ); $userToBeInvited = User::factory()->create(); $data = [ - "id" => $userToBeInvited->hashid, - "email" => $userToBeInvited->email, - "level" => "member", + 'id' => $userToBeInvited->hashid, + 'email' => $userToBeInvited->email, + 'level' => 'member', ]; $group->users()->sync([$user->id => ['level' => GroupUserLevel::Admin]]); @@ -358,8 +357,8 @@ ); $userToBeInvited = User::factory()->create(); $data = [ - "email" => $userToBeInvited->email, - "level" => "member", + 'email' => $userToBeInvited->email, + 'level' => 'member', ]; $group->users()->sync([$user->id => ['level' => GroupUserLevel::Admin]]); @@ -376,8 +375,8 @@ ); $userToBeInvited = User::factory()->create(); $data = [ - "email" => $userToBeInvited->email, - "level" => "member", + 'email' => $userToBeInvited->email, + 'level' => 'member', ]; $group->users()->sync([$user->id => ['level' => GroupUserLevel::Member]]); @@ -385,7 +384,6 @@ $request->assertForbidden(); }); - test('Remove member to group as admin', function () { $group = Group::factory()->create(); @@ -400,18 +398,17 @@ ]); assertDatabaseHas('group_user', [ - "user_id" => $userToBeDeleted->id, - "group_id" => $group->id, + 'user_id' => $userToBeDeleted->id, + 'group_id' => $group->id, ]); - $request = delete(route('api.v1.groups.users.destroy', ["group" => $group, "user" => $userToBeDeleted])); + $request = delete(route('api.v1.groups.users.destroy', ['group' => $group, 'user' => $userToBeDeleted])); $request->assertSuccessful(); assertDatabaseMissing('group_user', [ - "user_id" => $userToBeDeleted->id, - "group_id" => $group->id, + 'user_id' => $userToBeDeleted->id, + 'group_id' => $group->id, ]); }); - test('Get list of members as admin', function () { $group = Group::factory()->create(); @@ -425,12 +422,12 @@ $userToBeDeleted->id => ['level' => GroupUserLevel::Member], ]); - $request = get(route('api.v1.groups.users.index', ["group" => $group])); + $request = get(route('api.v1.groups.users.index', ['group' => $group])); $request->assertSuccessful(); $request->assertJsonFragment([ - "user_id" => $user->hashid, - "group_id" => $group->hashid, - "level" => GroupUserLevel::Admin, + 'user_id' => $user->hashid, + 'group_id' => $group->hashid, + 'level' => GroupUserLevel::Admin, ]); }); @@ -445,11 +442,10 @@ $request = get(route('api.v1.groups.index', $group)); $request->assertSuccessful(); $request->assertJsonMissing([ - "name" => $group->name, + 'name' => $group->name, ]); }); - test('Ensure that staff user can see all department and own groups', function () { $user = Sanctum::actingAs( User::factory()->create(), @@ -457,28 +453,28 @@ ); // Add user to group with system_name staff, create it first $staffGroup = Group::factory()->create([ - "system_name" => "staff", - "type" => GroupTypeEnum::Automated, + 'system_name' => 'staff', + 'type' => GroupTypeEnum::Automated, ]); // Add user to group $staffGroup->users()->sync([$user->id => ['level' => GroupUserLevel::Member]]); // Other Group of type none $groupMem = Group::factory()->create([ - "type" => GroupTypeEnum::Default, + 'type' => GroupTypeEnum::Default, ]); // Add user to group $groupMem->users()->sync([$user->id => ['level' => GroupUserLevel::Member]]); // Other group where user is not member $group2 = Group::factory()->create([ - "type" => GroupTypeEnum::Default, + 'type' => GroupTypeEnum::Default, ]); // Remove user $group2->users()->detach($user->id); $group = Group::factory()->create([ - "type" => GroupTypeEnum::Department, + 'type' => GroupTypeEnum::Department, ]); // Add user to group $group->users()->sync([$user->id => ['level' => GroupUserLevel::Member]]); @@ -486,13 +482,13 @@ $request = get(route('api.v1.groups.index')); $request->assertSuccessful(); $request->assertJsonFragment([ - "name" => $groupMem->name, + 'name' => $groupMem->name, ]); $request->assertJsonFragment([ - "name" => $staffGroup->name, + 'name' => $staffGroup->name, ]); // group2 should be missing $request->assertJsonMissing([ - "name" => $group2->name, + 'name' => $group2->name, ]); }); diff --git a/tests/Feature/Api/v1/UserinfoTest.php b/tests/Feature/Api/v1/UserinfoTest.php index 3c6457b..ad32336 100644 --- a/tests/Feature/Api/v1/UserinfoTest.php +++ b/tests/Feature/Api/v1/UserinfoTest.php @@ -5,6 +5,7 @@ use App\Models\User; use Illuminate\Foundation\Testing\RefreshDatabase; use Laravel\Sanctum\Sanctum; + use function Pest\Laravel\get; uses(RefreshDatabase::class); @@ -18,10 +19,10 @@ $response = get(route('api.v1.userinfo')); $response->assertStatus(200); $response->assertJson([ - "sub" => $user->hashid, + 'sub' => $user->hashid, ]); $response->assertJsonMissing([ - "name" => $user->name, + 'name' => $user->name, ]); }); @@ -34,12 +35,11 @@ $response = get(route('api.v1.userinfo')); $response->assertStatus(200); $response->assertJson([ - "sub" => $user->hashid, - "name" => $user->name, + 'sub' => $user->hashid, + 'name' => $user->name, ]); }); - test('Userinfo Authenticated - Show groups that user is member', function () { $user = Sanctum::actingAs( User::factory()->create(), @@ -50,15 +50,15 @@ /** * @type User $user */ - $user->groups()->attach($group, ["level" => GroupUserLevel::Member]); + $user->groups()->attach($group, ['level' => GroupUserLevel::Member]); $response = get(route('api.v1.userinfo')); $response->assertStatus(200); $response->assertJsonFragment([ - "groups" => [ + 'groups' => [ $group->hashid, ], ]); }); -# echo hello +// echo hello diff --git a/tests/Feature/Auth/CreateNewAccountTest.php b/tests/Feature/Auth/CreateNewAccountTest.php index c300673..9f1ea4e 100644 --- a/tests/Feature/Auth/CreateNewAccountTest.php +++ b/tests/Feature/Auth/CreateNewAccountTest.php @@ -3,6 +3,7 @@ use App\Models\User; use Illuminate\Auth\Events\Registered; use Illuminate\Foundation\Testing\RefreshDatabase; + use function Pest\Laravel\post; use function PHPUnit\Framework\assertEquals; @@ -13,10 +14,10 @@ Event::fake(); Notification::fake(); $response = post(route('auth.register.store'), [ - "username" => "Test", - "email" => "test@eurofurence.org", - "password" => "OSANR&dbb^0GDp^19UiSxRlM3Wm", - "password_confirmation" => "OSANR&dbb^0GDp^19UiSxRlM3Wm", + 'username' => 'Test', + 'email' => 'test@eurofurence.org', + 'password' => 'OSANR&dbb^0GDp^19UiSxRlM3Wm', + 'password_confirmation' => 'OSANR&dbb^0GDp^19UiSxRlM3Wm', ]); $response->assertRedirect(route('login.apps.redirect', ['app' => 'portal'])); Event::assertDispatched(Registered::class); @@ -26,5 +27,5 @@ Mail::fake(); $user = User::factory()->create(); event(new Registered($user)); - assertEquals("registered", $user->actions->first()->description); + assertEquals('registered', $user->actions->first()->description); }); diff --git a/tests/Feature/Auth/LoginTest.php b/tests/Feature/Auth/LoginTest.php index f22f16f..3566bfd 100644 --- a/tests/Feature/Auth/LoginTest.php +++ b/tests/Feature/Auth/LoginTest.php @@ -2,6 +2,7 @@ use App\Models\User; use Illuminate\Foundation\Testing\RefreshDatabase; + use function Pest\Laravel\post; use function Pest\Laravel\postJson; @@ -10,18 +11,18 @@ test('User login success', function () { $password = Str::random(15); $user = User::factory()->create([ - "password" => Hash::make($password), + 'password' => Hash::make($password), ]); Http::fake([ - "*" => Http::response([ - "redirect_to" => "https://success.com", + '*' => Http::response([ + 'redirect_to' => 'https://success.com', ]), ]); $response = post(route('auth.login.submit'), [ - "login_challenge" => "test", - "remember" => true, - "email" => $user->email, - "password" => $password, + 'login_challenge' => 'test', + 'remember' => true, + 'email' => $user->email, + 'password' => $password, ]); $response->assertStatus(302); @@ -30,46 +31,45 @@ test('User false password error', function () { $password = Str::random(15); $user = User::factory()->create([ - "password" => Hash::make($password), + 'password' => Hash::make($password), ]); $response = postJson(route('auth.login.submit'), [ - "login_challenge" => "test", - "remember" => true, - "email" => $user->email, - "password" => "wrong password", + 'login_challenge' => 'test', + 'remember' => true, + 'email' => $user->email, + 'password' => 'wrong password', ]); - $response->assertJsonValidationErrorFor("nouser"); + $response->assertJsonValidationErrorFor('nouser'); }); - test('User false email error', function () { $password = Str::random(15); $user = User::factory()->create([ - "password" => Hash::make($password), + 'password' => Hash::make($password), ]); $response = postJson(route('auth.login.submit'), [ - "login_challenge" => "test", - "remember" => true, - "email" => "falsemail@test.de", - "password" => $password, + 'login_challenge' => 'test', + 'remember' => true, + 'email' => 'falsemail@test.de', + 'password' => $password, ]); - $response->assertJsonValidationErrorFor("nouser"); + $response->assertJsonValidationErrorFor('nouser'); }); test('User false email formatting error', function () { $password = Str::random(15); $user = User::factory()->create([ - "password" => Hash::make($password), + 'password' => Hash::make($password), ]); $response = postJson(route('auth.login.submit'), [ - "login_challenge" => "test", - "remember" => true, - "email" => "falsemai2121ltest.de", - "password" => $password, + 'login_challenge' => 'test', + 'remember' => true, + 'email' => 'falsemai2121ltest.de', + 'password' => $password, ]); - $response->assertJsonValidationErrorFor("email"); + $response->assertJsonValidationErrorFor('email'); }); diff --git a/tests/Feature/ErrorUserDeletedTest.php b/tests/Feature/ErrorUserDeletedTest.php index ac1a4cd..6e67a33 100644 --- a/tests/Feature/ErrorUserDeletedTest.php +++ b/tests/Feature/ErrorUserDeletedTest.php @@ -6,32 +6,31 @@ test('If user is deleted, system should reject consent', function () { Http::fake([ - config('services.hydra.admin')."/admin/oauth2/auth/requests/consent?challenge=*" => Http::response([ - "subject" => "I_do_not_exist", - "challenge" => "TEST123" + config('services.hydra.admin') . '/admin/oauth2/auth/requests/consent?challenge=*' => Http::response([ + 'subject' => 'I_do_not_exist', + 'challenge' => 'TEST123', ]), - config('services.hydra.admin')."/admin/oauth2/auth/requests/consent/reject?challenge=*" => Http::response([ - "redirect_to" => "https://unverified" + config('services.hydra.admin') . '/admin/oauth2/auth/requests/consent/reject?challenge=*' => Http::response([ + 'redirect_to' => 'https://unverified', ]), ]); - $response = \Pest\Laravel\get(route('auth.consent',["consent_challenge" => "TEST123"])); - $response->assertRedirect("https://unverified"); + $response = \Pest\Laravel\get(route('auth.consent', ['consent_challenge' => 'TEST123'])); + $response->assertRedirect('https://unverified'); }); - test('If user exists, consent should be forwarded', function () { $user = \App\Models\User::factory()->create(); Http::fake([ - config('services.hydra.admin')."/admin/oauth2/auth/requests/consent?challenge=*" => Http::response([ - "subject" => $user->hashid(), - "challenge" => "TEST123", - "requested_scope" => ["openid"], - "requested_access_token_audience" => ["https://localhost/"], + config('services.hydra.admin') . '/admin/oauth2/auth/requests/consent?challenge=*' => Http::response([ + 'subject' => $user->hashid(), + 'challenge' => 'TEST123', + 'requested_scope' => ['openid'], + 'requested_access_token_audience' => ['https://localhost/'], ]), - config('services.hydra.admin')."/admin/oauth2/auth/requests/consent/accept?challenge=*" => Http::response([ - "redirect_to" => "https://verified" + config('services.hydra.admin') . '/admin/oauth2/auth/requests/consent/accept?challenge=*' => Http::response([ + 'redirect_to' => 'https://verified', ]), ]); - $response = \Pest\Laravel\get(route('auth.consent',["consent_challenge" => "TEST123"])); - $response->assertRedirect("https://verified"); + $response = \Pest\Laravel\get(route('auth.consent', ['consent_challenge' => 'TEST123'])); + $response->assertRedirect('https://verified'); }); diff --git a/tests/Feature/Profile/UpdateEmailTest.php b/tests/Feature/Profile/UpdateEmailTest.php index e1e1ee8..d1223b3 100644 --- a/tests/Feature/Profile/UpdateEmailTest.php +++ b/tests/Feature/Profile/UpdateEmailTest.php @@ -23,8 +23,8 @@ public function testCanUpdateEmail() $user = $this->makeAuthSession(); $response = $this->postJson(route('settings.update-profile.update'), [ - "name" => 'validname', - "email" => "test2@email.de" + 'name' => 'validname', + 'email' => 'test2@email.de', ]); $response->assertRedirect(); $response->assertSessionHasNoErrors(); @@ -36,18 +36,18 @@ public function testCanUseSignedRouteToUpdateEmail() $user = $this->makeAuthSession(); $oldMail = $user->email; - $this->assertNotEquals($user->email, "test2@email.de"); - Cache::put('user:'.$user->hashid.':newEmail', "test2@email.de"); + $this->assertNotEquals($user->email, 'test2@email.de'); + Cache::put('user:' . $user->hashid . ':newEmail', 'test2@email.de'); $response = $this->get(URL::signedRoute('settings.update-profile.email.update', [ 'id' => $user->hashid, - "newEmail" => sha1("test2@email.de") + 'newEmail' => sha1('test2@email.de'), ])); $user->refresh(); - $response->assertInertia(fn($page) => $page->component('Auth/VerifyEmailSuccess')); + $response->assertInertia(fn ($page) => $page->component('Auth/VerifyEmailSuccess')); $response->assertSuccessful(); - $this->assertEquals("test2@email.de", $user->email); + $this->assertEquals('test2@email.de', $user->email); } diff --git a/tests/Feature/Staff/GroupMemberTest.php b/tests/Feature/Staff/GroupMemberTest.php index 4d5eed6..4a5bf4d 100644 --- a/tests/Feature/Staff/GroupMemberTest.php +++ b/tests/Feature/Staff/GroupMemberTest.php @@ -7,6 +7,7 @@ use App\Models\Group; use App\Models\User; use Illuminate\Foundation\Testing\RefreshDatabase; + use function Pest\Laravel\patchJson; uses(RefreshDatabase::class); @@ -36,11 +37,11 @@ var_dump(GroupUserLevel::Admin->name); $response = patchJson( - route('staff.groups.members.update', ["group" => $group, 'member' => $userToBeUpdated]), - ["level" => GroupUserLevel::Admin->value], + route('staff.groups.members.update', ['group' => $group, 'member' => $userToBeUpdated]), + ['level' => GroupUserLevel::Admin->value], ); - $response->assertRedirect(route('staff.groups.members.index', ["group" => $group])); + $response->assertRedirect(route('staff.groups.members.index', ['group' => $group])); expect($group->users()->find($userToBeUpdated)->pivot->level) ->toBe(GroupUserLevel::Admin); diff --git a/tests/TestCase.php b/tests/TestCase.php index 31e402a..e5a3a9b 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -13,6 +13,7 @@ public function makeAuthSession() { $user = User::factory()->create(); $this->actingAs($user); + return $user; } } diff --git a/tests/Unit/HydraAppTest.php b/tests/Unit/HydraAppTest.php index c5499e9..67306f7 100644 --- a/tests/Unit/HydraAppTest.php +++ b/tests/Unit/HydraAppTest.php @@ -14,53 +14,53 @@ public function test_create_hydra_app() { Http::fake([ '*' => Http::response([ - "client_id" => "2b83b3ea-7021-455f-b07d-9c00c74436f2", - "client_name" => "Test", - "client_secret" => "mM~CL93svezjf-5Yr3xG51u6jm", - "redirect_uris" => null, - "grant_types" => [ - 0 => "authorization_code", - 1 => "refresh_token", + 'client_id' => '2b83b3ea-7021-455f-b07d-9c00c74436f2', + 'client_name' => 'Test', + 'client_secret' => 'mM~CL93svezjf-5Yr3xG51u6jm', + 'redirect_uris' => null, + 'grant_types' => [ + 0 => 'authorization_code', + 1 => 'refresh_token', ], - "response_types" => [ - 0 => "code", + 'response_types' => [ + 0 => 'code', ], - "scope" => "openid", - "audience" => [], - "owner" => "", - "policy_uri" => "", - "allowed_cors_origins" => [], - "tos_uri" => "", - "client_uri" => "", - "logo_uri" => "", - "contacts" => null, - "client_secret_expires_at" => 0, - "subject_type" => "public", - "jwks" => [], - "token_endpoint_auth_method" => "client_secret_post", - "request_object_signing_alg" => "RS256", - "userinfo_signed_response_alg" => "none", - "created_at" => "2023-02-05T20:17:23Z", - "updated_at" => "2023-02-05T20:17:23.301609Z", - "metadata" => [], - "registration_access_token" => "ory_at_udqWbEdg3tE_dcwJT2-8SjM107L5trNo6aGpz0kCJ3w.yEiDwxN-lEDus4PNWDA_WhYOO-ZYJofvRc-EK_5d-00", - "registration_client_uri" => "http://identity.eurofurence.localhost/oauth2/register/2b83b3ea-7021-455f-b07d-9c00c74436f2", - "authorization_code_grant_access_token_lifespan" => null, - "authorization_code_grant_id_token_lifespan" => null, - "authorization_code_grant_refresh_token_lifespan" => null, - "client_credentials_grant_access_token_lifespan" => null, - "implicit_grant_access_token_lifespan" => null, - "implicit_grant_id_token_lifespan" => null, - "jwt_bearer_grant_access_token_lifespan" => null, - "refresh_token_grant_id_token_lifespan" => null, - "refresh_token_grant_access_token_lifespan" => null, - "refresh_token_grant_refresh_token_lifespan" => null, - ]) + 'scope' => 'openid', + 'audience' => [], + 'owner' => '', + 'policy_uri' => '', + 'allowed_cors_origins' => [], + 'tos_uri' => '', + 'client_uri' => '', + 'logo_uri' => '', + 'contacts' => null, + 'client_secret_expires_at' => 0, + 'subject_type' => 'public', + 'jwks' => [], + 'token_endpoint_auth_method' => 'client_secret_post', + 'request_object_signing_alg' => 'RS256', + 'userinfo_signed_response_alg' => 'none', + 'created_at' => '2023-02-05T20:17:23Z', + 'updated_at' => '2023-02-05T20:17:23.301609Z', + 'metadata' => [], + 'registration_access_token' => 'ory_at_udqWbEdg3tE_dcwJT2-8SjM107L5trNo6aGpz0kCJ3w.yEiDwxN-lEDus4PNWDA_WhYOO-ZYJofvRc-EK_5d-00', + 'registration_client_uri' => 'http://identity.eurofurence.localhost/oauth2/register/2b83b3ea-7021-455f-b07d-9c00c74436f2', + 'authorization_code_grant_access_token_lifespan' => null, + 'authorization_code_grant_id_token_lifespan' => null, + 'authorization_code_grant_refresh_token_lifespan' => null, + 'client_credentials_grant_access_token_lifespan' => null, + 'implicit_grant_access_token_lifespan' => null, + 'implicit_grant_id_token_lifespan' => null, + 'jwt_bearer_grant_access_token_lifespan' => null, + 'refresh_token_grant_id_token_lifespan' => null, + 'refresh_token_grant_access_token_lifespan' => null, + 'refresh_token_grant_refresh_token_lifespan' => null, + ]), ]); $app = new App(); $app = $app->create([ - "client_name" => "Test", - "token_endpoint_auth_method" => "client_secret_post" + 'client_name' => 'Test', + 'token_endpoint_auth_method' => 'client_secret_post', ]); $app->delete(); @@ -71,106 +71,106 @@ public function test_update_hydra_app() { Http::fake([ 'http://localhost:4445/admin/clients' => [ - "client_id" => "2b83b3ea-7021-455f-b07d-9c00c74436f2", - "client_name" => "Test", - "client_secret" => "mM~CL93svezjf-5Yr3xG51u6jm", - "redirect_uris" => null, - "grant_types" => [ - 0 => "authorization_code", - 1 => "refresh_token", + 'client_id' => '2b83b3ea-7021-455f-b07d-9c00c74436f2', + 'client_name' => 'Test', + 'client_secret' => 'mM~CL93svezjf-5Yr3xG51u6jm', + 'redirect_uris' => null, + 'grant_types' => [ + 0 => 'authorization_code', + 1 => 'refresh_token', ], - "response_types" => [ - 0 => "code", + 'response_types' => [ + 0 => 'code', ], - "scope" => "openid", - "audience" => [], - "owner" => "", - "policy_uri" => "", - "allowed_cors_origins" => [], - "tos_uri" => "", - "client_uri" => "", - "logo_uri" => "", - "contacts" => null, - "client_secret_expires_at" => 0, - "subject_type" => "public", - "jwks" => [], - "token_endpoint_auth_method" => "client_secret_post", - "request_object_signing_alg" => "RS256", - "userinfo_signed_response_alg" => "none", - "created_at" => "2023-02-05T20:17:23Z", - "updated_at" => "2023-02-05T20:17:23.301609Z", - "metadata" => [], - "registration_access_token" => "ory_at_udqWbEdg3tE_dcwJT2-8SjM107L5trNo6aGpz0kCJ3w.yEiDwxN-lEDus4PNWDA_WhYOO-ZYJofvRc-EK_5d-00", - "registration_client_uri" => "http://identity.eurofurence.localhost/oauth2/register/2b83b3ea-7021-455f-b07d-9c00c74436f2", - "authorization_code_grant_access_token_lifespan" => null, - "authorization_code_grant_id_token_lifespan" => null, - "authorization_code_grant_refresh_token_lifespan" => null, - "client_credentials_grant_access_token_lifespan" => null, - "implicit_grant_access_token_lifespan" => null, - "implicit_grant_id_token_lifespan" => null, - "jwt_bearer_grant_access_token_lifespan" => null, - "refresh_token_grant_id_token_lifespan" => null, - "refresh_token_grant_access_token_lifespan" => null, - "refresh_token_grant_refresh_token_lifespan" => null, + 'scope' => 'openid', + 'audience' => [], + 'owner' => '', + 'policy_uri' => '', + 'allowed_cors_origins' => [], + 'tos_uri' => '', + 'client_uri' => '', + 'logo_uri' => '', + 'contacts' => null, + 'client_secret_expires_at' => 0, + 'subject_type' => 'public', + 'jwks' => [], + 'token_endpoint_auth_method' => 'client_secret_post', + 'request_object_signing_alg' => 'RS256', + 'userinfo_signed_response_alg' => 'none', + 'created_at' => '2023-02-05T20:17:23Z', + 'updated_at' => '2023-02-05T20:17:23.301609Z', + 'metadata' => [], + 'registration_access_token' => 'ory_at_udqWbEdg3tE_dcwJT2-8SjM107L5trNo6aGpz0kCJ3w.yEiDwxN-lEDus4PNWDA_WhYOO-ZYJofvRc-EK_5d-00', + 'registration_client_uri' => 'http://identity.eurofurence.localhost/oauth2/register/2b83b3ea-7021-455f-b07d-9c00c74436f2', + 'authorization_code_grant_access_token_lifespan' => null, + 'authorization_code_grant_id_token_lifespan' => null, + 'authorization_code_grant_refresh_token_lifespan' => null, + 'client_credentials_grant_access_token_lifespan' => null, + 'implicit_grant_access_token_lifespan' => null, + 'implicit_grant_id_token_lifespan' => null, + 'jwt_bearer_grant_access_token_lifespan' => null, + 'refresh_token_grant_id_token_lifespan' => null, + 'refresh_token_grant_access_token_lifespan' => null, + 'refresh_token_grant_refresh_token_lifespan' => null, ], 'http://localhost:4445/admin/clients/2b83b3ea-7021-455f-b07d-9c00c74436f2' => [ - "client_id" => "2b83b3ea-7021-455f-b07d-9c00c74436f2", - "client_name" => "New", - "client_secret" => null, - "redirect_uris" => null, - "grant_types" => [ - 0 => "authorization_code", - 1 => "refresh_token", + 'client_id' => '2b83b3ea-7021-455f-b07d-9c00c74436f2', + 'client_name' => 'New', + 'client_secret' => null, + 'redirect_uris' => null, + 'grant_types' => [ + 0 => 'authorization_code', + 1 => 'refresh_token', ], - "response_types" => [ - 0 => "code", + 'response_types' => [ + 0 => 'code', ], - "scope" => "openid", - "audience" => [], - "owner" => "", - "policy_uri" => "", - "allowed_cors_origins" => [], - "tos_uri" => "", - "client_uri" => "", - "logo_uri" => "", - "contacts" => null, - "client_secret_expires_at" => 0, - "subject_type" => "public", - "jwks" => [], - "token_endpoint_auth_method" => "client_secret_post", - "request_object_signing_alg" => "RS256", - "userinfo_signed_response_alg" => "none", - "created_at" => "2023-02-05T20:17:23Z", - "updated_at" => "2023-02-05T20:17:23.301609Z", - "metadata" => [], - "registration_access_token" => "ory_at_udqWbEdg3tE_dcwJT2-8SjM107L5trNo6aGpz0kCJ3w.yEiDwxN-lEDus4PNWDA_WhYOO-ZYJofvRc-EK_5d-00", - "registration_client_uri" => "http://identity.eurofurence.localhost/oauth2/register/2b83b3ea-7021-455f-b07d-9c00c74436f2", - "authorization_code_grant_access_token_lifespan" => null, - "authorization_code_grant_id_token_lifespan" => null, - "authorization_code_grant_refresh_token_lifespan" => null, - "client_credentials_grant_access_token_lifespan" => null, - "implicit_grant_access_token_lifespan" => null, - "implicit_grant_id_token_lifespan" => null, - "jwt_bearer_grant_access_token_lifespan" => null, - "refresh_token_grant_id_token_lifespan" => null, - "refresh_token_grant_access_token_lifespan" => null, - "refresh_token_grant_refresh_token_lifespan" => null, + 'scope' => 'openid', + 'audience' => [], + 'owner' => '', + 'policy_uri' => '', + 'allowed_cors_origins' => [], + 'tos_uri' => '', + 'client_uri' => '', + 'logo_uri' => '', + 'contacts' => null, + 'client_secret_expires_at' => 0, + 'subject_type' => 'public', + 'jwks' => [], + 'token_endpoint_auth_method' => 'client_secret_post', + 'request_object_signing_alg' => 'RS256', + 'userinfo_signed_response_alg' => 'none', + 'created_at' => '2023-02-05T20:17:23Z', + 'updated_at' => '2023-02-05T20:17:23.301609Z', + 'metadata' => [], + 'registration_access_token' => 'ory_at_udqWbEdg3tE_dcwJT2-8SjM107L5trNo6aGpz0kCJ3w.yEiDwxN-lEDus4PNWDA_WhYOO-ZYJofvRc-EK_5d-00', + 'registration_client_uri' => 'http://identity.eurofurence.localhost/oauth2/register/2b83b3ea-7021-455f-b07d-9c00c74436f2', + 'authorization_code_grant_access_token_lifespan' => null, + 'authorization_code_grant_id_token_lifespan' => null, + 'authorization_code_grant_refresh_token_lifespan' => null, + 'client_credentials_grant_access_token_lifespan' => null, + 'implicit_grant_access_token_lifespan' => null, + 'implicit_grant_id_token_lifespan' => null, + 'jwt_bearer_grant_access_token_lifespan' => null, + 'refresh_token_grant_id_token_lifespan' => null, + 'refresh_token_grant_access_token_lifespan' => null, + 'refresh_token_grant_refresh_token_lifespan' => null, ], ]); $initialApp = new App(); $initialApp->create([ - "client_name" => "Test", - "token_endpoint_auth_method" => "client_secret_post", - "client_secret" => "test123" + 'client_name' => 'Test', + 'token_endpoint_auth_method' => 'client_secret_post', + 'client_secret' => 'test123', ]); $app = App::find($initialApp->client_id); $app->update([ - "client_name" => "New" + 'client_name' => 'New', ]); - $this->assertEquals("New", $app->client_name); - $this->assertEquals($app->token_endpoint_auth_method, "client_secret_post"); + $this->assertEquals('New', $app->client_name); + $this->assertEquals($app->token_endpoint_auth_method, 'client_secret_post'); $this->assertNull($app->client_secret); } @@ -178,53 +178,53 @@ public function test_delete_hydra_app() { Http::fake([ '*' => Http::response([ - "client_id" => "2b83b3ea-7021-455f-b07d-9c00c74436f2", - "client_name" => "New", - "client_secret" => null, - "redirect_uris" => null, - "grant_types" => [ - 0 => "authorization_code", - 1 => "refresh_token", + 'client_id' => '2b83b3ea-7021-455f-b07d-9c00c74436f2', + 'client_name' => 'New', + 'client_secret' => null, + 'redirect_uris' => null, + 'grant_types' => [ + 0 => 'authorization_code', + 1 => 'refresh_token', ], - "response_types" => [ - 0 => "code", + 'response_types' => [ + 0 => 'code', ], - "scope" => "openid", - "audience" => [], - "owner" => "", - "policy_uri" => "", - "allowed_cors_origins" => [], - "tos_uri" => "", - "client_uri" => "", - "logo_uri" => "", - "contacts" => null, - "client_secret_expires_at" => 0, - "subject_type" => "public", - "jwks" => [], - "token_endpoint_auth_method" => "client_secret_post", - "request_object_signing_alg" => "RS256", - "userinfo_signed_response_alg" => "none", - "created_at" => "2023-02-05T20:17:23Z", - "updated_at" => "2023-02-05T20:17:23.301609Z", - "metadata" => [], - "registration_access_token" => "ory_at_udqWbEdg3tE_dcwJT2-8SjM107L5trNo6aGpz0kCJ3w.yEiDwxN-lEDus4PNWDA_WhYOO-ZYJofvRc-EK_5d-00", - "registration_client_uri" => "http://identity.eurofurence.localhost/oauth2/register/2b83b3ea-7021-455f-b07d-9c00c74436f2", - "authorization_code_grant_access_token_lifespan" => null, - "authorization_code_grant_id_token_lifespan" => null, - "authorization_code_grant_refresh_token_lifespan" => null, - "client_credentials_grant_access_token_lifespan" => null, - "implicit_grant_access_token_lifespan" => null, - "implicit_grant_id_token_lifespan" => null, - "jwt_bearer_grant_access_token_lifespan" => null, - "refresh_token_grant_id_token_lifespan" => null, - "refresh_token_grant_access_token_lifespan" => null, - "refresh_token_grant_refresh_token_lifespan" => null, - ]) + 'scope' => 'openid', + 'audience' => [], + 'owner' => '', + 'policy_uri' => '', + 'allowed_cors_origins' => [], + 'tos_uri' => '', + 'client_uri' => '', + 'logo_uri' => '', + 'contacts' => null, + 'client_secret_expires_at' => 0, + 'subject_type' => 'public', + 'jwks' => [], + 'token_endpoint_auth_method' => 'client_secret_post', + 'request_object_signing_alg' => 'RS256', + 'userinfo_signed_response_alg' => 'none', + 'created_at' => '2023-02-05T20:17:23Z', + 'updated_at' => '2023-02-05T20:17:23.301609Z', + 'metadata' => [], + 'registration_access_token' => 'ory_at_udqWbEdg3tE_dcwJT2-8SjM107L5trNo6aGpz0kCJ3w.yEiDwxN-lEDus4PNWDA_WhYOO-ZYJofvRc-EK_5d-00', + 'registration_client_uri' => 'http://identity.eurofurence.localhost/oauth2/register/2b83b3ea-7021-455f-b07d-9c00c74436f2', + 'authorization_code_grant_access_token_lifespan' => null, + 'authorization_code_grant_id_token_lifespan' => null, + 'authorization_code_grant_refresh_token_lifespan' => null, + 'client_credentials_grant_access_token_lifespan' => null, + 'implicit_grant_access_token_lifespan' => null, + 'implicit_grant_id_token_lifespan' => null, + 'jwt_bearer_grant_access_token_lifespan' => null, + 'refresh_token_grant_id_token_lifespan' => null, + 'refresh_token_grant_access_token_lifespan' => null, + 'refresh_token_grant_refresh_token_lifespan' => null, + ]), ]); $app = new App(); $app = $app->create([ - "client_name" => "Test", - "token_endpoint_auth_method" => "client_secret_post" + 'client_name' => 'Test', + 'token_endpoint_auth_method' => 'client_secret_post', ]); $this->assertTrue($app->delete()); }