From 8400e26a3fa68e29747178308c8fcd591f739ffe Mon Sep 17 00:00:00 2001 From: Andras Bacsai <5845193+andrasbacsai@users.noreply.github.com> Date: Tue, 18 Aug 2026 14:22:49 +0200 Subject: [PATCH] feat(auth): consolidate OAuth settings into standard authentication page Display all OAuth providers on one settings page, prioritize OpenID Connect, and add its provider icon. --- app/Livewire/SettingsOauth.php | 10 +- public/svgs/oidc.svg | 5 + .../views/livewire/settings-oauth.blade.php | 255 ++++++++---------- tests/Feature/SettingsOauthTest.php | 40 +-- 4 files changed, 144 insertions(+), 166 deletions(-) create mode 100644 public/svgs/oidc.svg diff --git a/app/Livewire/SettingsOauth.php b/app/Livewire/SettingsOauth.php index a3ee2c987..3b24d0cd2 100644 --- a/app/Livewire/SettingsOauth.php +++ b/app/Livewire/SettingsOauth.php @@ -66,11 +66,13 @@ public function mount(?string $provider = null): ?RedirectResponse $this->settings = instanceSettings(); $this->selectedProvider = $provider; $this->disable_registration_when_oauth_enabled = (bool) $this->settings->disable_registration_when_oauth_enabled; - $this->oauth_settings_map = OauthSetting::all()->sortBy('provider')->reduce(function ($carry, $setting) { - $carry[$setting->provider] = $this->oauthSettingToArray($setting); + $this->oauth_settings_map = OauthSetting::all() + ->sortBy(fn (OauthSetting $setting): string => $setting->isOidc() ? '' : $setting->provider) + ->reduce(function ($carry, $setting) { + $carry[$setting->provider] = $this->oauthSettingToArray($setting); - return $carry; - }, []); + return $carry; + }, []); if ($this->selectedProvider !== null && ! array_key_exists($this->selectedProvider, $this->oauth_settings_map)) { abort(404); diff --git a/public/svgs/oidc.svg b/public/svgs/oidc.svg new file mode 100644 index 000000000..9c542584e --- /dev/null +++ b/public/svgs/oidc.svg @@ -0,0 +1,5 @@ + + OpenID Connect + + + diff --git a/resources/views/livewire/settings-oauth.blade.php b/resources/views/livewire/settings-oauth.blade.php index 1ff75512e..4a394a0b9 100644 --- a/resources/views/livewire/settings-oauth.blade.php +++ b/resources/views/livewire/settings-oauth.blade.php @@ -1,153 +1,122 @@
- Settings | Coolify + Authentication | Coolify - -
- - - - @if ($selectedProvider === null) -
-
-

Authentication

-
-
General authentication settings for your Coolify instance.
-
-
-
-
-

Registration

- + + +
+ + {{ $oauth_setting['enabled'] ? 'Disable' : 'Enable' }} +
-
+ + +
+ + + + + @if ($provider === 'azure') + + @endif + + @if ($provider === 'google') + + @endif + + @if (in_array($provider, ['authentik', 'clerk', 'zitadel', 'gitlab'], true)) + + @endif + + @if ($provider === 'oidc') + + + + + @endif +
+ +
+ @if ($provider === 'oidc') -
+ id="oauth_settings_map.{{ $provider }}.allow_registration" + label="Allow OIDC user creation" + helper="Allow a successful OIDC login to create a user when password registration is disabled." /> + + + @endif +
-
- @else - @php - $oauth_setting = $oauth_settings_map[$selectedProvider] ?? null; - @endphp - - @if ($oauth_setting) -
-
-

{{ $oauth_setting['label'] }}

- @if ($oauth_setting['enabled']) - - Save - - - Disable {{ $oauth_setting['label'] }} - - @else - - Enable {{ $oauth_setting['label'] }} - - @endif -
-
OAuth configuration for {{ $oauth_setting['label'] }}.
-
-
-
-
- - - - @if ($oauth_setting['provider'] == 'azure') - - @endif - @if ($oauth_setting['provider'] == 'google') - - @endif - @if ( - $oauth_setting['provider'] == 'authentik' || - $oauth_setting['provider'] == 'clerk' || - $oauth_setting['provider'] == 'zitadel' || - $oauth_setting['provider'] == 'gitlab') - - @endif - @if ($oauth_setting['provider'] == 'oidc') - - @endif -
- @if ($oauth_setting['provider'] == 'oidc') -
- - - -
-
-
- -
-
- -
-
- -
-
- @endif -
-
- -
-
-
-
- @endif - @endif + + @endforeach -
+
diff --git a/tests/Feature/SettingsOauthTest.php b/tests/Feature/SettingsOauthTest.php index e55cdac4f..6849b3d79 100644 --- a/tests/Feature/SettingsOauthTest.php +++ b/tests/Feature/SettingsOauthTest.php @@ -36,31 +36,33 @@ function actingAsInstanceAdmin(): User OauthSetting::create(['provider' => 'bitbucket']); }); -it('shows oauth general settings with provider subnavigation', function () { +it('uses the standard settings design and keeps every oauth provider on one page', function () { actingAsInstanceAdmin(); $this->withoutMiddleware(DecideWhatToDoWithUser::class) ->get(route('settings.oauth')) ->assertSuccessful() - ->assertSee('General') + ->assertSee('Authentication') + ->assertSee('Registration') ->assertSee('Authentik') ->assertSee('Bitbucket') - ->assertSee(route('settings.oauth.provider', 'authentik'), false) - ->assertSee(route('settings.oauth.provider', 'bitbucket'), false) + ->assertSee('OpenID Connect') ->assertSee('Disable password registration when OAuth is enabled') - ->assertDontSee('Client Secret'); + ->assertSee('Client secret') + ->assertSee('application-settings-form', false) + ->assertDontSee(route('settings.oauth.provider', 'authentik'), false); }); -it('shows the registration helper next to the section title in a wider row', function () { +it('lists openid connect before the other oauth providers', function () { actingAsInstanceAdmin(); - $this->withoutMiddleware(DecideWhatToDoWithUser::class) - ->get(route('settings.oauth')) - ->assertSuccessful() - ->assertSee('flex items-center gap-2', false) - ->assertSee('max-w-2xl', false) - ->assertSee('Disable password registration when OAuth is enabled') - ->assertDontSee('md:w-96', false); + $providers = array_keys(Livewire::test(SettingsOauth::class)->get('oauth_settings_map')); + + expect($providers[0])->toBe('oidc'); +}); + +it('has an icon for openid connect', function () { + expect(public_path('svgs/oidc.svg'))->toBeFile(); }); it('auto saves registration policy without a general save button', function () { @@ -81,24 +83,24 @@ function actingAsInstanceAdmin(): User expect(instanceSettings()->fresh()->disable_registration_when_oauth_enabled)->toBeTrue(); }); -it('shows a provider settings page with a naked okta issuer url example', function () { +it('shows oidc fields with a naked okta issuer url example', function () { actingAsInstanceAdmin(); $this->withoutMiddleware(DecideWhatToDoWithUser::class) - ->get(route('settings.oauth.provider', 'oidc')) + ->get(route('settings.oauth')) ->assertSuccessful() ->assertSee('OpenID Connect') ->assertSee('https://example.okta.com', false) ->assertDontSee('/oauth2/default', false); }); -it('shows provider enable controls as actions without boxed sections', function () { +it('shows provider enable controls as settings section actions', function () { actingAsInstanceAdmin(); $this->withoutMiddleware(DecideWhatToDoWithUser::class) - ->get(route('settings.oauth.provider', 'authentik')) + ->get(route('settings.oauth')) ->assertSuccessful() - ->assertSee('Enable Authentik') + ->assertSee('Enable') ->assertDontSee('label="Enabled"', false) ->assertDontSee('p-4 border dark:border-coolgray-300 border-neutral-200', false); }); @@ -107,7 +109,7 @@ function actingAsInstanceAdmin(): User actingAsInstanceAdmin(); $this->withoutMiddleware(DecideWhatToDoWithUser::class) - ->get(route('settings.oauth.provider', 'oidc')) + ->get(route('settings.oauth')) ->assertSuccessful() ->assertSee('Allow OIDC user creation') ->assertSee('Require verified email')