From 57df5d52539a2e0f4bec78971a76f4a2c359cf97 Mon Sep 17 00:00:00 2001 From: Paulo Castellano Date: Wed, 1 Apr 2026 15:27:26 -0300 Subject: [PATCH 1/6] feat: add TRYPOST_GOOGLE_AUTH_ENABLED toggle to show/hide Google login on auth pages --- .../Middleware/App/HandleInertiaRequests.php | 1 + config/trypost.php | 12 +++++++++++ resources/js/pages/auth/Login.vue | 20 ++++++++++--------- resources/js/pages/auth/Register.vue | 20 ++++++++++--------- routes/auth.php | 6 ++++-- 5 files changed, 39 insertions(+), 20 deletions(-) diff --git a/app/Http/Middleware/App/HandleInertiaRequests.php b/app/Http/Middleware/App/HandleInertiaRequests.php index dab26efc..6deda69c 100644 --- a/app/Http/Middleware/App/HandleInertiaRequests.php +++ b/app/Http/Middleware/App/HandleInertiaRequests.php @@ -47,6 +47,7 @@ public function share(Request $request): array 'name' => $name, ])->values()->all(), 'selfHosted' => config('trypost.self_hosted'), + 'googleAuthEnabled' => config('trypost.google_auth_enabled'), ]; } } diff --git a/config/trypost.php b/config/trypost.php index f860264f..e8e2f8da 100644 --- a/config/trypost.php +++ b/config/trypost.php @@ -16,6 +16,18 @@ 'self_hosted' => env('SELF_HOSTED', true), + /* + |-------------------------------------------------------------------------- + | Google Authentication + |-------------------------------------------------------------------------- + | + | Enable or disable "Login with Google" on the login and register pages. + | Disable this if you don't have Google OAuth credentials configured. + | + */ + + 'google_auth_enabled' => env('TRYPOST_GOOGLE_AUTH_ENABLED', false), + /* |-------------------------------------------------------------------------- | Social Platforms diff --git a/resources/js/pages/auth/Login.vue b/resources/js/pages/auth/Login.vue index 9d5a1b9f..2be5550e 100644 --- a/resources/js/pages/auth/Login.vue +++ b/resources/js/pages/auth/Login.vue @@ -66,16 +66,18 @@ defineProps<{ -
- {{ $t('auth.or_continue_with') }} -
+
{{ $t('auth.login.no_account') }} diff --git a/resources/js/pages/auth/Register.vue b/resources/js/pages/auth/Register.vue index 4f59fc62..0fa1becd 100644 --- a/resources/js/pages/auth/Register.vue +++ b/resources/js/pages/auth/Register.vue @@ -123,16 +123,18 @@ const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
-
- {{ $t('auth.or_continue_with') }} -
+
{{ $t('auth.register.has_account') }} diff --git a/routes/auth.php b/routes/auth.php index 798ec5e8..cd3deaab 100644 --- a/routes/auth.php +++ b/routes/auth.php @@ -29,8 +29,10 @@ Route::get('/reset-password/{token}', [NewPasswordController::class, 'create'])->name('password.reset'); Route::post('/reset-password', [NewPasswordController::class, 'store'])->name('password.store'); - Route::get('/auth/google/redirect', [SocialLoginController::class, 'redirect'])->name('auth.google.redirect'); - Route::get('/auth/google/callback', [SocialLoginController::class, 'callback'])->name('auth.google.callback'); + if (config('trypost.google_auth_enabled')) { + Route::get('/auth/google/redirect', [SocialLoginController::class, 'redirect'])->name('auth.google.redirect'); + Route::get('/auth/google/callback', [SocialLoginController::class, 'callback'])->name('auth.google.callback'); + } }); Route::middleware(['auth'])->group(function () { From 25c43a3906b6a2d8b8685cda94580a6a4267c211 Mon Sep 17 00:00:00 2001 From: Paulo Castellano Date: Tue, 14 Apr 2026 14:16:34 -0300 Subject: [PATCH 2/6] refactor: rename TRYPOST_GOOGLE_AUTH_ENABLED to GOOGLE_AUTH_ENABLED Aligns with existing Google env naming convention (GOOGLE_AUTH_CALLBACK). --- config/trypost.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/trypost.php b/config/trypost.php index e8e2f8da..7554e1ff 100644 --- a/config/trypost.php +++ b/config/trypost.php @@ -26,7 +26,7 @@ | */ - 'google_auth_enabled' => env('TRYPOST_GOOGLE_AUTH_ENABLED', false), + 'google_auth_enabled' => env('GOOGLE_AUTH_ENABLED', false), /* |-------------------------------------------------------------------------- From d94374c31a9c9001fe7443a757f77ca152443025 Mon Sep 17 00:00:00 2001 From: Paulo Castellano Date: Tue, 14 Apr 2026 14:19:51 -0300 Subject: [PATCH 3/6] refactor: remove TRYPOST_ prefix from platform env variables Standardizes env naming to match existing convention (THREADS_CLIENT_ID, GOOGLE_AUTH_ENABLED, etc). --- config/trypost.php | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/config/trypost.php b/config/trypost.php index 7554e1ff..c3ba10f0 100644 --- a/config/trypost.php +++ b/config/trypost.php @@ -41,37 +41,37 @@ 'platforms' => [ 'linkedin' => [ - 'enabled' => env('TRYPOST_LINKEDIN_ENABLED', true), + 'enabled' => env('LINKEDIN_ENABLED', true), ], 'linkedin-page' => [ - 'enabled' => env('TRYPOST_LINKEDIN_PAGE_ENABLED', true), + 'enabled' => env('LINKEDIN_PAGE_ENABLED', true), ], 'x' => [ - 'enabled' => env('TRYPOST_X_ENABLED', true), + 'enabled' => env('X_ENABLED', true), ], 'tiktok' => [ - 'enabled' => env('TRYPOST_TIKTOK_ENABLED', true), + 'enabled' => env('TIKTOK_ENABLED', true), ], 'youtube' => [ - 'enabled' => env('TRYPOST_YOUTUBE_ENABLED', true), + 'enabled' => env('YOUTUBE_ENABLED', true), ], 'facebook' => [ - 'enabled' => env('TRYPOST_FACEBOOK_ENABLED', true), + 'enabled' => env('FACEBOOK_ENABLED', true), ], 'instagram' => [ - 'enabled' => env('TRYPOST_INSTAGRAM_ENABLED', true), + 'enabled' => env('INSTAGRAM_ENABLED', true), ], 'threads' => [ - 'enabled' => env('TRYPOST_THREADS_ENABLED', true), + 'enabled' => env('THREADS_ENABLED', true), ], 'pinterest' => [ - 'enabled' => env('TRYPOST_PINTEREST_ENABLED', true), + 'enabled' => env('PINTEREST_ENABLED', true), ], 'bluesky' => [ - 'enabled' => env('TRYPOST_BLUESKY_ENABLED', true), + 'enabled' => env('BLUESKY_ENABLED', true), ], 'mastodon' => [ - 'enabled' => env('TRYPOST_MASTODON_ENABLED', true), + 'enabled' => env('MASTODON_ENABLED', true), ], ], From 557507672e26032f0ba1ae7da7f425f63cd033d4 Mon Sep 17 00:00:00 2001 From: Paulo Castellano Date: Tue, 14 Apr 2026 14:28:17 -0300 Subject: [PATCH 4/6] fix: keep Google OAuth routes always registered and add tests Routes must always exist so Wayfinder can generate TypeScript helpers. The toggle now only controls frontend visibility via Inertia prop. --- routes/auth.php | 6 +-- tests/Feature/GoogleAuthToggleTest.php | 71 ++++++++++++++++++++++++++ 2 files changed, 73 insertions(+), 4 deletions(-) create mode 100644 tests/Feature/GoogleAuthToggleTest.php diff --git a/routes/auth.php b/routes/auth.php index cd3deaab..798ec5e8 100644 --- a/routes/auth.php +++ b/routes/auth.php @@ -29,10 +29,8 @@ Route::get('/reset-password/{token}', [NewPasswordController::class, 'create'])->name('password.reset'); Route::post('/reset-password', [NewPasswordController::class, 'store'])->name('password.store'); - if (config('trypost.google_auth_enabled')) { - Route::get('/auth/google/redirect', [SocialLoginController::class, 'redirect'])->name('auth.google.redirect'); - Route::get('/auth/google/callback', [SocialLoginController::class, 'callback'])->name('auth.google.callback'); - } + Route::get('/auth/google/redirect', [SocialLoginController::class, 'redirect'])->name('auth.google.redirect'); + Route::get('/auth/google/callback', [SocialLoginController::class, 'callback'])->name('auth.google.callback'); }); Route::middleware(['auth'])->group(function () { diff --git a/tests/Feature/GoogleAuthToggleTest.php b/tests/Feature/GoogleAuthToggleTest.php new file mode 100644 index 00000000..bb01975e --- /dev/null +++ b/tests/Feature/GoogleAuthToggleTest.php @@ -0,0 +1,71 @@ + false]); + + $response = $this->get(route('login')); + + $response->assertOk(); +}); + +test('login page loads when google auth is enabled', function () { + config(['trypost.google_auth_enabled' => true]); + + $response = $this->get(route('login')); + + $response->assertOk(); +}); + +test('register page loads when google auth is disabled', function () { + config(['trypost.google_auth_enabled' => false]); + + $response = $this->get(route('register')); + + $response->assertOk(); +}); + +test('register page loads when google auth is enabled', function () { + config(['trypost.google_auth_enabled' => true]); + + $response = $this->get(route('register')); + + $response->assertOk(); +}); + +test('login page shares google auth enabled prop as false when disabled', function () { + config(['trypost.google_auth_enabled' => false]); + + $response = $this->get(route('login')); + + $response->assertOk(); + + $page = $response->original->getData()['page']; + expect($page['props']['googleAuthEnabled'])->toBeFalse(); +}); + +test('login page shares google auth enabled prop as true when enabled', function () { + config(['trypost.google_auth_enabled' => true]); + + $response = $this->get(route('login')); + + $response->assertOk(); + + $page = $response->original->getData()['page']; + expect($page['props']['googleAuthEnabled'])->toBeTrue(); +}); + +test('google auth redirect route exists', function () { + $response = $this->get(route('auth.google.redirect')); + + // Should redirect to Google OAuth, not 404 + $response->assertRedirect(); +}); + +test('google auth callback route exists', function () { + $response = $this->get(route('auth.google.callback')); + + // Should redirect to login on failure (no OAuth code), not 404 + $response->assertRedirect(route('login')); +}); From 2fcf0a7e7a8fd75ff79ac94a441926deb2a78c33 Mon Sep 17 00:00:00 2001 From: Paulo Castellano Date: Tue, 14 Apr 2026 14:44:15 -0300 Subject: [PATCH 5/6] fix: update Socialite mocks in social controller tests The mock shorthand Mockery::mock([...]) was not compatible with the Socialite facade mock. Replaced with explicit shouldReceive chains matching each controller's actual Socialite method calls. Also keeps Google OAuth routes always registered so Wayfinder can generate TypeScript helpers regardless of GOOGLE_AUTH_ENABLED setting. --- tests/Feature/Social/FacebookControllerTest.php | 14 ++++++++------ tests/Feature/Social/InstagramControllerTest.php | 13 +++++++------ tests/Feature/Social/LinkedInControllerTest.php | 13 +++++++------ .../Feature/Social/LinkedInPageControllerTest.php | 15 ++++++++------- tests/Feature/Social/PinterestControllerTest.php | 13 +++++++------ tests/Feature/Social/TikTokControllerTest.php | 13 +++++++------ tests/Feature/Social/XControllerTest.php | 13 +++++++------ tests/Feature/Social/YouTubeControllerTest.php | 15 ++++++++------- 8 files changed, 59 insertions(+), 50 deletions(-) diff --git a/tests/Feature/Social/FacebookControllerTest.php b/tests/Feature/Social/FacebookControllerTest.php index d95cb690..abb0d747 100644 --- a/tests/Feature/Social/FacebookControllerTest.php +++ b/tests/Feature/Social/FacebookControllerTest.php @@ -20,14 +20,16 @@ }); test('facebook connect redirects to oauth provider', function () { + $driverMock = Mockery::mock(); + $driverMock->shouldReceive('usingGraphVersion')->andReturnSelf(); + $driverMock->shouldReceive('setScopes')->andReturnSelf(); + $driverMock->shouldReceive('redirect')->andReturn(Mockery::mock([ + 'getTargetUrl' => 'https://www.facebook.com/v25.0/dialog/oauth?test=1', + ])); + Socialite::shouldReceive('driver') ->with('facebook') - ->andReturn(Mockery::mock([ - 'scopes' => Mockery::self(), - 'redirect' => Mockery::mock([ - 'getTargetUrl' => 'https://www.facebook.com/v21.0/dialog/oauth?test=1', - ]), - ])); + ->andReturn($driverMock); $response = $this->actingAs($this->user) ->withHeader('X-Inertia', 'true') diff --git a/tests/Feature/Social/InstagramControllerTest.php b/tests/Feature/Social/InstagramControllerTest.php index 20b3a2d8..b0117173 100644 --- a/tests/Feature/Social/InstagramControllerTest.php +++ b/tests/Feature/Social/InstagramControllerTest.php @@ -19,14 +19,15 @@ }); test('instagram connect redirects to oauth provider', function () { + $driverMock = Mockery::mock(); + $driverMock->shouldReceive('scopes')->andReturnSelf(); + $driverMock->shouldReceive('redirect')->andReturn(Mockery::mock([ + 'getTargetUrl' => 'https://www.instagram.com/oauth/authorize?test=1', + ])); + Socialite::shouldReceive('driver') ->with('instagram') - ->andReturn(Mockery::mock([ - 'scopes' => Mockery::self(), - 'redirect' => Mockery::mock([ - 'getTargetUrl' => 'https://www.instagram.com/oauth/authorize?test=1', - ]), - ])); + ->andReturn($driverMock); $response = $this->actingAs($this->user) ->withHeader('X-Inertia', 'true') diff --git a/tests/Feature/Social/LinkedInControllerTest.php b/tests/Feature/Social/LinkedInControllerTest.php index 6ced6a71..26aee84a 100644 --- a/tests/Feature/Social/LinkedInControllerTest.php +++ b/tests/Feature/Social/LinkedInControllerTest.php @@ -20,14 +20,15 @@ }); test('linkedin connect redirects to oauth provider', function () { + $driverMock = Mockery::mock(); + $driverMock->shouldReceive('scopes')->andReturnSelf(); + $driverMock->shouldReceive('redirect')->andReturn(Mockery::mock([ + 'getTargetUrl' => 'https://www.linkedin.com/oauth/v2/authorization?test=1', + ])); + Socialite::shouldReceive('driver') ->with('linkedin') - ->andReturn(Mockery::mock([ - 'scopes' => Mockery::self(), - 'redirect' => Mockery::mock([ - 'getTargetUrl' => 'https://www.linkedin.com/oauth/v2/authorization?test=1', - ]), - ])); + ->andReturn($driverMock); $response = $this->actingAs($this->user) ->withHeader('X-Inertia', 'true') diff --git a/tests/Feature/Social/LinkedInPageControllerTest.php b/tests/Feature/Social/LinkedInPageControllerTest.php index e4517af3..ce703bfa 100644 --- a/tests/Feature/Social/LinkedInPageControllerTest.php +++ b/tests/Feature/Social/LinkedInPageControllerTest.php @@ -20,15 +20,16 @@ }); test('linkedin page connect redirects to oauth provider', function () { + $driverMock = Mockery::mock(); + $driverMock->shouldReceive('scopes')->andReturnSelf(); + $driverMock->shouldReceive('with')->andReturnSelf(); + $driverMock->shouldReceive('redirect')->andReturn(Mockery::mock([ + 'getTargetUrl' => 'https://www.linkedin.com/oauth/v2/authorization?test=1', + ])); + Socialite::shouldReceive('driver') ->with('linkedin-openid') - ->andReturn(Mockery::mock([ - 'scopes' => Mockery::self(), - 'with' => Mockery::self(), - 'redirect' => Mockery::mock([ - 'getTargetUrl' => 'https://www.linkedin.com/oauth/v2/authorization?test=1', - ]), - ])); + ->andReturn($driverMock); $response = $this->actingAs($this->user) ->withHeader('X-Inertia', 'true') diff --git a/tests/Feature/Social/PinterestControllerTest.php b/tests/Feature/Social/PinterestControllerTest.php index 1ee6b7e4..0336d742 100644 --- a/tests/Feature/Social/PinterestControllerTest.php +++ b/tests/Feature/Social/PinterestControllerTest.php @@ -19,14 +19,15 @@ }); test('pinterest connect redirects to oauth provider', function () { + $driverMock = Mockery::mock(); + $driverMock->shouldReceive('scopes')->andReturnSelf(); + $driverMock->shouldReceive('redirect')->andReturn(Mockery::mock([ + 'getTargetUrl' => 'https://www.pinterest.com/oauth?test=1', + ])); + Socialite::shouldReceive('driver') ->with('pinterest') - ->andReturn(Mockery::mock([ - 'scopes' => Mockery::self(), - 'redirect' => Mockery::mock([ - 'getTargetUrl' => 'https://www.pinterest.com/oauth?test=1', - ]), - ])); + ->andReturn($driverMock); $response = $this->actingAs($this->user) ->withHeader('X-Inertia', 'true') diff --git a/tests/Feature/Social/TikTokControllerTest.php b/tests/Feature/Social/TikTokControllerTest.php index 707777b2..1df0a79f 100644 --- a/tests/Feature/Social/TikTokControllerTest.php +++ b/tests/Feature/Social/TikTokControllerTest.php @@ -19,14 +19,15 @@ }); test('tiktok connect redirects to oauth provider', function () { + $driverMock = Mockery::mock(); + $driverMock->shouldReceive('scopes')->andReturnSelf(); + $driverMock->shouldReceive('redirect')->andReturn(Mockery::mock([ + 'getTargetUrl' => 'https://www.tiktok.com/v2/auth/authorize?test=1', + ])); + Socialite::shouldReceive('driver') ->with('tiktok') - ->andReturn(Mockery::mock([ - 'scopes' => Mockery::self(), - 'redirect' => Mockery::mock([ - 'getTargetUrl' => 'https://www.tiktok.com/v2/auth/authorize?test=1', - ]), - ])); + ->andReturn($driverMock); $response = $this->actingAs($this->user) ->withHeader('X-Inertia', 'true') diff --git a/tests/Feature/Social/XControllerTest.php b/tests/Feature/Social/XControllerTest.php index 1cdac102..7af106d8 100644 --- a/tests/Feature/Social/XControllerTest.php +++ b/tests/Feature/Social/XControllerTest.php @@ -19,14 +19,15 @@ }); test('x connect redirects to oauth provider', function () { + $driverMock = Mockery::mock(); + $driverMock->shouldReceive('scopes')->andReturnSelf(); + $driverMock->shouldReceive('redirect')->andReturn(Mockery::mock([ + 'getTargetUrl' => 'https://twitter.com/i/oauth2/authorize?test=1', + ])); + Socialite::shouldReceive('driver') ->with('x') - ->andReturn(Mockery::mock([ - 'scopes' => Mockery::self(), - 'redirect' => Mockery::mock([ - 'getTargetUrl' => 'https://twitter.com/i/oauth2/authorize?test=1', - ]), - ])); + ->andReturn($driverMock); $response = $this->actingAs($this->user) ->withHeader('X-Inertia', 'true') diff --git a/tests/Feature/Social/YouTubeControllerTest.php b/tests/Feature/Social/YouTubeControllerTest.php index 21db5603..1d8532f7 100644 --- a/tests/Feature/Social/YouTubeControllerTest.php +++ b/tests/Feature/Social/YouTubeControllerTest.php @@ -20,15 +20,16 @@ }); test('youtube connect redirects to oauth provider', function () { + $driverMock = Mockery::mock(); + $driverMock->shouldReceive('scopes')->andReturnSelf(); + $driverMock->shouldReceive('with')->andReturnSelf(); + $driverMock->shouldReceive('redirect')->andReturn(Mockery::mock([ + 'getTargetUrl' => 'https://accounts.google.com/o/oauth2/v2/auth?test=1', + ])); + Socialite::shouldReceive('driver') ->with('google') - ->andReturn(Mockery::mock([ - 'scopes' => Mockery::self(), - 'with' => Mockery::self(), - 'redirect' => Mockery::mock([ - 'getTargetUrl' => 'https://accounts.google.com/o/oauth2/v2/auth?test=1', - ]), - ])); + ->andReturn($driverMock); $response = $this->actingAs($this->user) ->withHeader('X-Inertia', 'true') From 80c193f69fd901890ace36ec141e7ba914b04ddf Mon Sep 17 00:00:00 2001 From: Paulo Castellano Date: Tue, 14 Apr 2026 14:49:38 -0300 Subject: [PATCH 6/6] feat: add localization files and update Instagram-Facebook environment variable key --- config/trypost.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/trypost.php b/config/trypost.php index 5b17a19b..32ce9b60 100644 --- a/config/trypost.php +++ b/config/trypost.php @@ -62,7 +62,7 @@ 'enabled' => env('INSTAGRAM_ENABLED', true), ], 'instagram-facebook' => [ - 'enabled' => env('TRYPOST_INSTAGRAM_FACEBOOK_ENABLED', true), + 'enabled' => env('INSTAGRAM_FACEBOOK_ENABLED', true), ], 'threads' => [ 'enabled' => env('THREADS_ENABLED', true),