From 9ab7fcc46e4fcbb7ceeb6c8577cc5d4fe0c999ee Mon Sep 17 00:00:00 2001 From: Dmitry Popov Date: Thu, 26 Mar 2026 00:41:07 +0100 Subject: [PATCH] fix(core): Fixed character re-auth issues --- lib/wanderer_app/esi/api_client.ex | 38 +++++++++++++------ .../controllers/auth_controller.ex | 4 ++ 2 files changed, 30 insertions(+), 12 deletions(-) diff --git a/lib/wanderer_app/esi/api_client.ex b/lib/wanderer_app/esi/api_client.ex index 1be536b8..38890cb3 100644 --- a/lib/wanderer_app/esi/api_client.ex +++ b/lib/wanderer_app/esi/api_client.ex @@ -897,21 +897,35 @@ defmodule WandererApp.Esi.ApiClient do end defp invalidate_character_tokens(character, character_id, expires_at, scopes) do - attrs = %{access_token: nil, refresh_token: nil, expires_at: expires_at, scopes: scopes} + # Re-load from DB to avoid race with concurrent re-auth + case WandererApp.Api.Character.by_id(character_id) do + {:ok, current_character} -> + # Only invalidate if tokens haven't been refreshed since we started + if current_character.access_token == character.access_token do + attrs = %{access_token: nil, refresh_token: nil, expires_at: expires_at, scopes: scopes} - with {:ok, _} <- WandererApp.Api.Character.update(character, attrs) do - WandererApp.Character.update_character(character_id, attrs) - else - error -> - Logger.error("Failed to clear tokens for #{character_id}: #{inspect(error)}") + with {:ok, _} <- WandererApp.Api.Character.update(current_character, attrs) do + WandererApp.Character.update_character(character_id, attrs) + else + error -> + Logger.error("Failed to clear tokens for #{character_id}: #{inspect(error)}") + end + + Phoenix.PubSub.broadcast( + WandererApp.PubSub, + "character:#{character_id}", + :character_token_invalid + ) + else + Logger.info( + "[ApiClient] Skipping token invalidation for #{character_id} - tokens were refreshed concurrently" + ) + end + + {:error, _} -> + Logger.error("Failed to load character #{character_id} for token invalidation") end - Phoenix.PubSub.broadcast( - WandererApp.PubSub, - "character:#{character_id}", - :character_token_invalid - ) - :ok end end diff --git a/lib/wanderer_app_web/controllers/auth_controller.ex b/lib/wanderer_app_web/controllers/auth_controller.ex index 730c9429..1d01a914 100644 --- a/lib/wanderer_app_web/controllers/auth_controller.ex +++ b/lib/wanderer_app_web/controllers/auth_controller.ex @@ -42,6 +42,10 @@ defmodule WandererAppWeb.AuthController do WandererApp.Character.update_character(character.id, character_update) + # Clear the invalid_grant counter so stale failures don't cause + # premature token invalidation after a successful re-auth + WandererApp.Cache.delete("character:#{character.id}:invalid_grant_count") + # Update corporation/alliance data from ESI to ensure access control is current update_character_affiliation(character)