MemberLoginLog.cs 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. using System.ComponentModel.DataAnnotations;
  2. using System.ComponentModel.DataAnnotations.Schema;
  3. namespace Domain.Entities.Members.Logs;
  4. /// <summary>
  5. /// 로그인 기록
  6. /// </summary>
  7. public class MemberLoginLog
  8. {
  9. [ForeignKey(nameof(MemberID))]
  10. public virtual Member Member { get; private set; } = null!;
  11. [Key]
  12. public int ID { get; private set; }
  13. public int? MemberID { get; private set; }
  14. public bool Success { get; private set; } = false;
  15. public string Account { get; private set; } = default!;
  16. public string? Reason { get; private set; }
  17. public string? Referer { get; private set; }
  18. public string? Url { get; private set; }
  19. public string? IpAddress { get; private set; }
  20. public string? UserAgent { get; private set; }
  21. public DateTime CreatedAt { get; private set; } = DateTime.UtcNow;
  22. private MemberLoginLog() { }
  23. private MemberLoginLog(int? memberID, bool success, string account, string? reason, string? referer, string? url, string? ipAddress, string? userAgent)
  24. {
  25. if (string.IsNullOrWhiteSpace(account))
  26. {
  27. throw new ArgumentException("Account is required.", nameof(account));
  28. }
  29. if (account.Length > 120)
  30. {
  31. throw new ArgumentOutOfRangeException(nameof(account));
  32. }
  33. if (reason is not null && reason.Length > 225)
  34. {
  35. throw new ArgumentOutOfRangeException(nameof(reason));
  36. }
  37. if (url is not null && url.Length > 500)
  38. {
  39. throw new ArgumentOutOfRangeException(nameof(url));
  40. }
  41. // Cloudflare 더블 경유 / 비정상 헤더 방어 — throw 대신 truncate.
  42. // 실 user IP 는 Next.js Route Handler 가 X-Original-Client-IP 로 forward (백엔드 GetClientIP 0순위).
  43. if (ipAddress is not null && ipAddress.Length > 45)
  44. {
  45. ipAddress = ipAddress[..45];
  46. }
  47. if (userAgent is not null && userAgent.Length > 512)
  48. {
  49. userAgent = userAgent[..512];
  50. }
  51. MemberID = memberID;
  52. Success = success;
  53. Account = account;
  54. Reason = reason;
  55. Referer = referer;
  56. Url = url;
  57. IpAddress = ipAddress;
  58. UserAgent = userAgent;
  59. CreatedAt = DateTime.UtcNow;
  60. }
  61. public static MemberLoginLog Create(int? memberID, bool success, string account, string? reason = null, string? referer = null, string? url = null, string? ipAddress = null, string? userAgent = null)
  62. {
  63. return new(memberID, success, account, reason, referer, url, ipAddress, userAgent);
  64. }
  65. }