using System; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; using System.Text.Json; using System.Text.Json.Serialization; using NodaTime; namespace DysonNetwork.Common.Models; /// /// Represents a connection between an account and an authentication provider /// public class AccountConnection : ModelBase { /// /// The account ID this connection is associated with /// public string? AccountId { get; set; } /// /// The authentication provider (e.g., "google", "github") /// [Required] [MaxLength(50)] public string Provider { get; set; } = null!; /// /// The unique identifier for the user from the provider /// [Required] [MaxLength(256)] public string ProvidedIdentifier { get; set; } = null!; /// /// Alias for ProvidedIdentifier for backward compatibility /// [NotMapped] public string ProviderId { get => ProvidedIdentifier; set => ProvidedIdentifier = value; } /// /// Display name for the connection /// [MaxLength(100)] public string? DisplayName { get; set; } /// /// OAuth access token from the provider /// public string? AccessToken { get; set; } /// /// OAuth refresh token from the provider (if available) /// public string? RefreshToken { get; set; } /// /// When the access token expires (if available) /// public Instant? ExpiresAt { get; set; } /// /// Raw profile data from the provider /// [Column(TypeName = "jsonb")] public JsonDocument? ProfileData { get; set; } /// /// When the connection was first established /// public Instant ConnectedAt { get; set; } = SystemClock.Instance.GetCurrentInstant(); /// /// Additional metadata about the connection /// [Column(TypeName = "jsonb")] public JsonDocument? Metadata { get; set; } /// /// Gets a value indicating whether the connection is currently active /// [NotMapped] /// /// When the connection was first established /// public Instant CreatedAt { get; set; } /// /// When the connection was last used /// public Instant? LastUsedAt { get; set; } /// /// Navigation property for the associated account /// [ForeignKey(nameof(AccountId))] [JsonIgnore] public virtual Account? Account { get; set; } /// /// Updates the connection's tokens and related metadata /// /// The new access token /// The new refresh token, if any /// When the access token expires, if any public void UpdateTokens(string? accessToken, string? refreshToken, Instant? expiresAt) { AccessToken = accessToken; if (!string.IsNullOrEmpty(refreshToken)) { RefreshToken = refreshToken; } if (expiresAt.HasValue) { ExpiresAt = expiresAt; } LastUsedAt = SystemClock.Instance.GetCurrentInstant(); } }