Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions Content.Server/Corvax/DiscordAuth/DiscordAlreadyLinkedException.cs
Original file line number Diff line number Diff line change
@@ -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;
}
}
10 changes: 10 additions & 0 deletions Content.Server/Corvax/DiscordAuth/DiscordLinkSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
19 changes: 19 additions & 0 deletions Content.Server/Corvax/DiscordAuth/ServerDiscordAuthManager.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System.Net;
using System.Net.Http;
using System.Net.Http.Json;
using System.Threading;
Expand Down Expand Up @@ -45,6 +46,24 @@ public async Task<string> 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<LinkApiResponse>(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<LinkTokenApiResponse>(cancellationToken: cancel);
Expand Down
Loading