diff --git a/generic-oidc-providers/database/migrations/003_add_use_pkce.php b/generic-oidc-providers/database/migrations/003_add_use_pkce.php new file mode 100644 index 00000000..0e85197c --- /dev/null +++ b/generic-oidc-providers/database/migrations/003_add_use_pkce.php @@ -0,0 +1,22 @@ +boolean('use_pkce')->nullable(); + }); + } + + public function down(): void + { + Schema::table('generic_oidc_providers', function (Blueprint $table) { + $table->dropColumn('use_pkce'); + }); + } +}; diff --git a/generic-oidc-providers/lang/de/strings.php b/generic-oidc-providers/lang/de/strings.php index f7eb14dd..2e787276 100644 --- a/generic-oidc-providers/lang/de/strings.php +++ b/generic-oidc-providers/lang/de/strings.php @@ -10,4 +10,5 @@ 'redirect_url' => 'Weiterleitungs-URL', 'verify_jwt' => 'JWT verifizieren?', 'jwt_public_key' => 'JWT Public Key', + 'use_pkce' => 'PKCE verwenden?', ]; diff --git a/generic-oidc-providers/lang/en/strings.php b/generic-oidc-providers/lang/en/strings.php index 85092955..8f6015aa 100644 --- a/generic-oidc-providers/lang/en/strings.php +++ b/generic-oidc-providers/lang/en/strings.php @@ -10,4 +10,5 @@ 'redirect_url' => 'Redirect URL', 'verify_jwt' => 'Verify JWT?', 'jwt_public_key' => 'JWT Public Key', + 'use_pkce' => 'Use PKCE?', ]; diff --git a/generic-oidc-providers/plugin.json b/generic-oidc-providers/plugin.json index 43ec7e5c..555f13c8 100644 --- a/generic-oidc-providers/plugin.json +++ b/generic-oidc-providers/plugin.json @@ -2,7 +2,7 @@ "id": "generic-oidc-providers", "name": "Generic OIDC Providers", "author": "Boy132", - "version": "1.1.0", + "version": "1.2.0", "description": "Allows to create generic OIDC providers.", "category": "plugin", "url": "https://hub.pelican.dev/plugins/generic-oidc-providers", @@ -14,4 +14,4 @@ "composer_packages": { "kovah/laravel-socialite-oidc": "^0.8" } -} \ No newline at end of file +} diff --git a/generic-oidc-providers/src/Extensions/OAuth/Providers/GenericOIDCProvider.php b/generic-oidc-providers/src/Extensions/OAuth/Providers/GenericOIDCProvider.php new file mode 100644 index 00000000..9e3237c2 --- /dev/null +++ b/generic-oidc-providers/src/Extensions/OAuth/Providers/GenericOIDCProvider.php @@ -0,0 +1,34 @@ +config['use_pkce'] ?? null; + + if (!is_null($configured)) { + return $configured; + } + + $openid_config = $this->getOpenIdConfig(); + if (isset($openid_config['code_challenge_methods_supported']) && in_array('S256', $openid_config['code_challenge_methods_supported'])) { + return true; + } + + return parent::usesPKCE(); + } +} diff --git a/generic-oidc-providers/src/Extensions/OAuth/Schemas/GenericOIDCProviderSchema.php b/generic-oidc-providers/src/Extensions/OAuth/Schemas/GenericOIDCProviderSchema.php index be663399..6a64e3c0 100644 --- a/generic-oidc-providers/src/Extensions/OAuth/Schemas/GenericOIDCProviderSchema.php +++ b/generic-oidc-providers/src/Extensions/OAuth/Schemas/GenericOIDCProviderSchema.php @@ -4,13 +4,13 @@ use App\Extensions\OAuth\Schemas\OAuthSchema; use App\Models\User; +use Boy132\GenericOIDCProviders\Extensions\OAuth\Providers\GenericOIDCProvider as Provider; use Boy132\GenericOIDCProviders\Filament\Admin\Resources\GenericOIDCProviders\Pages\EditGenericOIDCProvider; use Boy132\GenericOIDCProviders\Models\GenericOIDCProvider; use Filament\Infolists\Components\TextEntry; use Filament\Schemas\Components\Wizard\Step; use Illuminate\Support\Str; use Laravel\Socialite\Contracts\User as OAuthUser; -use SocialiteProviders\OIDC\Provider; final class GenericOIDCProviderSchema extends OAuthSchema { @@ -34,6 +34,7 @@ public function getServiceConfig(): array 'base_url' => $this->model->base_url, 'verify_jwt' => $this->model->verify_jwt, 'jwt_public_key' => $this->model->jwt_public_key, + 'use_pkce' => $this->model->use_pkce, ]; } diff --git a/generic-oidc-providers/src/Filament/Admin/Resources/GenericOIDCProviders/GenericOIDCProviderResource.php b/generic-oidc-providers/src/Filament/Admin/Resources/GenericOIDCProviders/GenericOIDCProviderResource.php index 613cf9f7..b3b964c9 100644 --- a/generic-oidc-providers/src/Filament/Admin/Resources/GenericOIDCProviders/GenericOIDCProviderResource.php +++ b/generic-oidc-providers/src/Filament/Admin/Resources/GenericOIDCProviders/GenericOIDCProviderResource.php @@ -117,7 +117,7 @@ public static function form(Schema $schema): Schema ->revealable() ->autocomplete(false), Group::make() - ->columns(3) + ->columns(4) ->columnSpanFull() ->schema([ Toggle::make('create_missing_users') @@ -145,6 +145,13 @@ public static function form(Schema $schema): Schema ->offColor('danger') ->stateCast(new BooleanStateCast(false)) ->live(), + Select::make('use_pkce') + ->label(trans('generic-oidc-providers::strings.use_pkce')) + ->nullable() + ->boolean( + trans('admin/server.yes'), + trans('admin/server.no'), + ), ]), Textarea::make('jwt_public_key') ->label(trans('generic-oidc-providers::strings.jwt_public_key')) @@ -188,6 +195,13 @@ public static function table(Table $table): Table IconColumn::make('link_missing_users') ->label(trans('admin/setting.oauth.link_missing_users')) ->boolean(), + IconColumn::make('use_pkce') + ->label(trans('generic-oidc-providers::strings.use_pkce')) + ->boolean() + // null is "blank" and would render nothing, so show it as 'auto' + ->default('auto') + ->icon(fn ($state) => $state === 'auto' ? 'tabler-wand' : null) + ->color(fn ($state) => $state === 'auto' ? 'gray' : null), ]) ->recordActions([ EditAction::make(), diff --git a/generic-oidc-providers/src/Models/GenericOIDCProvider.php b/generic-oidc-providers/src/Models/GenericOIDCProvider.php index cc622a0c..2a474bdd 100644 --- a/generic-oidc-providers/src/Models/GenericOIDCProvider.php +++ b/generic-oidc-providers/src/Models/GenericOIDCProvider.php @@ -16,6 +16,7 @@ * @property string $client_secret * @property bool $verify_jwt * @property ?string $jwt_public_key + * @property ?bool $use_pkce */ class GenericOIDCProvider extends Model { @@ -35,6 +36,7 @@ class GenericOIDCProvider extends Model 'client_secret', 'verify_jwt', 'jwt_public_key', + 'use_pkce', ]; protected function casts(): array @@ -45,6 +47,7 @@ protected function casts(): array 'client_id' => 'encrypted', 'client_secret' => 'encrypted', 'verify_jwt' => 'bool', + 'use_pkce' => 'bool', ]; } }