| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135 |
- using System.ComponentModel.DataAnnotations;
- using System.ComponentModel.DataAnnotations.Schema;
- using Domain.Entities.Developers.ValueObject;
- namespace Domain.Entities.Developers;
- /// <summary>
- /// NICE 통합인증 1회 진행 세션. StartKyc 시 생성 → callback 에서 매칭 → Completed/Failed/Expired.
- ///
- /// 가이드: .claude/plan/nice-auth-integration.md §5
- /// </summary>
- public class NiceAuthSession
- {
- /// <summary>유효기간: 10분 (NICE transaction_id 의 효력과 동일).</summary>
- public static readonly TimeSpan DefaultLifetime = TimeSpan.FromMinutes(10);
- [ForeignKey(nameof(DeveloperID))]
- public virtual Developer? Developer { get; private set; }
- [Key]
- public int ID { get; private set; }
- public int DeveloperID { get; private set; }
- /// <summary>
- /// 가맹점 측 세션 식별자. NICE return_url path segment 로 embed → callback 매칭.
- /// URL-safe (Base64Url no-padding 22 char).
- /// </summary>
- public string SessionToken { get; private set; } = default!;
- /// <summary>NICE auth/url request 의 request_no.</summary>
- public string RequestNo { get; private set; } = default!;
- /// <summary>NICE auth/url 응답의 transaction_id.</summary>
- public string TransactionID { get; private set; } = default!;
- /// <summary>NICE 표준창이 return_url 로 넘긴 web_transaction_id (callback 시점에 set).</summary>
- public string? WebTransactionID { get; private set; }
- /// <summary>auth/url 호출 시점 token 의 ticket. result 복호화 KDF 입력.</summary>
- public string Ticket { get; private set; } = default!;
- /// <summary>auth/url 호출 시점 token 의 iterators. result 복호화 KDF 입력.</summary>
- public int Iterators { get; private set; }
- public NiceAuthSessionStatus Status { get; private set; } = NiceAuthSessionStatus.Pending;
- public string? FailReason { get; private set; }
- public DateTime CreatedAt { get; private set; } = DateTime.UtcNow;
- public DateTime ExpiresAt { get; private set; }
- public DateTime? CompletedAt { get; private set; }
- private NiceAuthSession() { }
- public static NiceAuthSession Create(
- int developerID,
- string sessionToken,
- string requestNo,
- string transactionID,
- string ticket,
- int iterators
- ) {
- if (string.IsNullOrWhiteSpace(sessionToken))
- {
- throw new ArgumentException("Session token is required.", nameof(sessionToken));
- }
- if (string.IsNullOrWhiteSpace(requestNo))
- {
- throw new ArgumentException("Request no is required.", nameof(requestNo));
- }
- if (string.IsNullOrWhiteSpace(transactionID))
- {
- throw new ArgumentException("Transaction ID is required.", nameof(transactionID));
- }
- if (string.IsNullOrWhiteSpace(ticket))
- {
- throw new ArgumentException("Ticket is required.", nameof(ticket));
- }
- if (iterators <= 0)
- {
- throw new ArgumentOutOfRangeException(nameof(iterators), iterators, "iterators must be positive.");
- }
- var now = DateTime.UtcNow;
- return new NiceAuthSession
- {
- DeveloperID = developerID,
- SessionToken = sessionToken,
- RequestNo = requestNo,
- TransactionID = transactionID,
- Ticket = ticket,
- Iterators = iterators,
- Status = NiceAuthSessionStatus.Pending,
- CreatedAt = now,
- ExpiresAt = now + DefaultLifetime
- };
- }
- /// <summary>callback 에서 web_transaction_id 받아 기록 — result 호출 직전 단계.</summary>
- public void MarkWebTransactionReceived(string webTransactionID)
- {
- if (string.IsNullOrWhiteSpace(webTransactionID))
- {
- throw new ArgumentException("Web transaction ID is required.", nameof(webTransactionID));
- }
- WebTransactionID = webTransactionID;
- }
- public void MarkCompleted()
- {
- Status = NiceAuthSessionStatus.Completed;
- CompletedAt = DateTime.UtcNow;
- }
- public void MarkFailed(string reason)
- {
- Status = NiceAuthSessionStatus.Failed;
- FailReason = reason;
- CompletedAt = DateTime.UtcNow;
- }
- public void MarkExpired()
- {
- Status = NiceAuthSessionStatus.Expired;
- FailReason = "유효시간이 만료되었습니다.";
- CompletedAt = DateTime.UtcNow;
- }
- public bool IsExpired(DateTime utcNow) => utcNow >= ExpiresAt;
- public bool CanProcessCallback() => Status == NiceAuthSessionStatus.Pending;
- }
|