using System.Text; using static System.Security.Cryptography.RandomNumberGenerator; namespace Femto.Modules.Auth.Models; public class LongTermSession { private static TimeSpan TokenTimeout { get; } = TimeSpan.FromDays(90); public int Id { get; private set; } public string Selector { get; private set; } public byte[] HashedVerifier { get; private set; } public DateTimeOffset Expires { get; private set; } public Guid UserId { get; private set; } private LongTermSession() {} public static (LongTermSession, string) Create(Guid userId) { var selector = GetString("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", 12); var verifier = GetString("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", 32); using var sha256 = System.Security.Cryptography.SHA256.Create(); var longTermSession = new LongTermSession { Selector = selector, HashedVerifier = sha256.ComputeHash(Encoding.UTF8.GetBytes(verifier)), UserId = userId, Expires = DateTimeOffset.UtcNow + TokenTimeout }; var rememberMeToken = $"{selector}.{verifier}"; return (longTermSession, rememberMeToken); } public bool Validate(string verifier) { if (this.Expires < DateTimeOffset.UtcNow) return false; using var sha256 = System.Security.Cryptography.SHA256.Create(); var hashedVerifier = sha256.ComputeHash(Encoding.UTF8.GetBytes(verifier)); return hashedVerifier.SequenceEqual(this.HashedVerifier); } }