licensere reTry (#5763)

# Description of Changes

<!--
Please provide a summary of the changes, including:

- What was changed
- Why the change was made
- Any challenges encountered

Closes #(issue_number)
-->

---

## 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.
This commit is contained in:
Anthony Stirling
2026-02-20 12:08:20 +00:00
committed by GitHub
parent dcda01c2b9
commit 7959b3f2a4
2 changed files with 69 additions and 36 deletions

View File

@@ -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(

View File

@@ -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();
}