using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace Domain.Entities.Members;
public class RefreshToken
{
[ForeignKey(nameof(MemberID))]
public virtual Member? Member { get; private set; }
[Key]
public long ID { get; private set; }
public int MemberID { get; private set; }
public string Token { get; private set; } = default!;
public DateTime ExpiresAt { get; private set; }
public DateTime CreatedAt { get; private set; } = DateTime.UtcNow;
public bool IsRevoked { get; private set; } = false;
public DateTime? RevokedAt { get; private set; }
/// 회전 시 발급된 후속 토큰. race condition grace period 흡수용.
public string? ReplacedByToken { get; private set; }
private RefreshToken() { }
public static RefreshToken Create(
int memberID,
string token,
DateTime expiresAt
) {
return new RefreshToken
{
MemberID = memberID,
Token = token,
ExpiresAt = expiresAt
};
}
public void Revoke()
{
IsRevoked = true;
RevokedAt = DateTime.UtcNow;
}
/// 회전 시 호출 — 새 토큰을 ReplacedByToken에 기록.
public void MarkReplaced(string newToken)
{
ReplacedByToken = newToken;
}
public bool IsExpired => DateTime.UtcNow >= ExpiresAt;
public bool IsActive => !IsRevoked && !IsExpired;
}