diff --git a/src/Core/Billing/Licenses/Extensions/LicenseExtensions.cs b/src/Core/Billing/Licenses/Extensions/LicenseExtensions.cs index 56209b6a7d..31569f02ac 100644 --- a/src/Core/Billing/Licenses/Extensions/LicenseExtensions.cs +++ b/src/Core/Billing/Licenses/Extensions/LicenseExtensions.cs @@ -116,23 +116,51 @@ public static class LicenseExtensions public static class OrganizationLicenseExtensions { - public static DateTime CalculateFreshExpirationDate(this Organization org, SubscriptionInfo subscriptionInfo) + public static DateTime CalculateFreshExpirationDate(this Organization org, SubscriptionInfo subscriptionInfo, DateTime issued) { if (subscriptionInfo?.Subscription == null) { - if (org.PlanType == PlanType.Custom && org.ExpirationDate.HasValue) - { - return org.ExpirationDate.Value; - } - - return DateTime.UtcNow.AddDays(7); + return org.PlanType == PlanType.Custom && org.ExpirationDate.HasValue + ? org.ExpirationDate.Value + : issued.AddDays(7); } - var subscription = subscriptionInfo.Subscription; - - if (subscription.TrialEndDate > DateTime.UtcNow) + if (subscriptionInfo.Subscription.TrialEndDate.HasValue && + subscriptionInfo.Subscription.TrialEndDate.Value > DateTime.UtcNow) { - return subscription.TrialEndDate.Value; + return subscriptionInfo.Subscription.TrialEndDate.Value; + } + + if (org.ExpirationDate.HasValue && org.ExpirationDate.Value < DateTime.UtcNow) + { + // expired + return org.ExpirationDate.Value; + } + + if (subscriptionInfo?.Subscription?.PeriodDuration != null && + subscriptionInfo.Subscription.PeriodDuration > TimeSpan.FromDays(180)) + { + return subscriptionInfo.Subscription.PeriodEndDate.Value.AddDays(Core.Constants.OrganizationSelfHostSubscriptionGracePeriodDays); + } + + return org.ExpirationDate.HasValue + ? org.ExpirationDate.Value.AddMonths(11) + : issued.AddYears(1); + } + + public static DateTime CalculateFreshRefreshDate(this Organization org, SubscriptionInfo subscriptionInfo, DateTime? expirationDate, DateTime issued) + { + if (subscriptionInfo?.Subscription == null) + { + return org.PlanType == PlanType.Custom && org.ExpirationDate.HasValue + ? org.ExpirationDate.Value + : issued.AddDays(7); + } + + if (subscriptionInfo.Subscription.TrialEndDate.HasValue && + subscriptionInfo.Subscription.TrialEndDate.Value > DateTime.UtcNow) + { + return subscriptionInfo.Subscription.TrialEndDate.Value; } if (org.ExpirationDate.HasValue && org.ExpirationDate.Value < DateTime.UtcNow) @@ -140,66 +168,48 @@ public static class OrganizationLicenseExtensions return org.ExpirationDate.Value; } - if (subscription.PeriodEndDate.HasValue && subscription.PeriodDuration > TimeSpan.FromDays(180)) + if (subscriptionInfo?.Subscription?.PeriodDuration != null && + subscriptionInfo.Subscription.PeriodDuration > TimeSpan.FromDays(180)) { - return subscription.PeriodEndDate - .Value - .AddDays(Bit.Core.Constants.OrganizationSelfHostSubscriptionGracePeriodDays); + return DateTime.UtcNow.AddDays(30); } - return org.ExpirationDate?.AddMonths(11) ?? DateTime.UtcNow.AddYears(1); - } - - public static DateTime CalculateFreshRefreshDate(this Organization org, SubscriptionInfo subscriptionInfo, DateTime expirationDate) - { - if (subscriptionInfo?.Subscription == null || - subscriptionInfo.Subscription.TrialEndDate > DateTime.UtcNow || - org.ExpirationDate < DateTime.UtcNow) - { - return expirationDate; - } - - return subscriptionInfo.Subscription.PeriodDuration > TimeSpan.FromDays(180) || - DateTime.UtcNow - expirationDate > TimeSpan.FromDays(30) + return !expirationDate.HasValue || DateTime.UtcNow - expirationDate.Value > TimeSpan.FromDays(30) ? DateTime.UtcNow.AddDays(30) - : expirationDate; + : expirationDate.Value; } - public static DateTime CalculateFreshExpirationDateWithoutGracePeriod(this Organization org, SubscriptionInfo subscriptionInfo, DateTime expirationDate) - { - if (subscriptionInfo?.Subscription is null) - { - return expirationDate; - } - - var subscription = subscriptionInfo.Subscription; - - if (subscription.TrialEndDate <= DateTime.UtcNow && - org.ExpirationDate >= DateTime.UtcNow && - subscription.PeriodEndDate.HasValue && - subscription.PeriodDuration > TimeSpan.FromDays(180)) - { - return subscription.PeriodEndDate.Value; - } - - return expirationDate; - } + public static DateTime? CalculateFreshExpirationDateWithoutGracePeriod(this Organization org, SubscriptionInfo subscriptionInfo) => + subscriptionInfo?.Subscription != null && + (!subscriptionInfo.Subscription.TrialEndDate.HasValue || subscriptionInfo.Subscription.TrialEndDate.Value <= DateTime.UtcNow) && + (!org.ExpirationDate.HasValue || org.ExpirationDate.Value >= DateTime.UtcNow) && + subscriptionInfo.Subscription.PeriodDuration != null && + subscriptionInfo.Subscription.PeriodDuration > TimeSpan.FromDays(180) + ? subscriptionInfo.Subscription.PeriodEndDate + : null; public static bool IsTrialing(this Organization org, SubscriptionInfo subscriptionInfo) => - subscriptionInfo?.Subscription is null + subscriptionInfo?.Subscription == null ? org.PlanType != PlanType.Custom || !org.ExpirationDate.HasValue - : subscriptionInfo.Subscription.TrialEndDate > DateTime.UtcNow; + : subscriptionInfo.Subscription.TrialEndDate.HasValue && subscriptionInfo.Subscription.TrialEndDate.Value > DateTime.UtcNow; } public static class UserLicenseExtensions { public static DateTime? CalculateFreshExpirationDate(this User user, SubscriptionInfo subscriptionInfo) => - subscriptionInfo?.UpcomingInvoice?.Date?.AddDays(7) ?? user.PremiumExpirationDate?.AddDays(7); + subscriptionInfo == null + ? user.PremiumExpirationDate?.AddDays(7) + : subscriptionInfo.UpcomingInvoice?.Date != null + ? subscriptionInfo.UpcomingInvoice.Date.Value.AddDays(7) + : user.PremiumExpirationDate?.AddDays(7); public static DateTime? CalculateFreshRefreshDate(this User user, SubscriptionInfo subscriptionInfo) => - subscriptionInfo?.UpcomingInvoice?.Date ?? user.PremiumExpirationDate; + subscriptionInfo == null + ? user.PremiumExpirationDate?.Date + : subscriptionInfo?.UpcomingInvoice?.Date; public static bool IsTrialing(this User user, SubscriptionInfo subscriptionInfo) => - (subscriptionInfo?.Subscription?.TrialEndDate.HasValue ?? false) && - subscriptionInfo.Subscription.TrialEndDate.Value > DateTime.UtcNow; + subscriptionInfo != null && + (subscriptionInfo?.Subscription?.TrialEndDate.HasValue ?? false) && + subscriptionInfo.Subscription.TrialEndDate.Value > DateTime.UtcNow; } diff --git a/src/Core/Billing/Licenses/Services/Implementations/OrganizationLicenseClaimsFactory.cs b/src/Core/Billing/Licenses/Services/Implementations/OrganizationLicenseClaimsFactory.cs index abe6299f5f..4df71e418f 100644 --- a/src/Core/Billing/Licenses/Services/Implementations/OrganizationLicenseClaimsFactory.cs +++ b/src/Core/Billing/Licenses/Services/Implementations/OrganizationLicenseClaimsFactory.cs @@ -11,10 +11,11 @@ public class OrganizationLicenseClaimsFactory : ILicenseClaimsFactory> GenerateClaims(Organization entity, LicenseContext licenseContext) { + var issued = DateTime.UtcNow; var subscriptionInfo = licenseContext.SubscriptionInfo; - var expires = entity.CalculateFreshExpirationDate(subscriptionInfo); - var refresh = entity.CalculateFreshRefreshDate(subscriptionInfo, expires); - var expirationWithoutGracePeriod = entity.CalculateFreshExpirationDateWithoutGracePeriod(subscriptionInfo, expires); + var expires = entity.CalculateFreshExpirationDate(subscriptionInfo, issued); + var refresh = entity.CalculateFreshRefreshDate(subscriptionInfo, expires, issued); + var expirationWithoutGracePeriod = entity.CalculateFreshExpirationDateWithoutGracePeriod(subscriptionInfo); var trial = entity.IsTrialing(subscriptionInfo); var claims = new List @@ -49,12 +50,16 @@ public class OrganizationLicenseClaimsFactory : ILicenseClaimsFactory DateTime.UtcNow) - { - Expires = Refresh = subscriptionInfo.Subscription.TrialEndDate.Value; - Trial = true; - } - else - { - if (org.ExpirationDate.HasValue && org.ExpirationDate.Value < DateTime.UtcNow) - { - // expired - Expires = Refresh = org.ExpirationDate.Value; - } - else if (subscriptionInfo?.Subscription?.PeriodDuration != null && - subscriptionInfo.Subscription.PeriodDuration > TimeSpan.FromDays(180)) - { - Refresh = DateTime.UtcNow.AddDays(30); - Expires = subscriptionInfo.Subscription.PeriodEndDate?.AddDays(Constants - .OrganizationSelfHostSubscriptionGracePeriodDays); - ExpirationWithoutGracePeriod = subscriptionInfo.Subscription.PeriodEndDate; - } - else - { - Expires = org.ExpirationDate.HasValue ? org.ExpirationDate.Value.AddMonths(11) : Issued.AddYears(1); - Refresh = DateTime.UtcNow - Expires > TimeSpan.FromDays(30) ? DateTime.UtcNow.AddDays(30) : Expires; - } - - Trial = false; - } + Expires = org.CalculateFreshExpirationDate(subscriptionInfo, Issued); + Refresh = org.CalculateFreshRefreshDate(subscriptionInfo, Expires, Issued); + ExpirationWithoutGracePeriod = org.CalculateFreshExpirationDateWithoutGracePeriod(subscriptionInfo); + Trial = org.IsTrialing(subscriptionInfo); UseAdminSponsoredFamilies = org.UseAdminSponsoredFamilies; Hash = Convert.ToBase64String(ComputeHash()); @@ -247,7 +209,7 @@ public class OrganizationLicense : BaseLicense private bool ValidLicenseVersion { - get => Version is >= 1 and <= 16; + get => Version is >= 1 and <= CurrentLicenseFileVersion + 1; } public override byte[] GetDataBytes(bool forHash = false) @@ -569,7 +531,7 @@ public class OrganizationLicense : BaseLicense * validation. */ - if (valid && Version >= 16) + if (valid && Version >= CurrentLicenseFileVersion + 1) { valid = organization.UseOrganizationDomains; } diff --git a/src/Core/Models/Business/UserLicense.cs b/src/Core/Models/Business/UserLicense.cs index 3528835836..34933a9c9b 100644 --- a/src/Core/Models/Business/UserLicense.cs +++ b/src/Core/Models/Business/UserLicense.cs @@ -24,12 +24,9 @@ public class UserLicense : BaseLicense Premium = user.Premium; MaxStorageGb = user.MaxStorageGb; Issued = DateTime.UtcNow; - Expires = subscriptionInfo?.UpcomingInvoice?.Date != null ? - subscriptionInfo.UpcomingInvoice.Date.Value.AddDays(7) : - user.PremiumExpirationDate?.AddDays(7); - Refresh = subscriptionInfo?.UpcomingInvoice?.Date; - Trial = (subscriptionInfo?.Subscription?.TrialEndDate.HasValue ?? false) && - subscriptionInfo.Subscription.TrialEndDate.Value > DateTime.UtcNow; + Expires = user.CalculateFreshExpirationDate(subscriptionInfo); + Refresh = user.CalculateFreshRefreshDate(subscriptionInfo); + Trial = user.IsTrialing(subscriptionInfo); Hash = Convert.ToBase64String(ComputeHash()); Signature = Convert.ToBase64String(licenseService.SignLicense(this)); @@ -46,9 +43,9 @@ public class UserLicense : BaseLicense Premium = user.Premium; MaxStorageGb = user.MaxStorageGb; Issued = DateTime.UtcNow; - Expires = user.PremiumExpirationDate?.AddDays(7); - Refresh = user.PremiumExpirationDate?.Date; - Trial = false; + Expires = user.CalculateFreshExpirationDate(null); + Refresh = user.CalculateFreshRefreshDate(null); + Trial = user.IsTrialing(null); Hash = Convert.ToBase64String(ComputeHash()); Signature = Convert.ToBase64String(licenseService.SignLicense(this));