using Knot.Contracts.Auth.Domain; using Knot.Shared.Kernel; using Knot.Shared.Kernel.Events; namespace Knot.Modules.Auth.Domain; /// /// �������� ������������ � ��������� ������������� (Identity). /// public sealed class User : AggregateRoot { public string Username { get; private set; } public string PasswordHash { get; private set; } public string DisplayName { get; private set; } public string? Email { get; private set; } public string? Bio { get; private set; } public string? Avatar { get; private set; } public DateTime? Birthday { get; private set; } public DateTime CreatedAt { get; private set; } public bool HideStoryViews { get; private set; } public bool IsExternal { get; private set; } public string? Domain { get; private set; } public bool IsOnline { get; private set; } public DateTime? LastSeen { get; private set; } public bool HideStatus { get; private set; } public bool IsBanned { get; private set; } public string? PhoneNumber { get; private set; } public string? RefreshToken { get; private set; } public DateTime? RefreshTokenExpiry { get; private set; } public DateTime? BannedUntil { get; private set; } public void Ban() { IsBanned = true; RaiseDomainEvent(new UserBannedDomainEvent(Id, true)); } public void Unban() { IsBanned = false; RaiseDomainEvent(new UserBannedDomainEvent(Id, false)); } public void SetOnline(bool isOnline, DateTime? lastSeen = null) { IsOnline = isOnline; LastSeen = lastSeen ?? DateTime.UtcNow; } public void SetPhoneNumber(string? phoneNumber) { PhoneNumber = phoneNumber; } public void SetRefreshToken(string? refreshToken, DateTime? expiry = null) { RefreshToken = refreshToken; RefreshTokenExpiry = expiry; } public void SetBannedUntil(DateTime? bannedUntil) { BannedUntil = bannedUntil; } public void SetAsExternal(string domain) { IsExternal = true; UserDomain = domain; } /// /// Updates user from contract (used by repository). /// public void UpdateFromContract(UserContract contract) { Username = contract.Username; DisplayName = contract.DisplayName; PhoneNumber = contract.PhoneNumber; Bio = contract.Bio; Avatar = contract.Avatar; Birthday = contract.Birthday; IsBanned = contract.IsBanned; BannedUntil = contract.BannedUntil; SetOnline(contract.IsOnline, contract.LastSeen); UserDomain = contract.Domain; RefreshToken = contract.RefreshToken; RefreshTokenExpiry = contract.RefreshTokenExpiry; } private User(Guid id, string username, string passwordHash, string displayName, string? email, string? bio = null) : base(id) { Username = username; PasswordHash = passwordHash; DisplayName = displayName; Email = email; Bio = bio; CreatedAt = DateTime.UtcNow; IsBanned = false; } /// /// ��������� ����� ��� �������� ������ ������������. /// public static User Create(string username, string passwordHash, string displayName, string? email = null, string? bio = null) { var user = new User(Guid.NewGuid(), username, passwordHash, displayName, email, bio); user.RaiseDomainEvent(new UserRegisteredDomainEvent(user.Id, user.Username, user.DisplayName, user.Bio)); return user; } /// /// ������� "��������" ������������ ��� �������� � ������� �������. /// public static User CreateExternal(Guid id, string username, string displayName, string domain, string? avatar = null) { var user = new User(id, username, "EXTERNAL_USER", displayName, null, null); user.SetAsExternal(domain); if (avatar != null) user.UpdateAvatar(avatar); return user; } private string? _domain; public string? UserDomain { get => _domain; set => _domain = value; } public void UpdateProfile(string displayName, string? bio, DateTime? birthday) { DisplayName = displayName; Bio = bio; Birthday = birthday; } public void UpdateAvatar(string? avatarUrl) { Avatar = avatarUrl; } public void UpdateSettings(bool hideStoryViews) { HideStoryViews = hideStoryViews; } public void ChangePassword(string newPasswordHash) { PasswordHash = newPasswordHash; } public void UpdateStatus(bool isOnline) { IsOnline = isOnline; LastSeen = DateTime.UtcNow; if (!HideStatus) { RaiseDomainEvent(new UserStatusChangedDomainEvent(Id, IsOnline, LastSeen.Value)); } } public void SetHideStatus(bool hide) { HideStatus = hide; } public UserContract ToContract() { return new UserContract { Id = Id, Username = Username, DisplayName = DisplayName, PasswordHash = PasswordHash, PhoneNumber = PhoneNumber, Email = Email, Bio = Bio, Avatar = Avatar, Birthday = Birthday, IsBot = false, CreatedAt = CreatedAt, IsBanned = IsBanned, BannedUntil = BannedUntil, IsOnline = IsOnline, IsExternal = IsExternal, Domain = _domain, LastSeen = LastSeen, RefreshToken = RefreshToken, RefreshTokenExpiry = RefreshTokenExpiry }; } }