87 lines
3.2 KiB
C#
87 lines
3.2 KiB
C#
using Modules.User.Domain.Gateways;
|
|
|
|
namespace Modules.User.Domain.Entities.Account;
|
|
|
|
public class Account
|
|
{
|
|
public Guid Id { get; private set; }
|
|
public Email Email { get; private set; }
|
|
public string HashedPassword { get; private set; }
|
|
|
|
private List<Session> _sessions = [];
|
|
|
|
public IReadOnlyList<Session> Sessions => _sessions.AsReadOnly();
|
|
|
|
public Account(Models.Account model)
|
|
{
|
|
Id = model.Id;
|
|
Email = new Email(model.Email);
|
|
HashedPassword = model.HashedPassword;
|
|
_sessions = model.Sessions.Select(q => new Session(q)).ToList();
|
|
}
|
|
|
|
private Account(Email email, string hashedPassword)
|
|
{
|
|
Email = email;
|
|
HashedPassword = hashedPassword;
|
|
}
|
|
|
|
public static Account Create(string email, string password, IPasswordGateway passwordHasher)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(email)) throw new ArgumentNullException(nameof(email));
|
|
if (string.IsNullOrWhiteSpace(password)) throw new ArgumentNullException(nameof(password));
|
|
var account = new Account(new Email(email), passwordHasher.HashPassword(password));
|
|
return account;
|
|
}
|
|
|
|
public void SetEmail(string email)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(email)) throw new ArgumentNullException(nameof(email));
|
|
Email = new Email(email);
|
|
}
|
|
|
|
public void SetPassword(string password, IPasswordGateway passwordHasher)
|
|
{
|
|
var newPasswordHash = passwordHasher.HashPassword(password);
|
|
if (newPasswordHash != HashedPassword) throw new Exception("Password must not be aqual to previous");
|
|
HashedPassword = newPasswordHash;
|
|
}
|
|
|
|
public Session AddSession(TimeSpan expirationTime, IRefreshTokenGateway gateway, string? userAgent, string? country, string? city)
|
|
{
|
|
if (Id == Guid.Empty) throw new ArgumentNullException(nameof(Id));
|
|
ClearExpiredSessions();
|
|
var sessionCollisions = FindSessions(userAgent);
|
|
var session = Session.Create(Id, expirationTime, gateway, userAgent, country, city);
|
|
if (sessionCollisions.Any())
|
|
{
|
|
session.SetId(sessionCollisions.OrderBy(q => q.ExpiredDate).Last().Id);
|
|
_sessions = _sessions.Where(q => !sessionCollisions.Contains(q)).ToList();
|
|
}
|
|
_sessions.Add(session);
|
|
return session;
|
|
}
|
|
|
|
public string? UpdateRefreshToken(Guid sessionId, IRefreshTokenGateway gateway, string? userAgent, string? country, string? city)
|
|
{
|
|
var session = _sessions.FirstOrDefault(s => s.Id == sessionId);
|
|
if (session == null) return null;
|
|
return session.UpdateRefreshToken(gateway, userAgent, country, city);
|
|
}
|
|
|
|
private IEnumerable<Session> FindSessions(string? userAgent) =>
|
|
_sessions.Where(q => q.ClientInfo.UserAgent == userAgent);
|
|
|
|
public bool DeleteSession(Guid sessionId)
|
|
{
|
|
var session = _sessions.FirstOrDefault(s => s.Id == sessionId);
|
|
if (session == null) return false;
|
|
_sessions.Remove(session);
|
|
return true;
|
|
}
|
|
|
|
public void ClearExpiredSessions() =>
|
|
_sessions = _sessions.Where(q => q.ExpiredDate >= DateTime.UtcNow).ToList();
|
|
|
|
public void ClearAllSessions() => _sessions.Clear();
|
|
} |