From 9ae24fb9d9cb0eecf42060b3d1c6058ebc542499 Mon Sep 17 00:00:00 2001 From: Boy132 Date: Mon, 18 Nov 2024 10:34:41 +0100 Subject: [PATCH 01/15] better oauth provider loading --- app/Http/Controllers/Auth/OAuthController.php | 8 ++++++++ app/Http/Controllers/Base/OAuthController.php | 5 +++++ app/Providers/AppServiceProvider.php | 18 +++++++++++++++--- config/auth.php | 14 ++++++++++++++ config/services.php | 12 ------------ 5 files changed, 42 insertions(+), 15 deletions(-) diff --git a/app/Http/Controllers/Auth/OAuthController.php b/app/Http/Controllers/Auth/OAuthController.php index 2989761efc..ca12898749 100644 --- a/app/Http/Controllers/Auth/OAuthController.php +++ b/app/Http/Controllers/Auth/OAuthController.php @@ -27,6 +27,10 @@ public function __construct( */ protected function redirect(string $driver): RedirectResponse { + if (!config("auth.oauth.$driver.enabled")) { + throw new Exception("OAuth driver $driver is disabled!"); + } + return Socialite::with($driver)->redirect(); } @@ -35,6 +39,10 @@ protected function redirect(string $driver): RedirectResponse */ protected function callback(Request $request, string $driver): RedirectResponse { + if (!config("auth.oauth.$driver.enabled")) { + throw new Exception("OAuth driver $driver is disabled!"); + } + $oauthUser = Socialite::driver($driver)->user(); // User is already logged in and wants to link a new OAuth Provider diff --git a/app/Http/Controllers/Base/OAuthController.php b/app/Http/Controllers/Base/OAuthController.php index bb078a3c8a..eccb48d771 100644 --- a/app/Http/Controllers/Base/OAuthController.php +++ b/app/Http/Controllers/Base/OAuthController.php @@ -7,6 +7,7 @@ use Laravel\Socialite\Facades\Socialite; use App\Http\Controllers\Controller; use App\Services\Users\UserUpdateService; +use Exception; use Illuminate\Http\Response; class OAuthController extends Controller @@ -26,6 +27,10 @@ protected function link(Request $request): RedirectResponse { $driver = $request->get('driver'); + if (!config("auth.oauth.$driver.enabled")) { + throw new Exception("OAuth driver $driver is disabled!"); + } + return Socialite::with($driver)->redirect(); } diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index 059c22a113..d2c1b95cbe 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -18,7 +18,6 @@ use Illuminate\Support\Facades\Http; use Illuminate\Support\ServiceProvider; use Laravel\Sanctum\Sanctum; -use SocialiteProviders\Discord\Provider; use SocialiteProviders\Manager\SocialiteWasCalled; class AppServiceProvider extends ServiceProvider @@ -62,8 +61,21 @@ public function boot(Application $app): void Scramble::registerApi('client', ['api_path' => 'api/client', 'info' => ['version' => '1.0']])->afterOpenApiGenerated($bearerTokens); Scramble::registerApi('remote', ['api_path' => 'api/remote', 'info' => ['version' => '1.0']])->afterOpenApiGenerated($bearerTokens); - Event::listen(function (SocialiteWasCalled $event) { - $event->extendSocialite('discord', Provider::class); + $oauthProviders = []; + foreach (config('auth.oauth') as $name => $data) { + config()->set("services.$name.client_id", $data['client_id']); + config()->set("services.$name.client_secret", $data['client_secret']); + config()->set("services.$name.redirect", "/auth/oauth/callback/$name"); + + if (isset($data['provider'])) { + $oauthProviders[$name] = $data['provider']; + } + } + + Event::listen(function (SocialiteWasCalled $event) use ($oauthProviders) { + foreach ($oauthProviders as $name => $provider) { + $event->extendSocialite($name, $provider); + } }); FilamentColor::register([ diff --git a/config/auth.php b/config/auth.php index eefb4ede4f..4c6a33c3f9 100644 --- a/config/auth.php +++ b/config/auth.php @@ -23,4 +23,18 @@ ], ], + 'oauth' => [ + 'github' => [ + 'enabled' => true, + 'client_id' => env('OAUTH_GITHUB_CLIENT_ID'), + 'client_secret' => env('OAUTH_GITHUB_CLIENT_SECRET'), + ], + 'discord' => [ + 'enabled' => true, + 'client_id' => env('OAUTH_DISCORD_CLIENT_ID'), + 'client_secret' => env('OAUTH_DISCORD_CLIENT_SECRET'), + 'provider' => \SocialiteProviders\Discord\Provider::class, + ], + ], + ]; diff --git a/config/services.php b/config/services.php index 7311fdc16f..62e0a08a8b 100644 --- a/config/services.php +++ b/config/services.php @@ -9,16 +9,4 @@ 'scheme' => 'https', ], - 'github' => [ - 'client_id' => env('OAUTH_GITHUB_CLIENT_ID'), - 'client_secret' => env('OAUTH_GITHUB_CLIENT_SECRET'), - 'redirect' => '/auth/oauth/callback/github', - ], - - 'discord' => [ - 'client_id' => env('OAUTH_DISCORD_CLIENT_ID'), - 'client_secret' => env('OAUTH_DISCORD_CLIENT_SECRET'), - 'redirect' => '/auth/oauth/callback/discord', - ], - ]; From 2b1ce024fd1c6b5324a288b6eae16ea5181a40c7 Mon Sep 17 00:00:00 2001 From: Boy132 Date: Mon, 18 Nov 2024 10:36:31 +0100 Subject: [PATCH 02/15] add auth frontend --- app/Filament/Pages/Auth/Login.php | 23 +++++++++++++++++++++++ config/auth.php | 4 ++++ 2 files changed, 27 insertions(+) diff --git a/app/Filament/Pages/Auth/Login.php b/app/Filament/Pages/Auth/Login.php index d1bf4b007d..62980aa0a5 100644 --- a/app/Filament/Pages/Auth/Login.php +++ b/app/Filament/Pages/Auth/Login.php @@ -3,9 +3,12 @@ namespace App\Filament\Pages\Auth; use Coderflex\FilamentTurnstile\Forms\Components\Turnstile; +use Filament\Forms\Components\Actions; +use Filament\Forms\Components\Actions\Action; use Filament\Forms\Components\Component; use Filament\Forms\Components\TextInput; use Filament\Pages\Auth\Login as BaseLogin; +use Illuminate\Support\Str; use Illuminate\Validation\ValidationException; class Login extends BaseLogin @@ -19,6 +22,7 @@ protected function getForms(): array $this->getLoginFormComponent(), $this->getPasswordFormComponent(), $this->getRememberFormComponent(), + $this->getOAuthFormComponent(), Turnstile::make('captcha') ->hidden(!config('turnstile.turnstile_enabled')) ->validationMessages([ @@ -49,6 +53,25 @@ protected function getLoginFormComponent(): Component ->extraInputAttributes(['tabindex' => 1]); } + protected function getOAuthFormComponent(): Component + { + $actions = []; + + foreach (config('auth.oauth') as $name => $data) { + if (!$data['enabled']) { + continue; + } + + $actions[] = Action::make("oauth_$name") + ->label(Str::title($name)) + ->icon($data['icon']) + ->color($data['color']) + ->url("/auth/oauth/redirect/$name"); + } + + return Actions::make($actions)->fullWidth(); + } + protected function getCredentialsFromFormData(array $data): array { $loginType = filter_var($data['login'], FILTER_VALIDATE_EMAIL) ? 'email' : 'username'; diff --git a/config/auth.php b/config/auth.php index 4c6a33c3f9..7cbe312b9b 100644 --- a/config/auth.php +++ b/config/auth.php @@ -26,11 +26,15 @@ 'oauth' => [ 'github' => [ 'enabled' => true, + 'icon' => 'tabler-brand-github', + 'color' => \Filament\Support\Colors\Color::hex('#4078c0'), 'client_id' => env('OAUTH_GITHUB_CLIENT_ID'), 'client_secret' => env('OAUTH_GITHUB_CLIENT_SECRET'), ], 'discord' => [ 'enabled' => true, + 'icon' => 'tabler-brand-discord', + 'color' => \Filament\Support\Colors\Color::hex('#5865F2'), 'client_id' => env('OAUTH_DISCORD_CLIENT_ID'), 'client_secret' => env('OAUTH_DISCORD_CLIENT_SECRET'), 'provider' => \SocialiteProviders\Discord\Provider::class, From 7b207306c35f8c4136f423f931593385edfc7b90 Mon Sep 17 00:00:00 2001 From: Boy132 Date: Mon, 18 Nov 2024 10:45:22 +0100 Subject: [PATCH 03/15] add configs for all default providers --- app/Filament/Pages/Auth/Login.php | 2 +- config/auth.php | 49 +++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 1 deletion(-) diff --git a/app/Filament/Pages/Auth/Login.php b/app/Filament/Pages/Auth/Login.php index 62980aa0a5..be564420f6 100644 --- a/app/Filament/Pages/Auth/Login.php +++ b/app/Filament/Pages/Auth/Login.php @@ -69,7 +69,7 @@ protected function getOAuthFormComponent(): Component ->url("/auth/oauth/redirect/$name"); } - return Actions::make($actions)->fullWidth(); + return Actions::make($actions); } protected function getCredentialsFromFormData(array $data): array diff --git a/config/auth.php b/config/auth.php index 7cbe312b9b..0a55ddb72a 100644 --- a/config/auth.php +++ b/config/auth.php @@ -24,6 +24,34 @@ ], 'oauth' => [ + 'facebook' => [ + 'enabled' => true, + 'icon' => 'tabler-brand-facebook', + 'color' => \Filament\Support\Colors\Color::hex('#1877f2'), + 'client_id' => env('OAUTH_FACEBOOK_CLIENT_ID'), + 'client_secret' => env('OAUTH_FACEBOOK_CLIENT_SECRET'), + ], + 'x' => [ + 'enabled' => true, + 'icon' => 'tabler-brand-x', + 'color' => \Filament\Support\Colors\Color::hex('#1da1f2'), + 'client_id' => env('OAUTH_X_CLIENT_ID'), + 'client_secret' => env('OAUTH_X_CLIENT_SECRET'), + ], + 'linkedin' => [ + 'enabled' => true, + 'icon' => 'tabler-brand-linkedin', + 'color' => \Filament\Support\Colors\Color::hex('#0a66c2'), + 'client_id' => env('OAUTH_LINKEDIN_CLIENT_ID'), + 'client_secret' => env('OAUTH_LINKEDIN_CLIENT_SECRET'), + ], + 'google' => [ + 'enabled' => true, + 'icon' => 'tabler-brand-google', + 'color' => \Filament\Support\Colors\Color::hex('#4285f4'), + 'client_id' => env('OAUTH_GOOGLE_CLIENT_ID'), + 'client_secret' => env('OAUTH_GOOGLE_CLIENT_SECRET'), + ], 'github' => [ 'enabled' => true, 'icon' => 'tabler-brand-github', @@ -31,6 +59,27 @@ 'client_id' => env('OAUTH_GITHUB_CLIENT_ID'), 'client_secret' => env('OAUTH_GITHUB_CLIENT_SECRET'), ], + 'gitlab' => [ + 'enabled' => true, + 'icon' => 'tabler-brand-gitlab', + 'color' => \Filament\Support\Colors\Color::hex('#fca326'), + 'client_id' => env('OAUTH_GITLAB_CLIENT_ID'), + 'client_secret' => env('OAUTH_GITLAB_CLIENT_SECRET'), + ], + 'bitbucket' => [ + 'enabled' => true, + 'icon' => 'tabler-brand-bitbucket', + 'color' => \Filament\Support\Colors\Color::hex('#205081'), + 'client_id' => env('OAUTH_BITBUCKET_CLIENT_ID'), + 'client_secret' => env('OAUTH_BITBUCKET_CLIENT_SECRET'), + ], + 'slack' => [ + 'enabled' => true, + 'icon' => 'tabler-brand-slack', + 'color' => \Filament\Support\Colors\Color::hex('#6ecadc'), + 'client_id' => env('OAUTH_SLACK_CLIENT_ID'), + 'client_secret' => env('OAUTH_SLACK_CLIENT_SECRET'), + ], 'discord' => [ 'enabled' => true, 'icon' => 'tabler-brand-discord', From 793a14dfa356d2bf9145ab67e6343c4f0cb0e84d Mon Sep 17 00:00:00 2001 From: Boy132 Date: Mon, 18 Nov 2024 11:00:41 +0100 Subject: [PATCH 04/15] add more default providers --- app/Providers/AppServiceProvider.php | 4 +- composer.json | 3 + composer.lock | 145 ++++++++++++++++++++++++++- config/auth.php | 91 +++++++++++++---- 4 files changed, 220 insertions(+), 23 deletions(-) diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index d2c1b95cbe..ead83d5b66 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -63,9 +63,7 @@ public function boot(Application $app): void $oauthProviders = []; foreach (config('auth.oauth') as $name => $data) { - config()->set("services.$name.client_id", $data['client_id']); - config()->set("services.$name.client_secret", $data['client_secret']); - config()->set("services.$name.redirect", "/auth/oauth/callback/$name"); + config()->set("services.$name", array_merge($data['service'], ['redirect' => "/auth/oauth/callback/$name"])); if (isset($data['provider'])) { $oauthProviders[$name] = $data['provider']; diff --git a/composer.json b/composer.json index e94f0ca6cb..92ce7dd08a 100644 --- a/composer.json +++ b/composer.json @@ -30,7 +30,10 @@ "predis/predis": "~2.1.1", "ryangjchandler/blade-tabler-icons": "^2.3", "s1lentium/iptools": "~1.2.0", + "socialiteproviders/authentik": "^5.2", "socialiteproviders/discord": "^4.2", + "socialiteproviders/steam": "^4.2", + "socialiteproviders/whmcs": "^4.1", "spatie/laravel-fractal": "^6.2", "spatie/laravel-permission": "^6.9", "spatie/laravel-query-builder": "^5.8.1", diff --git a/composer.lock b/composer.lock index 3c73e9efa9..6670e7d02b 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": "6be29c745a7e8809ca315ffb815a196d", + "content-hash": "423a2b81acd486e17e2f969516bf8f45", "packages": [ { "name": "abdelhamiderrahmouni/filament-monaco-editor", @@ -6813,6 +6813,56 @@ }, "time": "2022-08-17T14:28:59+00:00" }, + { + "name": "socialiteproviders/authentik", + "version": "5.2.0", + "source": { + "type": "git", + "url": "https://github.com/SocialiteProviders/Authentik.git", + "reference": "4cf129cf04728a38e0531c54454464b162f0fa66" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/SocialiteProviders/Authentik/zipball/4cf129cf04728a38e0531c54454464b162f0fa66", + "reference": "4cf129cf04728a38e0531c54454464b162f0fa66", + "shasum": "" + }, + "require": { + "ext-json": "*", + "php": "^8.0", + "socialiteproviders/manager": "^4.4" + }, + "type": "library", + "autoload": { + "psr-4": { + "SocialiteProviders\\Authentik\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "rf152", + "email": "git@rf152.co.uk" + } + ], + "description": "Authentik OAuth2 Provider for Laravel Socialite", + "keywords": [ + "authentik", + "laravel", + "oauth", + "provider", + "socialite" + ], + "support": { + "docs": "https://socialiteproviders.com/authentik", + "issues": "https://github.com/socialiteproviders/providers/issues", + "source": "https://github.com/socialiteproviders/providers" + }, + "time": "2023-11-07T22:21:16+00:00" + }, { "name": "socialiteproviders/discord", "version": "4.2.0", @@ -6937,6 +6987,97 @@ }, "time": "2024-05-04T07:57:39+00:00" }, + { + "name": "socialiteproviders/steam", + "version": "4.2.0", + "source": { + "type": "git", + "url": "https://github.com/SocialiteProviders/Steam.git", + "reference": "922f82a26fb7243d7e7ff2ec8ba7e957e7b9eeb7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/SocialiteProviders/Steam/zipball/922f82a26fb7243d7e7ff2ec8ba7e957e7b9eeb7", + "reference": "922f82a26fb7243d7e7ff2ec8ba7e957e7b9eeb7", + "shasum": "" + }, + "require": { + "ext-json": "*", + "php": "^7.2 || ^8.0", + "socialiteproviders/manager": "~4.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "SocialiteProviders\\Steam\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christopher Eklund", + "email": "eklundchristopher@gmail.com" + } + ], + "description": "Steam OpenID Provider for Laravel Socialite", + "keywords": [ + "OpenId", + "laravel", + "provider", + "socialite", + "steam" + ], + "support": { + "docs": "https://socialiteproviders.com/steam", + "issues": "https://github.com/socialiteproviders/providers/issues", + "source": "https://github.com/socialiteproviders/providers" + }, + "time": "2022-03-28T22:38:40+00:00" + }, + { + "name": "socialiteproviders/whmcs", + "version": "4.1.0", + "source": { + "type": "git", + "url": "https://github.com/SocialiteProviders/Whmcs.git", + "reference": "a384912383d3e1e986ec6e30c81f5d30a618dfe5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/SocialiteProviders/Whmcs/zipball/a384912383d3e1e986ec6e30c81f5d30a618dfe5", + "reference": "a384912383d3e1e986ec6e30c81f5d30a618dfe5", + "shasum": "" + }, + "require": { + "ext-json": "*", + "php": "^7.2 || ^8.0", + "socialiteproviders/manager": "~4.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "SocialiteProviders\\Whmcs\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Adnan RIHAN", + "email": "adnan@rihan.fr" + } + ], + "description": "WHMCS OAuth2 Provider for Laravel Socialite", + "support": { + "source": "https://github.com/SocialiteProviders/Whmcs/tree/4.1.0" + }, + "time": "2020-12-01T23:10:59+00:00" + }, { "name": "spatie/color", "version": "1.6.0", @@ -13506,4 +13647,4 @@ }, "platform-dev": [], "plugin-api-version": "2.6.0" -} \ No newline at end of file +} diff --git a/config/auth.php b/config/auth.php index 0a55ddb72a..300c1f764b 100644 --- a/config/auth.php +++ b/config/auth.php @@ -24,70 +24,125 @@ ], 'oauth' => [ + // Default providers 'facebook' => [ 'enabled' => true, 'icon' => 'tabler-brand-facebook', 'color' => \Filament\Support\Colors\Color::hex('#1877f2'), - 'client_id' => env('OAUTH_FACEBOOK_CLIENT_ID'), - 'client_secret' => env('OAUTH_FACEBOOK_CLIENT_SECRET'), + 'service' => [ + 'client_id' => env('OAUTH_FACEBOOK_CLIENT_ID'), + 'client_secret' => env('OAUTH_FACEBOOK_CLIENT_SECRET'), + ], ], 'x' => [ 'enabled' => true, 'icon' => 'tabler-brand-x', 'color' => \Filament\Support\Colors\Color::hex('#1da1f2'), - 'client_id' => env('OAUTH_X_CLIENT_ID'), - 'client_secret' => env('OAUTH_X_CLIENT_SECRET'), + 'service' => [ + 'client_id' => env('OAUTH_X_CLIENT_ID'), + 'client_secret' => env('OAUTH_X_CLIENT_SECRET'), + ], ], 'linkedin' => [ 'enabled' => true, 'icon' => 'tabler-brand-linkedin', 'color' => \Filament\Support\Colors\Color::hex('#0a66c2'), - 'client_id' => env('OAUTH_LINKEDIN_CLIENT_ID'), - 'client_secret' => env('OAUTH_LINKEDIN_CLIENT_SECRET'), + 'service' => [ + 'client_id' => env('OAUTH_LINKEDIN_CLIENT_ID'), + 'client_secret' => env('OAUTH_LINKEDIN_CLIENT_SECRET'), + ], ], 'google' => [ 'enabled' => true, 'icon' => 'tabler-brand-google', 'color' => \Filament\Support\Colors\Color::hex('#4285f4'), - 'client_id' => env('OAUTH_GOOGLE_CLIENT_ID'), - 'client_secret' => env('OAUTH_GOOGLE_CLIENT_SECRET'), + 'service' => [ + 'client_id' => env('OAUTH_GOOGLE_CLIENT_ID'), + 'client_secret' => env('OAUTH_GOOGLE_CLIENT_SECRET'), + ], ], 'github' => [ 'enabled' => true, 'icon' => 'tabler-brand-github', 'color' => \Filament\Support\Colors\Color::hex('#4078c0'), - 'client_id' => env('OAUTH_GITHUB_CLIENT_ID'), - 'client_secret' => env('OAUTH_GITHUB_CLIENT_SECRET'), + 'service' => [ + 'client_id' => env('OAUTH_GITHUB_CLIENT_ID'), + 'client_secret' => env('OAUTH_GITHUB_CLIENT_SECRET'), + ], ], 'gitlab' => [ 'enabled' => true, 'icon' => 'tabler-brand-gitlab', 'color' => \Filament\Support\Colors\Color::hex('#fca326'), - 'client_id' => env('OAUTH_GITLAB_CLIENT_ID'), - 'client_secret' => env('OAUTH_GITLAB_CLIENT_SECRET'), + 'service' => [ + 'client_id' => env('OAUTH_GITLAB_CLIENT_ID'), + 'client_secret' => env('OAUTH_GITLAB_CLIENT_SECRET'), + ], ], 'bitbucket' => [ 'enabled' => true, 'icon' => 'tabler-brand-bitbucket', 'color' => \Filament\Support\Colors\Color::hex('#205081'), - 'client_id' => env('OAUTH_BITBUCKET_CLIENT_ID'), - 'client_secret' => env('OAUTH_BITBUCKET_CLIENT_SECRET'), + 'service' => [ + 'client_id' => env('OAUTH_BITBUCKET_CLIENT_ID'), + 'client_secret' => env('OAUTH_BITBUCKET_CLIENT_SECRET'), + ], ], 'slack' => [ 'enabled' => true, 'icon' => 'tabler-brand-slack', 'color' => \Filament\Support\Colors\Color::hex('#6ecadc'), - 'client_id' => env('OAUTH_SLACK_CLIENT_ID'), - 'client_secret' => env('OAUTH_SLACK_CLIENT_SECRET'), + 'service' => [ + 'client_id' => env('OAUTH_SLACK_CLIENT_ID'), + 'client_secret' => env('OAUTH_SLACK_CLIENT_SECRET'), + ], + ], + + // Additional providers from socialiteproviders.com + 'authentik' => [ + 'enabled' => true, + 'icon' => null, + 'color' => \Filament\Support\Colors\Color::hex('#fd4b2d'), + 'service' => [ + 'base_url' => env('OAUTH_AUTHENTIK_BASE_URL'), + 'client_id' => env('OAUTH_AUTHENTIK_CLIENT_ID'), + 'client_secret' => env('OAUTH_AUTHENTIK_CLIENT_SECRET'), + ], + 'provider' => \SocialiteProviders\Authentik\Provider::class, ], 'discord' => [ 'enabled' => true, 'icon' => 'tabler-brand-discord', 'color' => \Filament\Support\Colors\Color::hex('#5865F2'), - 'client_id' => env('OAUTH_DISCORD_CLIENT_ID'), - 'client_secret' => env('OAUTH_DISCORD_CLIENT_SECRET'), + 'service' => [ + 'client_id' => env('OAUTH_DISCORD_CLIENT_ID'), + 'client_secret' => env('OAUTH_DISCORD_CLIENT_SECRET'), + ], 'provider' => \SocialiteProviders\Discord\Provider::class, ], + 'steam' => [ + 'enabled' => true, + 'icon' => 'tabler-brand-steam', + 'color' => \Filament\Support\Colors\Color::hex('#00adee'), + 'service' => [ + 'client_secret' => env('OAUTH_STEAM_CLIENT_SECRET'), + 'allowed_hosts' => [ + env('APP_URL'), + ], + ], + 'provider' => \SocialiteProviders\Steam\Provider::class, + ], + 'whmcs' => [ + 'enabled' => true, + 'icon' => null, + 'color' => \Filament\Support\Colors\Color::hex('#7bc143'), + 'service' => [ + 'client_id' => env('OAUTH_WHMCS_CLIENT_ID'), + 'client_secret' => env('OAUTH_WHMCS_CLIENT_SECRET'), + 'url' => env('OAUTH_WHMCS_URL'), + ], + 'provider' => \SocialiteProviders\Whmcs\Provider::class, + ], ], ]; From d89b273628affe87c887a1a45672d6e0a35ef010 Mon Sep 17 00:00:00 2001 From: Boy132 Date: Mon, 18 Nov 2024 11:03:27 +0100 Subject: [PATCH 05/15] add env variables to enable oauth providers --- config/auth.php | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/config/auth.php b/config/auth.php index 300c1f764b..01e97e37bc 100644 --- a/config/auth.php +++ b/config/auth.php @@ -26,7 +26,7 @@ 'oauth' => [ // Default providers 'facebook' => [ - 'enabled' => true, + 'enabled' => env('OAUTH_FACEBOOK_ENABLED'), 'icon' => 'tabler-brand-facebook', 'color' => \Filament\Support\Colors\Color::hex('#1877f2'), 'service' => [ @@ -35,7 +35,7 @@ ], ], 'x' => [ - 'enabled' => true, + 'enabled' => env('OAUTH_X_ENABLED'), 'icon' => 'tabler-brand-x', 'color' => \Filament\Support\Colors\Color::hex('#1da1f2'), 'service' => [ @@ -44,7 +44,7 @@ ], ], 'linkedin' => [ - 'enabled' => true, + 'enabled' => env('OAUTH_LINKEDIN_ENABLED'), 'icon' => 'tabler-brand-linkedin', 'color' => \Filament\Support\Colors\Color::hex('#0a66c2'), 'service' => [ @@ -53,7 +53,7 @@ ], ], 'google' => [ - 'enabled' => true, + 'enabled' => env('OAUTH_GOOGLE_ENABLED'), 'icon' => 'tabler-brand-google', 'color' => \Filament\Support\Colors\Color::hex('#4285f4'), 'service' => [ @@ -62,7 +62,7 @@ ], ], 'github' => [ - 'enabled' => true, + 'enabled' => env('OAUTH_GITHUB_ENABLED'), 'icon' => 'tabler-brand-github', 'color' => \Filament\Support\Colors\Color::hex('#4078c0'), 'service' => [ @@ -71,7 +71,7 @@ ], ], 'gitlab' => [ - 'enabled' => true, + 'enabled' => env('OAUTH_GITLAB_ENABLED'), 'icon' => 'tabler-brand-gitlab', 'color' => \Filament\Support\Colors\Color::hex('#fca326'), 'service' => [ @@ -80,7 +80,7 @@ ], ], 'bitbucket' => [ - 'enabled' => true, + 'enabled' => env('OAUTH_BITBUCKET_ENABLED'), 'icon' => 'tabler-brand-bitbucket', 'color' => \Filament\Support\Colors\Color::hex('#205081'), 'service' => [ @@ -89,7 +89,7 @@ ], ], 'slack' => [ - 'enabled' => true, + 'enabled' => env('OAUTH_SLACK_ENABLED'), 'icon' => 'tabler-brand-slack', 'color' => \Filament\Support\Colors\Color::hex('#6ecadc'), 'service' => [ @@ -100,7 +100,7 @@ // Additional providers from socialiteproviders.com 'authentik' => [ - 'enabled' => true, + 'enabled' => env('OAUTH_AUTHENTIK_ENABLED'), 'icon' => null, 'color' => \Filament\Support\Colors\Color::hex('#fd4b2d'), 'service' => [ @@ -111,7 +111,7 @@ 'provider' => \SocialiteProviders\Authentik\Provider::class, ], 'discord' => [ - 'enabled' => true, + 'enabled' => env('OAUTH_DISCORD_ENABLED'), 'icon' => 'tabler-brand-discord', 'color' => \Filament\Support\Colors\Color::hex('#5865F2'), 'service' => [ @@ -121,7 +121,7 @@ 'provider' => \SocialiteProviders\Discord\Provider::class, ], 'steam' => [ - 'enabled' => true, + 'enabled' => env('OAUTH_STEAM_ENABLED'), 'icon' => 'tabler-brand-steam', 'color' => \Filament\Support\Colors\Color::hex('#00adee'), 'service' => [ @@ -133,7 +133,7 @@ 'provider' => \SocialiteProviders\Steam\Provider::class, ], 'whmcs' => [ - 'enabled' => true, + 'enabled' => env('OAUTH_WHMCS_ENABLED'), 'icon' => null, 'color' => \Filament\Support\Colors\Color::hex('#7bc143'), 'service' => [ From b6c525615d9d4f3650d51cf5c92b42f2563d8377 Mon Sep 17 00:00:00 2001 From: Boy132 Date: Mon, 18 Nov 2024 11:28:40 +0100 Subject: [PATCH 06/15] small refactor to link/ unlink routes --- app/Http/Controllers/Base/OAuthController.php | 8 +++----- routes/base.php | 4 ++-- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/app/Http/Controllers/Base/OAuthController.php b/app/Http/Controllers/Base/OAuthController.php index eccb48d771..6c32437bb2 100644 --- a/app/Http/Controllers/Base/OAuthController.php +++ b/app/Http/Controllers/Base/OAuthController.php @@ -23,10 +23,8 @@ public function __construct( /** * Link a new OAuth */ - protected function link(Request $request): RedirectResponse + protected function link(string $driver): RedirectResponse { - $driver = $request->get('driver'); - if (!config("auth.oauth.$driver.enabled")) { throw new Exception("OAuth driver $driver is disabled!"); } @@ -37,10 +35,10 @@ protected function link(Request $request): RedirectResponse /** * Remove a OAuth link */ - protected function unlink(Request $request): Response + protected function unlink(Request $request, string $driver): Response { $oauth = $request->user()->oauth; - unset($oauth[$request->get('driver')]); + unset($oauth[$driver]); $this->updateService->handle($request->user(), ['oauth' => $oauth]); diff --git a/routes/base.php b/routes/base.php index b07e1e5310..9014628ab3 100644 --- a/routes/base.php +++ b/routes/base.php @@ -10,8 +10,8 @@ ->withoutMiddleware(RequireTwoFactorAuthentication::class) ->name('account'); -Route::get('/account/oauth/link', [Base\OAuthController::class, 'link'])->name('account.oauth.link'); -Route::get('/account/oauth/unlink', [Base\OAuthController::class, 'unlink'])->name('account.oauth.unlink'); +Route::get('/account/oauth/link/{driver}', [Base\OAuthController::class, 'link'])->name('account.oauth.link'); +Route::get('/account/oauth/unlink{driver}', [Base\OAuthController::class, 'unlink'])->name('account.oauth.unlink'); Route::get('/locales/locale.json', Base\LocaleController::class) ->withoutMiddleware(['auth', RequireTwoFactorAuthentication::class]) From 028fea7a008ee1220e55196201835c270e1c6294 Mon Sep 17 00:00:00 2001 From: Boy132 Date: Mon, 18 Nov 2024 11:29:47 +0100 Subject: [PATCH 07/15] add oauth tab to (admin) profile --- .../UserResource/Pages/EditProfile.php | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/app/Filament/Resources/UserResource/Pages/EditProfile.php b/app/Filament/Resources/UserResource/Pages/EditProfile.php index 5b35deff32..27b095e994 100644 --- a/app/Filament/Resources/UserResource/Pages/EditProfile.php +++ b/app/Filament/Resources/UserResource/Pages/EditProfile.php @@ -16,6 +16,7 @@ use Closure; use DateTimeZone; use Exception; +use Filament\Forms\Components\Actions; use Filament\Forms\Components\Actions\Action; use Filament\Forms\Components\Grid; use Filament\Forms\Components\Placeholder; @@ -33,6 +34,7 @@ use Illuminate\Database\Eloquent\Model; use Illuminate\Support\Facades\Hash; use Illuminate\Support\HtmlString; +use Illuminate\Support\Str; use Illuminate\Validation\Rules\Password; /** @@ -113,6 +115,28 @@ protected function getForms(): array ->options(fn (User $user) => $user->getAvailableLanguages()), ]), + Tab::make('OAuth') + ->icon('tabler-brand-oauth') + ->schema(function () { + $providers = []; + + foreach (config('auth.oauth') as $name => $data) { + if (!$data['enabled']) { + continue; + } + + $unlink = array_key_exists($name, $this->getUser()->oauth); + + $providers[] = Action::make("oauth_$name") + ->label(($unlink ? 'Unlink ' : 'Link ') . Str::title($name)) + ->icon($unlink ? 'tabler-unlink' : 'tabler-link') + ->color($data['color']) + ->url('/account/oauth/' . ($unlink ? 'unlink' : 'link') . "/$name"); + } + + return [Actions::make($providers)]; + }), + Tab::make('2FA') ->icon('tabler-shield-lock') ->schema(function (TwoFactorSetupService $setupService) { From 886d047ccb6e35095d0502b9cbc56b2c145f2d8a Mon Sep 17 00:00:00 2001 From: Boy132 Date: Mon, 18 Nov 2024 11:47:55 +0100 Subject: [PATCH 08/15] use redirects instead of exceptions --- app/Http/Controllers/Auth/OAuthController.php | 8 +++++--- app/Http/Controllers/Base/OAuthController.php | 4 ++-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/app/Http/Controllers/Auth/OAuthController.php b/app/Http/Controllers/Auth/OAuthController.php index ca12898749..77c50198ad 100644 --- a/app/Http/Controllers/Auth/OAuthController.php +++ b/app/Http/Controllers/Auth/OAuthController.php @@ -27,8 +27,9 @@ public function __construct( */ protected function redirect(string $driver): RedirectResponse { + // Driver is disabled - redirect to normal login if (!config("auth.oauth.$driver.enabled")) { - throw new Exception("OAuth driver $driver is disabled!"); + return redirect()->route('auth.login'); } return Socialite::with($driver)->redirect(); @@ -39,8 +40,9 @@ protected function redirect(string $driver): RedirectResponse */ protected function callback(Request $request, string $driver): RedirectResponse { + // Driver is disabled - redirect to normal login if (!config("auth.oauth.$driver.enabled")) { - throw new Exception("OAuth driver $driver is disabled!"); + return redirect()->route('auth.login'); } $oauthUser = Socialite::driver($driver)->user(); @@ -59,7 +61,7 @@ protected function callback(Request $request, string $driver): RedirectResponse $user = User::query()->whereJsonContains('oauth->'. $driver, $oauthUser->getId())->firstOrFail(); $this->auth->guard()->login($user, true); - } catch (Exception $e) { + } catch (Exception) { // No user found - redirect to normal login return redirect()->route('auth.login'); } diff --git a/app/Http/Controllers/Base/OAuthController.php b/app/Http/Controllers/Base/OAuthController.php index 6c32437bb2..f4aaab4f7e 100644 --- a/app/Http/Controllers/Base/OAuthController.php +++ b/app/Http/Controllers/Base/OAuthController.php @@ -7,7 +7,6 @@ use Laravel\Socialite\Facades\Socialite; use App\Http\Controllers\Controller; use App\Services\Users\UserUpdateService; -use Exception; use Illuminate\Http\Response; class OAuthController extends Controller @@ -25,8 +24,9 @@ public function __construct( */ protected function link(string $driver): RedirectResponse { + // Driver is disabled - redirect to account page if (!config("auth.oauth.$driver.enabled")) { - throw new Exception("OAuth driver $driver is disabled!"); + return redirect()->route('account'); } return Socialite::with($driver)->redirect(); From a483142f4d7f590379a71349b3999f0e8c4a728e Mon Sep 17 00:00:00 2001 From: Boy132 Date: Mon, 18 Nov 2024 17:37:51 +0100 Subject: [PATCH 09/15] add notification if no oauth user is found --- app/Http/Controllers/Auth/OAuthController.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/app/Http/Controllers/Auth/OAuthController.php b/app/Http/Controllers/Auth/OAuthController.php index 77c50198ad..77fbae3486 100644 --- a/app/Http/Controllers/Auth/OAuthController.php +++ b/app/Http/Controllers/Auth/OAuthController.php @@ -2,6 +2,7 @@ namespace App\Http\Controllers\Auth; +use Filament\Notifications\Notification; use Illuminate\Auth\AuthManager; use Illuminate\Http\RedirectResponse; use Laravel\Socialite\Facades\Socialite; @@ -63,6 +64,12 @@ protected function callback(Request $request, string $driver): RedirectResponse $this->auth->guard()->login($user, true); } catch (Exception) { // No user found - redirect to normal login + Notification::make() + ->title('No linked User found') + ->danger() + ->persistent() + ->send(); + return redirect()->route('auth.login'); } From 0a673daa68d778c234c0bee8f3907a434e4dbd14 Mon Sep 17 00:00:00 2001 From: Boy132 Date: Wed, 20 Nov 2024 08:49:49 +0100 Subject: [PATCH 10/15] use import in config --- config/auth.php | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/config/auth.php b/config/auth.php index 01e97e37bc..68eeb81ac5 100644 --- a/config/auth.php +++ b/config/auth.php @@ -1,5 +1,7 @@ [ @@ -28,7 +30,7 @@ 'facebook' => [ 'enabled' => env('OAUTH_FACEBOOK_ENABLED'), 'icon' => 'tabler-brand-facebook', - 'color' => \Filament\Support\Colors\Color::hex('#1877f2'), + 'color' => Color::hex('#1877f2'), 'service' => [ 'client_id' => env('OAUTH_FACEBOOK_CLIENT_ID'), 'client_secret' => env('OAUTH_FACEBOOK_CLIENT_SECRET'), @@ -37,7 +39,7 @@ 'x' => [ 'enabled' => env('OAUTH_X_ENABLED'), 'icon' => 'tabler-brand-x', - 'color' => \Filament\Support\Colors\Color::hex('#1da1f2'), + 'color' => Color::hex('#1da1f2'), 'service' => [ 'client_id' => env('OAUTH_X_CLIENT_ID'), 'client_secret' => env('OAUTH_X_CLIENT_SECRET'), @@ -46,7 +48,7 @@ 'linkedin' => [ 'enabled' => env('OAUTH_LINKEDIN_ENABLED'), 'icon' => 'tabler-brand-linkedin', - 'color' => \Filament\Support\Colors\Color::hex('#0a66c2'), + 'color' => Color::hex('#0a66c2'), 'service' => [ 'client_id' => env('OAUTH_LINKEDIN_CLIENT_ID'), 'client_secret' => env('OAUTH_LINKEDIN_CLIENT_SECRET'), @@ -55,7 +57,7 @@ 'google' => [ 'enabled' => env('OAUTH_GOOGLE_ENABLED'), 'icon' => 'tabler-brand-google', - 'color' => \Filament\Support\Colors\Color::hex('#4285f4'), + 'color' => Color::hex('#4285f4'), 'service' => [ 'client_id' => env('OAUTH_GOOGLE_CLIENT_ID'), 'client_secret' => env('OAUTH_GOOGLE_CLIENT_SECRET'), @@ -64,7 +66,7 @@ 'github' => [ 'enabled' => env('OAUTH_GITHUB_ENABLED'), 'icon' => 'tabler-brand-github', - 'color' => \Filament\Support\Colors\Color::hex('#4078c0'), + 'color' => Color::hex('#4078c0'), 'service' => [ 'client_id' => env('OAUTH_GITHUB_CLIENT_ID'), 'client_secret' => env('OAUTH_GITHUB_CLIENT_SECRET'), @@ -73,7 +75,7 @@ 'gitlab' => [ 'enabled' => env('OAUTH_GITLAB_ENABLED'), 'icon' => 'tabler-brand-gitlab', - 'color' => \Filament\Support\Colors\Color::hex('#fca326'), + 'color' => Color::hex('#fca326'), 'service' => [ 'client_id' => env('OAUTH_GITLAB_CLIENT_ID'), 'client_secret' => env('OAUTH_GITLAB_CLIENT_SECRET'), @@ -82,7 +84,7 @@ 'bitbucket' => [ 'enabled' => env('OAUTH_BITBUCKET_ENABLED'), 'icon' => 'tabler-brand-bitbucket', - 'color' => \Filament\Support\Colors\Color::hex('#205081'), + 'color' => Color::hex('#205081'), 'service' => [ 'client_id' => env('OAUTH_BITBUCKET_CLIENT_ID'), 'client_secret' => env('OAUTH_BITBUCKET_CLIENT_SECRET'), @@ -91,7 +93,7 @@ 'slack' => [ 'enabled' => env('OAUTH_SLACK_ENABLED'), 'icon' => 'tabler-brand-slack', - 'color' => \Filament\Support\Colors\Color::hex('#6ecadc'), + 'color' => Color::hex('#6ecadc'), 'service' => [ 'client_id' => env('OAUTH_SLACK_CLIENT_ID'), 'client_secret' => env('OAUTH_SLACK_CLIENT_SECRET'), @@ -102,7 +104,7 @@ 'authentik' => [ 'enabled' => env('OAUTH_AUTHENTIK_ENABLED'), 'icon' => null, - 'color' => \Filament\Support\Colors\Color::hex('#fd4b2d'), + 'color' => Color::hex('#fd4b2d'), 'service' => [ 'base_url' => env('OAUTH_AUTHENTIK_BASE_URL'), 'client_id' => env('OAUTH_AUTHENTIK_CLIENT_ID'), @@ -113,7 +115,7 @@ 'discord' => [ 'enabled' => env('OAUTH_DISCORD_ENABLED'), 'icon' => 'tabler-brand-discord', - 'color' => \Filament\Support\Colors\Color::hex('#5865F2'), + 'color' => Color::hex('#5865F2'), 'service' => [ 'client_id' => env('OAUTH_DISCORD_CLIENT_ID'), 'client_secret' => env('OAUTH_DISCORD_CLIENT_SECRET'), @@ -123,7 +125,7 @@ 'steam' => [ 'enabled' => env('OAUTH_STEAM_ENABLED'), 'icon' => 'tabler-brand-steam', - 'color' => \Filament\Support\Colors\Color::hex('#00adee'), + 'color' => Color::hex('#00adee'), 'service' => [ 'client_secret' => env('OAUTH_STEAM_CLIENT_SECRET'), 'allowed_hosts' => [ @@ -135,7 +137,7 @@ 'whmcs' => [ 'enabled' => env('OAUTH_WHMCS_ENABLED'), 'icon' => null, - 'color' => \Filament\Support\Colors\Color::hex('#7bc143'), + 'color' => Color::hex('#7bc143'), 'service' => [ 'client_id' => env('OAUTH_WHMCS_CLIENT_ID'), 'client_secret' => env('OAUTH_WHMCS_CLIENT_SECRET'), From 9d7d41c951e0cc8e9169dfa6931afd39d20eb091 Mon Sep 17 00:00:00 2001 From: Boy132 Date: Wed, 20 Nov 2024 08:51:34 +0100 Subject: [PATCH 11/15] remove whmcs provider --- composer.json | 1 - composer.lock | 43 +------------------------------------------ config/auth.php | 11 ----------- 3 files changed, 1 insertion(+), 54 deletions(-) diff --git a/composer.json b/composer.json index 92ce7dd08a..f37c671124 100644 --- a/composer.json +++ b/composer.json @@ -33,7 +33,6 @@ "socialiteproviders/authentik": "^5.2", "socialiteproviders/discord": "^4.2", "socialiteproviders/steam": "^4.2", - "socialiteproviders/whmcs": "^4.1", "spatie/laravel-fractal": "^6.2", "spatie/laravel-permission": "^6.9", "spatie/laravel-query-builder": "^5.8.1", diff --git a/composer.lock b/composer.lock index 6670e7d02b..c1b1255c42 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": "423a2b81acd486e17e2f969516bf8f45", + "content-hash": "d64fe6d5eabb837dcdbc5c2420b03910", "packages": [ { "name": "abdelhamiderrahmouni/filament-monaco-editor", @@ -7037,47 +7037,6 @@ }, "time": "2022-03-28T22:38:40+00:00" }, - { - "name": "socialiteproviders/whmcs", - "version": "4.1.0", - "source": { - "type": "git", - "url": "https://github.com/SocialiteProviders/Whmcs.git", - "reference": "a384912383d3e1e986ec6e30c81f5d30a618dfe5" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/SocialiteProviders/Whmcs/zipball/a384912383d3e1e986ec6e30c81f5d30a618dfe5", - "reference": "a384912383d3e1e986ec6e30c81f5d30a618dfe5", - "shasum": "" - }, - "require": { - "ext-json": "*", - "php": "^7.2 || ^8.0", - "socialiteproviders/manager": "~4.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "SocialiteProviders\\Whmcs\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Adnan RIHAN", - "email": "adnan@rihan.fr" - } - ], - "description": "WHMCS OAuth2 Provider for Laravel Socialite", - "support": { - "source": "https://github.com/SocialiteProviders/Whmcs/tree/4.1.0" - }, - "time": "2020-12-01T23:10:59+00:00" - }, { "name": "spatie/color", "version": "1.6.0", diff --git a/config/auth.php b/config/auth.php index 68eeb81ac5..78ec9b3f18 100644 --- a/config/auth.php +++ b/config/auth.php @@ -134,17 +134,6 @@ ], 'provider' => \SocialiteProviders\Steam\Provider::class, ], - 'whmcs' => [ - 'enabled' => env('OAUTH_WHMCS_ENABLED'), - 'icon' => null, - 'color' => Color::hex('#7bc143'), - 'service' => [ - 'client_id' => env('OAUTH_WHMCS_CLIENT_ID'), - 'client_secret' => env('OAUTH_WHMCS_CLIENT_SECRET'), - 'url' => env('OAUTH_WHMCS_URL'), - ], - 'provider' => \SocialiteProviders\Whmcs\Provider::class, - ], ], ]; From 45581aa51e4ad0ea89332597852b128584308b5b Mon Sep 17 00:00:00 2001 From: Boy132 Date: Wed, 20 Nov 2024 09:04:31 +0100 Subject: [PATCH 12/15] replace hardcoded links with `route` --- app/Filament/Pages/Auth/Login.php | 2 +- app/Filament/Resources/UserResource/Pages/EditProfile.php | 2 +- routes/base.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/Filament/Pages/Auth/Login.php b/app/Filament/Pages/Auth/Login.php index be564420f6..7740884449 100644 --- a/app/Filament/Pages/Auth/Login.php +++ b/app/Filament/Pages/Auth/Login.php @@ -66,7 +66,7 @@ protected function getOAuthFormComponent(): Component ->label(Str::title($name)) ->icon($data['icon']) ->color($data['color']) - ->url("/auth/oauth/redirect/$name"); + ->url(route('auth.oauth.redirect', ['driver' => $name], false)); } return Actions::make($actions); diff --git a/app/Filament/Resources/UserResource/Pages/EditProfile.php b/app/Filament/Resources/UserResource/Pages/EditProfile.php index 27b095e994..ea8143d928 100644 --- a/app/Filament/Resources/UserResource/Pages/EditProfile.php +++ b/app/Filament/Resources/UserResource/Pages/EditProfile.php @@ -131,7 +131,7 @@ protected function getForms(): array ->label(($unlink ? 'Unlink ' : 'Link ') . Str::title($name)) ->icon($unlink ? 'tabler-unlink' : 'tabler-link') ->color($data['color']) - ->url('/account/oauth/' . ($unlink ? 'unlink' : 'link') . "/$name"); + ->url(route('account.oauth.' . ($unlink ? 'unlink' : 'link'), ['driver' => $name], false)); } return [Actions::make($providers)]; diff --git a/routes/base.php b/routes/base.php index 9014628ab3..2a127c7f79 100644 --- a/routes/base.php +++ b/routes/base.php @@ -11,7 +11,7 @@ ->name('account'); Route::get('/account/oauth/link/{driver}', [Base\OAuthController::class, 'link'])->name('account.oauth.link'); -Route::get('/account/oauth/unlink{driver}', [Base\OAuthController::class, 'unlink'])->name('account.oauth.unlink'); +Route::get('/account/oauth/unlink/{driver}', [Base\OAuthController::class, 'unlink'])->name('account.oauth.unlink'); Route::get('/locales/locale.json', Base\LocaleController::class) ->withoutMiddleware(['auth', RequireTwoFactorAuthentication::class]) From 1b195d2a98ed2d7a01c4c2e6b98f851c7e1fb0a7 Mon Sep 17 00:00:00 2001 From: Boy132 Date: Wed, 20 Nov 2024 23:39:21 +0100 Subject: [PATCH 13/15] redirect to account page on unlink --- app/Http/Controllers/Auth/OAuthController.php | 1 + app/Http/Controllers/Base/OAuthController.php | 7 ++++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/app/Http/Controllers/Auth/OAuthController.php b/app/Http/Controllers/Auth/OAuthController.php index 77fbae3486..63293756d4 100644 --- a/app/Http/Controllers/Auth/OAuthController.php +++ b/app/Http/Controllers/Auth/OAuthController.php @@ -55,6 +55,7 @@ protected function callback(Request $request, string $driver): RedirectResponse $this->updateService->handle($request->user(), ['oauth' => $oauth]); + // TODO: replace with profile route once new client area is merged return redirect()->route('account'); } diff --git a/app/Http/Controllers/Base/OAuthController.php b/app/Http/Controllers/Base/OAuthController.php index f4aaab4f7e..a97d253c8f 100644 --- a/app/Http/Controllers/Base/OAuthController.php +++ b/app/Http/Controllers/Base/OAuthController.php @@ -7,7 +7,6 @@ use Laravel\Socialite\Facades\Socialite; use App\Http\Controllers\Controller; use App\Services\Users\UserUpdateService; -use Illuminate\Http\Response; class OAuthController extends Controller { @@ -26,6 +25,7 @@ protected function link(string $driver): RedirectResponse { // Driver is disabled - redirect to account page if (!config("auth.oauth.$driver.enabled")) { + // TODO: replace with profile route once new client area is merged return redirect()->route('account'); } @@ -35,13 +35,14 @@ protected function link(string $driver): RedirectResponse /** * Remove a OAuth link */ - protected function unlink(Request $request, string $driver): Response + protected function unlink(Request $request, string $driver): RedirectResponse { $oauth = $request->user()->oauth; unset($oauth[$driver]); $this->updateService->handle($request->user(), ['oauth' => $oauth]); - return new Response('', Response::HTTP_NO_CONTENT); + // TODO: replace with profile route once new client area is merged + return redirect()->route('account'); } } From e49d3b966285498e872eb20282055fe5cb83ec19 Mon Sep 17 00:00:00 2001 From: Boy132 Date: Mon, 25 Nov 2024 10:11:48 +0100 Subject: [PATCH 14/15] remove unnecessary controller and handle linking/ unlinking in action --- .../UserResource/Pages/EditProfile.php | 20 +++++++- app/Http/Controllers/Auth/OAuthController.php | 4 +- app/Http/Controllers/Base/OAuthController.php | 47 ------------------- routes/base.php | 3 -- 4 files changed, 21 insertions(+), 53 deletions(-) delete mode 100644 app/Http/Controllers/Base/OAuthController.php diff --git a/app/Filament/Resources/UserResource/Pages/EditProfile.php b/app/Filament/Resources/UserResource/Pages/EditProfile.php index 0b98c79423..684d8c55f6 100644 --- a/app/Filament/Resources/UserResource/Pages/EditProfile.php +++ b/app/Filament/Resources/UserResource/Pages/EditProfile.php @@ -9,6 +9,7 @@ use App\Models\User; use App\Services\Users\ToggleTwoFactorService; use App\Services\Users\TwoFactorSetupService; +use App\Services\Users\UserUpdateService; use chillerlan\QRCode\Common\EccLevel; use chillerlan\QRCode\Common\Version; use chillerlan\QRCode\QRCode; @@ -36,6 +37,7 @@ use Illuminate\Support\HtmlString; use Illuminate\Support\Str; use Illuminate\Validation\Rules\Password; +use Laravel\Socialite\Facades\Socialite; /** * @method User getUser() @@ -131,7 +133,23 @@ protected function getForms(): array ->label(($unlink ? 'Unlink ' : 'Link ') . Str::title($name)) ->icon($unlink ? 'tabler-unlink' : 'tabler-link') ->color($data['color']) - ->url(route('account.oauth.' . ($unlink ? 'unlink' : 'link'), ['driver' => $name], false)); + ->action(function (UserUpdateService $updateService) use ($name, $unlink) { + if ($unlink) { + $oauth = auth()->user()->oauth; + unset($oauth[$name]); + + $updateService->handle(auth()->user(), ['oauth' => $oauth]); + + $this->fillForm(); + + Notification::make() + ->title("OAuth provider '$name' unlinked") + ->success() + ->send(); + } elseif (config("auth.oauth.$name.enabled")) { + redirect(Socialite::with($name)->redirect()->getTargetUrl()); + } + }); } return [Actions::make($providers)]; diff --git a/app/Http/Controllers/Auth/OAuthController.php b/app/Http/Controllers/Auth/OAuthController.php index 43db86b32e..9df0978c12 100644 --- a/app/Http/Controllers/Auth/OAuthController.php +++ b/app/Http/Controllers/Auth/OAuthController.php @@ -2,6 +2,7 @@ namespace App\Http\Controllers\Auth; +use App\Filament\Resources\UserResource\Pages\EditProfile; use Filament\Notifications\Notification; use Illuminate\Auth\AuthManager; use Illuminate\Http\RedirectResponse; @@ -54,8 +55,7 @@ protected function callback(Request $request, string $driver): RedirectResponse $this->updateService->handle($request->user(), ['oauth' => $oauth]); - // TODO: replace with profile route once new client area is merged - return redirect()->route('account'); + return redirect(EditProfile::getUrl(['tab' => '-oauth-tab'])); } try { diff --git a/app/Http/Controllers/Base/OAuthController.php b/app/Http/Controllers/Base/OAuthController.php deleted file mode 100644 index 2dd9b3a5e7..0000000000 --- a/app/Http/Controllers/Base/OAuthController.php +++ /dev/null @@ -1,47 +0,0 @@ -route('account'); - } - - return Socialite::with($driver)->redirect(); - } - - /** - * Remove a OAuth link - */ - protected function unlink(Request $request, string $driver): RedirectResponse - { - $oauth = $request->user()->oauth; - unset($oauth[$driver]); - - $this->updateService->handle($request->user(), ['oauth' => $oauth]); - - // TODO: replace with profile route once new client area is merged - return redirect()->route('account'); - } -} diff --git a/routes/base.php b/routes/base.php index 2a127c7f79..d10490b2e7 100644 --- a/routes/base.php +++ b/routes/base.php @@ -10,9 +10,6 @@ ->withoutMiddleware(RequireTwoFactorAuthentication::class) ->name('account'); -Route::get('/account/oauth/link/{driver}', [Base\OAuthController::class, 'link'])->name('account.oauth.link'); -Route::get('/account/oauth/unlink/{driver}', [Base\OAuthController::class, 'unlink'])->name('account.oauth.unlink'); - Route::get('/locales/locale.json', Base\LocaleController::class) ->withoutMiddleware(['auth', RequireTwoFactorAuthentication::class]) ->where('namespace', '.*'); From 3aaf2ae21edb09998c8ecad65ec6ea2cd26758e4 Mon Sep 17 00:00:00 2001 From: Boy132 Date: Mon, 25 Nov 2024 10:18:26 +0100 Subject: [PATCH 15/15] only show oauth tab if at least one oauth provider is enabled --- .../Resources/UserResource/Pages/EditProfile.php | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/app/Filament/Resources/UserResource/Pages/EditProfile.php b/app/Filament/Resources/UserResource/Pages/EditProfile.php index 684d8c55f6..3895422539 100644 --- a/app/Filament/Resources/UserResource/Pages/EditProfile.php +++ b/app/Filament/Resources/UserResource/Pages/EditProfile.php @@ -119,6 +119,15 @@ protected function getForms(): array Tab::make('OAuth') ->icon('tabler-brand-oauth') + ->visible(function () { + foreach (config('auth.oauth') as $name => $data) { + if ($data['enabled']) { + return true; + } + } + + return false; + }) ->schema(function () { $providers = [];