Code cleanup
This commit is contained in:
@@ -8,8 +8,7 @@ public static class ApiEndpointRegistration
|
||||
api.MapSystemEndpoints();
|
||||
api.MapAuthEndpoints();
|
||||
|
||||
var authenticatedApi = api.MapGroup(string.Empty)
|
||||
.AddEndpointFilter<RequireSessionTokenFilter>();
|
||||
var authenticatedApi = api.MapGroup(string.Empty).AddEndpointFilter<RequireSessionTokenFilter>();
|
||||
|
||||
authenticatedApi.MapMeEndpoints();
|
||||
authenticatedApi.MapCampaignEndpoints();
|
||||
@@ -17,4 +16,4 @@ public static class ApiEndpointRegistration
|
||||
authenticatedApi.MapSkillEndpoints();
|
||||
authenticatedApi.MapStateEventEndpoints();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,14 +9,10 @@ internal static class ApiResultMapper
|
||||
public static Results<Ok<T>, BadRequest<ApiError>, UnauthorizedHttpResult> ToApiResult<T>(ServiceResult<T> result)
|
||||
{
|
||||
if (result.Succeeded)
|
||||
{
|
||||
return TypedResults.Ok(result.Value!);
|
||||
}
|
||||
|
||||
if (result.Error!.Code == "unauthorized")
|
||||
{
|
||||
return TypedResults.Unauthorized();
|
||||
}
|
||||
|
||||
return TypedResults.BadRequest(new ApiError(result.Error.Message));
|
||||
}
|
||||
@@ -25,4 +21,4 @@ internal static class ApiResultMapper
|
||||
{
|
||||
return TypedResults.BadRequest(new ApiError(error.Message));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,9 +12,7 @@ internal static class AuthEndpoints
|
||||
{
|
||||
var result = game.Register(request.Username, request.Password, request.DisplayName);
|
||||
if (!result.Succeeded)
|
||||
{
|
||||
return ApiResultMapper.ToBadRequest(result.Error!);
|
||||
}
|
||||
|
||||
return TypedResults.Ok(result.Value!);
|
||||
});
|
||||
@@ -23,11 +21,9 @@ internal static class AuthEndpoints
|
||||
{
|
||||
var result = game.Login(request.Username, request.Password);
|
||||
if (!result.Succeeded)
|
||||
{
|
||||
return ApiResultMapper.ToBadRequest(result.Error!);
|
||||
}
|
||||
|
||||
context.Response.Cookies.Append(SessionCookie.Name, result.Value.SessionToken, new CookieOptions
|
||||
context.Response.Cookies.Append(SessionCookie.Name, result.Value.SessionToken, new()
|
||||
{
|
||||
HttpOnly = true,
|
||||
SameSite = SameSiteMode.Strict,
|
||||
@@ -41,9 +37,7 @@ internal static class AuthEndpoints
|
||||
group.MapPost("/auth/logout", (HttpContext context, IGameService game) =>
|
||||
{
|
||||
if (context.TryReadSessionTokenFromCookie(out var sessionToken))
|
||||
{
|
||||
game.Logout(sessionToken);
|
||||
}
|
||||
|
||||
context.Response.Cookies.Delete(SessionCookie.Name);
|
||||
return TypedResults.NoContent();
|
||||
@@ -51,4 +45,4 @@ internal static class AuthEndpoints
|
||||
|
||||
return group;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -33,4 +33,4 @@ internal static class CampaignEndpoints
|
||||
|
||||
return group;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -33,4 +33,4 @@ internal static class CharacterEndpoints
|
||||
|
||||
return group;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -16,4 +16,4 @@ internal static class MeEndpoints
|
||||
|
||||
return group;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,4 +2,4 @@ namespace RpgRoller.Api;
|
||||
|
||||
internal static class RequestMappings
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -5,11 +5,9 @@ internal sealed class RequireSessionTokenFilter : IEndpointFilter
|
||||
public ValueTask<object?> InvokeAsync(EndpointFilterInvocationContext context, EndpointFilterDelegate next)
|
||||
{
|
||||
if (!context.HttpContext.TryReadSessionTokenFromCookie(out var sessionToken))
|
||||
{
|
||||
return ValueTask.FromResult<object?>(TypedResults.Unauthorized());
|
||||
}
|
||||
|
||||
context.HttpContext.StoreSessionToken(sessionToken);
|
||||
return next(context);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,4 +3,4 @@ namespace RpgRoller.Api;
|
||||
internal static class SessionCookie
|
||||
{
|
||||
public const string Name = "rpgroller_session";
|
||||
}
|
||||
}
|
||||
@@ -2,8 +2,6 @@ namespace RpgRoller.Api;
|
||||
|
||||
internal static class SessionTokenHttpContextExtensions
|
||||
{
|
||||
private const string SessionTokenItemKey = "__rpgroller.session-token";
|
||||
|
||||
public static bool TryReadSessionTokenFromCookie(this HttpContext context, out string sessionToken)
|
||||
{
|
||||
sessionToken = context.Request.Cookies[SessionCookie.Name] ?? string.Empty;
|
||||
@@ -17,13 +15,11 @@ internal static class SessionTokenHttpContextExtensions
|
||||
|
||||
public static string GetRequiredSessionToken(this HttpContext context)
|
||||
{
|
||||
if (context.Items.TryGetValue(SessionTokenItemKey, out var token)
|
||||
&& token is string sessionToken
|
||||
&& !string.IsNullOrWhiteSpace(sessionToken))
|
||||
{
|
||||
if (context.Items.TryGetValue(SessionTokenItemKey, out var token) && token is string sessionToken && !string.IsNullOrWhiteSpace(sessionToken))
|
||||
return sessionToken;
|
||||
}
|
||||
|
||||
throw new InvalidOperationException("Session token is not available in this request.");
|
||||
}
|
||||
}
|
||||
|
||||
private const string SessionTokenItemKey = "__rpgroller.session-token";
|
||||
}
|
||||
@@ -27,4 +27,4 @@ internal static class SkillEndpoints
|
||||
|
||||
return group;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,18 +7,13 @@ internal static class StateEventEndpoints
|
||||
{
|
||||
public static RouteGroupBuilder MapStateEventEndpoints(this RouteGroupBuilder group)
|
||||
{
|
||||
group.MapGet("/events/state", async Task<IResult> (
|
||||
Guid campaignId,
|
||||
HttpContext context,
|
||||
IGameService game) =>
|
||||
group.MapGet("/events/state", async Task<IResult> (Guid campaignId, HttpContext context, IGameService game) =>
|
||||
{
|
||||
var sessionToken = context.GetRequiredSessionToken();
|
||||
var versionResult = game.GetCampaignVersion(sessionToken, campaignId);
|
||||
if (!versionResult.Succeeded)
|
||||
{
|
||||
return versionResult.Error!.Code == "unauthorized"
|
||||
? TypedResults.Unauthorized()
|
||||
: TypedResults.BadRequest(new ApiError(versionResult.Error.Message));
|
||||
return versionResult.Error!.Code == "unauthorized" ? TypedResults.Unauthorized() : TypedResults.BadRequest(new ApiError(versionResult.Error.Message));
|
||||
}
|
||||
|
||||
context.Response.Headers.CacheControl = "no-cache";
|
||||
@@ -37,9 +32,7 @@ internal static class StateEventEndpoints
|
||||
|
||||
var currentVersionResult = game.GetCampaignVersion(sessionToken, campaignId);
|
||||
if (!currentVersionResult.Succeeded)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (currentVersionResult.Value != lastVersion)
|
||||
{
|
||||
@@ -47,9 +40,7 @@ internal static class StateEventEndpoints
|
||||
await context.Response.WriteAsync($"event: state\ndata: {{\"campaignId\":\"{campaignId}\",\"version\":{lastVersion}}}\n\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
await context.Response.WriteAsync(": heartbeat\n\n");
|
||||
}
|
||||
|
||||
await context.Response.Body.FlushAsync();
|
||||
}
|
||||
@@ -63,4 +54,4 @@ internal static class StateEventEndpoints
|
||||
|
||||
return group;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11,4 +11,4 @@ internal static class SystemEndpoints
|
||||
group.MapGet("/rulesets", (IGameService game) => TypedResults.Ok(game.GetRulesets()));
|
||||
return group;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user