Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix expired license error handling #1895

Merged
merged 6 commits into from Dec 28, 2023

Conversation

smrdotgg
Copy link
Contributor

@smrdotgg smrdotgg commented Nov 30, 2023

Features and Changes

  • Fixes the issue where an expired license key causes an API error, preventing them from logging in and accessing the UI for license management. This issue was limited to API keys who's trials expired. Paying enterprise members who's license expired did not face this issue.

  • Fixes Expired License Keys Cause API Error State (#1774)

Dependencies

None

Tests

Test 1 - Login

  1. Add an enterprise or pro key on a new account through the GrowthBook UI. (Ensure it is a trial key)
  2. Allow the key to expire. (Can be simulated by changing your machine's date/time settings)
  3. Ensure the license data isn't cached in server memory from when you added the key. (Memory can be flushed by restarting the dev server)
  4. Attempt to log in using an account associated with the expired trial key.

Before this change, the login would fail.
After this change, the login succeeds and displays a banner on the top bar.

Test 2 - Unauthorized requests

  1. Add an enterprise or pro key on a new account through the GrowthBook UI. (Ensure it is a trial key)
  2. Allow the key to expire. (Can be simulated by changing your machine's date/time settings)
  3. Ensure the license data isn't cached in server memory from when you added the key. (Memory can be flushed by restarting the dev server)
  4. Log in using an account associated with the expired trial key.
  5. Find an enterprise only feature that has been disabled. We can take exporting logs as json, which can be found in the /events route of the frontend.
  6. The button will be disabled. Force-enable the button. For the case of the events export feature, this can be done by setting the disabled flag on the button in the EventsPage component (packages/front-end/components/Events/EventsPage/EventsPage.tsx) to false.
  7. Once the button is enabled, press it.

Before this change, the backend would process the request and provide a valid json response eventhough the license has expired. The feature-blocking was only happening in the frontend logic. (This could have also been bypassed with curl)

After this change, the backend will do its own check to see if the license key has expired. If it has, it will not process the request for the premium feature. So in this case, it would not process the invalid request.

Screenshots (for Test 1)

Before

Before

After

After

@smrdotgg smrdotgg marked this pull request as draft November 30, 2023 13:46
@smrdotgg smrdotgg marked this pull request as ready for review November 30, 2023 13:46
@smrdotgg smrdotgg changed the title Fix expired license error handling (#1774) Fix expired license error handling Nov 30, 2023
@august-growthbook august-growthbook requested a review from a team November 30, 2023 14:58
@august-growthbook august-growthbook added the bug Something isn't working label Nov 30, 2023
@august-growthbook
Copy link
Contributor

Thanks for the PR! Someone from Engineering will review it.

@jdorn
Copy link
Member

jdorn commented Dec 1, 2023

For paying customers (non-trial license keys), we are super lenient on the expiration date. We don't want someone to lose access to all of the Enterprise features they rely on in production, just because they are a little late renewing. For trials, however, we want to be a lot stricter since it's just meant as a way to preview Enterprise features for a short time before deciding whether or not to pay.

The current solution of throwing an Exception is bad since it stops the app from loading entirely. The change in this PR makes trials too lenient - basically allowing them to continue using Enterprise features forever without paying. We want to do something in between - downgrade the app to the Open Source version, but don't throw an Exception.

This will likely require digging a bit deeper into the code and might make sense for our engineers to help out with the implementation.

@tzjames tzjames self-requested a review December 4, 2023 18:31
Copy link
Collaborator

@tzjames tzjames left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks again for doing this Semere! It looks almost perfect. I left a few comments though. Did you check out an api endpoint that has enterprise features using curl? Do they throw good error messages?

Comment on lines 192 to 210
// The `trial` field used to be optional, force it to always be defined
decodedLicense.trial = !!decodedLicense.trial;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Something else might still rely on this code. Better to leave it in.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good call, I'll leave that in.

Comment on lines 283 to 474
// Create a date object for the expiration date
const expirationDate = new Date(licenseData.exp);

// Add a buffer of 2 days to the expiration date
const expiresWithBuffer = new Date(expirationDate);
expiresWithBuffer.setDate(expirationDate.getDate() + 2);

// Check if the adjusted expiration date is in the past
if (expiresWithBuffer < new Date()) {
// The license is expired
return true;
}
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From my understanding before if it was a .trial license and it expired we errored immediately with no buffer. It errored too harshly to the point that the app became unusable. This change would give them the two day buffer as well, but I think we only want to have the two day grace period with enterprise customers.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, as it is, it adds the buffer for all users. I'll make sure it only does so for non-trial users.

@smrdotgg
Copy link
Contributor Author

smrdotgg commented Dec 5, 2023

Thanks again for doing this Semere! It looks almost perfect. I left a few comments though. Did you check out an api endpoint that has enterprise features using curl? Do they throw good error messages?

I have tested the api endpoints with curl, and they only execute if the license key is valid. If its invalid, they throw appropriate errors with correct codes and proper messages.

I've also added the changes you proposed. 😃

Copy link
Collaborator

@tzjames tzjames left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks good now. Congrats!

const expirationDate = new Date(licenseData.exp);

// Add a buffer of 2 days to the expiration date for non-trial users
if (licenseData.trial) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you are missing a !

Copy link
Collaborator

@tzjames tzjames left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We chatted in person about making the non-trial licenses just show the warning but not impede functionality.

Copy link
Collaborator

@tzjames tzjames left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is looking good now.

@tzjames tzjames merged commit bb88729 into growthbook:main Dec 28, 2023
2 of 3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Bug] Expired License Keys Cause API Error State
4 participants