< Summary - Heimdall API

Information
Class: ArturRios.Heimdall.WebApi.Retention.TokenRetentionService
Assembly: ArturRios.Heimdall.WebApi
File(s): /home/runner/work/heimdall-api/heimdall-api/src/Presentation/ArturRios.Heimdall.WebApi/Retention/TokenRetentionService.cs
Line coverage
15%
Covered lines: 3
Uncovered lines: 17
Coverable lines: 20
Total lines: 47
Line coverage: 15%
Branch coverage
0%
Covered branches: 0
Total branches: 4
Branch coverage: 0%
Method coverage
66%
Covered methods: 2
Fully covered methods: 2
Total methods: 3
Method coverage: 66.6%
Full method coverage: 66.6%

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%
get_StartupDescription()100%11100%
RunAsync()0%2040%

File(s)

/home/runner/work/heimdall-api/heimdall-api/src/Presentation/ArturRios.Heimdall.WebApi/Retention/TokenRetentionService.cs

#LineLine coverage
 1using ArturRios.Heimdall.Command.Input;
 2using ArturRios.Heimdall.Command.Output;
 3using ArturRios.Heimdall.Shared.Retention;
 4using ArturRios.Mediator.Command;
 5
 6namespace ArturRios.Heimdall.WebApi.Retention;
 7
 8/// <summary>
 9///     Runs <see cref="PurgeExpiredTokensCommand" /> on an interval, so the single-use token
 10///     retention period of NFR-19 is enforced without anyone having to call anything.
 11/// </summary>
 12public class TokenRetentionService(
 13    IServiceScopeFactory scopeFactory,
 14    DataRetentionOptions retention,
 15    ILogger<TokenRetentionService> logger)
 89916    : ScheduledPassService(scopeFactory, retention.PurgeInterval, logger)
 17{
 18    protected override string StartupDescription =>
 89919        $"Token retention purge scheduled every {retention.PurgeInterval}, removing tokens more than " +
 89920        $"{retention.SingleUseTokenGrace} past expiry";
 21
 22    protected override async Task<string?> RunAsync(IServiceProvider scope)
 23    {
 024        var mediator = scope.GetRequiredService<CommandMediator>();
 25
 026        var result = await mediator
 027            .ExecuteCommandAsync<PurgeExpiredTokensCommand, PurgeExpiredTokensCommandOutput>(
 028                new PurgeExpiredTokensCommand());
 29
 030        if (!result.Success)
 31        {
 032            return $"Token retention purge failed: {string.Join("; ", result.Errors)}";
 33        }
 34
 035        var purged = result.Data!;
 36
 037        return purged.TotalPurged == 0
 038            ? null
 039            : $"Token retention purge removed {purged.TotalPurged} rows: " +
 040              $"{purged.PasswordResetTokensPurged} password reset, " +
 041              $"{purged.EmailVerificationTokensPurged} email verification, " +
 042              $"{purged.TwoFactorEmailCodesPurged} two-factor email, " +
 043              $"{purged.PendingRegistrationsPurged} pending registration, " +
 044              $"{purged.ApplicationCredentialsPurged} application credential, " +
 045              $"{purged.AttemptNoticeBudgetsPurged} attempt-notice budget";
 046    }
 47}