BitBetter icon indicating copy to clipboard operation
BitBetter copied to clipboard

Unidentified fields in generated license

Open captainhook opened this issue 5 months ago • 3 comments

As per #237, there are two unidentified fields in the latest license file:

"ExpirationWithoutGracePeriod"
"Token"

captainhook avatar Jul 12 '25 14:07 captainhook

Looking at https://github.com/bitwarden/server/blob/v2025.7.2/src/Core/Billing/Models/Business/OrganizationLicense.cs a bit to try and figure some of this out.

Looks like ExpirationWithoutGracePeriod is the end date of the license term. When calculating when the license expires, grace period days get added to determine when the license should actually expire. So ExpirationWithoutGracePeriod is literally what is says, what the expiration date would be if grace period days were not added to Expires. From https://bitwarden.com/help/organization-renewal/ it looks like self hosted organization license normally get a 2 month (60 day) grace period between when the license expires and when the organization is disabled. I suspect this means ExpirationWithoutGracePeriod is what shows as when the license expires in the UI but it won't actually be disabled until Expires. I guess if ExpirationWithoutGracePeriod is null it shows Expires?

Lines 128-130: Expires = subscriptionInfo.Subscription.PeriodEndDate?.AddDays(Core.Constants. OrganizationSelfHostSubscriptionGracePeriodDays); ExpirationWithoutGracePeriod = subscriptionInfo.Subscription.PeriodEndDate;

This probably should be tested but I suggest we set ExpirationWithoutGracePeriod to what we currently set Expires to DateTime.UtcNow.AddYears(100) and set Expires to DateTime.UtcNow.AddYears(100).AddMonths(2)) to match upstream behavior. End behavior should be licenses are issued now, expire in 100 years plus 2 months, refresh in 100 years minus 1 month, and expiration with out the grace period is 100 years.

Jgigantino31 avatar Aug 04 '25 02:08 Jgigantino31

Also seems like current license version is now 16, not 15 from same file as above.

/// <summary> /// Represents the current version of the license format. Should be updated whenever new fields are added. /// </summary> /// <remarks>Intentionally set one version behind to allow self hosted users some time to update before /// getting out of date license errors /// </remarks> public const int CurrentLicenseFileVersion = 15; private bool ValidLicenseVersion { get => Version is >= 1 and <= 16; }

// UseOrganizationDomains was added in Version 16 (Version >= 16 || !p.Name.Equals(nameof(UseOrganizationDomains))) &&

Jgigantino31 avatar Aug 04 '25 02:08 Jgigantino31

The token fields only allow for displaying the info in the WebUI, nice bonus, but not required.

GieltjE avatar Aug 12 '25 14:08 GieltjE