< Summary - Heimdall API

Information
Class: ArturRios.Heimdall.Command.Services.TwoFactorChallengePrincipal
Assembly: ArturRios.Heimdall.Command
File(s): /home/runner/work/heimdall-api/heimdall-api/src/Application/ArturRios.Heimdall.Command/Services/ITwoFactorChallengeTokenIssuer.cs
Line coverage
100%
Covered lines: 1
Uncovered lines: 0
Coverable lines: 1
Total lines: 47
Line coverage: 100%
Branch coverage
N/A
Covered branches: 0
Total branches: 0
Branch coverage: N/A
Method coverage
100%
Covered methods: 1
Fully covered methods: 1
Total methods: 1
Method coverage: 100%
Full method coverage: 100%

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
get_PersonId()100%11100%

File(s)

/home/runner/work/heimdall-api/heimdall-api/src/Application/ArturRios.Heimdall.Command/Services/ITwoFactorChallengeTokenIssuer.cs

#LineLine coverage
 1namespace ArturRios.Heimdall.Command.Services;
 2
 3/// <summary>
 4///     The person a UC-38 challenge token was redeemed for. Carries only what
 5///     <c>VerifyTwoFactorAuthCommandHandler</c> needs to look the person back up — the rest of the
 6///     token's claims are the presentation layer's concern.
 7/// </summary>
 8/// <param name="PersonId">The <c>PublicId</c> of the person the challenge token names.</param>
 9/// <param name="ChallengeId">
 10///     Which challenge this is. It must still equal the configuration's <c>TwoFactorAuth.ChallengeId</c>
 11///     for the token to be honoured, which is what makes a challenge redeemable once (FR-2F-10).
 12/// </param>
 13/// <param name="SecurityStamp">
 14///     The person's <c>SecurityStamp</c> when the challenge was issued, or <c>null</c> when the token
 15///     carries none. It must still equal the person's for the token to be honoured (FR-AU-11), so a
 16///     credential change in between ends the challenge as it ends every other token.
 17/// </param>
 79818public record TwoFactorChallengePrincipal(Guid PersonId, Guid ChallengeId, Guid? SecurityStamp = null);
 19
 20/// <summary>
 21///     Issues the short-lived challenge token AF-11g returns instead of a full authentication token
 22///     (FR-2F-07, NFR-17), when a person with active two-factor authentication passes UC-11's
 23///     password check. Separate from <see cref="IAuthTokenIssuer" /> because the two tokens carry
 24///     deliberately different claims — this one is scoped only to second-factor verification and
 25///     expires far sooner.
 26/// </summary>
 27public interface ITwoFactorChallengeTokenIssuer
 28{
 29    /// <param name="personId">The <c>PublicId</c> of the person who passed the password check.</param>
 30    /// <param name="roleId">Their role value (see <c>Roles</c>) — carried so the mapper that reads the token back can b
 31    /// <param name="challengeId">The identifier recorded as the configuration's outstanding challenge, carried in the t
 32    /// <param name="securityStamp">The person's current <c>SecurityStamp</c>, carried so a credential change before the
 33    /// <returns>The signed challenge token and its (short) expiry.</returns>
 34    Task<AuthToken> IssueAsync(Guid personId, int roleId, Guid challengeId, Guid securityStamp);
 35}
 36
 37/// <summary>
 38///     Validates a UC-38 challenge token — signature, expiry, and the MFA-pending claim (AF-38a,
 39///     FR-2F-10) — and resolves the person and challenge it names, without any database read. Whether
 40///     that challenge is still outstanding is the handler's question, answered against the database.
 41/// </summary>
 42public interface ITwoFactorChallengeTokenValidator
 43{
 44    /// <param name="token">The challenge token submitted to <c>POST /api/auth/2fa/verify</c>.</param>
 45    /// <returns>The named person and challenge, or <see langword="null" /> if the token is missing, malformed, unsigned
 46    Task<TwoFactorChallengePrincipal?> ValidateAsync(string? token);
 47}

Methods/Properties

get_PersonId()