< Summary

Information
Class: Anichron.API.Infrastructure.MustChangePasswordMiddleware
Assembly: Anichron.API
File(s): /home/runner/work/anichron/anichron/src/Anichron.API/Infrastructure/MustChangePasswordMiddleware.cs
Tag: 228_36821334185
Line coverage
100%
Covered lines: 19
Uncovered lines: 0
Coverable lines: 19
Total lines: 31
Line coverage: 100%
Branch coverage
87%
Covered branches: 7
Total branches: 8
Branch coverage: 87.5%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%
.cctor()100%11100%
InvokeAsync()87.5%88100%
IsExemptRequest(...)100%11100%

File(s)

/home/runner/work/anichron/anichron/src/Anichron.API/Infrastructure/MustChangePasswordMiddleware.cs

#LineLine coverage
 1using Anichron.API.Security;
 2
 3namespace Anichron.API.Infrastructure;
 4
 95internal sealed class MustChangePasswordMiddleware(RequestDelegate next)
 6{
 17    private static readonly (string Method, PathString Path)[] exemptRoutes =
 18    [
 19        (HttpMethods.Get,  new(ApiPaths.Users.MePath)),
 110        (HttpMethods.Post, new(ApiPaths.Users.ChangePasswordPath)),
 111        (HttpMethods.Post, new(ApiPaths.Auth.LogoutPath)),
 112    ];
 13
 14    public async Task InvokeAsync(HttpContext context)
 915    {
 916        if (context.User.Identity?.IsAuthenticated == true
 917            && context.User.HasClaim(AppClaimTypes.MustChangePassword, "true")
 918            && !IsExemptRequest(context.Request))
 319        {
 320            context.Response.StatusCode = StatusCodes.Status403Forbidden;
 321            await context.Response.WriteAsJsonAsync(
 322                new { error = AuthMessages.MustChangePassword }, context.RequestAborted);
 323            return;
 24        }
 25
 626        await next(context);
 927    }
 28
 29    private static bool IsExemptRequest(HttpRequest request)
 630        => exemptRoutes.Any(e => e.Method == request.Method && e.Path == request.Path);
 31}