36 lines
1.4 KiB
C#
36 lines
1.4 KiB
C#
namespace ROLAC.API.Entities;
|
|
|
|
/// <summary>
|
|
/// A single-use, expiring invitation that lets a member set their own password and log in for
|
|
/// the first time — without an admin-generated temporary password. The raw token is e-mailed /
|
|
/// copied to the member; only its SHA-256 hash is stored here (same scheme as RefreshToken).
|
|
/// </summary>
|
|
public class UserInvitation
|
|
{
|
|
public int Id { get; set; }
|
|
|
|
public string UserId { get; set; } = null!;
|
|
public AppUser User { get; set; } = null!;
|
|
|
|
/// <summary>SHA-256 hex of the raw invitation token. Never store raw tokens.</summary>
|
|
public string TokenHash { get; set; } = null!;
|
|
|
|
public DateTime ExpiresAt { get; set; }
|
|
public DateTime CreatedAt { get; set; }
|
|
|
|
/// <summary>Id of the admin who generated the link.</summary>
|
|
public string CreatedBy { get; set; } = null!;
|
|
|
|
/// <summary>Set when the member consumes the link to set their password (single-use).</summary>
|
|
public DateTime? UsedAt { get; set; }
|
|
|
|
/// <summary>Set when superseded by a newer invitation for the same user (re-issue).</summary>
|
|
public DateTime? RevokedAt { get; set; }
|
|
|
|
// Computed helpers — NOT mapped to DB columns (ignored in OnModelCreating)
|
|
public bool IsExpired => DateTime.UtcNow >= ExpiresAt;
|
|
public bool IsUsed => UsedAt.HasValue;
|
|
public bool IsRevoked => RevokedAt.HasValue;
|
|
public bool IsActive => !IsUsed && !IsRevoked && !IsExpired;
|
|
}
|