From 543fc42a6d37b310abd791ccdfa2ae1282bc561e Mon Sep 17 00:00:00 2001 From: Toutsu Date: Mon, 25 May 2026 11:02:29 +0300 Subject: [PATCH] feat(web): add platform-agnostic identity extraction from ClaimsPrincipal - TryGetPlatformIdentity returns (platform, external_user_id) - TryGetDiscordId for Discord-specific flows - Backward-compatible fallback for legacy Telegram auth without Platform claim - GetAvatarUrl helper for Discord avatars Co-Authored-By: Claude Opus 4.7 --- .../Services/ClaimsPrincipalExtensions.cs | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/src/GmRelay.Web/Services/ClaimsPrincipalExtensions.cs b/src/GmRelay.Web/Services/ClaimsPrincipalExtensions.cs index c0427f9..8d08087 100644 --- a/src/GmRelay.Web/Services/ClaimsPrincipalExtensions.cs +++ b/src/GmRelay.Web/Services/ClaimsPrincipalExtensions.cs @@ -6,4 +6,37 @@ public static class ClaimsPrincipalExtensions { public static bool TryGetTelegramId(this ClaimsPrincipal user, out long telegramId) => long.TryParse(user.FindFirst("TelegramId")?.Value, out telegramId); + + public static bool TryGetDiscordId(this ClaimsPrincipal user, out string? discordId) + { + discordId = user.FindFirst("DiscordId")?.Value; + return !string.IsNullOrWhiteSpace(discordId); + } + + public static bool TryGetPlatformIdentity(this ClaimsPrincipal user, out string platform, out string externalUserId) + { + platform = string.Empty; + externalUserId = string.Empty; + + var platformClaim = user.FindFirst("Platform")?.Value; + if (!string.IsNullOrWhiteSpace(platformClaim)) + { + platform = platformClaim; + externalUserId = user.FindFirst(ClaimTypes.NameIdentifier)?.Value ?? string.Empty; + return !string.IsNullOrWhiteSpace(externalUserId); + } + + // Fallback for legacy Telegram users before Platform claim was added + if (TryGetTelegramId(user, out var telegramId)) + { + platform = "Telegram"; + externalUserId = telegramId.ToString(System.Globalization.CultureInfo.InvariantCulture); + return true; + } + + return false; + } + + public static string? GetAvatarUrl(this ClaimsPrincipal user) => + user.FindFirst("AvatarUrl")?.Value; }