fix(web): address PR review critical issues for Discord OAuth
PR Checks / test-and-build (pull_request) Successful in 6m6s
PR Checks / test-and-build (pull_request) Successful in 6m6s
- Add V019 migration: rename session_audit_log.actor_telegram_id → actor_external_user_id - Add CSRF protection to Discord OAuth flow (state cookie with HttpOnly/Secure/Strict) - Add Discord OAuth env vars to compose.yaml, deploy.yml, and .env.example - Fix SQL COALESCE for nullable telegram_id in GetGroupManagersAsync and GetSessionParticipantsAsync Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -8,6 +8,7 @@ using Microsoft.AspNetCore.DataProtection;
|
||||
using Microsoft.AspNetCore.Diagnostics.HealthChecks;
|
||||
using Microsoft.Extensions.Diagnostics.HealthChecks;
|
||||
using System.Security.Claims;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text.Json;
|
||||
using Telegram.Bot;
|
||||
using Npgsql;
|
||||
@@ -184,9 +185,16 @@ app.MapPost("/auth/logout", async (HttpContext context) =>
|
||||
});
|
||||
|
||||
// Discord OAuth endpoints
|
||||
app.MapGet("/auth/discord", (DiscordAuthService discordAuth) =>
|
||||
app.MapGet("/auth/discord", (HttpContext context, DiscordAuthService discordAuth) =>
|
||||
{
|
||||
var state = Guid.NewGuid().ToString("N");
|
||||
context.Response.Cookies.Append("__DiscordOAuthState", state, new CookieOptions
|
||||
{
|
||||
HttpOnly = true,
|
||||
Secure = true,
|
||||
SameSite = SameSiteMode.Strict,
|
||||
MaxAge = TimeSpan.FromMinutes(5)
|
||||
});
|
||||
var url = discordAuth.BuildAuthorizeUrl(state);
|
||||
return Results.Redirect(url);
|
||||
});
|
||||
@@ -197,8 +205,19 @@ app.MapGet("/auth/discord/callback", async (
|
||||
ISessionStore sessionStore) =>
|
||||
{
|
||||
var code = context.Request.Query["code"].ToString();
|
||||
if (string.IsNullOrWhiteSpace(code))
|
||||
var state = context.Request.Query["state"].ToString();
|
||||
var storedState = context.Request.Cookies["__DiscordOAuthState"];
|
||||
|
||||
context.Response.Cookies.Delete("__DiscordOAuthState");
|
||||
|
||||
if (string.IsNullOrWhiteSpace(code) ||
|
||||
string.IsNullOrWhiteSpace(state) ||
|
||||
!CryptographicOperations.FixedTimeEquals(
|
||||
System.Text.Encoding.UTF8.GetBytes(state),
|
||||
System.Text.Encoding.UTF8.GetBytes(storedState ?? string.Empty)))
|
||||
{
|
||||
return Results.Redirect("/login?error=auth_failed");
|
||||
}
|
||||
|
||||
var user = await discordAuth.ExchangeCodeAsync(code);
|
||||
if (user is null)
|
||||
|
||||
Reference in New Issue
Block a user