7a2ed808c4
- Replace __DiscordOAuthState cookie (blocked by third-party cookie policies) with in-memory DiscordOAuthStateStore singleton - State is created server-side and validated on callback, eliminating cross-site cookie transmission issues entirely - Removed CryptographicOperations dependency from Program.cs Bump version → 2.8.1 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
33 lines
995 B
C#
33 lines
995 B
C#
namespace GmRelay.Web.Services;
|
|
|
|
public sealed class DiscordOAuthStateStore(ILogger<DiscordOAuthStateStore> logger)
|
|
{
|
|
private readonly System.Collections.Concurrent.ConcurrentDictionary<string, DateTime> _states = new();
|
|
|
|
public string CreateState()
|
|
{
|
|
var state = Guid.NewGuid().ToString("N");
|
|
_states[state] = DateTime.UtcNow.AddMinutes(5);
|
|
logger.LogDebug("Discord OAuth state created: {State}", state);
|
|
return state;
|
|
}
|
|
|
|
public bool ValidateAndRemove(string state)
|
|
{
|
|
if (!_states.TryRemove(state, out var expiresAt))
|
|
{
|
|
logger.LogWarning("Discord OAuth state not found or already used: {State}", state);
|
|
return false;
|
|
}
|
|
|
|
if (DateTime.UtcNow > expiresAt)
|
|
{
|
|
logger.LogWarning("Discord OAuth state expired: {State}", state);
|
|
return false;
|
|
}
|
|
|
|
logger.LogDebug("Discord OAuth state validated: {State}", state);
|
|
return true;
|
|
}
|
|
}
|