126 lines
3.4 KiB
C#
126 lines
3.4 KiB
C#
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;
|
|
|
|
/// <summary>
|
|
/// Represents a connection between an account and an authentication provider
|
|
/// </summary>
|
|
public class AccountConnection : ModelBase
|
|
{
|
|
/// <summary>
|
|
/// The account ID this connection is associated with
|
|
/// </summary>
|
|
public string? AccountId { get; set; }
|
|
|
|
/// <summary>
|
|
/// The authentication provider (e.g., "google", "github")
|
|
/// </summary>
|
|
[Required]
|
|
[MaxLength(50)]
|
|
public string Provider { get; set; } = null!;
|
|
|
|
/// <summary>
|
|
/// The unique identifier for the user from the provider
|
|
/// </summary>
|
|
[Required]
|
|
[MaxLength(256)]
|
|
public string ProvidedIdentifier { get; set; } = null!;
|
|
|
|
/// <summary>
|
|
/// Alias for ProvidedIdentifier for backward compatibility
|
|
/// </summary>
|
|
[NotMapped]
|
|
public string ProviderId
|
|
{
|
|
get => ProvidedIdentifier;
|
|
set => ProvidedIdentifier = value;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Display name for the connection
|
|
/// </summary>
|
|
[MaxLength(100)]
|
|
public string? DisplayName { get; set; }
|
|
|
|
/// <summary>
|
|
/// OAuth access token from the provider
|
|
/// </summary>
|
|
public string? AccessToken { get; set; }
|
|
|
|
/// <summary>
|
|
/// OAuth refresh token from the provider (if available)
|
|
/// </summary>
|
|
public string? RefreshToken { get; set; }
|
|
|
|
/// <summary>
|
|
/// When the access token expires (if available)
|
|
/// </summary>
|
|
public Instant? ExpiresAt { get; set; }
|
|
|
|
/// <summary>
|
|
/// Raw profile data from the provider
|
|
/// </summary>
|
|
[Column(TypeName = "jsonb")]
|
|
public JsonDocument? ProfileData { get; set; }
|
|
|
|
/// <summary>
|
|
/// When the connection was first established
|
|
/// </summary>
|
|
public Instant ConnectedAt { get; set; } = SystemClock.Instance.GetCurrentInstant();
|
|
|
|
/// <summary>
|
|
/// Additional metadata about the connection
|
|
/// </summary>
|
|
[Column(TypeName = "jsonb")]
|
|
public JsonDocument? Metadata { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets a value indicating whether the connection is currently active
|
|
/// </summary>
|
|
[NotMapped]
|
|
/// <summary>
|
|
/// When the connection was first established
|
|
/// </summary>
|
|
public Instant CreatedAt { get; set; }
|
|
|
|
/// <summary>
|
|
/// When the connection was last used
|
|
/// </summary>
|
|
public Instant? LastUsedAt { get; set; }
|
|
|
|
/// <summary>
|
|
/// Navigation property for the associated account
|
|
/// </summary>
|
|
[ForeignKey(nameof(AccountId))]
|
|
[JsonIgnore]
|
|
public virtual Account? Account { get; set; }
|
|
|
|
/// <summary>
|
|
/// Updates the connection's tokens and related metadata
|
|
/// </summary>
|
|
/// <param name="accessToken">The new access token</param>
|
|
/// <param name="refreshToken">The new refresh token, if any</param>
|
|
/// <param name="expiresAt">When the access token expires, if any</param>
|
|
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();
|
|
}
|
|
}
|