using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace Domain.Entities.Members;
///
/// 회원별 OAuth 토큰 저장 (Google OAuth 2.0 등)
/// YouTube API 호출 시 Access Token 사용
///
public class MemberOAuthToken
{
[ForeignKey(nameof(MemberID))]
public virtual Member? Member { get; private set; }
[Key]
public long ID { get; private set; }
public int MemberID { get; private set; }
public string Provider { get; private set; } = "Google";
///
/// provider 측 고유 사용자 ID (카카오 id, 네이버 response.id). 로그인 시 backfill.
/// 소셜 연결 끊기(disconnect) webhook 이 Provider + ProviderUserKey 로 연동행을 찾는다.
///
public string? ProviderUserKey { get; private set; }
public string AccessTokenEnc { get; private set; } = default!;
public string? RefreshTokenEnc { get; private set; }
public DateTime ExpiresAt { get; private set; }
public string Scopes { get; private set; } = string.Empty;
public DateTime CreatedAt { get; private set; } = DateTime.UtcNow;
public DateTime UpdatedAt { get; private set; } = DateTime.UtcNow;
private MemberOAuthToken() { }
public static MemberOAuthToken Create(
int memberID,
string provider,
string accessTokenEnc,
string? refreshTokenEnc,
DateTime expiresAt,
string scopes,
string? providerUserKey = null
)
{
return new MemberOAuthToken
{
MemberID = memberID,
Provider = provider,
ProviderUserKey = providerUserKey,
AccessTokenEnc = accessTokenEnc,
RefreshTokenEnc = refreshTokenEnc,
ExpiresAt = expiresAt,
Scopes = scopes
};
}
public void UpdateTokens(string accessTokenEnc, string? refreshTokenEnc, DateTime expiresAt, string scopes, string? providerUserKey = null)
{
AccessTokenEnc = accessTokenEnc;
if (refreshTokenEnc is not null)
{
RefreshTokenEnc = refreshTokenEnc;
}
if (!string.IsNullOrEmpty(providerUserKey))
{
ProviderUserKey = providerUserKey;
}
ExpiresAt = expiresAt;
Scopes = scopes;
UpdatedAt = DateTime.UtcNow;
}
public bool IsExpired => DateTime.UtcNow >= ExpiresAt;
public bool HasRefreshToken => !string.IsNullOrEmpty(RefreshTokenEnc);
}