< Summary - Heimdall API

Information
Class: ArturRios.Heimdall.Domain.Entities.TwoFactorEmailCode
Assembly: ArturRios.Heimdall.Domain
File(s): /home/runner/work/heimdall-api/heimdall-api/src/Domain/ArturRios.Heimdall.Domain/Entities/TwoFactorEmailCode.cs
Line coverage
100%
Covered lines: 8
Uncovered lines: 0
Coverable lines: 8
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: 8
Fully covered methods: 8
Total methods: 8
Method coverage: 100%
Full method coverage: 100%

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
get_TwoFactorAuthId()100%11100%
get_CodeHash()100%11100%
get_Salt()100%11100%
get_ExpiresAt()100%11100%
get_Used()100%11100%
get_FailedAttempts()100%11100%
get_CreatedAt()100%11100%
get_TwoFactorAuth()100%11100%

File(s)

/home/runner/work/heimdall-api/heimdall-api/src/Domain/ArturRios.Heimdall.Domain/Entities/TwoFactorEmailCode.cs

#LineLine coverage
 1using ArturRios.Data.Relational.Core.Entities;
 2
 3namespace ArturRios.Heimdall.Domain.Entities;
 4
 5/// <summary>
 6///     A time-limited, single-use numeric code issued for the email two-factor method (UC-36 step 4,
 7///     FR-2F-03). Not part of the System Requirements Document's data model — an implementation
 8///     detail of how the email method's pending code is tracked between UC-36 (issue) and UC-37
 9///     (confirm), shaped after <see cref="PasswordResetToken" />. Never addressed by ID; a person's
 10///     current code is reached through their <see cref="TwoFactorAuth" /> configuration.
 11/// </summary>
 12public class TwoFactorEmailCode : Entity<long>
 13{
 14    /// <summary>
 15    ///     Foreign key to the owning <see cref="TwoFactorAuth" /> configuration (internal Id).
 16    ///     Required.
 17    /// </summary>
 15318    public long TwoFactorAuthId { get; set; }
 19
 20    /// <summary>Hash computed from the 6-digit code and <see cref="Salt" />.</summary>
 31321    public byte[] CodeHash { get; set; } = [];
 22
 23    /// <summary>Randomly generated per code, used to hash it.</summary>
 31224    public byte[] Salt { get; set; } = [];
 25
 26    /// <summary>Expiration timestamp, 10 minutes after issue (FR-2F-03).</summary>
 17627    public DateTime ExpiresAt { get; set; }
 28
 29    /// <summary>Whether the code has already been consumed or superseded by a fresher one.</summary>
 24230    public bool Used { get; set; }
 31
 32    /// <summary>
 33    ///     Wrong guesses made against this code. A six-digit code has a million values and lives ten
 34    ///     minutes, which a distributed attacker can cover a real fraction of; retiring the code once
 35    ///     this reaches its cap bounds each issued code to a handful of attempts, so guessing costs a
 36    ///     fresh login per few tries rather than being free.
 37    /// </summary>
 12238    public int FailedAttempts { get; set; }
 39
 40    /// <summary>Creation timestamp.</summary>
 1741    public DateTime CreatedAt { get; set; }
 42
 43    // Navigation properties
 44
 45    /// <summary>The two-factor configuration this code was issued for.</summary>
 1446    public TwoFactorAuth TwoFactorAuth { get; set; } = null!;
 47}