diff --git a/app/Auth/Oidc/Socialite/OidcProvider.php b/app/Auth/Oidc/Socialite/OidcProvider.php index b9fc16f9c..383b0cc91 100644 --- a/app/Auth/Oidc/Socialite/OidcProvider.php +++ b/app/Auth/Oidc/Socialite/OidcProvider.php @@ -209,9 +209,11 @@ public function getAccessTokenResponse($code) $fields = $this->getTokenFields($code); if ($this->getConfig()->usePkce) { $verifier = $this->pullOidcFlowValue($this->verifierSessionKey((string) $this->request->input('state'))); - if ($verifier !== null) { - $fields['code_verifier'] = $verifier; + if ($verifier === null) { + throw new OidcException('OIDC login session expired. Please try again.'); } + + $fields['code_verifier'] = $verifier; } $response = $this->getHttpClient()->post($this->getTokenUrl(), [ diff --git a/app/Livewire/SettingsOauth.php b/app/Livewire/SettingsOauth.php index 8b4c902d5..d038d9a95 100644 --- a/app/Livewire/SettingsOauth.php +++ b/app/Livewire/SettingsOauth.php @@ -5,6 +5,7 @@ use App\Models\InstanceSettings; use App\Models\OauthSetting; use Illuminate\Foundation\Auth\Access\AuthorizesRequests; +use Illuminate\Http\RedirectResponse; use Illuminate\Validation\ValidationException; use Livewire\Component; @@ -55,7 +56,7 @@ private function validationRules(?string $provider = null): array return $rules; } - public function mount(?string $provider = null) + public function mount(?string $provider = null): ?RedirectResponse { if (! isInstanceAdmin()) { return redirect()->route('home'); @@ -73,6 +74,8 @@ public function mount(?string $provider = null) if ($this->selectedProvider !== null && ! array_key_exists($this->selectedProvider, $this->oauth_settings_map)) { abort(404); } + + return null; } private function updateOauthSettings(?string $provider = null): void diff --git a/tests/Unit/OidcProviderPkceTest.php b/tests/Unit/OidcProviderPkceTest.php index 9726f08b0..b92ff58ff 100644 --- a/tests/Unit/OidcProviderPkceTest.php +++ b/tests/Unit/OidcProviderPkceTest.php @@ -1,5 +1,6 @@ and($session->has('oidc.code_verifier.state-value'))->toBeFalse(); }); -it('does not send an expired oidc pkce verifier during token exchange', function () { +it('throws a session expired error for an expired oidc pkce verifier during token exchange', function () { $session = oidc_provider_session(); $session->put('oidc.code_verifier.state-value', [ 'value' => 'expired-verifier', @@ -144,9 +145,4 @@ function oidc_provider(Request $request): TestOidcProviderWithExposedAuthUrl $provider->setHttpClient(new Client(['handler' => $handler])); $provider->getAccessTokenResponse('authorization-code'); - - parse_str((string) $history[0]['request']->getBody(), $tokenRequestFields); - - expect($tokenRequestFields)->not->toHaveKey('code_verifier') - ->and($session->has('oidc.code_verifier.state-value'))->toBeFalse(); -}); +})->throws(OidcException::class, 'OIDC login session expired. Please try again.');