From e5e793545653d42a9a824507025780269dd430e4 Mon Sep 17 00:00:00 2001 From: Anthony Stirling <77850077+Frooodle@users.noreply.github.com> Date: Fri, 9 May 2025 16:42:20 +0100 Subject: [PATCH 1/6] pixel changes, redact color fix, version bump, aggressive compression (#3502) # 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/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/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/HowToAddNewLanguage.md#add-new-translation-tags) (for new translation tags only) ### 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/DeveloperGuide.md#6-testing) for more details. --- build.gradle | 2 +- .../software/SPDF/EE/EEAppConfig.java | 5 ++ .../software/SPDF/config/AppConfig.java | 37 ++++++++++++++ .../api/misc/CompressController.java | 51 +++++++++++-------- .../api/security/RedactController.java | 11 ++-- .../model/api/security/RedactPdfRequest.java | 2 +- .../resources/templates/fragments/common.html | 10 +++- src/main/resources/templates/home.html | 2 +- 8 files changed, 90 insertions(+), 30 deletions(-) diff --git a/build.gradle b/build.gradle index e91f0a467..7359d0b6a 100644 --- a/build.gradle +++ b/build.gradle @@ -29,7 +29,7 @@ ext { } group = "stirling.software" -version = "0.46.0" +version = "0.46.1" java { // 17 is lowest but we support and recommend 21 diff --git a/src/main/java/stirling/software/SPDF/EE/EEAppConfig.java b/src/main/java/stirling/software/SPDF/EE/EEAppConfig.java index a83b17090..0bbb531ef 100644 --- a/src/main/java/stirling/software/SPDF/EE/EEAppConfig.java +++ b/src/main/java/stirling/software/SPDF/EE/EEAppConfig.java @@ -33,6 +33,11 @@ public class EEAppConfig { public boolean runningProOrHigher() { return licenseKeyChecker.getPremiumLicenseEnabledResult() != License.NORMAL; } + + @Bean(name = "license") + public String licenseType() { + return licenseKeyChecker.getPremiumLicenseEnabledResult().name(); + } @Bean(name = "runningEE") public boolean runningEnterprise() { diff --git a/src/main/java/stirling/software/SPDF/config/AppConfig.java b/src/main/java/stirling/software/SPDF/config/AppConfig.java index f07368527..5b52ed3a5 100644 --- a/src/main/java/stirling/software/SPDF/config/AppConfig.java +++ b/src/main/java/stirling/software/SPDF/config/AppConfig.java @@ -5,6 +5,7 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.List; +import java.util.Locale; import java.util.Properties; import java.util.function.Predicate; @@ -15,6 +16,7 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Lazy; import org.springframework.context.annotation.Scope; +import org.springframework.core.env.Environment; import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.Resource; import org.springframework.core.io.ResourceLoader; @@ -33,6 +35,8 @@ public class AppConfig { private final ApplicationProperties applicationProperties; + private final Environment env; + @Bean @ConditionalOnProperty(name = "system.customHTMLFiles", havingValue = "true") public SpringTemplateEngine templateEngine(ResourceLoader resourceLoader) { @@ -193,4 +197,37 @@ public class AppConfig { public String uuid() { return applicationProperties.getAutomaticallyGenerated().getUUID(); } + + @Bean(name = "disablePixel") + public boolean disablePixel() { + return Boolean.getBoolean(env.getProperty("DISABLE_PIXEL")); + } + + @Bean(name = "machineType") + public String determineMachineType() { + try { + boolean isDocker = runningInDocker(); + boolean isKubernetes = System.getenv("KUBERNETES_SERVICE_HOST") != null; + boolean isBrowserOpen = "true".equalsIgnoreCase(env.getProperty("BROWSER_OPEN")); + + if (isKubernetes) { + return "Kubernetes"; + } else if (isDocker) { + return "Docker"; + } else if (isBrowserOpen) { + String os = System.getProperty("os.name").toLowerCase(Locale.ROOT); + if (os.contains("win")) { + return "Client-windows"; + } else if (os.contains("mac")) { + return "Client-mac"; + } else { + return "Client-unix"; + } + } else { + return "Server-jar"; + } + } catch (Exception e) { + return "Unknown"; + } + } } diff --git a/src/main/java/stirling/software/SPDF/controller/api/misc/CompressController.java b/src/main/java/stirling/software/SPDF/controller/api/misc/CompressController.java index 79d46cc45..da4a77962 100644 --- a/src/main/java/stirling/software/SPDF/controller/api/misc/CompressController.java +++ b/src/main/java/stirling/software/SPDF/controller/api/misc/CompressController.java @@ -626,25 +626,32 @@ public class CompressController { // Scale factors for different optimization levels private double getScaleFactorForLevel(int optimizeLevel) { - return switch (optimizeLevel) { - case 4 -> 0.9; // 90% - lite compression - case 5 -> 0.8; // 80% - lite compression - case 6 -> 0.7; // 70% - lite compression - case 7 -> 0.6; // 60% - intense compression - case 8 -> 0.5; // 50% - intense compression - case 9, 10 -> 0.4; // 40% - intense compression - default -> 1.0; // No scaling for levels 1-3 - }; + return switch (optimizeLevel) { + case 3 -> 0.85; + case 4 -> 0.75; + case 5 -> 0.65; + case 6 -> 0.55; + case 7 -> 0.45; + case 8 -> 0.35; + case 9 -> 0.25; + case 10 -> 0.15; + default -> 1.0; + }; } // JPEG quality for different optimization levels private float getJpegQualityForLevel(int optimizeLevel) { - return switch (optimizeLevel) { - case 7 -> 0.8f; // 80% quality - case 8 -> 0.6f; // 60% quality - case 9, 10 -> 0.4f; // 40% quality - default -> 0.7f; // 70% quality for levels 1-6 - }; + return switch (optimizeLevel) { + case 3 -> 0.85f; + case 4 -> 0.80f; + case 5 -> 0.75f; + case 6 -> 0.70f; + case 7 -> 0.60f; + case 8 -> 0.50f; + case 9 -> 0.35f; + case 10 -> 0.2f; + default -> 0.7f; + }; } @PostMapping(consumes = "multipart/form-data", value = "/compress-pdf") @@ -698,7 +705,7 @@ public class CompressController { while (!sizeMet && optimizeLevel <= 9) { // Apply image compression for levels 4-9 - if ((optimizeLevel >= 4 || Boolean.TRUE.equals(convertToGrayscale)) + if ((optimizeLevel >= 3 || Boolean.TRUE.equals(convertToGrayscale)) && !imageCompressionApplied) { double scaleFactor = getScaleFactorForLevel(optimizeLevel); float jpegQuality = getJpegQualityForLevel(optimizeLevel); @@ -790,10 +797,14 @@ public class CompressController { log.info("Pre-QPDF file size: {}", GeneralUtils.formatBytes(preQpdfSize)); // Map optimization levels to QPDF compression levels - int qpdfCompressionLevel = - optimizeLevel <= 3 - ? optimizeLevel * 3 // Level 1->3, 2->6, 3->9 - : 9; // Max compression for levels 4-9 + int qpdfCompressionLevel; + if (optimizeLevel == 1) { + qpdfCompressionLevel = 5; + } else if (optimizeLevel == 2) { + qpdfCompressionLevel = 9; + } else { + qpdfCompressionLevel = 9; + } // Create output file for QPDF Path qpdfOutputFile = Files.createTempFile("qpdf_output_", ".pdf"); diff --git a/src/main/java/stirling/software/SPDF/controller/api/security/RedactController.java b/src/main/java/stirling/software/SPDF/controller/api/security/RedactController.java index 0c8a7f7e6..df5e2499e 100644 --- a/src/main/java/stirling/software/SPDF/controller/api/security/RedactController.java +++ b/src/main/java/stirling/software/SPDF/controller/api/security/RedactController.java @@ -170,16 +170,17 @@ public class RedactController { } private Color decodeOrDefault(String hex, Color defaultColor) { - Color color = null; try { - color = Color.decode(hex); + if (hex != null && !hex.startsWith("#")) { + hex = "#" + hex; + } + return Color.decode(hex); } catch (Exception e) { - color = defaultColor; + return defaultColor; } - - return color; } + private List getPageNumbers(ManualRedactPdfRequest request, int pagesCount) { String pageNumbersInput = request.getPageNumbers(); String[] parsedPageNumbers = diff --git a/src/main/java/stirling/software/SPDF/model/api/security/RedactPdfRequest.java b/src/main/java/stirling/software/SPDF/model/api/security/RedactPdfRequest.java index 54c6a0aad..e92ae7c5a 100644 --- a/src/main/java/stirling/software/SPDF/model/api/security/RedactPdfRequest.java +++ b/src/main/java/stirling/software/SPDF/model/api/security/RedactPdfRequest.java @@ -23,7 +23,7 @@ public class RedactPdfRequest extends PDFFile { @Schema(description = "Whether to use whole word search", defaultValue = "false") private boolean wholeWordSearch; - @Schema(description = "The color for redaction", defaultValue = "#000000") + @Schema(description = "Hexadecimal color code for redaction, e.g. #FF0000 or 000000", defaultValue = "#000000") private String redactColor = "#000000"; @Schema(description = "Custom padding for redaction", type = "number") diff --git a/src/main/resources/templates/fragments/common.html b/src/main/resources/templates/fragments/common.html index 7fd26c777..02d919b2b 100644 --- a/src/main/resources/templates/fragments/common.html +++ b/src/main/resources/templates/fragments/common.html @@ -41,8 +41,14 @@ - - + + diff --git a/src/main/resources/templates/home.html b/src/main/resources/templates/home.html index bba498db5..a7cbbbd80 100644 --- a/src/main/resources/templates/home.html +++ b/src/main/resources/templates/home.html @@ -43,7 +43,7 @@ th:insert="~{fragments/navbarEntry :: navbarEntry ('multi-tool', 'construction', 'home.multiTool.title', 'home.multiTool.desc', 'multiTool.tags', 'organize')}">
+ th:insert="~{fragments/navbarEntry :: navbarEntry('compress-pdf', 'zoom_in_map', 'home.compressPdfs.title', 'home.compressPdfs.desc', 'compressPDFs.tags', 'advance')}">
From 9ffc0037b76764d802ffff3c935437d9cb1c5036 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bal=C3=A1zs=20Sz=C3=BCcs?= <127139797+Balazs-Szucs@users.noreply.github.com> Date: Fri, 9 May 2025 19:41:31 +0200 Subject: [PATCH 2/6] Refactor permission variable names (#3457) ## Refactor: Improve clarity of permission variable names Renamed confusing `can[Action]` boolean variables to `prevent[Action]` (e.g., `canPrint` -> `preventPrinting`) in `PasswordController.java`, `AddPasswordRequest.java`, and `add-password.html`. The previous `can[Action]` convention was misleading, as `true` meant the action was *disallowed*. The new `prevent[Action]` naming directly reflects the intent (`true` = prevented), improving code clarity. **Changes:** * Updated variable names in controller logic * Updated `@Schema` descriptions in `AddPasswordRequest.java` * Updated corresponding HTML element attributes (`id`, `name`, `for`) in `add-password.html` **Important Notes:** * The underlying logic still inverts the boolean when setting permissions (e.g., `AccessPermission.setCanPrint(!preventPrinting)`). * User-facing UI text remains unchanged per request of @Frooodle in #3420. **Why not invert the API logic** * Inverting API (to can[action] logic) would either invalidate the UI * Inverting API AND changing UI would warrant bigger translation effort to change it in all languages * This version is consistent (meaning what the UI says is actually done) and preserve the UI language (meaning no translations needed) however it is inconsistent with PDFBox methods naming scheme **PDFBox** * **PDFBox Interaction:** This refactor addresses the naming *within* Stirling-PDF's API and Front-end layers only. The controller logic intentionally inverts the `prevent[Action]` boolean (`ap.setCanPrint(!preventPrinting)`) to correctly interact with the underlying PDFBox methods. No further renaming related to these permissions is necessary as the PDFBox methods themselves retain the `can[Action]` names. Underlying logic is not changed so it should work but just in case I tested locally on an Adobe PDF that contained form in Chrome. ## New variable names in API ![new API variable names](https://github.com/user-attachments/assets/f3d56aaf-0455-4f65-af14-c1a07a02d11a) **Related Issues:** Closes #3427 Closes #3420 --- ## Checklist ### General - [x] I have read the [Contribution Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md) - [x] I have read the [Stirling-PDF Developer Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/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/HowToAddNewLanguage.md) (if applicable) - [x] I have performed a self-review of my own code - [x] 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/HowToAddNewLanguage.md#add-new-translation-tags) (for new translation tags only) ### 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) - [x] I have tested my changes locally. Refer to the [Testing Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md#6-testing) for more details. --- .../controller/api/AnalysisController.java | 13 +++---- .../controller/api/security/GetInfoOnPDF.java | 4 +-- .../api/security/PasswordController.java | 32 ++++++++--------- .../api/security/AddPasswordRequest.java | 36 +++++++++---------- .../templates/security/add-password.html | 32 ++++++++--------- .../security/change-permissions.html | 32 ++++++++--------- 6 files changed, 74 insertions(+), 75 deletions(-) diff --git a/src/main/java/stirling/software/SPDF/controller/api/AnalysisController.java b/src/main/java/stirling/software/SPDF/controller/api/AnalysisController.java index 49c5bc81c..8909c70e5 100644 --- a/src/main/java/stirling/software/SPDF/controller/api/AnalysisController.java +++ b/src/main/java/stirling/software/SPDF/controller/api/AnalysisController.java @@ -180,14 +180,15 @@ public class AnalysisController { // Get permissions Map permissions = new HashMap<>(); - permissions.put("canPrint", document.getCurrentAccessPermission().canPrint()); - permissions.put("canModify", document.getCurrentAccessPermission().canModify()); + permissions.put("preventPrinting", !document.getCurrentAccessPermission().canPrint()); permissions.put( - "canExtractContent", - document.getCurrentAccessPermission().canExtractContent()); + "preventModify", !document.getCurrentAccessPermission().canModify()); permissions.put( - "canModifyAnnotations", - document.getCurrentAccessPermission().canModifyAnnotations()); + "preventExtractContent", + !document.getCurrentAccessPermission().canExtractContent()); + permissions.put( + "preventModifyAnnotations", + !document.getCurrentAccessPermission().canModifyAnnotations()); securityInfo.put("permissions", permissions); } else { diff --git a/src/main/java/stirling/software/SPDF/controller/api/security/GetInfoOnPDF.java b/src/main/java/stirling/software/SPDF/controller/api/security/GetInfoOnPDF.java index ef82a2942..95049b0bd 100644 --- a/src/main/java/stirling/software/SPDF/controller/api/security/GetInfoOnPDF.java +++ b/src/main/java/stirling/software/SPDF/controller/api/security/GetInfoOnPDF.java @@ -622,8 +622,8 @@ public class GetInfoOnPDF { permissionsNode.put("Document Assembly", getPermissionState(ap.canAssembleDocument())); permissionsNode.put("Extracting Content", getPermissionState(ap.canExtractContent())); permissionsNode.put( - "Extracting for accessibility", - getPermissionState(ap.canExtractForAccessibility())); + "Extracting for accessibility", + getPermissionState(ap.canExtractForAccessibility())); permissionsNode.put("Form Filling", getPermissionState(ap.canFillInForm())); permissionsNode.put("Modifying", getPermissionState(ap.canModify())); permissionsNode.put("Modifying annotations", getPermissionState(ap.canModifyAnnotations())); diff --git a/src/main/java/stirling/software/SPDF/controller/api/security/PasswordController.java b/src/main/java/stirling/software/SPDF/controller/api/security/PasswordController.java index 830810628..c0f341782 100644 --- a/src/main/java/stirling/software/SPDF/controller/api/security/PasswordController.java +++ b/src/main/java/stirling/software/SPDF/controller/api/security/PasswordController.java @@ -63,25 +63,25 @@ public class PasswordController { String ownerPassword = request.getOwnerPassword(); String password = request.getPassword(); int keyLength = request.getKeyLength(); - boolean canAssembleDocument = request.isCanAssembleDocument(); - boolean canExtractContent = request.isCanExtractContent(); - boolean canExtractForAccessibility = request.isCanExtractForAccessibility(); - boolean canFillInForm = request.isCanFillInForm(); - boolean canModify = request.isCanModify(); - boolean canModifyAnnotations = request.isCanModifyAnnotations(); - boolean canPrint = request.isCanPrint(); - boolean canPrintFaithful = request.isCanPrintFaithful(); + boolean preventAssembly = request.isPreventAssembly(); + boolean preventExtractContent = request.isPreventExtractContent(); + boolean preventExtractForAccessibility = request.isPreventExtractForAccessibility(); + boolean preventFillInForm = request.isPreventFillInForm(); + boolean preventModify = request.isPreventModify(); + boolean preventModifyAnnotations = request.isPreventModifyAnnotations(); + boolean preventPrinting = request.isPreventPrinting(); + boolean preventPrintingFaithful = request.isPreventPrintingFaithful(); PDDocument document = pdfDocumentFactory.load(fileInput); AccessPermission ap = new AccessPermission(); - ap.setCanAssembleDocument(!canAssembleDocument); - ap.setCanExtractContent(!canExtractContent); - ap.setCanExtractForAccessibility(!canExtractForAccessibility); - ap.setCanFillInForm(!canFillInForm); - ap.setCanModify(!canModify); - ap.setCanModifyAnnotations(!canModifyAnnotations); - ap.setCanPrint(!canPrint); - ap.setCanPrintFaithful(!canPrintFaithful); + ap.setCanAssembleDocument(!preventAssembly); + ap.setCanExtractContent(!preventExtractContent); + ap.setCanExtractForAccessibility(!preventExtractForAccessibility); + ap.setCanFillInForm(!preventFillInForm); + ap.setCanModify(!preventModify); + ap.setCanModifyAnnotations(!preventModifyAnnotations); + ap.setCanPrint(!preventPrinting); + ap.setCanPrintFaithful(!preventPrintingFaithful); StandardProtectionPolicy spp = new StandardProtectionPolicy(ownerPassword, password, ap); if (!"".equals(ownerPassword) || !"".equals(password)) { diff --git a/src/main/java/stirling/software/SPDF/model/api/security/AddPasswordRequest.java b/src/main/java/stirling/software/SPDF/model/api/security/AddPasswordRequest.java index ef85dfead..982a31244 100644 --- a/src/main/java/stirling/software/SPDF/model/api/security/AddPasswordRequest.java +++ b/src/main/java/stirling/software/SPDF/model/api/security/AddPasswordRequest.java @@ -29,31 +29,29 @@ public class AddPasswordRequest extends PDFFile { defaultValue = "256") private int keyLength = 256; - @Schema(description = "Whether the document assembly is allowed", example = "false") - private boolean canAssembleDocument; + @Schema(description = "Whether document assembly is prevented", example = "false") + private boolean preventAssembly; + + @Schema(description = "Whether content extraction is prevented", example = "false") + private boolean preventExtractContent; @Schema( - description = "Whether content extraction for accessibility is allowed", + description = "Whether content extraction for accessibility is prevented", example = "false") - private boolean canExtractContent; + private boolean preventExtractForAccessibility; - @Schema( - description = "Whether content extraction for accessibility is allowed", - example = "false") - private boolean canExtractForAccessibility; + @Schema(description = "Whether form filling is prevented", example = "false") + private boolean preventFillInForm; - @Schema(description = "Whether form filling is allowed", example = "false") - private boolean canFillInForm; + @Schema(description = "Whether document modification is prevented", example = "false") + private boolean preventModify; - @Schema(description = "Whether the document modification is allowed", example = "false") - private boolean canModify; + @Schema(description = "Whether modification of annotations is prevented", example = "false") + private boolean preventModifyAnnotations; - @Schema(description = "Whether modification of annotations is allowed", example = "false") - private boolean canModifyAnnotations; + @Schema(description = "Whether printing of the document is prevented", example = "false") + private boolean preventPrinting; - @Schema(description = "Whether printing of the document is allowed", example = "false") - private boolean canPrint; - - @Schema(description = "Whether faithful printing is allowed", example = "false") - private boolean canPrintFaithful; + @Schema(description = "Whether faithful printing is prevented", example = "false") + private boolean preventPrintingFaithful; } diff --git a/src/main/resources/templates/security/add-password.html b/src/main/resources/templates/security/add-password.html index 1283a4268..f55f55fb7 100644 --- a/src/main/resources/templates/security/add-password.html +++ b/src/main/resources/templates/security/add-password.html @@ -41,36 +41,36 @@
- - + +
- - + +
- - + +
- - + +
- - + +
- - + +
- - + +
- - + +

diff --git a/src/main/resources/templates/security/change-permissions.html b/src/main/resources/templates/security/change-permissions.html index 52d743913..1996df35e 100644 --- a/src/main/resources/templates/security/change-permissions.html +++ b/src/main/resources/templates/security/change-permissions.html @@ -25,36 +25,36 @@
- - + +
- - + +
- - + +
- - + +
- - + +
- - + +
- - + +
- - + +

From e0c06ecebfb1c05969f51c0bc9fac5eef43e431e Mon Sep 17 00:00:00 2001 From: Thomas BERNARD Date: Fri, 9 May 2025 19:50:30 +0200 Subject: [PATCH 3/6] Fix French translation. (#2981) redact (black out) => Caviarder/Caviardage thanks @ralmn # 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 - [x] I have read the [Contribution Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md) - [x] I have read the [Stirling-PDF Developer Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md) (if applicable) - [x] I have read the [How to add new languages to Stirling-PDF](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/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/HowToAddNewLanguage.md#add-new-translation-tags) (for new translation tags only) ### 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/DeveloperGuide.md#6-testing) for more details. --------- Co-authored-by: Dylan Broussard Co-authored-by: Anthony Stirling <77850077+Frooodle@users.noreply.github.com> --- src/main/resources/messages_fr_FR.properties | 28 ++++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/main/resources/messages_fr_FR.properties b/src/main/resources/messages_fr_FR.properties index 83510d6f0..1944cd20d 100644 --- a/src/main/resources/messages_fr_FR.properties +++ b/src/main/resources/messages_fr_FR.properties @@ -517,13 +517,13 @@ home.showJS.title=Afficher le JavaScript home.showJS.desc=Recherche et affiche tout JavaScript injecté dans un PDF. showJS.tags=JS -home.autoRedact.title=Censure automatique -home.autoRedact.desc=Censurer automatiquement les informations sensibles d'un PDF. -autoRedact.tags=caviarder,rédiger,censurer,redact,auto +home.autoRedact.title=Caviardage automatique +home.autoRedact.desc=Caviardez automatiquement les informations sensibles d'un PDF. +autoRedact.tags=caviarder,redact,auto,Masquer,noircir,noir,marqueur,caché,rédiger,censurer -home.redact.title=Censure manuelle -home.redact.desc=Censurer un PDF en fonction de texte sélectionné, formes dessinées et/ou des pages sélectionnées. -redact.tags=Redact,Hide,black out,black,marker,hidden,manual,caviarder,rédiger,censurer +home.redact.title=Caviardage manuel +home.redact.desc=Caviarder un PDF en fonction de texte sélectionné, formes dessinées et/ou des pages sélectionnées. +redact.tags=Caviarder,Redact,Masquer,noircir,noir,marqueur,caché,rédiger,censurer home.tableExtraxt.title=PDF en CSV home.tableExtraxt.desc=Extrait les tableaux d'un PDF et les transforme en CSV. @@ -624,31 +624,31 @@ autoRedact.convertPDFToImageLabel=Convertir un PDF en PDF-Image (utilisé pour s autoRedact.submitButton=Caviarder #redact -redact.title=Rédaction manuelle -redact.header=Rédaction manuelle -redact.submit=Rédiger -redact.textBasedRedaction=Rédaction en fonction de texte -redact.pageBasedRedaction=Rédaction en fonction de pages +redact.title=Caviardage manuel +redact.header=Caviardage manuel +redact.submit=Caviarder +redact.textBasedRedaction=Caviarder du texte +redact.pageBasedRedaction=Caviarder des pages redact.convertPDFToImageLabel=Convertir en PDF-Image (pour supprimer le texte derrière le rectangle) redact.pageRedactionNumbers.title=Pages redact.pageRedactionNumbers.placeholder=(ex: 1,2,8 ou 4,7,12-16 ou 2n-1) redact.redactionColor.title=Couleur redact.export=Exporter redact.upload=Téléverser -redact.boxRedaction=Dessiner le rectangle à rédiger +redact.boxRedaction=Tracer le rectangle à caviarder redact.zoom=Zoom redact.zoomIn=Zoom avant redact.zoomOut=Zoom arrière redact.nextPage=Page suivante redact.previousPage=Page précédente -redact.toggleSidebar=Toggle Sidebar +redact.toggleSidebar=Montrer la barre latérale redact.showThumbnails=Afficher les miniatures redact.showDocumentOutline=Montrer les contours du document (double-click pour agrandir/réduire tous les éléments) redact.showAttatchments=Montrer les éléments attachés redact.showLayers=Montrer les calques (double-click pour réinitialiser tous les calques à l'état par défaut) redact.colourPicker=Sélection de couleur redact.findCurrentOutlineItem=Trouver l'élément de contour courrant -redact.applyChanges=Apply Changes +redact.applyChanges=Appliquer les changements #showJS showJS.title=Afficher le JavaScript From 1bb3b68a87c8bae1b5c76c8c43e7879b703c6af1 Mon Sep 17 00:00:00 2001 From: Anthony Stirling <77850077+Frooodle@users.noreply.github.com> Date: Fri, 9 May 2025 18:53:13 +0100 Subject: [PATCH 4/6] Potential fix for code scanning alert no. 11: DOM text reinterpreted as HTML (#3497) Potential fix for [https://github.com/Stirling-Tools/Stirling-PDF/security/code-scanning/11](https://github.com/Stirling-Tools/Stirling-PDF/security/code-scanning/11) To fix the issue, we should avoid using `innerHTML` to insert untrusted data into the DOM. Instead, we can use DOM manipulation methods like `createElement` and `appendChild` to construct the required HTML structure safely. These methods do not interpret strings as HTML, thereby mitigating the risk of XSS. Specifically: 1. Replace the `innerHTML` assignment on line 302 with code that creates the required DOM elements programmatically. 2. Ensure that the `selectedOperation` value is inserted as plain text using `textContent` or equivalent methods. --- _Suggested fixes powered by Copilot Autofix. Review carefully before merging._ Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> --- src/main/resources/static/js/pipeline.js | 51 +++++++++++++++++------- 1 file changed, 36 insertions(+), 15 deletions(-) diff --git a/src/main/resources/static/js/pipeline.js b/src/main/resources/static/js/pipeline.js index 7633a6bbd..c44779c1f 100644 --- a/src/main/resources/static/js/pipeline.js +++ b/src/main/resources/static/js/pipeline.js @@ -299,21 +299,42 @@ document.getElementById("addOperationBtn").addEventListener("click", function () } } - listItem.innerHTML = ` -
-
${selectedOperation}
-
- - - - -
-
- `; + let containerDiv = document.createElement("div"); + containerDiv.className = "d-flex justify-content-between align-items-center w-100"; + + let operationNameDiv = document.createElement("div"); + operationNameDiv.className = "operationName"; + operationNameDiv.textContent = selectedOperation; + containerDiv.appendChild(operationNameDiv); + + let arrowsDiv = document.createElement("div"); + arrowsDiv.className = "arrows d-flex"; + + let moveUpButton = document.createElement("button"); + moveUpButton.className = "btn btn-secondary move-up ms-1"; + moveUpButton.innerHTML = 'arrow_upward'; + arrowsDiv.appendChild(moveUpButton); + + let moveDownButton = document.createElement("button"); + moveDownButton.className = "btn btn-secondary move-down ms-1"; + moveDownButton.innerHTML = 'arrow_downward'; + arrowsDiv.appendChild(moveDownButton); + + let settingsButton = document.createElement("button"); + settingsButton.className = `btn ${hasSettings ? "btn-warning" : "btn-secondary"} pipelineSettings ms-1`; + if (!hasSettings) { + settingsButton.disabled = true; + } + settingsButton.innerHTML = 'settings'; + arrowsDiv.appendChild(settingsButton); + + let removeButton = document.createElement("button"); + removeButton.className = "btn btn-danger remove ms-1"; + removeButton.innerHTML = 'close'; + arrowsDiv.appendChild(removeButton); + + containerDiv.appendChild(arrowsDiv); + listItem.appendChild(containerDiv); pipelineList.appendChild(listItem); From ff3fe19d98a93580a2c10d575ba6603d70dfaf0b Mon Sep 17 00:00:00 2001 From: "stirlingbot[bot]" <195170888+stirlingbot[bot]@users.noreply.github.com> Date: Fri, 9 May 2025 19:38:29 +0100 Subject: [PATCH 5/6] :globe_with_meridians: Sync Translations + Update README Progress Table (#3503) ### Description of Changes This Pull Request was automatically generated to synchronize updates to translation files and documentation. Below are the details of the changes made: #### **1. Synchronization of Translation Files** - Updated translation files (`messages_*.properties`) to reflect changes in the reference file `messages_en_GB.properties`. - Ensured consistency and synchronization across all supported language files. - Highlighted any missing or incomplete translations. #### **2. Update README.md** - Generated the translation progress table in `README.md`. - Added a summary of the current translation status for all supported languages. - Included up-to-date statistics on translation coverage. #### **Why these changes are necessary** - Keeps translation files aligned with the latest reference updates. - Ensures the documentation reflects the current translation progress. --- Auto-generated by [create-pull-request][1]. [1]: https://github.com/peter-evans/create-pull-request Co-authored-by: stirlingbot[bot] <195170888+stirlingbot[bot]@users.noreply.github.com> --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e642dd8b4..b81b26a36 100644 --- a/README.md +++ b/README.md @@ -127,7 +127,7 @@ Stirling-PDF currently supports 39 languages! | Dutch (Nederlands) (nl_NL) | ![79%](https://geps.dev/progress/79) | | English (English) (en_GB) | ![100%](https://geps.dev/progress/100) | | English (US) (en_US) | ![100%](https://geps.dev/progress/100) | -| French (Français) (fr_FR) | ![91%](https://geps.dev/progress/91) | +| French (Français) (fr_FR) | ![92%](https://geps.dev/progress/92) | | German (Deutsch) (de_DE) | ![99%](https://geps.dev/progress/99) | | Greek (Ελληνικά) (el_GR) | ![91%](https://geps.dev/progress/91) | | Hindi (हिंदी) (hi_IN) | ![91%](https://geps.dev/progress/91) | From 8bb6dea70a7aca941ee5a3f3c1dc7c4be982f1bd Mon Sep 17 00:00:00 2001 From: Reece Browne <74901996+reecebrowne@users.noreply.github.com> Date: Sat, 10 May 2025 13:25:21 +0100 Subject: [PATCH 6/6] =?UTF-8?q?accept/decline=20cookies=20based=20on=20ana?= =?UTF-8?q?lytics=20and=20hide=20cookie=20banner=20when=E2=80=A6=20(#3505)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit … analytics modal open Close cookies banner when analytics modal is open Accept/decline cookies based on analytics response. Please provide a summary of the changes, including: - What was changed - Why the change was made - Any challenges encountered Closes #(3403) --- ## Checklist ### General - [x ] I have read the [Contribution Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md) - [ x] I have read the [Stirling-PDF Developer Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md) (if applicable) - [ x] I have read the [How to add new languages to Stirling-PDF](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/HowToAddNewLanguage.md) (if applicable) - [ x] I have performed a self-review of my own code - [ x] 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/HowToAddNewLanguage.md#add-new-translation-tags) (for new translation tags only) ### 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/DeveloperGuide.md#6-testing) for more details. --- src/main/resources/static/js/pages/home.js | 24 ++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/src/main/resources/static/js/pages/home.js b/src/main/resources/static/js/pages/home.js index 6c48fe81d..bb1e1ad4a 100644 --- a/src/main/resources/static/js/pages/home.js +++ b/src/main/resources/static/js/pages/home.js @@ -4,10 +4,21 @@ document.addEventListener('DOMContentLoaded', function () { if (window.analyticsPromptBoolean) { const analyticsModal = new bootstrap.Modal(document.getElementById('analyticsModal')); analyticsModal.show(); + + let retryCount = 0; +function hideCookieBanner() { + const cookieBanner = document.querySelector('#cc-main'); + if (cookieBanner && cookieBanner.offsetHeight > 0) { + cookieBanner.style.display = "none"; + } else if (retryCount < 20) { + retryCount++; + setTimeout(hideCookieBanner, 100); + } +} +hideCookieBanner(); } }); -/*]]>*/ -function setAnalytics(enabled) { +/*]]>*/function setAnalytics(enabled) { fetchWithCsrf('api/v1/settings/update-enable-analytics', { method: 'POST', headers: { @@ -19,6 +30,15 @@ function setAnalytics(enabled) { if (response.status === 200) { console.log('Analytics setting updated successfully'); bootstrap.Modal.getInstance(document.getElementById('analyticsModal')).hide(); + + if (typeof CookieConsent !== "undefined") { + if (enabled) { + CookieConsent.acceptCategory(['analytics']); + } else { + CookieConsent.acceptCategory([]); + } + } + } else if (response.status === 208) { console.log('Analytics setting has already been set. Please edit /config/settings.yml to change it.', response); alert('Analytics setting has already been set. Please edit /config/settings.yml to change it.');