Refine admin workflows and team access

This commit is contained in:
AzuTear
2026-06-26 18:09:29 +02:00
parent b7804e10ea
commit 8b69dfbafb
71 changed files with 5066 additions and 751 deletions
@@ -47,38 +47,6 @@ public static partial class AuthEndpoints
return Results.Ok(await ToAuthSessionDtoAsync(db, session, member.MustChangePassword, context.RequestAborted));
}
private static async Task<IResult> TeamTwitchLogin(
HttpContext context,
TeamTwitchLoginRequest request,
AwardsDbContext db,
IUserSessionService userSessionService)
{
var twitchUserId = NormalizeTwitchUserId(request.TwitchUserId);
if (string.IsNullOrWhiteSpace(twitchUserId))
{
return Results.Unauthorized();
}
var member = await db.TeamMembers.FirstOrDefaultAsync(
item => item.BoundTwitchUserId == twitchUserId,
context.RequestAborted);
if (member is null || !member.IsActive)
{
return Results.Unauthorized();
}
member.LastLoginAt = DateTimeOffset.UtcNow;
var session = await userSessionService.CreateSessionAsync(
twitchUserId,
member.DisplayName,
member.Role,
RequestMetadataReader.Read(context),
context.RequestAborted);
await db.SaveChangesAsync(context.RequestAborted);
return Results.Ok(await ToAuthSessionDtoAsync(db, session, member.MustChangePassword, context.RequestAborted));
}
private static async Task<IResult> ChangePassword(
HttpContext context,
ChangePasswordRequest request,
@@ -127,64 +95,6 @@ public static partial class AuthEndpoints
return Results.Ok(await ToAuthSessionDtoAsync(db, session, false, context.RequestAborted));
}
private static async Task<IResult> BindTeamTwitch(
HttpContext context,
BindTeamTwitchRequest request,
AwardsDbContext db,
IUserSessionService userSessionService)
{
var session = await userSessionService.ResolveSessionAsync(context, context.RequestAborted);
if (session is null)
{
return Results.Unauthorized();
}
var member = await FindTeamMemberForSessionAsync(db, session, context.RequestAborted);
if (member is null || !member.IsActive)
{
return Results.BadRequest(new { message = "Dieser Account ist kein aktiver Team-Login." });
}
if (member.MustChangePassword)
{
return Results.BadRequest(new { message = "Bitte ändere zuerst dein temporäres Passwort." });
}
var twitchUserId = NormalizeTwitchUserId(request.TwitchUserId);
var twitchDisplayName = NormalizeTwitchDisplayName(request.DisplayName);
if (string.IsNullOrWhiteSpace(twitchUserId))
{
return Results.BadRequest(new { message = "Bitte gib deine private Twitch-ID an." });
}
var alreadyBound = await db.TeamMembers.AnyAsync(
item => item.Id != member.Id && item.BoundTwitchUserId == twitchUserId,
context.RequestAborted);
if (alreadyBound)
{
return Results.Conflict(new { message = "Diese Twitch-ID ist bereits mit einem Team-Account verbunden." });
}
var previousTwitchUserId = member.BoundTwitchUserId;
if (!string.IsNullOrWhiteSpace(previousTwitchUserId)
&& !string.Equals(previousTwitchUserId, twitchUserId, StringComparison.OrdinalIgnoreCase))
{
foreach (var oldSession in db.UserSessions.Where(item => item.TwitchUserId == previousTwitchUserId))
{
oldSession.IsActive = false;
}
}
member.BoundTwitchUserId = twitchUserId;
member.BoundTwitchDisplayName = string.IsNullOrWhiteSpace(twitchDisplayName) ? twitchUserId : twitchDisplayName;
member.TwitchBoundAt = DateTimeOffset.UtcNow;
member.UpdatedAt = DateTimeOffset.UtcNow;
member.UpdatedByTwitchId = session.TwitchUserId;
await db.SaveChangesAsync(context.RequestAborted);
return Results.Ok(await ToAuthSessionDtoAsync(db, session, false, context.RequestAborted));
}
private static string BuildTeamSessionId(string login) =>
$"{TeamSessionPrefix}{login}";
@@ -215,7 +125,4 @@ public static partial class AuthEndpoints
private static string NormalizeTwitchUserId(string? value) =>
(value ?? string.Empty).Trim().TrimStart('@').ToLowerInvariant();
private static string NormalizeTwitchDisplayName(string? value) =>
(value ?? string.Empty).Trim();
}