validated(); $response = $broker->reset( $credentials, function ($user) use ($request) { // At this time, the WebAuthnUserProvider is already registered in the Laravel Service Container, // with a password_fallback value set using the useWebauthnOnly user setting (see AuthServiceProvider.php). // To ensure user login with email+pwd credentials, we replace the registered WebAuthnUserProvider instance // with a new instance configured with password_fallback On. $provider = new \Laragear\WebAuthn\Auth\WebAuthnUserProvider( app()->make('hash'), \App\Models\User::class, app()->make(\Laragear\WebAuthn\Assertion\Validator\AssertionValidator::class), true, ); Auth::setProvider($provider); if (Auth::attempt($request->only('email', 'password'))) { if ($this->shouldRevokeAllCredentials($request)) { $user->flushCredentials(); } $user['preferences->useWebauthnOnly'] = false; $user->save(); Log::notice(sprintf('Legacy login restored for user ID #%s', $user->id)); } else { throw new AuthenticationException; } } ); return $response === Password::PASSWORD_RESET ? $this->sendRecoveryResponse($request, $response) : $this->sendRecoveryFailedResponse($request, $response); } /** * Check if the user has set to revoke all credentials. * * @return bool|mixed */ protected function shouldRevokeAllCredentials(WebauthnRecoveryRequest $request) : mixed { return filter_var($request->header('WebAuthn-Unique'), FILTER_VALIDATE_BOOLEAN) ?: $request->input('revokeAll', true); } /** * Get the response for a successful account recovery. */ protected function sendRecoveryResponse(Request $request, string $response) : JsonResponse { return response()->json(['message' => __('auth.webauthn.webauthn_login_disabled')]); } /** * Get the response for a failed account recovery. * * * @throws \Illuminate\Validation\ValidationException */ protected function sendRecoveryFailedResponse(Request $request, string $response) : JsonResponse { switch ($response) { case Password::INVALID_TOKEN: throw ValidationException::withMessages(['token' => [__('auth.webauthn.invalid_reset_token')]]); default: throw ValidationException::withMessages(['email' => [trans($response)]]); } } }