From b7d40934e3225e71037798414a4dde5cd3395c46 Mon Sep 17 00:00:00 2001 From: insvrg3ncy Date: Wed, 13 May 2026 22:59:46 +0300 Subject: [PATCH] discord auth fixes --- .../DiscordAlreadyLinkedException.cs | 13 +++++++++++++ .../Corvax/DiscordAuth/DiscordLinkSystem.cs | 10 ++++++++++ .../DiscordAuth/ServerDiscordAuthManager.cs | 19 +++++++++++++++++++ 3 files changed, 42 insertions(+) create mode 100644 Content.Server/Corvax/DiscordAuth/DiscordAlreadyLinkedException.cs diff --git a/Content.Server/Corvax/DiscordAuth/DiscordAlreadyLinkedException.cs b/Content.Server/Corvax/DiscordAuth/DiscordAlreadyLinkedException.cs new file mode 100644 index 00000000000..111560cfc9f --- /dev/null +++ b/Content.Server/Corvax/DiscordAuth/DiscordAlreadyLinkedException.cs @@ -0,0 +1,13 @@ +namespace Content.Server.Corvax.DiscordAuth; + +// Thrown when POST /api/links/token returns 409 and by-ss14 shows an existing link. +public sealed class DiscordAlreadyLinkedException : Exception +{ + public string? DiscordUserName { get; } + + public DiscordAlreadyLinkedException(string? discordUserName) + : base("Discord is already linked for this account.") + { + DiscordUserName = discordUserName; + } +} diff --git a/Content.Server/Corvax/DiscordAuth/DiscordLinkSystem.cs b/Content.Server/Corvax/DiscordAuth/DiscordLinkSystem.cs index 8b18a1fd531..ab12bb4b280 100644 --- a/Content.Server/Corvax/DiscordAuth/DiscordLinkSystem.cs +++ b/Content.Server/Corvax/DiscordAuth/DiscordLinkSystem.cs @@ -100,6 +100,16 @@ private async void OnLinkRequest(DiscordLinkRequestEvent ev, EntitySessionEventA RaiseNetworkEvent(new DiscordLinkUrlEvent { Url = url }, session); }); } + catch (DiscordAlreadyLinkedException ex) + { + _sponsorsManager?.InvalidateCache(session.UserId); + _taskManager.RunOnMainThread(() => + { + RaiseNetworkEvent( + new DiscordLinkStatusEvent { IsLinked = true, DiscordName = ex.DiscordUserName }, + session); + }); + } catch (Exception ex) { Log.Error( diff --git a/Content.Server/Corvax/DiscordAuth/ServerDiscordAuthManager.cs b/Content.Server/Corvax/DiscordAuth/ServerDiscordAuthManager.cs index 8e4686cf537..3bacbb6ab33 100644 --- a/Content.Server/Corvax/DiscordAuth/ServerDiscordAuthManager.cs +++ b/Content.Server/Corvax/DiscordAuth/ServerDiscordAuthManager.cs @@ -1,3 +1,4 @@ +using System.Net; using System.Net.Http; using System.Net.Http.Json; using System.Threading; @@ -45,6 +46,24 @@ public async Task GenerateAuthLink(NetUserId userId, string userName, Ca var payload = new { ss14UserId = userId.UserId, ss14UserName = userName }; var response = await _httpClient.PostAsJsonAsync(url, payload, cancel); + + if (response.StatusCode == HttpStatusCode.Conflict) + { + // Often returned when requesting a new token while already linked (or a token already exists). + var statusUrl = $"{_apiUrl.TrimEnd('/')}/api/links/by-ss14/{userId.UserId}"; + var statusResponse = await _httpClient.GetAsync(statusUrl, cancel); + if (statusResponse.IsSuccessStatusCode) + { + var link = await statusResponse.Content.ReadFromJsonAsync(cancellationToken: cancel) + .ConfigureAwait(false); + throw new DiscordAlreadyLinkedException(link?.DiscordUserName); + } + + _sawmill.Warning( + "POST /api/links/token returned 409 but GET by-ss14 was not successful for {0}", + userId); + } + response.EnsureSuccessStatusCode(); var result = await response.Content.ReadFromJsonAsync(cancellationToken: cancel);