From 7959b3f2a4034cebfdc2f6cdbbd319a5191c5bb9 Mon Sep 17 00:00:00 2001 From: Anthony Stirling <77850077+Frooodle@users.noreply.github.com> Date: Fri, 20 Feb 2026 12:08:20 +0000 Subject: [PATCH] licensere reTry (#5763) # Description of Changes --- ## Checklist ### General - [ ] I have read the [Contribution Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md) - [ ] I have read the [Stirling-PDF Developer Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/DeveloperGuide.md) (if applicable) - [ ] I have read the [How to add new languages to Stirling-PDF](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md) (if applicable) - [ ] I have performed a self-review of my own code - [ ] My changes generate no new warnings ### Documentation - [ ] I have updated relevant docs on [Stirling-PDF's doc repo](https://github.com/Stirling-Tools/Stirling-Tools.github.io/blob/main/docs/) (if functionality has heavily changed) - [ ] I have read the section [Add New Translation Tags](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md#add-new-translation-tags) (for new translation tags only) ### Translations (if applicable) - [ ] I ran [`scripts/counter_translation.py`](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/docs/counter_translation.md) ### UI Changes (if applicable) - [ ] Screenshots or videos demonstrating the UI changes are attached (e.g., as comments or direct attachments in the PR) ### Testing (if applicable) - [ ] I have tested my changes locally. Refer to the [Testing Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/DeveloperGuide.md#6-testing) for more details. --- .../ee/KeygenLicenseVerifier.java | 96 ++++++++++++------- .../configuration/ee/LicenseKeyChecker.java | 9 +- 2 files changed, 69 insertions(+), 36 deletions(-) diff --git a/app/proprietary/src/main/java/stirling/software/proprietary/security/configuration/ee/KeygenLicenseVerifier.java b/app/proprietary/src/main/java/stirling/software/proprietary/security/configuration/ee/KeygenLicenseVerifier.java index 3f48cd4e5..3fe63b3f3 100644 --- a/app/proprietary/src/main/java/stirling/software/proprietary/security/configuration/ee/KeygenLicenseVerifier.java +++ b/app/proprietary/src/main/java/stirling/software/proprietary/security/configuration/ee/KeygenLicenseVerifier.java @@ -480,47 +480,73 @@ public class KeygenLicenseVerifier { } private boolean verifyStandardLicense(String licenseKey, LicenseContext context) { - try { - log.info("Checking standard license key"); - String machineFingerprint = generateMachineFingerprint(); + int maxRetries = 5; + Exception lastException = null; - // First, try to validate the license - JsonNode validationResponse = validateLicense(licenseKey, machineFingerprint, context); - if (validationResponse != null) { - boolean isValid = validationResponse.path("meta").path("valid").asBoolean(); - String licenseId = validationResponse.path("data").path("id").asText(); - if (!isValid) { - String code = validationResponse.path("meta").path("code").asText(); - log.info(code); - if ("NO_MACHINE".equals(code) - || "NO_MACHINES".equals(code) - || "FINGERPRINT_SCOPE_MISMATCH".equals(code)) { - log.info( - "License not activated for this machine. Attempting to" - + " activate..."); - boolean activated = - activateMachine(licenseKey, licenseId, machineFingerprint, context); - if (activated) { - // Revalidate after activation - validationResponse = - validateLicense(licenseKey, machineFingerprint, context); - isValid = - validationResponse != null - && validationResponse - .path("meta") - .path("valid") - .asBoolean(); + for (int attempt = 1; attempt <= maxRetries; attempt++) { + try { + log.info("Checking standard license key (attempt {}/{})", attempt, maxRetries); + String machineFingerprint = generateMachineFingerprint(); + + // First, try to validate the license + JsonNode validationResponse = + validateLicense(licenseKey, machineFingerprint, context); + if (validationResponse != null) { + boolean isValid = validationResponse.path("meta").path("valid").asBoolean(); + String licenseId = validationResponse.path("data").path("id").asText(); + if (!isValid) { + String code = validationResponse.path("meta").path("code").asText(); + log.info(code); + if ("NO_MACHINE".equals(code) + || "NO_MACHINES".equals(code) + || "FINGERPRINT_SCOPE_MISMATCH".equals(code)) { + log.info( + "License not activated for this machine. Attempting to" + + " activate..."); + boolean activated = + activateMachine( + licenseKey, licenseId, machineFingerprint, context); + if (activated) { + // Revalidate after activation + validationResponse = + validateLicense(licenseKey, machineFingerprint, context); + isValid = + validationResponse != null + && validationResponse + .path("meta") + .path("valid") + .asBoolean(); + } } } + return isValid; } - return isValid; - } - return false; - } catch (Exception e) { - log.error("Error verifying standard license: {}", e.getMessage()); - return false; + return false; + } catch (Exception e) { + lastException = e; + log.error( + "Error verifying standard license (attempt {}/{}): {}", + attempt, + maxRetries, + e.getMessage()); + if (attempt < maxRetries) { + try { + Thread.sleep(3000L * attempt); + } catch (InterruptedException ie) { + Thread.currentThread().interrupt(); + break; + } + } + } } + + throw new RuntimeException( + "License verification failed after " + + maxRetries + + " attempts: " + + (lastException != null ? lastException.getMessage() : "unknown error"), + lastException); } private JsonNode validateLicense( diff --git a/app/proprietary/src/main/java/stirling/software/proprietary/security/configuration/ee/LicenseKeyChecker.java b/app/proprietary/src/main/java/stirling/software/proprietary/security/configuration/ee/LicenseKeyChecker.java index 3e9a8a413..0183e58f2 100644 --- a/app/proprietary/src/main/java/stirling/software/proprietary/security/configuration/ee/LicenseKeyChecker.java +++ b/app/proprietary/src/main/java/stirling/software/proprietary/security/configuration/ee/LicenseKeyChecker.java @@ -55,7 +55,14 @@ public class LicenseKeyChecker { @Scheduled(initialDelay = 604800000, fixedRate = 604800000) // 7 days in milliseconds public void checkLicensePeriodically() { - evaluateLicense(); + try { + evaluateLicense(); + } catch (RuntimeException e) { + log.error( + "Periodic license check failed after all retries: {}. Keeping existing license" + + " status.", + e.getMessage()); + } synchronizeLicenseSettings(); }