using System.Security.Cryptography; using PnvPanel.Domain.Common; using PnvPanel.Domain.Exceptions; namespace PnvPanel.Domain.Telegram; /// Короткоживущий одноразовый токен для флоу привязки Telegram (deep-link в бота). public sealed class TelegramLinkToken : Entity { public string Token { get; private set; } = string.Empty; public Guid UserId { get; private set; } public DateTimeOffset ExpiresAt { get; private set; } public DateTimeOffset? ConsumedAt { get; private set; } private TelegramLinkToken() { } public static TelegramLinkToken Create(Guid userId, TimeSpan ttl) { return new TelegramLinkToken { Id = Guid.NewGuid(), Token = GenerateToken(), UserId = userId, ExpiresAt = DateTimeOffset.UtcNow.Add(ttl), }; } public bool IsValid => ConsumedAt is null && DateTimeOffset.UtcNow < ExpiresAt; public void Consume() { if (!IsValid) throw new DomainException("Токен привязки недействителен или уже использован."); ConsumedAt = DateTimeOffset.UtcNow; } private static string GenerateToken() => Convert.ToHexString(RandomNumberGenerator.GetBytes(24)).ToLowerInvariant(); }