using System;
namespace StellaOps.Configuration;
///
/// API lifecycle controls for the Authority service.
///
public sealed class AuthorityApiLifecycleOptions
{
///
/// Settings for the legacy OAuth endpoint shim (/oauth/* → canonical).
///
public AuthorityLegacyAuthEndpointOptions LegacyAuth { get; } = new();
internal void Validate()
{
LegacyAuth.Validate();
}
}
///
/// Configuration for legacy OAuth endpoint shims and deprecation signalling.
///
public sealed class AuthorityLegacyAuthEndpointOptions
{
private static readonly DateTimeOffset DefaultDeprecationDate = new(2025, 11, 1, 0, 0, 0, TimeSpan.Zero);
private static readonly DateTimeOffset DefaultSunsetDate = new(2026, 5, 1, 0, 0, 0, TimeSpan.Zero);
///
/// Enables the legacy endpoint shim that routes /oauth/* to the canonical endpoints.
///
public bool Enabled { get; set; } = true;
///
/// Date when clients should consider the legacy endpoints deprecated.
///
public DateTimeOffset DeprecationDate { get; set; } = DefaultDeprecationDate;
///
/// Date when legacy endpoints will be removed.
///
public DateTimeOffset SunsetDate { get; set; } = DefaultSunsetDate;
///
/// Optional documentation URL included in the Sunset link header.
///
public string? DocumentationUrl { get; set; } = "https://docs.stella-ops.org/authority/legacy-auth";
internal void Validate()
{
if (!Enabled)
{
return;
}
var normalizedDeprecation = DeprecationDate.ToUniversalTime();
var normalizedSunset = SunsetDate.ToUniversalTime();
if (normalizedSunset <= normalizedDeprecation)
{
throw new InvalidOperationException("Legacy auth sunset date must be after the deprecation date.");
}
DeprecationDate = normalizedDeprecation;
SunsetDate = normalizedSunset;
if (!string.IsNullOrWhiteSpace(DocumentationUrl))
{
if (!Uri.TryCreate(DocumentationUrl, UriKind.Absolute, out var uri) ||
(uri.Scheme != Uri.UriSchemeHttps && uri.Scheme != Uri.UriSchemeHttp))
{
throw new InvalidOperationException("Legacy auth documentation URL must be an absolute HTTP or HTTPS URL.");
}
}
}
}