Compare commits

...
77 Commits
Author SHA1 Message Date
Anthony Stirling 6f9be99cbc Add files via upload 2025-09-05 00:22:02 +01:00
Anthony Stirling 97afb27183 Remove application/x-www-form-urlencoded content type 2025-09-05 00:20:19 +01:00
Anthony Stirling bd08359ac8 Rename operationId from redactPdf to redactPdfAuto 2025-09-05 00:14:37 +01:00
Anthony Stirling 2043ee1d18 Update pdftools.yml 2025-09-05 00:10:27 +01:00
Anthony Stirling 4963303341 Add files via upload 2025-09-05 00:07:11 +01:00
Anthony Stirling 34c21b1894 Add files via upload 2025-09-04 16:27:17 +01:00
Anthony Stirling 8c345de103 Add files via upload 2025-09-04 16:26:21 +01:00
Anthony Stirling 0619f0d4e4 Add files via upload 2025-09-04 16:23:37 +01:00
Ludy cb7471024b feat(common): add ChecksumUtils for MD5/SHA*/CRC32/Adler32 with Base64 and multi-algorithm support (#4261) 2025-09-04 15:38:28 +01:00
Balázs Szücs 74870615df Replace uses of Arrays.asList() with either List.of() or Collections.singletonList() (#4219) 2025-09-04 15:30:45 +01:00
Ludy 02d096d622 feat(security): add PFX alias for PKCS12; accept .crt/.cer/.der certs & .key keys; add certificate-signing tests (#4297) 2025-09-04 15:30:32 +01:00
LudyandCopilot 0d7649bee8 fix(ci:testdriver): conditionally run frontend tests based on file changes (#4064)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-09-04 15:11:09 +01:00
Ludy 0776ecc96b test(common): add dedicated unit tests for FileInfo and InputStreamTemplateResource (#4140) 2025-09-04 15:10:35 +01:00
Ludy 8113728d3d feat(database): make backup schedule configurable via system keys (#4251) 2025-09-04 15:02:31 +01:00
albanobattistella 528968bfe9 Update messages_it_IT.properties (#4285)
# 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)

### 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.
2025-09-04 14:50:16 +01:00
dependabot[bot] 61b85a9273 build(deps): bump jakarta.mail:jakarta.mail-api from 2.1.3 to 2.1.4 (#4351)
Bumps
[jakarta.mail:jakarta.mail-api](https://github.com/jakartaee/mail-api)
from 2.1.3 to 2.1.4.
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/jakartaee/mail-api/commit/0d13f04450f9590afa37761e04591526f47312e5"><code>0d13f04</code></a>
Prepare release jakarta.mail:jakarta.mail-api:2.1.4</li>
<li><a
href="https://github.com/jakartaee/mail-api/commit/958fb97ab1ebae1844629226fb06e27b05872c52"><code>958fb97</code></a>
services/jakarta.mail.Provider override not working <a
href="https://redirect.github.com/jakartaee/mail-api/issues/777">#777</a>
(<a
href="https://redirect.github.com/jakartaee/mail-api/issues/779">#779</a>)</li>
<li><a
href="https://github.com/jakartaee/mail-api/commit/3446c942412cb324ce448d65d6a805f3a6af599e"><code>3446c94</code></a>
services/jakarta.mail.Provider override not working <a
href="https://redirect.github.com/jakartaee/mail-api/issues/170">#170</a>
(<a
href="https://redirect.github.com/jakartaee/mail-api/issues/778">#778</a>)</li>
<li><a
href="https://github.com/jakartaee/mail-api/commit/892fae4ac7601976ee3270040a5b16d6349ce955"><code>892fae4</code></a>
Multipart performs blocking call in every instantiation <a
href="https://redirect.github.com/jakartaee/mail-api/issues/699">#699</a>
(<a
href="https://redirect.github.com/jakartaee/mail-api/issues/716">#716</a>)</li>
<li><a
href="https://github.com/jakartaee/mail-api/commit/666ec999d8931041d89eabf10d807e5262195f8f"><code>666ec99</code></a>
Bump rexml from 3.2.8 to 3.3.6 in /www</li>
<li><a
href="https://github.com/jakartaee/mail-api/commit/8eddc342b11436c2ab8a68ff5ab464e343edee99"><code>8eddc34</code></a>
Bump rexml from 3.2.5 to 3.2.8 in /www</li>
<li><a
href="https://github.com/jakartaee/mail-api/commit/1259b86a8c195db3337db9eff81214c357758c0e"><code>1259b86</code></a>
Bump nokogiri from 1.16.2 to 1.16.5 in /www</li>
<li><a
href="https://github.com/jakartaee/mail-api/commit/bf2bfc18c0d2b9b3f57417203c2a462a3a94a7de"><code>bf2bfc1</code></a>
Update README.md</li>
<li><a
href="https://github.com/jakartaee/mail-api/commit/038fa7038a26251bbf4a43ea577a5e7171d3a2e4"><code>038fa70</code></a>
Prepare next development cycle for 2.1.4-SNAPSHOT</li>
<li><a
href="https://github.com/jakartaee/mail-api/commit/1e520275467de4b1cc658fd83e1783c43d451b2e"><code>1e52027</code></a>
Prepare release jakarta.mail:jakarta.mail-api:2.1.3</li>
<li>See full diff in <a
href="https://github.com/jakartaee/mail-api/compare/2.1.3...2.1.4">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=jakarta.mail:jakarta.mail-api&package-manager=gradle&previous-version=2.1.3&new-version=2.1.4)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-04 14:50:03 +01:00
Ludy c055f9456a feat(convert): PDF conversion with unoconvert fallback soffice (#4316)
# Description of Changes

- **What was changed**
- Reworked `ConvertOfficeController` to use a dedicated temporary
working directory per request and cleaned up with directory-level
deletion.
- Added detection for converter availability via `EndpointConfiguration`
to choose between **unoconvert** and a **soffice** headless fallback.
- Ensured safe filename handling (sanitization, extension checks,
lowercase normalization) and early validation errors for missing/invalid
filenames.
- Switched raw temp file writes to `Files.copy` / `Files.writeString`
with `StandardCopyOption.REPLACE_EXISTING`.
  - Implemented robust output handling:
    - Verified non-zero exit codes and null results.
    - Checked for missing/empty PDF outputs.
- Added fallback lookup for any produced `.pdf` within the work
directory if the expected name is not present.
  - Introduced `@Slf4j` logging; improved error and cleanup logging.
- Replaced ad-hoc temp cleanup with `FileUtils.deleteDirectory` for full
working-dir removal.
- Minor imports/cleanup: removed unused `Arrays`, added
`StandardCopyOption`, `FileUtils`, and related imports.

- **Why the change was made**
- Increase conversion reliability across environments where either
unoconvert or soffice may be available.
- Harden security and stability through strict input validation and
sanitized HTML processing.
- Prevent orphaned files/directories and ensure consistent cleanup to
reduce disk footprint and operational issues.
- Provide clearer operational signals (logging, explicit exceptions) for
easier troubleshooting.


---

## 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/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)
- [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/devGuide/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/devGuide/DeveloperGuide.md#6-testing)
for more details.
2025-09-04 14:33:35 +01:00
Balázs SzücsandCopilot fe84b3ff15 feat: Add Lombok @Getter and @Setter annotations to reduce boilerplate code in multiple classes (#4321)
# Description of Changes

Update classes across the codebase to use Lombok's `@Getter` and
`@Setter` annotations, replacing manually written getter and setter
methods. This change streamlines the code, reduces boilerplate, and
improves maintainability.

<!--
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/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)
- [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/devGuide/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/devGuide/DeveloperGuide.md#6-testing)
for more details.

---------

Signed-off-by: Balázs Szücs <bszucs1209@gmail.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-09-04 14:29:55 +01:00
Ludy 9a213c4bf6 feat(misc): Add font color option for page numbers; improve alignment & robustness (#4334)
# Description of Changes

**What was changed**
- **API & backend**
- Added optional `fontColor` (hex, e.g. `#FF0000`) to
`AddPageNumbersRequest` with OpenAPI docs, default `#000000`.
- Decode hex color with safe fallback to black; apply via
`setNonStrokingColor`.
- Switched multiple `switch` statements to concise switch expressions
and used `Locale.ROOT` for case operations.
- Clamped `position` to `1..9` and reworked alignment using proper font
metrics (`ascent`/`descent`) for top/middle/bottom positioning.
  - Centralized filename base extraction; reduced repeated calls.  
  - Used try-with-resources for `PDPageContentStream`.
- **UI & i18n**
  - Added `addPageNumbers.fontColor` label (en_GB).  
- Introduced `<input type="color" id="fontColor" ...>` with live
background preview in the Add Page Numbers form.

**Why the change was made**
- Enable users to render page numbers in a chosen color (not just
black).
- Produce visually correct placement by accounting for font metrics
(baseline vs. optical middle).
- Improve resilience (locale-safe parsing, bounds checking) and code
clarity.

Closes #3839


[after.pdf](https://github.com/user-attachments/files/22064425/after.pdf)

[before.pdf](https://github.com/user-attachments/files/22064426/before.pdf)


---

## 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/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)
- [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/devGuide/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/devGuide/DeveloperGuide.md#6-testing)
for more details.
2025-09-04 14:04:11 +01:00
Ludy a4a57cef92 fix(api): prevent MultipartFile binding errors in StampController (#4331)
# Description of Changes

- **What was changed**
- Added a Spring `@InitBinder` in `StampController` that registers a
`PropertyEditorSupport` for `MultipartFile` to safely handle text inputs
by setting the value to `null`.
- Replaced multiple `switch` statements with modern Java **switch
expressions**:
    - Margin selection (`customMargin`) now uses a concise expression.
- Font selection (`alphabet` → font resource path) rewritten as an
expression.
- Position calculations (`calculatePositionX` / `calculatePositionY`)
now return via switch expressions with `yield`.
- Minor readability and maintainability improvements without changing
public API or behavior (besides the binding fix).

- **Why the change was made**
- The `@InitBinder` prevents conversion/binding issues when Spring
attempts to map string form fields to `MultipartFile`, which could cause
exceptions or unexpected behavior in multipart/form-data requests.
- Using switch expressions reduces boilerplate, clarifies intent, and
makes the control flow safer and more maintainable.

---

## 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/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)
- [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/devGuide/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/devGuide/DeveloperGuide.md#6-testing)
for more details.
2025-09-04 13:55:09 +01:00
stirlingbot[bot] 6f6f4a14dc 🌐 Sync Translations + Update README Progress Table (#4374)
### 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>
2025-09-04 12:56:18 +01:00
stirlingbot[bot] c50aadeb35 🤖 format everything with pre-commit by stirlingbot (#4185)
Auto-generated by [create-pull-request][1] with **stirlingbot**

[1]: https://github.com/peter-evans/create-pull-request

Signed-off-by: stirlingbot[bot] <stirlingbot[bot]@users.noreply.github.com>
Co-authored-by: stirlingbot[bot] <195170888+stirlingbot[bot]@users.noreply.github.com>
2025-09-04 12:56:02 +01:00
Ludy 963b4ee69d refactor(ssrf): default enum MEDIUM prevents OFF=false (#4280)
# Description of Changes

- **What was changed**
  - **URL to PDF flow**
- Changed `ConvertWebsiteToPDF#urlToPdf` to return `ResponseEntity<?>`
and perform a redirect (`303 SEE_OTHER`) back to `/url-to-pdf` with an
`error` query param instead of throwing exceptions.
- Added alert rendering in `url-to-pdf.html` using `param.error` for
localized error display.
- Introduced new translation key `error.invalidUrlFormat` in
`messages_en_GB.properties`.
  - **Security / SSRF**
- Migrated `ApplicationProperties.System.UrlSecurity.level` from
`String` to `SsrfProtectionLevel` enum.
- Default now set to `SsrfProtectionLevel.MEDIUM` (`// MAX, MEDIUM,
OFF`).
- This avoids the issue where setting `OFF` returned `false` in
configuration parsing.
- Updated `SsrfProtectionService#parseProtectionLevel` accordingly
(using `level.name()`).
  - **Repo hygiene**
    - Added `**/LOCAL_APPDATA_FONTCONFIG_CACHE/**` to `.gitignore`.

- **Why the change was made**
- Provide user-friendly, localized error messages instead of exposing
internal exceptions on URL-to-PDF conversions.
- Ensure SSRF protection level parsing is type-safe and consistent—`OFF`
can now be set without yielding a misleading `false` state.
  - Prevent unwanted fontconfig cache files from being tracked in Git.

---

## 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/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)
- [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/devGuide/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/devGuide/DeveloperGuide.md#6-testing)
for more details.
2025-09-04 12:39:37 +01:00
stirlingbot[bot] cd76f5e50a Update 3rd Party Licenses (#4278)
Auto-generated by stirlingbot[bot]

Signed-off-by: stirlingbot[bot] <stirlingbot[bot]@users.noreply.github.com>
Co-authored-by: stirlingbot[bot] <195170888+stirlingbot[bot]@users.noreply.github.com>
2025-09-04 12:37:39 +01:00
stirlingbot[bot] 763d50ba8d 🌐 Sync Translations + Update README Progress Table (#4277)
### 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>
2025-09-04 12:37:07 +01:00
dependabot[bot] 4987932f60 build(deps): bump org.panteleyev.jpackageplugin from 1.7.3 to 1.7.5 (#4347)
Bumps org.panteleyev.jpackageplugin from 1.7.3 to 1.7.5.


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=org.panteleyev.jpackageplugin&package-manager=gradle&previous-version=1.7.3&new-version=1.7.5)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-04 12:31:56 +01:00
dependabot[bot] 1036befaf1 build(deps): bump com.bucket4j:bucket4j_jdk17-core from 8.14.0 to 8.15.0 (#4279)
[//]: # (dependabot-start)
⚠️  **Dependabot is rebasing this PR** ⚠️ 

Rebasing might not happen immediately, so don't worry if this takes some
time.

Note: if you make any changes to this PR yourself, they will take
precedence over the rebase.

---

[//]: # (dependabot-end)

Bumps
[com.bucket4j:bucket4j_jdk17-core](https://github.com/bucket4j/bucket4j)
from 8.14.0 to 8.15.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/bucket4j/bucket4j/releases">com.bucket4j:bucket4j_jdk17-core's
releases</a>.</em></p>
<blockquote>
<h2>8.15.0</h2>
<h2>What's Changed</h2>
<ul>
<li>Fix typo in previous-releases link by <a
href="https://github.com/DominiQN"><code>@​DominiQN</code></a> in <a
href="https://redirect.github.com/bucket4j/bucket4j/pull/533">bucket4j/bucket4j#533</a></li>
<li>Fix typo in verbose-api docs by <a
href="https://github.com/cmg1411"><code>@​cmg1411</code></a> in <a
href="https://redirect.github.com/bucket4j/bucket4j/pull/540">bucket4j/bucket4j#540</a></li>
<li>Fix comment in redisson.adoc by <a
href="https://github.com/K-jun98"><code>@​K-jun98</code></a> in <a
href="https://redirect.github.com/bucket4j/bucket4j/pull/541">bucket4j/bucket4j#541</a></li>
<li>Add valid example using Redisson library by <a
href="https://github.com/JoshWein"><code>@​JoshWein</code></a> in <a
href="https://redirect.github.com/bucket4j/bucket4j/pull/542">bucket4j/bucket4j#542</a></li>
<li>MongoDB backend by <a
href="https://github.com/granikartem"><code>@​granikartem</code></a> in
<a
href="https://redirect.github.com/bucket4j/bucket4j/pull/549">bucket4j/bucket4j#549</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/DominiQN"><code>@​DominiQN</code></a>
made their first contribution in <a
href="https://redirect.github.com/bucket4j/bucket4j/pull/533">bucket4j/bucket4j#533</a></li>
<li><a href="https://github.com/cmg1411"><code>@​cmg1411</code></a> made
their first contribution in <a
href="https://redirect.github.com/bucket4j/bucket4j/pull/540">bucket4j/bucket4j#540</a></li>
<li><a href="https://github.com/K-jun98"><code>@​K-jun98</code></a> made
their first contribution in <a
href="https://redirect.github.com/bucket4j/bucket4j/pull/541">bucket4j/bucket4j#541</a></li>
<li><a href="https://github.com/JoshWein"><code>@​JoshWein</code></a>
made their first contribution in <a
href="https://redirect.github.com/bucket4j/bucket4j/pull/542">bucket4j/bucket4j#542</a></li>
<li><a
href="https://github.com/granikartem"><code>@​granikartem</code></a>
made their first contribution in <a
href="https://redirect.github.com/bucket4j/bucket4j/pull/549">bucket4j/bucket4j#549</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/bucket4j/bucket4j/compare/8.14.0...8.15.0">https://github.com/bucket4j/bucket4j/compare/8.14.0...8.15.0</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/bucket4j/bucket4j/commit/1ecc3152b8c9383d12e37aae1e6a431dbac9baa1"><code>1ecc315</code></a>
Documentation for release 8.15.0</li>
<li><a
href="https://github.com/bucket4j/bucket4j/commit/0d257fd2f4f9ff871268feef50c7f40a7b8bb486"><code>0d257fd</code></a>
Documentation for release 8.15.0</li>
<li><a
href="https://github.com/bucket4j/bucket4j/commit/621f5d58043cad215fae598e432c45d6ebaa32e0"><code>621f5d5</code></a>
Documentation for release 8.15.0</li>
<li><a
href="https://github.com/bucket4j/bucket4j/commit/2930d8388b6168f8056ffa9e0ac6a72a8efa230d"><code>2930d83</code></a>
<a
href="https://redirect.github.com/bucket4j/bucket4j/issues/549">#549</a>
documentations</li>
<li><a
href="https://github.com/bucket4j/bucket4j/commit/9b7f66a80f69b48dd2b7cc79699d651eb5eaba20"><code>9b7f66a</code></a>
Changes according to the OSSRH Sunset <a
href="https://central.sonatype.org/pages/ossr">https://central.sonatype.org/pages/ossr</a>...</li>
<li><a
href="https://github.com/bucket4j/bucket4j/commit/a9dae860eae3298cdd223cb06ede4669222463b5"><code>a9dae86</code></a>
<a
href="https://redirect.github.com/bucket4j/bucket4j/issues/549">#549</a>
do not insist on specific the mongo-driver versions</li>
<li><a
href="https://github.com/bucket4j/bucket4j/commit/4c4f1b9f7a0fd1987690ac728214bc06bc9332f1"><code>4c4f1b9</code></a>
<a
href="https://redirect.github.com/bucket4j/bucket4j/issues/549">#549</a>
add project names</li>
<li><a
href="https://github.com/bucket4j/bucket4j/commit/3e024b0fb0d5d7c0c9f7dbee948f64ac9bda69ed"><code>3e024b0</code></a>
<a
href="https://redirect.github.com/bucket4j/bucket4j/issues/549">#549</a>
add license</li>
<li><a
href="https://github.com/bucket4j/bucket4j/commit/70e9cf58f93d3641d91a4428bb5eb9c25c7a9d3b"><code>70e9cf5</code></a>
<a
href="https://redirect.github.com/bucket4j/bucket4j/issues/549">#549</a>
fix modular-name</li>
<li><a
href="https://github.com/bucket4j/bucket4j/commit/1cbc7e1f3e70de94ec1ff4d6deea7d5b1bf15ea4"><code>1cbc7e1</code></a>
<a
href="https://redirect.github.com/bucket4j/bucket4j/issues/549">#549</a>
fix maven configuration</li>
<li>Additional commits viewable in <a
href="https://github.com/bucket4j/bucket4j/compare/8.14.0...8.15.0">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=com.bucket4j:bucket4j_jdk17-core&package-manager=gradle&previous-version=8.14.0&new-version=8.15.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-04 12:29:40 +01:00
dependabot[bot] 8a4acd4c98 build(deps): bump org.sonarqube from 6.2.0.5505 to 6.3.1.5724 (#4352)
Bumps org.sonarqube from 6.2.0.5505 to 6.3.1.5724.


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=org.sonarqube&package-manager=gradle&previous-version=6.2.0.5505&new-version=6.3.1.5724)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-04 12:29:30 +01:00
dependabot[bot] f93d8511e8 build(deps): bump actions/dependency-review-action from 4.7.2 to 4.7.3 (#4353)
[//]: # (dependabot-start)
⚠️  **Dependabot is rebasing this PR** ⚠️ 

Rebasing might not happen immediately, so don't worry if this takes some
time.

Note: if you make any changes to this PR yourself, they will take
precedence over the rebase.

---

[//]: # (dependabot-end)

Bumps
[actions/dependency-review-action](https://github.com/actions/dependency-review-action)
from 4.7.2 to 4.7.3.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/actions/dependency-review-action/releases">actions/dependency-review-action's
releases</a>.</em></p>
<blockquote>
<h2>4.7.3</h2>
<h2>What's Changed</h2>
<ul>
<li>Add explicit permissions to workflow files by <a
href="https://github.com/AshelyTC"><code>@​AshelyTC</code></a> in <a
href="https://redirect.github.com/actions/dependency-review-action/pull/966">actions/dependency-review-action#966</a></li>
<li>Claire153/fix spamming mentioned issue by <a
href="https://github.com/claire153"><code>@​claire153</code></a> in <a
href="https://redirect.github.com/actions/dependency-review-action/pull/974">actions/dependency-review-action#974</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/dependency-review-action/compare/v4...v4.7.3">https://github.com/actions/dependency-review-action/compare/v4...v4.7.3</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/actions/dependency-review-action/commit/595b5aeba73380359d98a5e087f648dbb0edce1b"><code>595b5ae</code></a>
Update package version (<a
href="https://redirect.github.com/actions/dependency-review-action/issues/975">#975</a>)</li>
<li><a
href="https://github.com/actions/dependency-review-action/commit/fc5fd661aa443a25c657922b187812d85d3c6fa7"><code>fc5fd66</code></a>
Claire153/fix spamming mentioned issue (<a
href="https://redirect.github.com/actions/dependency-review-action/issues/974">#974</a>)</li>
<li><a
href="https://github.com/actions/dependency-review-action/commit/d38d1a4f40f1e9fd802865455d695d0ae924edee"><code>d38d1a4</code></a>
Merge pull request <a
href="https://redirect.github.com/actions/dependency-review-action/issues/965">#965</a>
from actions/dependabot/npm_and_yarn/multi-c22e25d29b</li>
<li><a
href="https://github.com/actions/dependency-review-action/commit/8d420b827cac87791e1303cb1b01d3447e0bb8df"><code>8d420b8</code></a>
Merge branch 'main' into dependabot/npm_and_yarn/multi-c22e25d29b</li>
<li><a
href="https://github.com/actions/dependency-review-action/commit/bde01290d367cf6ae7232580700fcca870e35a80"><code>bde0129</code></a>
Merge pull request <a
href="https://redirect.github.com/actions/dependency-review-action/issues/966">#966</a>
from actions/ashelytc/add-permissions</li>
<li><a
href="https://github.com/actions/dependency-review-action/commit/ab524903e88a228b6df0ab1dc878a34aebc28b70"><code>ab52490</code></a>
remove ruby</li>
<li><a
href="https://github.com/actions/dependency-review-action/commit/ef00a0afbb540db022eb79fc3aea57b5603d7a47"><code>ef00a0a</code></a>
add permissions to workflows</li>
<li><a
href="https://github.com/actions/dependency-review-action/commit/74c8179d39388ccd6863b1a230d2cd3e1d0de71d"><code>74c8179</code></a>
Bump brace-expansion</li>
<li>See full diff in <a
href="https://github.com/actions/dependency-review-action/compare/bc41886e18ea39df68b1b1245f4184881938e050...595b5aeba73380359d98a5e087f648dbb0edce1b">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/dependency-review-action&package-manager=github_actions&previous-version=4.7.2&new-version=4.7.3)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-04 12:28:46 +01:00
dependabot[bot] 54c7b0e689 build(deps): bump actions/setup-java from 4.7.1 to 5.0.0 (#4269)
Bumps [actions/setup-java](https://github.com/actions/setup-java) from
4.7.1 to 5.0.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/actions/setup-java/releases">actions/setup-java's
releases</a>.</em></p>
<blockquote>
<h2>v5.0.0</h2>
<h2>What's Changed</h2>
<h3>Breaking Changes</h3>
<ul>
<li>Upgrade to node 24 by <a
href="https://github.com/salmanmkc"><code>@​salmanmkc</code></a> in <a
href="https://redirect.github.com/actions/setup-java/pull/888">actions/setup-java#888</a></li>
</ul>
<p>Make sure your runner is updated to this version or newer to use this
release. v2.327.1 <a
href="https://github.com/actions/runner/releases/tag/v2.327.1">Release
Notes</a></p>
<h3>Dependency Upgrades</h3>
<ul>
<li>Upgrade Publish Immutable Action by <a
href="https://github.com/HarithaVattikuti"><code>@​HarithaVattikuti</code></a>
in <a
href="https://redirect.github.com/actions/setup-java/pull/798">actions/setup-java#798</a></li>
<li>Upgrade eslint-plugin-jest from 27.9.0 to 28.11.0 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/actions/setup-java/pull/730">actions/setup-java#730</a></li>
<li>Upgrade undici from 5.28.5 to 5.29.0 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/actions/setup-java/pull/833">actions/setup-java#833</a></li>
<li>Upgrade form-data to bring in fix for critical vulnerability by <a
href="https://github.com/gowridurgad"><code>@​gowridurgad</code></a> in
<a
href="https://redirect.github.com/actions/setup-java/pull/887">actions/setup-java#887</a></li>
<li>Upgrade actions/checkout from 4 to 5 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/actions/setup-java/pull/896">actions/setup-java#896</a></li>
</ul>
<h3>Bug Fixes</h3>
<ul>
<li>Prevent default installation of JetBrains pre-releases by <a
href="https://github.com/priyagupta108"><code>@​priyagupta108</code></a>
in <a
href="https://redirect.github.com/actions/setup-java/pull/859">actions/setup-java#859</a></li>
<li>Improve Error Handling for Setup-Java Action to Help Debug
Intermittent Failures by <a
href="https://github.com/gowridurgad"><code>@​gowridurgad</code></a> in
<a
href="https://redirect.github.com/actions/setup-java/pull/848">actions/setup-java#848</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a
href="https://github.com/gowridurgad"><code>@​gowridurgad</code></a>
made their first contribution in <a
href="https://redirect.github.com/actions/setup-java/pull/848">actions/setup-java#848</a></li>
<li><a href="https://github.com/salmanmkc"><code>@​salmanmkc</code></a>
made their first contribution in <a
href="https://redirect.github.com/actions/setup-java/pull/888">actions/setup-java#888</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/setup-java/compare/v4...v5.0.0">https://github.com/actions/setup-java/compare/v4...v5.0.0</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/actions/setup-java/commit/dded0888837ed1f317902acf8a20df0ad188d165"><code>dded088</code></a>
Bump actions/checkout from 4 to 5 (<a
href="https://redirect.github.com/actions/setup-java/issues/896">#896</a>)</li>
<li><a
href="https://github.com/actions/setup-java/commit/0913e9a06eb8b69c62db76aa61f580c2b3a5b4e0"><code>0913e9a</code></a>
Upgrade to node 24 (<a
href="https://redirect.github.com/actions/setup-java/issues/888">#888</a>)</li>
<li><a
href="https://github.com/actions/setup-java/commit/e9343db97e09d87a3c50e544105d99fe912c204b"><code>e9343db</code></a>
Bumps form-data (<a
href="https://redirect.github.com/actions/setup-java/issues/887">#887</a>)</li>
<li><a
href="https://github.com/actions/setup-java/commit/ae2b61dbc685e60e4427b2e8ed4f0135c6ea8597"><code>ae2b61d</code></a>
Bump undici from 5.28.5 to 5.29.0 (<a
href="https://redirect.github.com/actions/setup-java/issues/833">#833</a>)</li>
<li><a
href="https://github.com/actions/setup-java/commit/c190c18febcf6c040d80b10ea201a05a2c320263"><code>c190c18</code></a>
Bump eslint-plugin-jest from 27.9.0 to 29.0.1 (<a
href="https://redirect.github.com/actions/setup-java/issues/730">#730</a>)</li>
<li><a
href="https://github.com/actions/setup-java/commit/67aec007b3fcabe15ca665bfccc1e255dd52e30d"><code>67aec00</code></a>
Fix: prevent default installation of JetBrains pre-releases (<a
href="https://redirect.github.com/actions/setup-java/issues/859">#859</a>)</li>
<li><a
href="https://github.com/actions/setup-java/commit/ebb356cc4e59bcf94f518203228485f5d40e4b58"><code>ebb356c</code></a>
Improve Error Handling for Setup-Java Action to Help Debug Intermittent
Failu...</li>
<li><a
href="https://github.com/actions/setup-java/commit/f4f1212c880fdec8162ea9a6493f4495191887b4"><code>f4f1212</code></a>
Update publish-immutable-actions.yml (<a
href="https://redirect.github.com/actions/setup-java/issues/798">#798</a>)</li>
<li>See full diff in <a
href="https://github.com/actions/setup-java/compare/c5195efecf7bdfc987ee8bae7a71cb8b11521c00...dded0888837ed1f317902acf8a20df0ad188d165">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/setup-java&package-manager=github_actions&previous-version=4.7.1&new-version=5.0.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-04 12:28:22 +01:00
dependabot[bot] 58ca41e5c5 build(deps): bump actions/checkout from 4.3.0 to 5.0.0 (#4194)
Bumps [actions/checkout](https://github.com/actions/checkout) from 4.3.0
to 5.0.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/actions/checkout/releases">actions/checkout's
releases</a>.</em></p>
<blockquote>
<h2>v5.0.0</h2>
<h2>What's Changed</h2>
<ul>
<li>Update actions checkout to use node 24 by <a
href="https://github.com/salmanmkc"><code>@​salmanmkc</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2226">actions/checkout#2226</a></li>
<li>Prepare v5.0.0 release by <a
href="https://github.com/salmanmkc"><code>@​salmanmkc</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2238">actions/checkout#2238</a></li>
</ul>
<h2>⚠️ Minimum Compatible Runner Version</h2>
<p><strong>v2.327.1</strong><br />
<a
href="https://github.com/actions/runner/releases/tag/v2.327.1">Release
Notes</a></p>
<p>Make sure your runner is updated to this version or newer to use this
release.</p>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/checkout/compare/v4...v5.0.0">https://github.com/actions/checkout/compare/v4...v5.0.0</a></p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/actions/checkout/blob/main/CHANGELOG.md">actions/checkout's
changelog</a>.</em></p>
<blockquote>
<h1>Changelog</h1>
<h2>V5.0.0</h2>
<ul>
<li>Update actions checkout to use node 24 by <a
href="https://github.com/salmanmkc"><code>@​salmanmkc</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2226">actions/checkout#2226</a></li>
</ul>
<h2>V4.3.0</h2>
<ul>
<li>docs: update README.md by <a
href="https://github.com/motss"><code>@​motss</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1971">actions/checkout#1971</a></li>
<li>Add internal repos for checking out multiple repositories by <a
href="https://github.com/mouismail"><code>@​mouismail</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1977">actions/checkout#1977</a></li>
<li>Documentation update - add recommended permissions to Readme by <a
href="https://github.com/benwells"><code>@​benwells</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2043">actions/checkout#2043</a></li>
<li>Adjust positioning of user email note and permissions heading by <a
href="https://github.com/joshmgross"><code>@​joshmgross</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2044">actions/checkout#2044</a></li>
<li>Update README.md by <a
href="https://github.com/nebuk89"><code>@​nebuk89</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2194">actions/checkout#2194</a></li>
<li>Update CODEOWNERS for actions by <a
href="https://github.com/TingluoHuang"><code>@​TingluoHuang</code></a>
in <a
href="https://redirect.github.com/actions/checkout/pull/2224">actions/checkout#2224</a></li>
<li>Update package dependencies by <a
href="https://github.com/salmanmkc"><code>@​salmanmkc</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2236">actions/checkout#2236</a></li>
</ul>
<h2>v4.2.2</h2>
<ul>
<li><code>url-helper.ts</code> now leverages well-known environment
variables by <a href="https://github.com/jww3"><code>@​jww3</code></a>
in <a
href="https://redirect.github.com/actions/checkout/pull/1941">actions/checkout#1941</a></li>
<li>Expand unit test coverage for <code>isGhes</code> by <a
href="https://github.com/jww3"><code>@​jww3</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1946">actions/checkout#1946</a></li>
</ul>
<h2>v4.2.1</h2>
<ul>
<li>Check out other refs/* by commit if provided, fall back to ref by <a
href="https://github.com/orhantoy"><code>@​orhantoy</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1924">actions/checkout#1924</a></li>
</ul>
<h2>v4.2.0</h2>
<ul>
<li>Add Ref and Commit outputs by <a
href="https://github.com/lucacome"><code>@​lucacome</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1180">actions/checkout#1180</a></li>
<li>Dependency updates by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>- <a
href="https://redirect.github.com/actions/checkout/pull/1777">actions/checkout#1777</a>,
<a
href="https://redirect.github.com/actions/checkout/pull/1872">actions/checkout#1872</a></li>
</ul>
<h2>v4.1.7</h2>
<ul>
<li>Bump the minor-npm-dependencies group across 1 directory with 4
updates by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1739">actions/checkout#1739</a></li>
<li>Bump actions/checkout from 3 to 4 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1697">actions/checkout#1697</a></li>
<li>Check out other refs/* by commit by <a
href="https://github.com/orhantoy"><code>@​orhantoy</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1774">actions/checkout#1774</a></li>
<li>Pin actions/checkout's own workflows to a known, good, stable
version. by <a href="https://github.com/jww3"><code>@​jww3</code></a> in
<a
href="https://redirect.github.com/actions/checkout/pull/1776">actions/checkout#1776</a></li>
</ul>
<h2>v4.1.6</h2>
<ul>
<li>Check platform to set archive extension appropriately by <a
href="https://github.com/cory-miller"><code>@​cory-miller</code></a> in
<a
href="https://redirect.github.com/actions/checkout/pull/1732">actions/checkout#1732</a></li>
</ul>
<h2>v4.1.5</h2>
<ul>
<li>Update NPM dependencies by <a
href="https://github.com/cory-miller"><code>@​cory-miller</code></a> in
<a
href="https://redirect.github.com/actions/checkout/pull/1703">actions/checkout#1703</a></li>
<li>Bump github/codeql-action from 2 to 3 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1694">actions/checkout#1694</a></li>
<li>Bump actions/setup-node from 1 to 4 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1696">actions/checkout#1696</a></li>
<li>Bump actions/upload-artifact from 2 to 4 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1695">actions/checkout#1695</a></li>
<li>README: Suggest <code>user.email</code> to be
<code>41898282+github-actions[bot]@users.noreply.github.com</code> by <a
href="https://github.com/cory-miller"><code>@​cory-miller</code></a> in
<a
href="https://redirect.github.com/actions/checkout/pull/1707">actions/checkout#1707</a></li>
</ul>
<h2>v4.1.4</h2>
<ul>
<li>Disable <code>extensions.worktreeConfig</code> when disabling
<code>sparse-checkout</code> by <a
href="https://github.com/jww3"><code>@​jww3</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1692">actions/checkout#1692</a></li>
<li>Add dependabot config by <a
href="https://github.com/cory-miller"><code>@​cory-miller</code></a> in
<a
href="https://redirect.github.com/actions/checkout/pull/1688">actions/checkout#1688</a></li>
<li>Bump the minor-actions-dependencies group with 2 updates by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1693">actions/checkout#1693</a></li>
<li>Bump word-wrap from 1.2.3 to 1.2.5 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1643">actions/checkout#1643</a></li>
</ul>
<h2>v4.1.3</h2>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/actions/checkout/commit/08c6903cd8c0fde910a37f88322edcfb5dd907a8"><code>08c6903</code></a>
Prepare v5.0.0 release (<a
href="https://redirect.github.com/actions/checkout/issues/2238">#2238</a>)</li>
<li><a
href="https://github.com/actions/checkout/commit/9f265659d3bb64ab1440b03b12f4d47a24320917"><code>9f26565</code></a>
Update actions checkout to use node 24 (<a
href="https://redirect.github.com/actions/checkout/issues/2226">#2226</a>)</li>
<li>See full diff in <a
href="https://github.com/actions/checkout/compare/08eba0b27e820071cde6df949e0beb9ba4906955...08c6903cd8c0fde910a37f88322edcfb5dd907a8">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/checkout&package-manager=github_actions&previous-version=4.3.0&new-version=5.0.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-04 12:27:59 +01:00
Anthony Stirling bf90f4b1da feat: add annotation option to PDF to image (#4365)
## Summary
- add optional flag to include PDF annotations when converting to images
- expose annotation option via API model and UI checkbox
- add translation for annotation option

## Testing
- `./gradlew spotlessApply`
- `./gradlew build`


------
https://chatgpt.com/codex/tasks/task_b_68b7fa1d5a1c83288342244a0ec85e9d
2025-09-04 12:21:29 +01:00
dependabot[bot] 7e276e8406 build(deps): bump github/codeql-action from 3.29.11 to 3.30.0 (#4355)
Bumps [github/codeql-action](https://github.com/github/codeql-action)
from 3.29.11 to 3.30.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/github/codeql-action/releases">github/codeql-action's
releases</a>.</em></p>
<blockquote>
<h2>v3.30.0</h2>
<h1>CodeQL Action Changelog</h1>
<p>See the <a
href="https://github.com/github/codeql-action/releases">releases
page</a> for the relevant changes to the CodeQL CLI and language
packs.</p>
<h2>3.30.0 - 01 Sep 2025</h2>
<p>No user facing changes.</p>
<p>See the full <a
href="https://github.com/github/codeql-action/blob/v3.30.0/CHANGELOG.md">CHANGELOG.md</a>
for more information.</p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/github/codeql-action/blob/main/CHANGELOG.md">github/codeql-action's
changelog</a>.</em></p>
<blockquote>
<h1>CodeQL Action Changelog</h1>
<p>See the <a
href="https://github.com/github/codeql-action/releases">releases
page</a> for the relevant changes to the CodeQL CLI and language
packs.</p>
<h2>[UNRELEASED]</h2>
<p>No user facing changes.</p>
<h2>3.30.0 - 01 Sep 2025</h2>
<p>No user facing changes.</p>
<h2>3.29.11 - 21 Aug 2025</h2>
<ul>
<li>Update default CodeQL bundle version to 2.22.4. <a
href="https://redirect.github.com/github/codeql-action/pull/3044">#3044</a></li>
</ul>
<h2>3.29.10 - 18 Aug 2025</h2>
<p>No user facing changes.</p>
<h2>3.29.9 - 12 Aug 2025</h2>
<p>No user facing changes.</p>
<h2>3.29.8 - 08 Aug 2025</h2>
<ul>
<li>Fix an issue where the Action would autodetect unsupported languages
such as HTML. <a
href="https://redirect.github.com/github/codeql-action/pull/3015">#3015</a></li>
</ul>
<h2>3.29.7 - 07 Aug 2025</h2>
<p>This release rolls back 3.29.6 to address issues with language
autodetection. It is identical to 3.29.5.</p>
<h2>3.29.6 - 07 Aug 2025</h2>
<ul>
<li>The <code>cleanup-level</code> input to the <code>analyze</code>
Action is now deprecated. The CodeQL Action has written a limited amount
of intermediate results to the database since version 2.2.5, and now
automatically manages cleanup. <a
href="https://redirect.github.com/github/codeql-action/pull/2999">#2999</a></li>
<li>Update default CodeQL bundle version to 2.22.3. <a
href="https://redirect.github.com/github/codeql-action/pull/3000">#3000</a></li>
</ul>
<h2>3.29.5 - 29 Jul 2025</h2>
<ul>
<li>Update default CodeQL bundle version to 2.22.2. <a
href="https://redirect.github.com/github/codeql-action/pull/2986">#2986</a></li>
</ul>
<h2>3.29.4 - 23 Jul 2025</h2>
<p>No user facing changes.</p>
<h2>3.29.3 - 21 Jul 2025</h2>
<p>No user facing changes.</p>
<h2>3.29.2 - 30 Jun 2025</h2>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/github/codeql-action/commit/2d92b76c45b91eb80fc44c74ce3fce0ee94e8f9d"><code>2d92b76</code></a>
Merge pull request <a
href="https://redirect.github.com/github/codeql-action/issues/3067">#3067</a>
from github/update-v3.30.0-92eada825</li>
<li><a
href="https://github.com/github/codeql-action/commit/390daafd7d971cca449e6aa45656ac85ca1d29fd"><code>390daaf</code></a>
Update changelog for v3.30.0</li>
<li><a
href="https://github.com/github/codeql-action/commit/92eada825a77b70d62c71adc29a0a9fe75c21bf5"><code>92eada8</code></a>
Merge pull request <a
href="https://redirect.github.com/github/codeql-action/issues/3033">#3033</a>
from github/mbg/ci/rollback-release</li>
<li><a
href="https://github.com/github/codeql-action/commit/872a6a41e95ca66b6ce89dac89c1fbb97b171c89"><code>872a6a4</code></a>
Add <code>pull-requests: write</code> permission</li>
<li><a
href="https://github.com/github/codeql-action/commit/9389ce0cc4cf11345ec3a2a7a61fc790feb44165"><code>9389ce0</code></a>
Merge remote-tracking branch 'origin/main' into
mbg/ci/rollback-release</li>
<li><a
href="https://github.com/github/codeql-action/commit/02ab253bd299d261d00cdf8a9bca38fea2697d50"><code>02ab253</code></a>
Merge pull request <a
href="https://redirect.github.com/github/codeql-action/issues/3054">#3054</a>
from github/henrymercer/bundle</li>
<li><a
href="https://github.com/github/codeql-action/commit/b06d32585026d970f28d3f3604a67ddf4c314f9e"><code>b06d325</code></a>
Add draft release URL to job summary</li>
<li><a
href="https://github.com/github/codeql-action/commit/43d629cdfd9a8e4ac201aeb0d9330b2eaf0f8699"><code>43d629c</code></a>
Use <code>argparse</code> in <code>rollback_changelog.py</code></li>
<li><a
href="https://github.com/github/codeql-action/commit/8f01f5d4296c6c45c71748648c333daa34454bb2"><code>8f01f5d</code></a>
Apply suggestions from code review</li>
<li><a
href="https://github.com/github/codeql-action/commit/3e493e72f755ad15a0ff97b25da2e232b3cb4f3f"><code>3e493e7</code></a>
Remove <code>removeNPMAbsolutePaths</code></li>
<li>Additional commits viewable in <a
href="https://github.com/github/codeql-action/compare/3c3833e0f8c1c83d449a7478aa59c036a9165498...2d92b76c45b91eb80fc44c74ce3fce0ee94e8f9d">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=github/codeql-action&package-manager=github_actions&previous-version=3.29.11&new-version=3.30.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-04 12:04:22 +01:00
dependabot[bot] 18e2078b8b build(deps): bump org.springdoc:springdoc-openapi-starter-webmvc-ui from 2.8.11 to 2.8.12 (#4356)
Bumps
[org.springdoc:springdoc-openapi-starter-webmvc-ui](https://github.com/springdoc/springdoc-openapi)
from 2.8.11 to 2.8.12.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/springdoc/springdoc-openapi/releases">org.springdoc:springdoc-openapi-starter-webmvc-ui's
releases</a>.</em></p>
<blockquote>
<h2>springdoc-openapi v2.8.12 released!</h2>
<h3>Changed</h3>
<ul>
<li>Upgrade swagger-ui to v5.28.0</li>
<li>Upgrade commons-lang3 to v3.18.0</li>
</ul>
<h3>Fixed</h3>
<ul>
<li><a
href="https://redirect.github.com/springdoc/springdoc-openapi/issues/3073">#3073</a>
- Duplicate key class Parameter when documenting two GET methods with
same path and PathVariable.</li>
<li><a
href="https://redirect.github.com/springdoc/springdoc-openapi/issues/3071">#3071</a>
- <a
href="https://github.com/io"><code>@​io</code></a>.swagger.v3.oas.annotations.parameters.RequestBody
does not work well with <a
href="https://github.com/RequestPart"><code>@​RequestPart</code></a></li>
<li><a
href="https://redirect.github.com/springdoc/springdoc-openapi/issues/3066">#3066</a>
- Parameter is now required after upgrading to springdoc-openapi
2.8.10</li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/springdoc/springdoc-openapi/compare/v2.8.11...v2.8.12">https://github.com/springdoc/springdoc-openapi/compare/v2.8.11...v2.8.12</a></p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/springdoc/springdoc-openapi/blob/main/CHANGELOG.md">org.springdoc:springdoc-openapi-starter-webmvc-ui's
changelog</a>.</em></p>
<blockquote>
<h2>[2.8.12] - 2025-09-01</h2>
<h3>Changed</h3>
<ul>
<li>Upgrade swagger-ui to v5.28.0</li>
<li>Upgrade commons-lang3 to v3.18.0</li>
</ul>
<h3>Fixed</h3>
<ul>
<li><a
href="https://redirect.github.com/springdoc/springdoc-openapi/issues/3073">#3073</a>
- Duplicate key class Parameter when documenting two GET methods with
same path and PathVariable.</li>
<li><a
href="https://redirect.github.com/springdoc/springdoc-openapi/issues/3071">#3071</a>
- <a
href="https://github.com/io"><code>@​io</code></a>.swagger.v3.oas.annotations.parameters.RequestBody
does not work well with <a
href="https://github.com/RequestPart"><code>@​RequestPart</code></a></li>
<li><a
href="https://redirect.github.com/springdoc/springdoc-openapi/issues/3066">#3066</a>
- Parameter is now required after upgrading to springdoc-openapi
2.8.10</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/springdoc/springdoc-openapi/commit/493cc68492922bbbc3d123bace668d1402be93b5"><code>493cc68</code></a>
[maven-release-plugin] prepare release v2.8.12</li>
<li><a
href="https://github.com/springdoc/springdoc-openapi/commit/8ef9eb819961a2effaaaa4358e911b9317372033"><code>8ef9eb8</code></a>
CHANGELOG.md update</li>
<li><a
href="https://github.com/springdoc/springdoc-openapi/commit/bc4ba682eb106596580a5d994ecea95c0c605769"><code>bc4ba68</code></a>
upgrade commons-lang3 to v3.18.0</li>
<li><a
href="https://github.com/springdoc/springdoc-openapi/commit/8741823941a6ec61f65024c3acd7a03fb5d8cd0d"><code>8741823</code></a>
upgrade swagger-ui to v5.28.0</li>
<li><a
href="https://github.com/springdoc/springdoc-openapi/commit/8d85e0e445afc4109e32a697c025ae44ffded884"><code>8d85e0e</code></a>
Duplicate key class Parameter when documenting two GET methods with same
path...</li>
<li><a
href="https://github.com/springdoc/springdoc-openapi/commit/4d505d62ddb39496243db7c8fd94e513e1baa11e"><code>4d505d6</code></a>
<a
href="https://github.com/io"><code>@​io</code></a>.swagger.v3.oas.annotations.parameters.RequestBody
does not work well with...</li>
<li><a
href="https://github.com/springdoc/springdoc-openapi/commit/3190ae2c7fc8320ad9e708e655e53c0bd7cfc754"><code>3190ae2</code></a>
Parameter is now required after upgrading to springdoc-openapi 2.8.10.
Fixes ...</li>
<li><a
href="https://github.com/springdoc/springdoc-openapi/commit/74dcd4f8459e824c687ef450b8be7656c008cd20"><code>74dcd4f</code></a>
[maven-release-plugin] prepare for next development iteration</li>
<li>See full diff in <a
href="https://github.com/springdoc/springdoc-openapi/compare/v2.8.11...v2.8.12">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=org.springdoc:springdoc-openapi-starter-webmvc-ui&package-manager=gradle&previous-version=2.8.11&new-version=2.8.12)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-04 12:03:59 +01:00
Adityarup LahaandAnthony Stirling 4b6ac87419 PdfContainer: zero-pad numeric suffix in nameAndArchiveFiles (#4265)
# Description of Changes

Zero pad the numeric suffix in `PdfContainer.nameAndArchiveFiles` to
close #4263.

---

## 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/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)
- [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/devGuide/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/devGuide/DeveloperGuide.md#6-testing)
for more details.

Co-authored-by: Anthony Stirling <77850077+Frooodle@users.noreply.github.com>
2025-08-28 19:48:06 +00:00
dependabot[bot]andDario Ghunney Ware 1d527db305 build(deps): bump jwtVersion from 0.12.7 to 0.13.0 (#4270)
Bumps `jwtVersion` from 0.12.7 to 0.13.0.
Updates `io.jsonwebtoken:jjwt-api` from 0.12.7 to 0.13.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/jwtk/jjwt/releases">io.jsonwebtoken:jjwt-api's
releases</a>.</em></p>
<blockquote>
<h2>0.13.0</h2>
<p><strong>This is the last minor JJWT release branch that will support
Java 7</strong>.</p>
<p>Any necessary emergency bug fixes will be fixed in subsequent
<code>0.13.x</code> patch releases, but all new development, including
<a
href="https://github.com/jwtk/jjwt/issues?q=is%3Aissue%20label%3Ajdk8">Java
8 compatible changes</a>, will be in the next minor
(<code>0.14.0</code>) release.</p>
<p><strong>All future JJWT major and minor versions (
<code>0.14.0</code> and later) will require Java 8 or
later.</strong></p>
<h2>What's Changed</h2>
<p>This release contains a single change:</p>
<ul>
<li>The previously private <code>JacksonDeserializer(ObjectMapper
objectMapper, Map&lt;String, Class&lt;?&gt;&gt; claimTypeMap)</code>
constructor is now <code>public</code> for those that want register a
claims type converter on their own specified <code>ObjectMapper</code>
instance. Thank you to <a
href="https://github.com/kesrishubham2510"><code>@​kesrishubham2510</code></a>
for PR <a
href="https://redirect.github.com/jwtk/jjwt/issues/972">#972</a>. See <a
href="https://redirect.github.com/jwtk/jjwt/issues/914">Issue
914</a>.</li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/jwtk/jjwt/compare/0.12.7...0.13.0">https://github.com/jwtk/jjwt/compare/0.12.7...0.13.0</a></p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/jwtk/jjwt/blob/master/CHANGELOG.md">io.jsonwebtoken:jjwt-api's
changelog</a>.</em></p>
<blockquote>
<h3>0.13.0</h3>
<p>This is the last minor JJWT release branch that will support Java 7.
Any necessary emergency bug fixes will be fixed in subsequent
<code>0.13.x</code> patch releases, but all new development, including
Java 8 compatible changes, will be in the next minor
(<code>0.14.0</code>) release.</p>
<p><strong>All future JJWT major and minor versions (
<code>0.14.0</code> and later) will require Java 8 or
later.</strong></p>
<p>This <code>0.13.0</code> minor release has only one change:</p>
<ul>
<li>The previously private <code>JacksonDeserializer(ObjectMapper
objectMapper, Map&lt;String, Class&lt;?&gt;&gt; claimTypeMap)</code>
constructor is now <code>public</code> for those that want register a
claims
type converter on their own specified <code>ObjectMapper</code>
instance. See <a
href="https://redirect.github.com/jwtk/jjwt/issues/914">Issue
914</a>.</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/jwtk/jjwt/commit/a757addce04f6b6d8086beeee8dafcf670550a5b"><code>a757add</code></a>
[maven-release-plugin] prepare release 0.13.0</li>
<li><a
href="https://github.com/jwtk/jjwt/commit/e357463c59cf62c1f70503ac0102d10efcdfc37d"><code>e357463</code></a>
Preparing for the 0.13.0 release.</li>
<li><a
href="https://github.com/jwtk/jjwt/commit/b6f8cb82a9c2e9817d842bfe72d2c8fb03124342"><code>b6f8cb8</code></a>
Made constructor public to allow users their own objectMapper instance
(<a
href="https://redirect.github.com/jwtk/jjwt/issues/972">#972</a>)</li>
<li><a
href="https://github.com/jwtk/jjwt/commit/03f088a4eb774bae2403c428aa885a12d3afde14"><code>03f088a</code></a>
Bumping development version to 0.13.0-SNAPSHOT (<a
href="https://redirect.github.com/jwtk/jjwt/issues/1014">#1014</a>)</li>
<li><a
href="https://github.com/jwtk/jjwt/commit/3f2697f854bedebe63e9eddb8c596f76086d11ca"><code>3f2697f</code></a>
Release 0.12.7 (<a
href="https://redirect.github.com/jwtk/jjwt/issues/1012">#1012</a>)</li>
<li><a
href="https://github.com/jwtk/jjwt/commit/a0a123e848fc25a7920bcbd84615f639c4cc098a"><code>a0a123e</code></a>
PR <a
href="https://redirect.github.com/jwtk/jjwt/issues/917">#917</a></li>
<li>See full diff in <a
href="https://github.com/jwtk/jjwt/compare/0.12.7...0.13.0">compare
view</a></li>
</ul>
</details>
<br />

Updates `io.jsonwebtoken:jjwt-impl` from 0.12.7 to 0.13.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/jwtk/jjwt/releases">io.jsonwebtoken:jjwt-impl's
releases</a>.</em></p>
<blockquote>
<h2>0.13.0</h2>
<p><strong>This is the last minor JJWT release branch that will support
Java 7</strong>.</p>
<p>Any necessary emergency bug fixes will be fixed in subsequent
<code>0.13.x</code> patch releases, but all new development, including
<a
href="https://github.com/jwtk/jjwt/issues?q=is%3Aissue%20label%3Ajdk8">Java
8 compatible changes</a>, will be in the next minor
(<code>0.14.0</code>) release.</p>
<p><strong>All future JJWT major and minor versions (
<code>0.14.0</code> and later) will require Java 8 or
later.</strong></p>
<h2>What's Changed</h2>
<p>This release contains a single change:</p>
<ul>
<li>The previously private <code>JacksonDeserializer(ObjectMapper
objectMapper, Map&lt;String, Class&lt;?&gt;&gt; claimTypeMap)</code>
constructor is now <code>public</code> for those that want register a
claims type converter on their own specified <code>ObjectMapper</code>
instance. Thank you to <a
href="https://github.com/kesrishubham2510"><code>@​kesrishubham2510</code></a>
for PR <a
href="https://redirect.github.com/jwtk/jjwt/issues/972">#972</a>. See <a
href="https://redirect.github.com/jwtk/jjwt/issues/914">Issue
914</a>.</li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/jwtk/jjwt/compare/0.12.7...0.13.0">https://github.com/jwtk/jjwt/compare/0.12.7...0.13.0</a></p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/jwtk/jjwt/blob/master/CHANGELOG.md">io.jsonwebtoken:jjwt-impl's
changelog</a>.</em></p>
<blockquote>
<h3>0.13.0</h3>
<p>This is the last minor JJWT release branch that will support Java 7.
Any necessary emergency bug fixes will be fixed in subsequent
<code>0.13.x</code> patch releases, but all new development, including
Java 8 compatible changes, will be in the next minor
(<code>0.14.0</code>) release.</p>
<p><strong>All future JJWT major and minor versions (
<code>0.14.0</code> and later) will require Java 8 or
later.</strong></p>
<p>This <code>0.13.0</code> minor release has only one change:</p>
<ul>
<li>The previously private <code>JacksonDeserializer(ObjectMapper
objectMapper, Map&lt;String, Class&lt;?&gt;&gt; claimTypeMap)</code>
constructor is now <code>public</code> for those that want register a
claims
type converter on their own specified <code>ObjectMapper</code>
instance. See <a
href="https://redirect.github.com/jwtk/jjwt/issues/914">Issue
914</a>.</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/jwtk/jjwt/commit/a757addce04f6b6d8086beeee8dafcf670550a5b"><code>a757add</code></a>
[maven-release-plugin] prepare release 0.13.0</li>
<li><a
href="https://github.com/jwtk/jjwt/commit/e357463c59cf62c1f70503ac0102d10efcdfc37d"><code>e357463</code></a>
Preparing for the 0.13.0 release.</li>
<li><a
href="https://github.com/jwtk/jjwt/commit/b6f8cb82a9c2e9817d842bfe72d2c8fb03124342"><code>b6f8cb8</code></a>
Made constructor public to allow users their own objectMapper instance
(<a
href="https://redirect.github.com/jwtk/jjwt/issues/972">#972</a>)</li>
<li><a
href="https://github.com/jwtk/jjwt/commit/03f088a4eb774bae2403c428aa885a12d3afde14"><code>03f088a</code></a>
Bumping development version to 0.13.0-SNAPSHOT (<a
href="https://redirect.github.com/jwtk/jjwt/issues/1014">#1014</a>)</li>
<li><a
href="https://github.com/jwtk/jjwt/commit/3f2697f854bedebe63e9eddb8c596f76086d11ca"><code>3f2697f</code></a>
Release 0.12.7 (<a
href="https://redirect.github.com/jwtk/jjwt/issues/1012">#1012</a>)</li>
<li><a
href="https://github.com/jwtk/jjwt/commit/a0a123e848fc25a7920bcbd84615f639c4cc098a"><code>a0a123e</code></a>
PR <a
href="https://redirect.github.com/jwtk/jjwt/issues/917">#917</a></li>
<li>See full diff in <a
href="https://github.com/jwtk/jjwt/compare/0.12.7...0.13.0">compare
view</a></li>
</ul>
</details>
<br />

Updates `io.jsonwebtoken:jjwt-jackson` from 0.12.7 to 0.13.0


Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Dario Ghunney Ware <dariogware@gmail.com>
2025-08-27 10:28:08 +00:00
LudyandCopilot 3af93f0adb feat(database,Jwt): relocate backups and Jwt-keys to config/backup and add Enterprise cleanup endpoints (#4225)
# Description of Changes

- **What was changed**
  - Centralized installation paths:
- Introduced `BACKUP_PATH`, `BACKUP_DB_PATH`, and
`BACKUP_PRIVATE_KEY_PATH` in `InstallationPathConfig`;
`getPrivateKeyPath()` now resolves to `backup/keys` and new
`getBackupPath()` returns `backup/db`.
- Removed old `PRIVATE_KEY_PATH` and switched all usages to the new
locations.
  - Database service enhancements:
- `DatabaseService` now uses `InstallationPathConfig.getBackupPath()`
and includes a one-time migration to move existing backups from
`config/db/backup` to `config/backup/db` (**@Deprecated(since = "2.0.0",
forRemoval = true)**).
- Added `deleteAllBackups()` and `deleteLastBackup()` methods and
exposed them via a new Enterprise controller.
  - New Enterprise-only API:
    - Added `DatabaseControllerEnterprise` with:
      - `DELETE /api/v1/database/deleteAll` — delete all backup files.
- `DELETE /api/v1/database/deleteLast` — delete the most recent backup.
- Endpoints gated by `@EnterpriseEndpoint` and
`@Conditional(H2SQLCondition.class)`.
  - Key persistence adjustments:
- `KeyPersistenceService` now migrates keys from `config/db/keys` to
`config/backup/keys` on startup (**@Deprecated(since = "2.0.0",
forRemoval = true)**).
  - Miscellaneous refactors/fixes:
- Switched driver resolution in `DatabaseConfig` to a switch expression.
    - Corrected HTTP status usage to `HttpStatus.SEE_OTHER`.
- Removed constructor `runningEE` flag from `AccountWebController` and
replaced EE checks with `@EnterpriseEndpoint`.
- Minor test and annotation improvements (e.g., `@Deprecated(since =
"0.45.0")`, method references, equals order).
  
- **Why the change was made**
- To standardize and future-proof storage locations for both backups and
keys under a clear `config/backup` hierarchy.
- To give Enterprise admins first-class, safe cleanup endpoints for
managing backup retention without manual file operations.
- To reduce conditional logic in controllers and rely on declarative EE
gating.
- To improve maintainability and correctness (status codes, switch
expression, null-safety patterns).

---

## 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/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)
- [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/devGuide/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/devGuide/DeveloperGuide.md#6-testing)
for more details.

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-08-24 22:16:55 +01:00
LudyandCopilot 40cf337b23 feat(ssrf): enhance private IP detection and IPv6 handling (#4191)
# Description of Changes

- Refactored `isPrivateAddress` to improve detection of private and
local addresses for both IPv4 and IPv6.
- Added explicit handling for:
  - IPv4-mapped IPv6 addresses
  - IPv6 link-local, site-local, and unique local (fc00::/7) addresses
  - Additional IPv4 private ranges such as link-local (169.254.0.0/16)
- Introduced `normalizeIpv4MappedAddress` to standardize IP checks in
cloud metadata detection.
- Replaced `switch` statement with modern `switch` expression for
cleaner control flow.

These changes were made to strengthen SSRF protection by covering more
address edge cases, especially in mixed IPv4/IPv6 environments.
This also improves detection of cloud metadata endpoints when accessed
via IPv4-mapped IPv6 addresses.


---

## 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/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
- [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/devGuide/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/devGuide/DeveloperGuide.md#6-testing)
for more details.

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-08-24 22:08:29 +01:00
Ludy f5f011f1e0 deps: Pin Python dev dependencies and lock hashes to remediate security alert 302 (#4173)
## Description of Changes

- **What was changed**
- Added `.github/scripts/requirements_dev.in` and an autogenerated,
hash-locked `.github/scripts/requirements_dev.txt` to control Python dev
dependencies via `pip-compile`.
- **Why the change was made**
- To remediate a GitHub code scanning alert by removing vulnerable
transitive ranges and ensuring reproducible installs with vetted
versions and hashes.
- **Any challenges encountered**
- Reconciling version constraints among image/PDF tooling (e.g., Pillow,
pdf2image, OpenCV, WeasyPrint) while keeping wheels available across CI
platforms.
- Ensuring the generated lockfile remains maintainable and can be
refreshed with `pip-compile` when needed.



Closes
#https://github.com/Stirling-Tools/Stirling-PDF/security/code-scanning/302

---

## 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/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)

### 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.
2025-08-24 22:03:12 +01:00
Ludy 73df0ae1a8 fix(config): recreate settings.yml if missing or below minimal size threshold (#4166)
# Description of Changes

- Added logic to verify the `settings.yml` file’s existence **and**
ensure it has at least 31 lines (minimum valid config since `v0.13.0`).
- If the file exists but is too small, it is moved to a timestamped
`.bak` backup before creating a new one from the template.
- Added logging to show current line count and backup location for
better traceability.

---

## 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/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)
- [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/devGuide/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/devGuide/DeveloperGuide.md#6-testing)
for more details.
2025-08-24 21:47:09 +01:00
Ludy f0cfd87a5a build(gradle): replace deprecated outputFile with destinationFile in writeVersion task (#4167)
# Description of Changes

- Replaced the deprecated `outputFile` property with `destinationFile`
in the `writeVersion` Gradle task.
- Updated the logging statement to use
`destinationFile.get().asFile.path` instead of the old
`outputFile.path`.
- This change ensures compatibility with newer Gradle versions and
removes deprecation warnings.

---

## 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/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)
- [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/devGuide/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/devGuide/DeveloperGuide.md#6-testing)
for more details.
2025-08-24 21:45:26 +01:00
Ludy 97132c28a4 build(gradle): include all subprojects in license report generation (#4170)
# Description of Changes

- Updated `build.gradle` to ensure the `licenseReport` task processes
both the root project and all subprojects.
- Introduced `allProjects` variable that merges `subprojects` with the
current project into a single set.
- This change ensures license reporting covers the full multi-module
project rather than only the root module.


---

## 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/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)
- [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/devGuide/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/devGuide/DeveloperGuide.md#6-testing)
for more details.
2025-08-24 21:44:50 +01:00
LudyandCopilot 930fcf01bf fix(downloader): reset progress bar after completion (#4192)
# Description of Changes

- Added a `setTimeout` to hide the `.progressBarContainer` 1 second
after reaching 100%.
- Reset progress bar width to `0%` and `aria-valuenow` to `0` to prepare
for future downloads.
- This change ensures the UI does not leave a full progress bar
displayed after a completed download.


---

## 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/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)
- [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/devGuide/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/devGuide/DeveloperGuide.md#6-testing)
for more details.

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-08-24 21:42:31 +01:00
Peter Dave Hello d9a1ed6df1 Update and improve the zh-TW Traditional Chinese translation (#4164)
# Description of Changes

Update and improve the zh-TW Traditional Chinese translation

Summary from GitHub Copilot:

> This pull request updates the Traditional Chinese localization file
`messages_zh_TW.properties` to improve translation accuracy and
consistency across the UI. The changes focus on refining update-related
strings, clarifying PDF tool descriptions, and localizing bookmark
editor actions.
> 
> **Update & Upgrade Experience:**
> * Improved wording and localization for update notifications, modal
dialogs, update priority levels, and migration guide references to
better match native language conventions.
> * Refined enterprise edition feature descriptions, specifically
clarifying SSO login language for professional features.
> * Updated SSO login string for the login screen to use more natural
phrasing.
> 
> **PDF Tool Descriptions:**
> * Enhanced descriptions for "Auto Split PDF" and "PDF to Single
Page/Image" tools, making instructions clearer and terminology more
consistent.
[[1]](diffhunk://#diff-b982180d8edd5c66aef4cfc826fe1cabeb4d22644359f2f749ce0bec4760b40aL809-R809)
[[2]](diffhunk://#diff-b982180d8edd5c66aef4cfc826fe1cabeb4d22644359f2f749ce0bec4760b40aL1111-R1118)
[[3]](diffhunk://#diff-b982180d8edd5c66aef4cfc826fe1cabeb4d22644359f2f749ce0bec4760b40aL1431-R1431)
> 
> **Bookmark Editor Localization:**
> * Fully localized import/export actions and descriptions in the
bookmark editor, replacing English terms with accurate Chinese
equivalents.

---

## Checklist

### General

- [x] 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)
- [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)
- [x] 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)

### 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.
2025-08-24 21:41:09 +01:00
Ludy 4a28c64dee fix(i18n): standardize {filename} placeholder in addPageNumbers.customNumberDesc across all translations (#4204)
# Description of Changes

- Standardized the placeholder for filename in
`addPageNumbers.customNumberDesc` to `{filename}` across all affected
translation files.
- Fixed inconsistent or localized variations (e.g., `{filnavn}`, `{ime
datoteke}`, `{nume_fisier}`, `{nome do arquivo}`, `{nama berkas}`) and
ensured the placeholder is uniform.
- Corrected missing closing braces and quotes in several language files.
- Affected locales include: `ar_AR`, `az_AZ`, `bg_BG`, `da_DK`, `el_GR`,
`en_GB`, `en_US`, `es_ES`, `ga_IE`, `hr_HR`, `id_ID`, `it_IT`, `nl_NL`,
`no_NB`, `pl_PL`, `pt_BR`, `pt_PT`, `ro_RO`, `sk_SK`, `sl_SI`,
`sr_LATN_RS`, `sv_SE`, `tr_TR`, `vi_VN`.



# @Frooodle please merge after
https://github.com/Stirling-Tools/Stirling-PDF/pull/4202

---

## 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/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)
- [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/devGuide/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/devGuide/DeveloperGuide.md#6-testing)
for more details.
2025-08-24 21:38:07 +01:00
Ludy cec5d1e1b6 ci(workflow): simplify PR deployment by removing redundant repo/ref lookup (#4266)
# Description of Changes

- Removed the separate step that fetched PR repository and ref
(`get-pr-info`).
- Simplified checkout by directly using `refs/pull/${{
needs.check-comment.outputs.pr_number }}/merge`.
- This reduces workflow complexity and avoids unnecessary API calls
while still supporting forked PRs.

---

## 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/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
- [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/devGuide/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/devGuide/DeveloperGuide.md#6-testing)
for more details.
2025-08-24 21:32:35 +01:00
Eray Türkay 4cd1de4101 Update messages_tr_TR.properties (#4274)
Translated 100% specifically into Turkish. No machine translation or
artificial intelligence was used. All files have been correctly
translated into Turkish together with the file providers.

Best regards.

- Türkay Software https://www.turkaysoftware.com

# 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/devGuide/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/devGuide/HowToAddNewLanguage.md)
(if applicable)
- [x] I have performed a self-review of my own code
- [x] My changes generate no new warnings

### Documentation

- [x] 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)
- [x] 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)

### 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.
2025-08-24 21:31:40 +01:00
stirlingbot[bot] 5fb207492e Update 3rd Party Licenses (#4247)
Auto-generated by stirlingbot[bot]

Signed-off-by: stirlingbot[bot] <stirlingbot[bot]@users.noreply.github.com>
Co-authored-by: stirlingbot[bot] <195170888+stirlingbot[bot]@users.noreply.github.com>
2025-08-24 21:26:01 +01:00
Ludy 9779c75df4 refactor(tests): move & expand TextFinder/RedactController tests; fix TextFinder empty search-term handling; update token filtering API (#4264)
# Description of Changes

- **What was changed**
  - Relocated and refactored unit tests:
- `TextFinderTest` and `RedactControllerTest` moved under
`app/core/src/test/...` to align with module structure.
- Expanded test coverage: whole-word vs. partial matches, complex
regexes (emails, SSNs, IPs, currency), international/accented
characters, multi-page documents, malformed PDFs, operator preservation,
color decoding, and performance assertions.
  - **API adjustments in redaction flow**:
- `createTokensWithoutTargetText(...)` now accepts the `PDDocument`
alongside `PDPage` to properly manage resources/streams.
- Introduced/used `createPlaceholderWithFont(...)` to maintain text
width with explicit font context.
  - **Bug fix in `TextFinder`**:
- Early-return when the (trimmed) search term is empty to prevent
unnecessary processing and avoid false positives/errors.
- Minor cleanup (removed redundant `super()` call) and improved guard
logic around regex/whole-word wrapping.

- **Why the change was made**
- Improve reliability and determinism of PDF redaction and text finding
by exercising real-world patterns and edge cases.
- Ensure structural PDF operators (graphics/positioning) are preserved
during token filtering.
- Prevent crashes or misleading matches when users provide
empty/whitespace-only search terms.
- Align tests with the current project layout and increase
maintainability.

---

## 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/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)
- [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/devGuide/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/devGuide/DeveloperGuide.md#6-testing)
for more details.
2025-08-24 21:20:28 +01:00
dependabot[bot] 2baa258e11 build(deps): bump io.micrometer:micrometer-core from 1.15.2 to 1.15.3 (#4190)
[//]: # (dependabot-start)
⚠️  **Dependabot is rebasing this PR** ⚠️ 

Rebasing might not happen immediately, so don't worry if this takes some
time.

Note: if you make any changes to this PR yourself, they will take
precedence over the rebase.

---

[//]: # (dependabot-end)

Bumps
[io.micrometer:micrometer-core](https://github.com/micrometer-metrics/micrometer)
from 1.15.2 to 1.15.3.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/micrometer-metrics/micrometer/releases">io.micrometer:micrometer-core's
releases</a>.</em></p>
<blockquote>
<h2>1.15.3</h2>
<h2>🐞 Bug Fixes</h2>
<ul>
<li>Catch IllegalArgumentException in VirtualThreadMetrics <a
href="https://redirect.github.com/micrometer-metrics/micrometer/pull/6584">#6584</a></li>
<li>Handle ArrayIndexOutOfBoundsException from DoubleHistogram in
TimeWindowPercentileHistogram.accumulate() defensively <a
href="https://redirect.github.com/micrometer-metrics/micrometer/pull/6563">#6563</a></li>
<li>Sync OutputCapture from Spring Boot <a
href="https://redirect.github.com/micrometer-metrics/micrometer/pull/6608">#6608</a></li>
</ul>
<h2>🔨 Dependency Upgrades</h2>
<ul>
<li>Bump jersey3 from 3.1.10 to 3.1.11 <a
href="https://redirect.github.com/micrometer-metrics/micrometer/pull/6607">#6607</a></li>
<li>Bump com.netflix.spectator:spectator-reg-atlas from 1.8.16 to 1.8.17
<a
href="https://redirect.github.com/micrometer-metrics/micrometer/pull/6600">#6600</a></li>
<li>Bump io.netty:netty-bom from 4.1.122.Final to 4.1.123.Final <a
href="https://redirect.github.com/micrometer-metrics/micrometer/pull/6537">#6537</a></li>
</ul>
<h2>❤️ Contributors</h2>
<p>Thank you to all the contributors who worked on this release:</p>
<p><a href="https://github.com/genuss"><code>@​genuss</code></a> and <a
href="https://github.com/izeye"><code>@​izeye</code></a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/micrometer-metrics/micrometer/commit/5b196107904eb875c0519e60dbba286439c2a343"><code>5b19610</code></a>
Merge branch '1.14.x' into 1.15.x</li>
<li><a
href="https://github.com/micrometer-metrics/micrometer/commit/942ac71ed57b27635cf045c605a181f75b1d04cd"><code>942ac71</code></a>
Fix javadoc in StringEscapeUtils</li>
<li><a
href="https://github.com/micrometer-metrics/micrometer/commit/240cdd34d1638b5ef677f92b679f74bef982940f"><code>240cdd3</code></a>
Merge branch '1.14.x' into 1.15.x</li>
<li><a
href="https://github.com/micrometer-metrics/micrometer/commit/7ef45eab42e8e6651330e50bb1cc5032936c7039"><code>7ef45ea</code></a>
Resolve AlmostJavadoc from Error Prone (<a
href="https://redirect.github.com/micrometer-metrics/micrometer/issues/6611">#6611</a>)</li>
<li><a
href="https://github.com/micrometer-metrics/micrometer/commit/f08fd1c1c894ef518b28ee15fed5765ac8c8de30"><code>f08fd1c</code></a>
Sync OutputCapture from Spring Boot (<a
href="https://redirect.github.com/micrometer-metrics/micrometer/issues/6608">#6608</a>)</li>
<li><a
href="https://github.com/micrometer-metrics/micrometer/commit/8f9ec4ffb18801537d215f02b3c5930b4f46862b"><code>8f9ec4f</code></a>
Bump jersey3 from 2.45 to 3.1.11 (<a
href="https://redirect.github.com/micrometer-metrics/micrometer/issues/6607">#6607</a>)</li>
<li><a
href="https://github.com/micrometer-metrics/micrometer/commit/1c200619262652a1fd052148dd00cf1fd1fa9566"><code>1c20061</code></a>
Bump jersey3 from 2.45 to 3.1.11 (<a
href="https://redirect.github.com/micrometer-metrics/micrometer/issues/6603">#6603</a>)</li>
<li><a
href="https://github.com/micrometer-metrics/micrometer/commit/f88770cf1964fce12bebc2dc11815846bf78da1b"><code>f88770c</code></a>
Merge branch '1.14.x' into 1.15.x</li>
<li><a
href="https://github.com/micrometer-metrics/micrometer/commit/69251027097473444b969b16f13bdf16a41a01eb"><code>6925102</code></a>
Polish (<a
href="https://redirect.github.com/micrometer-metrics/micrometer/issues/6602">#6602</a>)</li>
<li><a
href="https://github.com/micrometer-metrics/micrometer/commit/8c5048973dabe8f734af067d48cc9998b887d9c2"><code>8c50489</code></a>
Bump com.netflix.spectator:spectator-reg-atlas from 1.8.16 to 1.8.17 (<a
href="https://redirect.github.com/micrometer-metrics/micrometer/issues/6601">#6601</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/micrometer-metrics/micrometer/compare/v1.15.2...v1.15.3">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=io.micrometer:micrometer-core&package-manager=gradle&previous-version=1.15.2&new-version=1.15.3)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-24 21:17:32 +01:00
dependabot[bot] 3f004dcad3 build(deps): bump io.swagger.core.v3:swagger-core-jakarta from 2.2.35 to 2.2.36 (#4226)
Bumps io.swagger.core.v3:swagger-core-jakarta from 2.2.35 to 2.2.36.


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=io.swagger.core.v3:swagger-core-jakarta&package-manager=gradle&previous-version=2.2.35&new-version=2.2.36)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-24 21:17:10 +01:00
dependabot[bot] 73d419cb39 build(deps): bump springSecuritySamlVersion from 6.5.2 to 6.5.3 (#4227)
Bumps `springSecuritySamlVersion` from 6.5.2 to 6.5.3.
Updates `org.springframework.security:spring-security-core` from 6.5.2
to 6.5.3
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/spring-projects/spring-security/releases">org.springframework.security:spring-security-core's
releases</a>.</em></p>
<blockquote>
<h2>6.5.3</h2>
<h2> New Features</h2>
<ul>
<li>Add META-INF/LICENSE.txt to published jars <a
href="https://redirect.github.com/spring-projects/spring-security/issues/17639">#17639</a></li>
<li>Update Angular documentation links in csrf.adoc <a
href="https://redirect.github.com/spring-projects/spring-security/issues/17653">#17653</a></li>
<li>Update Shibboleth Repository URL <a
href="https://redirect.github.com/spring-projects/spring-security/issues/17637">#17637</a></li>
<li>Use 2004-present Copyright <a
href="https://redirect.github.com/spring-projects/spring-security/issues/17634">#17634</a></li>
</ul>
<h2>🪲 Bug Fixes</h2>
<ul>
<li>Add Missing Navigation in Preparing for 7.0 Guide <a
href="https://redirect.github.com/spring-projects/spring-security/issues/17731">#17731</a></li>
<li>DPoP authentication throws JwtDecoderFactory ClassNotFoundException
<a
href="https://redirect.github.com/spring-projects/spring-security/issues/17249">#17249</a></li>
<li>OpenSamlAssertingPartyDetails Should Be Serializable <a
href="https://redirect.github.com/spring-projects/spring-security/issues/17727">#17727</a></li>
<li>Use final values in equals and hashCode <a
href="https://redirect.github.com/spring-projects/spring-security/pull/17621">#17621</a></li>
</ul>
<h2>🔨 Dependency Upgrades</h2>
<ul>
<li>Bump com.webauthn4j:webauthn4j-core from 0.29.4.RELEASE to
0.29.5.RELEASE <a
href="https://redirect.github.com/spring-projects/spring-security/pull/17739">#17739</a></li>
<li>Bump com.webauthn4j:webauthn4j-core from 0.29.4.RELEASE to
0.29.5.RELEASE <a
href="https://redirect.github.com/spring-projects/spring-security/pull/17690">#17690</a></li>
<li>Bump com.webauthn4j:webauthn4j-core from 0.29.4.RELEASE to
0.29.5.RELEASE <a
href="https://redirect.github.com/spring-projects/spring-security/pull/17684">#17684</a></li>
<li>Bump com.webauthn4j:webauthn4j-core from 0.29.4.RELEASE to
0.29.5.RELEASE <a
href="https://redirect.github.com/spring-projects/spring-security/pull/17661">#17661</a></li>
<li>Bump io.micrometer:micrometer-observation from 1.14.8 to 1.14.9 <a
href="https://redirect.github.com/spring-projects/spring-security/pull/17615">#17615</a></li>
<li>Bump io.micrometer:micrometer-observation from 1.14.8 to 1.14.9 <a
href="https://redirect.github.com/spring-projects/spring-security/pull/17599">#17599</a></li>
<li>Bump io.micrometer:micrometer-observation from 1.14.9 to 1.14.10 <a
href="https://redirect.github.com/spring-projects/spring-security/pull/17737">#17737</a></li>
<li>Bump io.micrometer:micrometer-observation from 1.14.9 to 1.14.10 <a
href="https://redirect.github.com/spring-projects/spring-security/pull/17701">#17701</a></li>
<li>Bump io.mockk:mockk from 1.14.4 to 1.14.5 <a
href="https://redirect.github.com/spring-projects/spring-security/pull/17614">#17614</a></li>
<li>Bump io.spring.develocity.conventions from 0.0.23 to 0.0.24 <a
href="https://redirect.github.com/spring-projects/spring-security/pull/17647">#17647</a></li>
<li>Bump io.spring.gradle:spring-security-release-plugin from 1.0.10 to
1.0.11 <a
href="https://redirect.github.com/spring-projects/spring-security/pull/17733">#17733</a></li>
<li>Bump io.spring.gradle:spring-security-release-plugin from 1.0.10 to
1.0.11 <a
href="https://redirect.github.com/spring-projects/spring-security/pull/17711">#17711</a></li>
<li>Bump io.spring.gradle:spring-security-release-plugin from 1.0.6 to
1.0.10 <a
href="https://redirect.github.com/spring-projects/spring-security/pull/17612">#17612</a></li>
<li>Bump io.spring.gradle:spring-security-release-plugin from 1.0.6 to
1.0.10 <a
href="https://redirect.github.com/spring-projects/spring-security/pull/17598">#17598</a></li>
<li>Bump org-eclipse-jetty from 11.0.25 to 11.0.26 <a
href="https://redirect.github.com/spring-projects/spring-security/pull/17742">#17742</a></li>
<li>Bump org.apache.maven:maven-resolver-provider from 3.9.10 to 3.9.11
<a
href="https://redirect.github.com/spring-projects/spring-security/pull/17613">#17613</a></li>
<li>Bump org.apache.maven:maven-resolver-provider from 3.9.10 to 3.9.11
<a
href="https://redirect.github.com/spring-projects/spring-security/pull/17595">#17595</a></li>
<li>Bump org.assertj:assertj-core from 3.27.3 to 3.27.4 <a
href="https://redirect.github.com/spring-projects/spring-security/pull/17760">#17760</a></li>
<li>Bump org.assertj:assertj-core from 3.27.3 to 3.27.4 <a
href="https://redirect.github.com/spring-projects/spring-security/pull/17692">#17692</a></li>
<li>Bump org.assertj:assertj-core from 3.27.3 to 3.27.4 <a
href="https://redirect.github.com/spring-projects/spring-security/pull/17683">#17683</a></li>
<li>Bump org.assertj:assertj-core from 3.27.3 to 3.27.4 <a
href="https://redirect.github.com/spring-projects/spring-security/pull/17671">#17671</a></li>
<li>Bump org.gretty:gretty from 4.1.6 to 4.1.7 <a
href="https://redirect.github.com/spring-projects/spring-security/pull/17616">#17616</a></li>
<li>Bump org.gretty:gretty from 4.1.6 to 4.1.7 <a
href="https://redirect.github.com/spring-projects/spring-security/pull/17597">#17597</a></li>
<li>Bump org.hibernate.orm:hibernate-core from 6.6.20.Final to
6.6.23.Final <a
href="https://redirect.github.com/spring-projects/spring-security/pull/17646">#17646</a></li>
<li>Bump org.hibernate.orm:hibernate-core from 6.6.23.Final to
6.6.24.Final <a
href="https://redirect.github.com/spring-projects/spring-security/pull/17660">#17660</a></li>
<li>Bump org.hibernate.orm:hibernate-core from 6.6.23.Final to
6.6.25.Final <a
href="https://redirect.github.com/spring-projects/spring-security/pull/17694">#17694</a></li>
<li>Bump org.hibernate.orm:hibernate-core from 6.6.23.Final to
6.6.25.Final <a
href="https://redirect.github.com/spring-projects/spring-security/pull/17685">#17685</a></li>
<li>Bump org.jfrog.buildinfo:build-info-extractor-gradle from 4.34.1 to
4.34.2 <a
href="https://redirect.github.com/spring-projects/spring-security/pull/17650">#17650</a></li>
<li>Bump org.springframework.data:spring-data-bom from 2024.1.7 to
2024.1.8 <a
href="https://redirect.github.com/spring-projects/spring-security/pull/17645">#17645</a></li>
<li>Bump org.springframework.ldap:spring-ldap-core from 3.2.13 to 3.2.14
<a
href="https://redirect.github.com/spring-projects/spring-security/pull/17757">#17757</a></li>
<li>Bump org.springframework:spring-framework-bom from 6.2.8 to 6.2.9 <a
href="https://redirect.github.com/spring-projects/spring-security/pull/17651">#17651</a></li>
<li>Bump org.springframework:spring-framework-bom from 6.2.8 to 6.2.9 <a
href="https://redirect.github.com/spring-projects/spring-security/pull/17596">#17596</a></li>
<li>Bump org.springframework:spring-framework-bom from 6.2.9 to 6.2.10
<a
href="https://redirect.github.com/spring-projects/spring-security/pull/17735">#17735</a></li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/spring-projects/spring-security/commit/44037c0ea4103dc599a84c0772f65c3aa4b6225f"><code>44037c0</code></a>
Release 6.5.3</li>
<li><a
href="https://github.com/spring-projects/spring-security/commit/9909dc615a59baead33ff050ff2825a73426268f"><code>9909dc6</code></a>
Merge branch '6.4.x' into 6.5.x</li>
<li><a
href="https://github.com/spring-projects/spring-security/commit/525601ea6782a49ae3fa66b4af98a3006dfce519"><code>525601e</code></a>
Fix version 6.4.9-SNAPSHOT</li>
<li><a
href="https://github.com/spring-projects/spring-security/commit/15a4d0d6279496c4f7f977cf1b1e616a1d6b31e2"><code>15a4d0d</code></a>
Fix version=6.5.3-SNAPSHOT</li>
<li><a
href="https://github.com/spring-projects/spring-security/commit/80b1a308abb4e32213c3e8671d50cbfa153a0d0a"><code>80b1a30</code></a>
Merge branch '6.4.x' into 6.5.x</li>
<li><a
href="https://github.com/spring-projects/spring-security/commit/644f7802d8bf21043286088a1c8cb28738fa3ebb"><code>644f780</code></a>
Bump org.springframework.ldap:spring-ldap-core from 3.2.13 to
3.2.14</li>
<li><a
href="https://github.com/spring-projects/spring-security/commit/a26d6fccb049576a2c438485aed535d60dcdcc0b"><code>a26d6fc</code></a>
Bump org.springframework.data:spring-data-bom from 2024.1.8 to
2024.1.9</li>
<li><a
href="https://github.com/spring-projects/spring-security/commit/74735a1a80efb9b6e907e7fe4780d58ae72ee911"><code>74735a1</code></a>
Bump org.hibernate.orm:hibernate-core from 6.6.23.Final to
6.6.26.Final</li>
<li><a
href="https://github.com/spring-projects/spring-security/commit/82a16d791776e7a8bb8e0efaaa3c5677aa6645c1"><code>82a16d7</code></a>
Bump org.assertj:assertj-core from 3.27.3 to 3.27.4</li>
<li><a
href="https://github.com/spring-projects/spring-security/commit/c1869c1db9105b8feb82f2128077376a606ead01"><code>c1869c1</code></a>
Bump org.hibernate.orm:hibernate-core from 6.6.23.Final to
6.6.26.Final</li>
<li>Additional commits viewable in <a
href="https://github.com/spring-projects/spring-security/compare/6.5.2...6.5.3">compare
view</a></li>
</ul>
</details>
<br />

Updates
`org.springframework.security:spring-security-saml2-service-provider`
from 6.5.2 to 6.5.3
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/spring-projects/spring-security/releases">org.springframework.security:spring-security-saml2-service-provider's
releases</a>.</em></p>
<blockquote>
<h2>6.5.3</h2>
<h2> New Features</h2>
<ul>
<li>Add META-INF/LICENSE.txt to published jars <a
href="https://redirect.github.com/spring-projects/spring-security/issues/17639">#17639</a></li>
<li>Update Angular documentation links in csrf.adoc <a
href="https://redirect.github.com/spring-projects/spring-security/issues/17653">#17653</a></li>
<li>Update Shibboleth Repository URL <a
href="https://redirect.github.com/spring-projects/spring-security/issues/17637">#17637</a></li>
<li>Use 2004-present Copyright <a
href="https://redirect.github.com/spring-projects/spring-security/issues/17634">#17634</a></li>
</ul>
<h2>🪲 Bug Fixes</h2>
<ul>
<li>Add Missing Navigation in Preparing for 7.0 Guide <a
href="https://redirect.github.com/spring-projects/spring-security/issues/17731">#17731</a></li>
<li>DPoP authentication throws JwtDecoderFactory ClassNotFoundException
<a
href="https://redirect.github.com/spring-projects/spring-security/issues/17249">#17249</a></li>
<li>OpenSamlAssertingPartyDetails Should Be Serializable <a
href="https://redirect.github.com/spring-projects/spring-security/issues/17727">#17727</a></li>
<li>Use final values in equals and hashCode <a
href="https://redirect.github.com/spring-projects/spring-security/pull/17621">#17621</a></li>
</ul>
<h2>🔨 Dependency Upgrades</h2>
<ul>
<li>Bump com.webauthn4j:webauthn4j-core from 0.29.4.RELEASE to
0.29.5.RELEASE <a
href="https://redirect.github.com/spring-projects/spring-security/pull/17739">#17739</a></li>
<li>Bump com.webauthn4j:webauthn4j-core from 0.29.4.RELEASE to
0.29.5.RELEASE <a
href="https://redirect.github.com/spring-projects/spring-security/pull/17690">#17690</a></li>
<li>Bump com.webauthn4j:webauthn4j-core from 0.29.4.RELEASE to
0.29.5.RELEASE <a
href="https://redirect.github.com/spring-projects/spring-security/pull/17684">#17684</a></li>
<li>Bump com.webauthn4j:webauthn4j-core from 0.29.4.RELEASE to
0.29.5.RELEASE <a
href="https://redirect.github.com/spring-projects/spring-security/pull/17661">#17661</a></li>
<li>Bump io.micrometer:micrometer-observation from 1.14.8 to 1.14.9 <a
href="https://redirect.github.com/spring-projects/spring-security/pull/17615">#17615</a></li>
<li>Bump io.micrometer:micrometer-observation from 1.14.8 to 1.14.9 <a
href="https://redirect.github.com/spring-projects/spring-security/pull/17599">#17599</a></li>
<li>Bump io.micrometer:micrometer-observation from 1.14.9 to 1.14.10 <a
href="https://redirect.github.com/spring-projects/spring-security/pull/17737">#17737</a></li>
<li>Bump io.micrometer:micrometer-observation from 1.14.9 to 1.14.10 <a
href="https://redirect.github.com/spring-projects/spring-security/pull/17701">#17701</a></li>
<li>Bump io.mockk:mockk from 1.14.4 to 1.14.5 <a
href="https://redirect.github.com/spring-projects/spring-security/pull/17614">#17614</a></li>
<li>Bump io.spring.develocity.conventions from 0.0.23 to 0.0.24 <a
href="https://redirect.github.com/spring-projects/spring-security/pull/17647">#17647</a></li>
<li>Bump io.spring.gradle:spring-security-release-plugin from 1.0.10 to
1.0.11 <a
href="https://redirect.github.com/spring-projects/spring-security/pull/17733">#17733</a></li>
<li>Bump io.spring.gradle:spring-security-release-plugin from 1.0.10 to
1.0.11 <a
href="https://redirect.github.com/spring-projects/spring-security/pull/17711">#17711</a></li>
<li>Bump io.spring.gradle:spring-security-release-plugin from 1.0.6 to
1.0.10 <a
href="https://redirect.github.com/spring-projects/spring-security/pull/17612">#17612</a></li>
<li>Bump io.spring.gradle:spring-security-release-plugin from 1.0.6 to
1.0.10 <a
href="https://redirect.github.com/spring-projects/spring-security/pull/17598">#17598</a></li>
<li>Bump org-eclipse-jetty from 11.0.25 to 11.0.26 <a
href="https://redirect.github.com/spring-projects/spring-security/pull/17742">#17742</a></li>
<li>Bump org.apache.maven:maven-resolver-provider from 3.9.10 to 3.9.11
<a
href="https://redirect.github.com/spring-projects/spring-security/pull/17613">#17613</a></li>
<li>Bump org.apache.maven:maven-resolver-provider from 3.9.10 to 3.9.11
<a
href="https://redirect.github.com/spring-projects/spring-security/pull/17595">#17595</a></li>
<li>Bump org.assertj:assertj-core from 3.27.3 to 3.27.4 <a
href="https://redirect.github.com/spring-projects/spring-security/pull/17760">#17760</a></li>
<li>Bump org.assertj:assertj-core from 3.27.3 to 3.27.4 <a
href="https://redirect.github.com/spring-projects/spring-security/pull/17692">#17692</a></li>
<li>Bump org.assertj:assertj-core from 3.27.3 to 3.27.4 <a
href="https://redirect.github.com/spring-projects/spring-security/pull/17683">#17683</a></li>
<li>Bump org.assertj:assertj-core from 3.27.3 to 3.27.4 <a
href="https://redirect.github.com/spring-projects/spring-security/pull/17671">#17671</a></li>
<li>Bump org.gretty:gretty from 4.1.6 to 4.1.7 <a
href="https://redirect.github.com/spring-projects/spring-security/pull/17616">#17616</a></li>
<li>Bump org.gretty:gretty from 4.1.6 to 4.1.7 <a
href="https://redirect.github.com/spring-projects/spring-security/pull/17597">#17597</a></li>
<li>Bump org.hibernate.orm:hibernate-core from 6.6.20.Final to
6.6.23.Final <a
href="https://redirect.github.com/spring-projects/spring-security/pull/17646">#17646</a></li>
<li>Bump org.hibernate.orm:hibernate-core from 6.6.23.Final to
6.6.24.Final <a
href="https://redirect.github.com/spring-projects/spring-security/pull/17660">#17660</a></li>
<li>Bump org.hibernate.orm:hibernate-core from 6.6.23.Final to
6.6.25.Final <a
href="https://redirect.github.com/spring-projects/spring-security/pull/17694">#17694</a></li>
<li>Bump org.hibernate.orm:hibernate-core from 6.6.23.Final to
6.6.25.Final <a
href="https://redirect.github.com/spring-projects/spring-security/pull/17685">#17685</a></li>
<li>Bump org.jfrog.buildinfo:build-info-extractor-gradle from 4.34.1 to
4.34.2 <a
href="https://redirect.github.com/spring-projects/spring-security/pull/17650">#17650</a></li>
<li>Bump org.springframework.data:spring-data-bom from 2024.1.7 to
2024.1.8 <a
href="https://redirect.github.com/spring-projects/spring-security/pull/17645">#17645</a></li>
<li>Bump org.springframework.ldap:spring-ldap-core from 3.2.13 to 3.2.14
<a
href="https://redirect.github.com/spring-projects/spring-security/pull/17757">#17757</a></li>
<li>Bump org.springframework:spring-framework-bom from 6.2.8 to 6.2.9 <a
href="https://redirect.github.com/spring-projects/spring-security/pull/17651">#17651</a></li>
<li>Bump org.springframework:spring-framework-bom from 6.2.8 to 6.2.9 <a
href="https://redirect.github.com/spring-projects/spring-security/pull/17596">#17596</a></li>
<li>Bump org.springframework:spring-framework-bom from 6.2.9 to 6.2.10
<a
href="https://redirect.github.com/spring-projects/spring-security/pull/17735">#17735</a></li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/spring-projects/spring-security/commit/44037c0ea4103dc599a84c0772f65c3aa4b6225f"><code>44037c0</code></a>
Release 6.5.3</li>
<li><a
href="https://github.com/spring-projects/spring-security/commit/9909dc615a59baead33ff050ff2825a73426268f"><code>9909dc6</code></a>
Merge branch '6.4.x' into 6.5.x</li>
<li><a
href="https://github.com/spring-projects/spring-security/commit/525601ea6782a49ae3fa66b4af98a3006dfce519"><code>525601e</code></a>
Fix version 6.4.9-SNAPSHOT</li>
<li><a
href="https://github.com/spring-projects/spring-security/commit/15a4d0d6279496c4f7f977cf1b1e616a1d6b31e2"><code>15a4d0d</code></a>
Fix version=6.5.3-SNAPSHOT</li>
<li><a
href="https://github.com/spring-projects/spring-security/commit/80b1a308abb4e32213c3e8671d50cbfa153a0d0a"><code>80b1a30</code></a>
Merge branch '6.4.x' into 6.5.x</li>
<li><a
href="https://github.com/spring-projects/spring-security/commit/644f7802d8bf21043286088a1c8cb28738fa3ebb"><code>644f780</code></a>
Bump org.springframework.ldap:spring-ldap-core from 3.2.13 to
3.2.14</li>
<li><a
href="https://github.com/spring-projects/spring-security/commit/a26d6fccb049576a2c438485aed535d60dcdcc0b"><code>a26d6fc</code></a>
Bump org.springframework.data:spring-data-bom from 2024.1.8 to
2024.1.9</li>
<li><a
href="https://github.com/spring-projects/spring-security/commit/74735a1a80efb9b6e907e7fe4780d58ae72ee911"><code>74735a1</code></a>
Bump org.hibernate.orm:hibernate-core from 6.6.23.Final to
6.6.26.Final</li>
<li><a
href="https://github.com/spring-projects/spring-security/commit/82a16d791776e7a8bb8e0efaaa3c5677aa6645c1"><code>82a16d7</code></a>
Bump org.assertj:assertj-core from 3.27.3 to 3.27.4</li>
<li><a
href="https://github.com/spring-projects/spring-security/commit/c1869c1db9105b8feb82f2128077376a606ead01"><code>c1869c1</code></a>
Bump org.hibernate.orm:hibernate-core from 6.6.23.Final to
6.6.26.Final</li>
<li>Additional commits viewable in <a
href="https://github.com/spring-projects/spring-security/compare/6.5.2...6.5.3">compare
view</a></li>
</ul>
</details>
<br />


Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-24 21:16:57 +01:00
dependabot[bot] 44dbeebd40 build(deps): bump org.springframework.boot:spring-boot-dependencies from 3.5.4 to 3.5.5 (#4268)
Bumps
[org.springframework.boot:spring-boot-dependencies](https://github.com/spring-projects/spring-boot)
from 3.5.4 to 3.5.5.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/spring-projects/spring-boot/releases">org.springframework.boot:spring-boot-dependencies's
releases</a>.</em></p>
<blockquote>
<h2>v3.5.5</h2>
<h2>🐞 Bug Fixes</h2>
<ul>
<li>Hazelcast health indicator reports the wrong status when Hazelcast
has shut down due to an out-of-memory error <a
href="https://redirect.github.com/spring-projects/spring-boot/issues/46909">#46909</a></li>
<li>Performance critical tracing code has high overhead due to the use
of the Stream API <a
href="https://redirect.github.com/spring-projects/spring-boot/issues/46844">#46844</a></li>
<li>SpringLiquibaseCustomizer is exposed outside its defined visibility
scope <a
href="https://redirect.github.com/spring-projects/spring-boot/issues/46758">#46758</a></li>
<li>Race condition in OutputCapture can result in stale data <a
href="https://redirect.github.com/spring-projects/spring-boot/issues/46721">#46721</a></li>
<li>Auto-configured WebClient no longer uses context's
ReactorResourceFactory <a
href="https://redirect.github.com/spring-projects/spring-boot/pull/46673">#46673</a></li>
<li>Default value not detected for a field annoted with
<code>@Name</code> <a
href="https://redirect.github.com/spring-projects/spring-boot/issues/46666">#46666</a></li>
<li>Missing metadata when using <code>@Name</code> with a
constructor-bound property <a
href="https://redirect.github.com/spring-projects/spring-boot/issues/46663">#46663</a></li>
<li>Missing property for Spring Authorization Server's PAR endpoint <a
href="https://redirect.github.com/spring-projects/spring-boot/pull/46641">#46641</a></li>
<li>Property name is incorrect when reporting a mis-configured OAuth 2
Resource Server JWT public key location <a
href="https://redirect.github.com/spring-projects/spring-boot/issues/46636">#46636</a></li>
<li>Memory not freed on context restart in JpaMetamodel#CACHE with
spring.main.lazy-initialization=true <a
href="https://redirect.github.com/spring-projects/spring-boot/issues/46634">#46634</a></li>
<li>Auto-configured MockMvc ignores <code>@FilterRegistration</code>
annotation <a
href="https://redirect.github.com/spring-projects/spring-boot/pull/46605">#46605</a></li>
<li>Failure to discover default value for a primitive should not lead to
document its default value <a
href="https://redirect.github.com/spring-projects/spring-boot/issues/46561">#46561</a></li>
</ul>
<h2>📔 Documentation</h2>
<ul>
<li>Kotlin samples for configuration metadata are in the wrong package
<a
href="https://redirect.github.com/spring-projects/spring-boot/issues/46857">#46857</a></li>
<li>Observability examples in the reference guide are missing the Kotlin
version <a
href="https://redirect.github.com/spring-projects/spring-boot/issues/46798">#46798</a></li>
<li>Align method descriptions for SslOptions getCiphers and
getEnabledProtocols with <code>@returns</code> <a
href="https://redirect.github.com/spring-projects/spring-boot/issues/46769">#46769</a></li>
<li>Tracing samples in the reference guide are missing the Kotlin
version <a
href="https://redirect.github.com/spring-projects/spring-boot/issues/46767">#46767</a></li>
<li>Improve Virtual Threads section to mention the changes in Java 24 <a
href="https://redirect.github.com/spring-projects/spring-boot/issues/46610">#46610</a></li>
<li>spring.test.webtestclient.timeout is not documented <a
href="https://redirect.github.com/spring-projects/spring-boot/issues/46588">#46588</a></li>
<li>spring-boot-test-autoconfigure should use the configuration
properties annotation processor like other modules <a
href="https://redirect.github.com/spring-projects/spring-boot/issues/46585">#46585</a></li>
<li>Adapt deprecation level for management.health.influxdb.enabled <a
href="https://redirect.github.com/spring-projects/spring-boot/issues/46580">#46580</a></li>
<li>spring.test.mockmvc properties are not documented <a
href="https://redirect.github.com/spring-projects/spring-boot/issues/46578">#46578</a></li>
</ul>
<h2>🔨 Dependency Upgrades</h2>
<ul>
<li>Upgrade to Angus Mail 2.0.4 <a
href="https://redirect.github.com/spring-projects/spring-boot/issues/46725">#46725</a></li>
<li>Upgrade to AssertJ 3.27.4 <a
href="https://redirect.github.com/spring-projects/spring-boot/issues/46726">#46726</a></li>
<li>Upgrade to Byte Buddy 1.17.7 <a
href="https://redirect.github.com/spring-projects/spring-boot/issues/46883">#46883</a></li>
<li>Upgrade to Couchbase Client 3.8.3 <a
href="https://redirect.github.com/spring-projects/spring-boot/issues/46794">#46794</a></li>
<li>Upgrade to Elasticsearch Client 8.18.5 <a
href="https://redirect.github.com/spring-projects/spring-boot/issues/46830">#46830</a></li>
<li>Upgrade to Hibernate 6.6.26.Final <a
href="https://redirect.github.com/spring-projects/spring-boot/issues/46884">#46884</a></li>
<li>Upgrade to Hibernate Validator 8.0.3.Final <a
href="https://redirect.github.com/spring-projects/spring-boot/issues/46728">#46728</a></li>
<li>Upgrade to HikariCP 6.3.2 <a
href="https://redirect.github.com/spring-projects/spring-boot/issues/46729">#46729</a></li>
<li>Upgrade to Jersey 3.1.11 <a
href="https://redirect.github.com/spring-projects/spring-boot/issues/46730">#46730</a></li>
<li>Upgrade to Jetty 12.0.25 <a
href="https://redirect.github.com/spring-projects/spring-boot/issues/46831">#46831</a></li>
<li>Upgrade to Jetty Reactive HTTPClient 4.0.11 <a
href="https://redirect.github.com/spring-projects/spring-boot/issues/46885">#46885</a></li>
<li>Upgrade to jOOQ 3.19.25 <a
href="https://redirect.github.com/spring-projects/spring-boot/issues/46808">#46808</a></li>
<li>Upgrade to MariaDB 3.5.5 <a
href="https://redirect.github.com/spring-projects/spring-boot/issues/46779">#46779</a></li>
<li>Upgrade to Maven Javadoc Plugin 3.11.3 <a
href="https://redirect.github.com/spring-projects/spring-boot/issues/46886">#46886</a></li>
<li>Upgrade to Micrometer 1.15.3 <a
href="https://redirect.github.com/spring-projects/spring-boot/issues/46701">#46701</a></li>
<li>Upgrade to Micrometer Tracing 1.5.3 <a
href="https://redirect.github.com/spring-projects/spring-boot/issues/46702">#46702</a></li>
<li>Upgrade to MySQL 9.4.0 <a
href="https://redirect.github.com/spring-projects/spring-boot/issues/46732">#46732</a></li>
<li>Upgrade to Netty 4.1.124.Final <a
href="https://redirect.github.com/spring-projects/spring-boot/issues/46832">#46832</a></li>
<li>Upgrade to Pulsar 4.0.6 <a
href="https://redirect.github.com/spring-projects/spring-boot/issues/46733">#46733</a></li>
<li>Upgrade to Reactor Bom 2024.0.9 <a
href="https://redirect.github.com/spring-projects/spring-boot/issues/46703">#46703</a></li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/spring-projects/spring-boot/commit/3537d255b579018851951da08262cd0178e40c66"><code>3537d25</code></a>
Release v3.5.5</li>
<li><a
href="https://github.com/spring-projects/spring-boot/commit/a22e28e9e00eca994b8e412a420110da5b58b64a"><code>a22e28e</code></a>
Merge branch '3.4.x' into 3.5.x</li>
<li><a
href="https://github.com/spring-projects/spring-boot/commit/4cb8c8a1b9670497046655393ab2a0f535e8442d"><code>4cb8c8a</code></a>
Next development version (v3.4.10-SNAPSHOT)</li>
<li><a
href="https://github.com/spring-projects/spring-boot/commit/9d205e21c4c007b317cc3c65bf8dcad543e61c81"><code>9d205e2</code></a>
Merge branch '3.4.x' into 3.5.x</li>
<li><a
href="https://github.com/spring-projects/spring-boot/commit/47b06322d3df72d886d838a090f506a6ba281892"><code>47b0632</code></a>
Merge pull request <a
href="https://redirect.github.com/spring-projects/spring-boot/issues/46927">#46927</a>
from izeye</li>
<li><a
href="https://github.com/spring-projects/spring-boot/commit/8b7145802503dc00720e24db67144e568648c96f"><code>8b71458</code></a>
Adapt checkstyle rules for 3.4.x</li>
<li><a
href="https://github.com/spring-projects/spring-boot/commit/fb99badf16072b3e49aca422abe8e5be184b1af8"><code>fb99bad</code></a>
Remove redundant suppressions from Checkstyle configuration</li>
<li><a
href="https://github.com/spring-projects/spring-boot/commit/8af836a428e65b8032483d5d8159099684054cd0"><code>8af836a</code></a>
Upgrade to Spring RESTDocs 3.0.5</li>
<li><a
href="https://github.com/spring-projects/spring-boot/commit/ae6c6a5ed4652134c8f35fb8ca9a3d0149a207c2"><code>ae6c6a5</code></a>
Merge branch '3.4.x' into 3.5.x</li>
<li><a
href="https://github.com/spring-projects/spring-boot/commit/b6bae9f59b38a2dc8234d2766b062a5986410a37"><code>b6bae9f</code></a>
Upgrade to Spring RESTDocs 3.0.5</li>
<li>Additional commits viewable in <a
href="https://github.com/spring-projects/spring-boot/compare/v3.5.4...v3.5.5">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=org.springframework.boot:spring-boot-dependencies&package-manager=gradle&previous-version=3.5.4&new-version=3.5.5)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-24 21:05:37 +01:00
dependabot[bot] 0d63bc4a41 build(deps): bump github/codeql-action from 3.29.10 to 3.29.11 (#4271)
Bumps [github/codeql-action](https://github.com/github/codeql-action)
from 3.29.10 to 3.29.11.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/github/codeql-action/releases">github/codeql-action's
releases</a>.</em></p>
<blockquote>
<h2>v3.29.11</h2>
<h1>CodeQL Action Changelog</h1>
<p>See the <a
href="https://github.com/github/codeql-action/releases">releases
page</a> for the relevant changes to the CodeQL CLI and language
packs.</p>
<h2>3.29.11 - 21 Aug 2025</h2>
<ul>
<li>Update default CodeQL bundle version to 2.22.4. <a
href="https://redirect.github.com/github/codeql-action/pull/3044">#3044</a></li>
</ul>
<p>See the full <a
href="https://github.com/github/codeql-action/blob/v3.29.11/CHANGELOG.md">CHANGELOG.md</a>
for more information.</p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/github/codeql-action/blob/main/CHANGELOG.md">github/codeql-action's
changelog</a>.</em></p>
<blockquote>
<h1>CodeQL Action Changelog</h1>
<p>See the <a
href="https://github.com/github/codeql-action/releases">releases
page</a> for the relevant changes to the CodeQL CLI and language
packs.</p>
<h2>[UNRELEASED]</h2>
<p>No user facing changes.</p>
<h2>3.29.11 - 21 Aug 2025</h2>
<ul>
<li>Update default CodeQL bundle version to 2.22.4. <a
href="https://redirect.github.com/github/codeql-action/pull/3044">#3044</a></li>
</ul>
<h2>3.29.10 - 18 Aug 2025</h2>
<p>No user facing changes.</p>
<h2>3.29.9 - 12 Aug 2025</h2>
<p>No user facing changes.</p>
<h2>3.29.8 - 08 Aug 2025</h2>
<ul>
<li>Fix an issue where the Action would autodetect unsupported languages
such as HTML. <a
href="https://redirect.github.com/github/codeql-action/pull/3015">#3015</a></li>
</ul>
<h2>3.29.7 - 07 Aug 2025</h2>
<p>This release rolls back 3.29.6 to address issues with language
autodetection. It is identical to 3.29.5.</p>
<h2>3.29.6 - 07 Aug 2025</h2>
<ul>
<li>The <code>cleanup-level</code> input to the <code>analyze</code>
Action is now deprecated. The CodeQL Action has written a limited amount
of intermediate results to the database since version 2.2.5, and now
automatically manages cleanup. <a
href="https://redirect.github.com/github/codeql-action/pull/2999">#2999</a></li>
<li>Update default CodeQL bundle version to 2.22.3. <a
href="https://redirect.github.com/github/codeql-action/pull/3000">#3000</a></li>
</ul>
<h2>3.29.5 - 29 Jul 2025</h2>
<ul>
<li>Update default CodeQL bundle version to 2.22.2. <a
href="https://redirect.github.com/github/codeql-action/pull/2986">#2986</a></li>
</ul>
<h2>3.29.4 - 23 Jul 2025</h2>
<p>No user facing changes.</p>
<h2>3.29.3 - 21 Jul 2025</h2>
<p>No user facing changes.</p>
<h2>3.29.2 - 30 Jun 2025</h2>
<ul>
<li>Experimental: When the <code>quality-queries</code> input for the
<code>init</code> action is provided with an argument, separate
<code>.quality.sarif</code> files are produced and uploaded for each
language with the results of the specified queries. Do not use this in
production as it is part of an internal experiment and subject to change
at any time. <a
href="https://redirect.github.com/github/codeql-action/pull/2935">#2935</a></li>
</ul>
<h2>3.29.1 - 27 Jun 2025</h2>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/github/codeql-action/commit/3c3833e0f8c1c83d449a7478aa59c036a9165498"><code>3c3833e</code></a>
Merge pull request <a
href="https://redirect.github.com/github/codeql-action/issues/3052">#3052</a>
from github/update-v3.29.11-14148a433</li>
<li><a
href="https://github.com/github/codeql-action/commit/8c4bfbd99ba6ef652eca12461ad7618142e00679"><code>8c4bfbd</code></a>
Update changelog for v3.29.11</li>
<li><a
href="https://github.com/github/codeql-action/commit/14148a433d789d9b6c7dadb56d8e3f8ad1e59605"><code>14148a4</code></a>
Merge pull request <a
href="https://redirect.github.com/github/codeql-action/issues/3044">#3044</a>
from github/update-bundle/codeql-bundle-v2.22.4</li>
<li><a
href="https://github.com/github/codeql-action/commit/71b2cb38a1e682cb9b2453a5f1400eef870a37df"><code>71b2cb3</code></a>
Add changelog note</li>
<li><a
href="https://github.com/github/codeql-action/commit/2bf78254cceec27aab20b1623ba68c63c6eb85c6"><code>2bf7825</code></a>
Update default bundle to codeql-bundle-v2.22.4</li>
<li><a
href="https://github.com/github/codeql-action/commit/db69a5182d331d562e511302ae3c9aafd5fada6c"><code>db69a51</code></a>
Merge pull request <a
href="https://redirect.github.com/github/codeql-action/issues/3049">#3049</a>
from github/update-supported-enterprise-server-versions</li>
<li><a
href="https://github.com/github/codeql-action/commit/a68d47bfa574c69f3de7d6484cf28a9c55ff7287"><code>a68d47b</code></a>
Merge pull request <a
href="https://redirect.github.com/github/codeql-action/issues/3050">#3050</a>
from github/henrymercer/init-not-called-config-error</li>
<li><a
href="https://github.com/github/codeql-action/commit/e496ff959372e828f30b1518fd22cb76170cf5db"><code>e496ff9</code></a>
Make &quot;init not called&quot; a configuration error</li>
<li><a
href="https://github.com/github/codeql-action/commit/fd2ea72d34cdf8157d85d93decf87671705166a3"><code>fd2ea72</code></a>
Update supported GitHub Enterprise Server versions</li>
<li><a
href="https://github.com/github/codeql-action/commit/6dee5bc9c165ca206a70f4e3d18271971cf6ff26"><code>6dee5bc</code></a>
Merge pull request <a
href="https://redirect.github.com/github/codeql-action/issues/3045">#3045</a>
from github/dependabot/npm_and_yarn/npm-5b4171dd16</li>
<li>Additional commits viewable in <a
href="https://github.com/github/codeql-action/compare/96f518a34f7a870018057716cc4d7a5c014bd61c...3c3833e0f8c1c83d449a7478aa59c036a9165498">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=github/codeql-action&package-manager=github_actions&previous-version=3.29.10&new-version=3.29.11)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-24 21:04:24 +01:00
dependabot[bot] ae53492751 build(deps): bump org.springframework.boot from 3.5.4 to 3.5.5 (#4272)
Bumps
[org.springframework.boot](https://github.com/spring-projects/spring-boot)
from 3.5.4 to 3.5.5.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/spring-projects/spring-boot/releases">org.springframework.boot's
releases</a>.</em></p>
<blockquote>
<h2>v3.5.5</h2>
<h2>🐞 Bug Fixes</h2>
<ul>
<li>Hazelcast health indicator reports the wrong status when Hazelcast
has shut down due to an out-of-memory error <a
href="https://redirect.github.com/spring-projects/spring-boot/issues/46909">#46909</a></li>
<li>Performance critical tracing code has high overhead due to the use
of the Stream API <a
href="https://redirect.github.com/spring-projects/spring-boot/issues/46844">#46844</a></li>
<li>SpringLiquibaseCustomizer is exposed outside its defined visibility
scope <a
href="https://redirect.github.com/spring-projects/spring-boot/issues/46758">#46758</a></li>
<li>Race condition in OutputCapture can result in stale data <a
href="https://redirect.github.com/spring-projects/spring-boot/issues/46721">#46721</a></li>
<li>Auto-configured WebClient no longer uses context's
ReactorResourceFactory <a
href="https://redirect.github.com/spring-projects/spring-boot/pull/46673">#46673</a></li>
<li>Default value not detected for a field annoted with
<code>@Name</code> <a
href="https://redirect.github.com/spring-projects/spring-boot/issues/46666">#46666</a></li>
<li>Missing metadata when using <code>@Name</code> with a
constructor-bound property <a
href="https://redirect.github.com/spring-projects/spring-boot/issues/46663">#46663</a></li>
<li>Missing property for Spring Authorization Server's PAR endpoint <a
href="https://redirect.github.com/spring-projects/spring-boot/pull/46641">#46641</a></li>
<li>Property name is incorrect when reporting a mis-configured OAuth 2
Resource Server JWT public key location <a
href="https://redirect.github.com/spring-projects/spring-boot/issues/46636">#46636</a></li>
<li>Memory not freed on context restart in JpaMetamodel#CACHE with
spring.main.lazy-initialization=true <a
href="https://redirect.github.com/spring-projects/spring-boot/issues/46634">#46634</a></li>
<li>Auto-configured MockMvc ignores <code>@FilterRegistration</code>
annotation <a
href="https://redirect.github.com/spring-projects/spring-boot/pull/46605">#46605</a></li>
<li>Failure to discover default value for a primitive should not lead to
document its default value <a
href="https://redirect.github.com/spring-projects/spring-boot/issues/46561">#46561</a></li>
</ul>
<h2>📔 Documentation</h2>
<ul>
<li>Kotlin samples for configuration metadata are in the wrong package
<a
href="https://redirect.github.com/spring-projects/spring-boot/issues/46857">#46857</a></li>
<li>Observability examples in the reference guide are missing the Kotlin
version <a
href="https://redirect.github.com/spring-projects/spring-boot/issues/46798">#46798</a></li>
<li>Align method descriptions for SslOptions getCiphers and
getEnabledProtocols with <code>@returns</code> <a
href="https://redirect.github.com/spring-projects/spring-boot/issues/46769">#46769</a></li>
<li>Tracing samples in the reference guide are missing the Kotlin
version <a
href="https://redirect.github.com/spring-projects/spring-boot/issues/46767">#46767</a></li>
<li>Improve Virtual Threads section to mention the changes in Java 24 <a
href="https://redirect.github.com/spring-projects/spring-boot/issues/46610">#46610</a></li>
<li>spring.test.webtestclient.timeout is not documented <a
href="https://redirect.github.com/spring-projects/spring-boot/issues/46588">#46588</a></li>
<li>spring-boot-test-autoconfigure should use the configuration
properties annotation processor like other modules <a
href="https://redirect.github.com/spring-projects/spring-boot/issues/46585">#46585</a></li>
<li>Adapt deprecation level for management.health.influxdb.enabled <a
href="https://redirect.github.com/spring-projects/spring-boot/issues/46580">#46580</a></li>
<li>spring.test.mockmvc properties are not documented <a
href="https://redirect.github.com/spring-projects/spring-boot/issues/46578">#46578</a></li>
</ul>
<h2>🔨 Dependency Upgrades</h2>
<ul>
<li>Upgrade to Angus Mail 2.0.4 <a
href="https://redirect.github.com/spring-projects/spring-boot/issues/46725">#46725</a></li>
<li>Upgrade to AssertJ 3.27.4 <a
href="https://redirect.github.com/spring-projects/spring-boot/issues/46726">#46726</a></li>
<li>Upgrade to Byte Buddy 1.17.7 <a
href="https://redirect.github.com/spring-projects/spring-boot/issues/46883">#46883</a></li>
<li>Upgrade to Couchbase Client 3.8.3 <a
href="https://redirect.github.com/spring-projects/spring-boot/issues/46794">#46794</a></li>
<li>Upgrade to Elasticsearch Client 8.18.5 <a
href="https://redirect.github.com/spring-projects/spring-boot/issues/46830">#46830</a></li>
<li>Upgrade to Hibernate 6.6.26.Final <a
href="https://redirect.github.com/spring-projects/spring-boot/issues/46884">#46884</a></li>
<li>Upgrade to Hibernate Validator 8.0.3.Final <a
href="https://redirect.github.com/spring-projects/spring-boot/issues/46728">#46728</a></li>
<li>Upgrade to HikariCP 6.3.2 <a
href="https://redirect.github.com/spring-projects/spring-boot/issues/46729">#46729</a></li>
<li>Upgrade to Jersey 3.1.11 <a
href="https://redirect.github.com/spring-projects/spring-boot/issues/46730">#46730</a></li>
<li>Upgrade to Jetty 12.0.25 <a
href="https://redirect.github.com/spring-projects/spring-boot/issues/46831">#46831</a></li>
<li>Upgrade to Jetty Reactive HTTPClient 4.0.11 <a
href="https://redirect.github.com/spring-projects/spring-boot/issues/46885">#46885</a></li>
<li>Upgrade to jOOQ 3.19.25 <a
href="https://redirect.github.com/spring-projects/spring-boot/issues/46808">#46808</a></li>
<li>Upgrade to MariaDB 3.5.5 <a
href="https://redirect.github.com/spring-projects/spring-boot/issues/46779">#46779</a></li>
<li>Upgrade to Maven Javadoc Plugin 3.11.3 <a
href="https://redirect.github.com/spring-projects/spring-boot/issues/46886">#46886</a></li>
<li>Upgrade to Micrometer 1.15.3 <a
href="https://redirect.github.com/spring-projects/spring-boot/issues/46701">#46701</a></li>
<li>Upgrade to Micrometer Tracing 1.5.3 <a
href="https://redirect.github.com/spring-projects/spring-boot/issues/46702">#46702</a></li>
<li>Upgrade to MySQL 9.4.0 <a
href="https://redirect.github.com/spring-projects/spring-boot/issues/46732">#46732</a></li>
<li>Upgrade to Netty 4.1.124.Final <a
href="https://redirect.github.com/spring-projects/spring-boot/issues/46832">#46832</a></li>
<li>Upgrade to Pulsar 4.0.6 <a
href="https://redirect.github.com/spring-projects/spring-boot/issues/46733">#46733</a></li>
<li>Upgrade to Reactor Bom 2024.0.9 <a
href="https://redirect.github.com/spring-projects/spring-boot/issues/46703">#46703</a></li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/spring-projects/spring-boot/commit/3537d255b579018851951da08262cd0178e40c66"><code>3537d25</code></a>
Release v3.5.5</li>
<li><a
href="https://github.com/spring-projects/spring-boot/commit/a22e28e9e00eca994b8e412a420110da5b58b64a"><code>a22e28e</code></a>
Merge branch '3.4.x' into 3.5.x</li>
<li><a
href="https://github.com/spring-projects/spring-boot/commit/4cb8c8a1b9670497046655393ab2a0f535e8442d"><code>4cb8c8a</code></a>
Next development version (v3.4.10-SNAPSHOT)</li>
<li><a
href="https://github.com/spring-projects/spring-boot/commit/9d205e21c4c007b317cc3c65bf8dcad543e61c81"><code>9d205e2</code></a>
Merge branch '3.4.x' into 3.5.x</li>
<li><a
href="https://github.com/spring-projects/spring-boot/commit/47b06322d3df72d886d838a090f506a6ba281892"><code>47b0632</code></a>
Merge pull request <a
href="https://redirect.github.com/spring-projects/spring-boot/issues/46927">#46927</a>
from izeye</li>
<li><a
href="https://github.com/spring-projects/spring-boot/commit/8b7145802503dc00720e24db67144e568648c96f"><code>8b71458</code></a>
Adapt checkstyle rules for 3.4.x</li>
<li><a
href="https://github.com/spring-projects/spring-boot/commit/fb99badf16072b3e49aca422abe8e5be184b1af8"><code>fb99bad</code></a>
Remove redundant suppressions from Checkstyle configuration</li>
<li><a
href="https://github.com/spring-projects/spring-boot/commit/8af836a428e65b8032483d5d8159099684054cd0"><code>8af836a</code></a>
Upgrade to Spring RESTDocs 3.0.5</li>
<li><a
href="https://github.com/spring-projects/spring-boot/commit/ae6c6a5ed4652134c8f35fb8ca9a3d0149a207c2"><code>ae6c6a5</code></a>
Merge branch '3.4.x' into 3.5.x</li>
<li><a
href="https://github.com/spring-projects/spring-boot/commit/b6bae9f59b38a2dc8234d2766b062a5986410a37"><code>b6bae9f</code></a>
Upgrade to Spring RESTDocs 3.0.5</li>
<li>Additional commits viewable in <a
href="https://github.com/spring-projects/spring-boot/compare/v3.5.4...v3.5.5">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=org.springframework.boot&package-manager=gradle&previous-version=3.5.4&new-version=3.5.5)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-24 21:03:53 +01:00
dependabot[bot] 1d89917e88 build(deps): bump org.springdoc:springdoc-openapi-starter-webmvc-ui from 2.8.9 to 2.8.11 (#4273)
Bumps
[org.springdoc:springdoc-openapi-starter-webmvc-ui](https://github.com/springdoc/springdoc-openapi)
from 2.8.9 to 2.8.11.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/springdoc/springdoc-openapi/releases">org.springdoc:springdoc-openapi-starter-webmvc-ui's
releases</a>.</em></p>
<blockquote>
<h2>springdoc-openapi v2.8.11 released!</h2>
<h3>Added</h3>
<ul>
<li><a
href="https://redirect.github.com/springdoc/springdoc-openapi/issues/3065">#3065</a>
- javadoc and overall performance optimization</li>
</ul>
<h3>Changed</h3>
<ul>
<li>Upgrade spring-boot to v3.5.5</li>
</ul>
<h3>Fixed</h3>
<ul>
<li><a
href="https://redirect.github.com/springdoc/springdoc-openapi/issues/3064">#3064</a>
-ClassNotFoundException: kotlin.reflect.full.KClasses</li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/rayuuuu"><code>@​rayuuuu</code></a> made
their first contribution in <a
href="https://redirect.github.com/springdoc/springdoc-openapi/pull/3065">springdoc/springdoc-openapi#3065</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/springdoc/springdoc-openapi/compare/v2.8.10...v2.8.11">https://github.com/springdoc/springdoc-openapi/compare/v2.8.10...v2.8.11</a></p>
<h2>springdoc-openapi v2.8.10 released!</h2>
<h2>What's Changed</h2>
<ul>
<li>Fix unexpected merging of media types by <a
href="https://github.com/Mattias-Sehlstedt"><code>@​Mattias-Sehlstedt</code></a>
in <a
href="https://redirect.github.com/springdoc/springdoc-openapi/pull/3026">springdoc/springdoc-openapi#3026</a></li>
<li>Fixed &quot;desciption&quot; typo by <a
href="https://github.com/lc-nyovchev"><code>@​lc-nyovchev</code></a> in
<a
href="https://redirect.github.com/springdoc/springdoc-openapi/pull/3036">springdoc/springdoc-openapi#3036</a></li>
<li>Fix: Property resolution for extensions within
<code>@OpenAPIDefinition</code> Info object by <a
href="https://github.com/limehee"><code>@​limehee</code></a> in <a
href="https://redirect.github.com/springdoc/springdoc-openapi/pull/3039">springdoc/springdoc-openapi#3039</a></li>
<li>Support externalDocs configure on SpecPropertiesCustomizer by <a
href="https://github.com/huisam"><code>@​huisam</code></a> in <a
href="https://redirect.github.com/springdoc/springdoc-openapi/pull/3042">springdoc/springdoc-openapi#3042</a></li>
<li>Use adaptFromForwardedHeaders instead of deprecated fromHttpRequest
by <a
href="https://github.com/thijsnissen"><code>@​thijsnissen</code></a> in
<a
href="https://redirect.github.com/springdoc/springdoc-openapi/pull/3060">springdoc/springdoc-openapi#3060</a></li>
<li>Fixes so that a RequestPart with a Map is added to the RequestBody
by <a
href="https://github.com/Mattias-Sehlstedt"><code>@​Mattias-Sehlstedt</code></a>
in <a
href="https://redirect.github.com/springdoc/springdoc-openapi/pull/3051">springdoc/springdoc-openapi#3051</a></li>
<li>Refactor webhook discovery and scanning mechanism by <a
href="https://github.com/zdary"><code>@​zdary</code></a> in <a
href="https://redirect.github.com/springdoc/springdoc-openapi/pull/3057">springdoc/springdoc-openapi#3057</a></li>
</ul>
<h3>Added</h3>
<ul>
<li><a
href="https://redirect.github.com/springdoc/springdoc-openapi/issues/3046">#3046</a>
- Feature Request: Support <a
href="https://github.com/jakarta"><code>@​jakarta</code></a>.annotation.Nonnull.</li>
<li><a
href="https://redirect.github.com/springdoc/springdoc-openapi/issues/3042">#3042</a>
- Support externalDocs configure on SpecPropertiesCustomizer</li>
<li><a
href="https://redirect.github.com/springdoc/springdoc-openapi/issues/3057">#3057</a>
- Refactor webhook discovery and scanning mechanism</li>
</ul>
<h3>Changed</h3>
<ul>
<li>Upgrade spring-boot to v3.5.4</li>
<li>Upgrade swagger-ui to v5.27.1</li>
<li>Upgrade swagger-core to 2.2.36</li>
</ul>
<h3>Fixed</h3>
<ul>
<li><a
href="https://redirect.github.com/springdoc/springdoc-openapi/issues/3050">#3050</a>
- <a
href="https://github.com/RequestPart"><code>@​RequestPart</code></a>
JSON parameters missing Content-Type in generated curl commands, causing
415 errors.</li>
<li><a
href="https://redirect.github.com/springdoc/springdoc-openapi/issues/2978">#2978</a>
- Parameter is no longer optional after upgrade to 2.8.8</li>
<li><a
href="https://redirect.github.com/springdoc/springdoc-openapi/issues/3022">#3022</a>
- NullPointerException thrown in SchemaUtils.</li>
<li><a
href="https://redirect.github.com/springdoc/springdoc-openapi/issues/3026">#3026</a>
- Fix unexpected merging of media types</li>
<li><a
href="https://redirect.github.com/springdoc/springdoc-openapi/issues/3036">#3036</a>
- Fixed &quot;desciption&quot;</li>
<li><a
href="https://redirect.github.com/springdoc/springdoc-openapi/issues/3039">#3039</a>
- Fix: Property resolution for extensions within <a
href="https://github.com/OpenAPIDefinition"><code>@​OpenAPIDefinition</code></a>
Info object</li>
<li><a
href="https://redirect.github.com/springdoc/springdoc-openapi/issues/3051">#3051</a>
- Fixes so that a RequestPart with a Map is added to the
RequestBody</li>
<li><a
href="https://redirect.github.com/springdoc/springdoc-openapi/issues/3060">#3060</a>
- Use adaptFromForwardedHeaders instead of deprecated
fromHttpRequest</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/springdoc/springdoc-openapi/blob/main/CHANGELOG.md">org.springdoc:springdoc-openapi-starter-webmvc-ui's
changelog</a>.</em></p>
<blockquote>
<h2>[2.8.11] - 2025-08-23</h2>
<h3>Added</h3>
<ul>
<li><a
href="https://redirect.github.com/springdoc/springdoc-openapi/issues/3065">#3065</a>
- javadoc and overall performance optimization</li>
</ul>
<h3>Changed</h3>
<ul>
<li>Upgrade spring-boot to v3.5.5</li>
</ul>
<h3>Fixed</h3>
<ul>
<li><a
href="https://redirect.github.com/springdoc/springdoc-openapi/issues/3064">#3064</a>
-ClassNotFoundException: kotlin.reflect.full.KClasses</li>
</ul>
<h2>[2.8.10] - 2025-08-20</h2>
<h3>Added</h3>
<ul>
<li><a
href="https://redirect.github.com/springdoc/springdoc-openapi/issues/3046">#3046</a>
- Feature Request: Support <a
href="https://github.com/jakarta"><code>@​jakarta</code></a>.annotation.Nonnull.</li>
<li><a
href="https://redirect.github.com/springdoc/springdoc-openapi/issues/3042">#3042</a>
- Support externalDocs configure on SpecPropertiesCustomizer</li>
<li><a
href="https://redirect.github.com/springdoc/springdoc-openapi/issues/3057">#3057</a>
- Refactor webhook discovery and scanning mechanism</li>
</ul>
<h3>Changed</h3>
<ul>
<li>Upgrade spring-boot to v3.5.4</li>
<li>Upgrade swagger-ui to v5.27.1</li>
<li>Upgrade swagger-core to 2.2.36</li>
</ul>
<h3>Fixed</h3>
<ul>
<li><a
href="https://redirect.github.com/springdoc/springdoc-openapi/issues/3050">#3050</a>
- <a
href="https://github.com/RequestPart"><code>@​RequestPart</code></a>
JSON parameters missing Content-Type in generated curl commands, causing
415 errors.</li>
<li><a
href="https://redirect.github.com/springdoc/springdoc-openapi/issues/2978">#2978</a>
- Parameter is no longer optional after upgrade to 2.8.8</li>
<li><a
href="https://redirect.github.com/springdoc/springdoc-openapi/issues/3022">#3022</a>
- NullPointerException thrown in SchemaUtils.</li>
<li><a
href="https://redirect.github.com/springdoc/springdoc-openapi/issues/3026">#3026</a>
- Fix unexpected merging of media types</li>
<li><a
href="https://redirect.github.com/springdoc/springdoc-openapi/issues/3036">#3036</a>
- Fixed &quot;desciption&quot;</li>
<li><a
href="https://redirect.github.com/springdoc/springdoc-openapi/issues/3039">#3039</a>
- Fix: Property resolution for extensions within <a
href="https://github.com/OpenAPIDefinition"><code>@​OpenAPIDefinition</code></a>
Info object</li>
<li><a
href="https://redirect.github.com/springdoc/springdoc-openapi/issues/3051">#3051</a>
- Fixes so that a RequestPart with a Map is added to the
RequestBody</li>
<li><a
href="https://redirect.github.com/springdoc/springdoc-openapi/issues/3060">#3060</a>
- Use adaptFromForwardedHeaders instead of deprecated
fromHttpRequest</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/springdoc/springdoc-openapi/commit/1cf8e58c4dd635520e377bea82be8821df8013ac"><code>1cf8e58</code></a>
[maven-release-plugin] prepare release v2.8.11</li>
<li><a
href="https://github.com/springdoc/springdoc-openapi/commit/9d811218ebce2c772a1964634485c579ab9f3622"><code>9d81121</code></a>
CHANGELOG.md update</li>
<li><a
href="https://github.com/springdoc/springdoc-openapi/commit/00d8525df43e5ecddcc81214aa013b42c62b8480"><code>00d8525</code></a>
performance tunning</li>
<li><a
href="https://github.com/springdoc/springdoc-openapi/commit/fba01145d3fdb6d0a9d5105d3bdaf743fdea146d"><code>fba0114</code></a>
upgrade to spring-boot 3.5.5</li>
<li><a
href="https://github.com/springdoc/springdoc-openapi/commit/957b4a91644f4148ed17a276780b3f5d3376d287"><code>957b4a9</code></a>
Merge branch 'rayuuuu-main'</li>
<li><a
href="https://github.com/springdoc/springdoc-openapi/commit/5823621fe367c7531d565401b609a2202dd2aeb4"><code>5823621</code></a>
Merge branch 'main' of <a
href="https://github.com/rayuuuu/springdoc-openapi">https://github.com/rayuuuu/springdoc-openapi</a>
into rayu...</li>
<li><a
href="https://github.com/springdoc/springdoc-openapi/commit/133b4c335849473135d43fa9c922a5439e6bcd36"><code>133b4c3</code></a>
java.lang.ClassNotFoundException: kotlin.reflect.full.KClasses when
upgrade f...</li>
<li><a
href="https://github.com/springdoc/springdoc-openapi/commit/7be993e5b8c2f3c988c4cdec621ad7123f60aaf1"><code>7be993e</code></a>
feat: javadoc performance optimization</li>
<li><a
href="https://github.com/springdoc/springdoc-openapi/commit/e1b9f7114a0660c7f9af6bd16bbe55efbe846194"><code>e1b9f71</code></a>
[maven-release-plugin] prepare for next development iteration</li>
<li><a
href="https://github.com/springdoc/springdoc-openapi/commit/2a59f95ff06b90023424e1021f6c8f09c87b21f5"><code>2a59f95</code></a>
[maven-release-plugin] prepare release v2.8.10</li>
<li>Additional commits viewable in <a
href="https://github.com/springdoc/springdoc-openapi/compare/v2.8.9...v2.8.11">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=org.springdoc:springdoc-openapi-starter-webmvc-ui&package-manager=gradle&previous-version=2.8.9&new-version=2.8.11)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-24 21:03:37 +01:00
Ludy 409cada93a chore(ci): include testing/** in file change detection for docker-compose-tests workflow (#4206)
# Description of Changes

- Added `testing/**` to `.github/config/.files.yaml` so that changes in
the `testing` directory will trigger the `docker-compose-tests` workflow
in `build.yml`.
- Updated Python dependencies in
`.github/scripts/requirements_pre_commit.txt` and
`testing/cucumber/requirements.txt` to newer versions, including
`behave`, `pypdf`, `reportlab`, and others.
- Introduced new dependencies like `colorama`, `cucumber-expressions`,
`cucumber-tag-expressions`, and `tomli` in the testing requirements to
support enhanced test execution.
- Ensured hash integrity for all dependency updates.

This change was made to ensure that modifications in the testing suite
automatically trigger relevant CI jobs and that testing dependencies
remain up-to-date for compatibility and stability.

---

## 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/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)
- [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/devGuide/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/devGuide/DeveloperGuide.md#6-testing)
for more details.
2025-08-21 10:31:25 +01:00
Ludy c141a15215 refactor(build): centralize security disable condition in shared Gradle property (#4209)
# Description of Changes

- Introduced `ext.isSecurityDisabled` closure in root `build.gradle` to
consolidate logic for determining if security features should be
disabled.
- Removed duplicated conditional checks from `sourceSets` configurations
in both root and `app/core` `build.gradle` files.
- Updated dependency inclusion for `:proprietary` module to use the new
`isSecurityDisabled()` method for clarity and maintainability.
- Simplified build logic by reducing repeated environment and property
checks.

This change improves maintainability by ensuring that the security
disable condition is defined in one place, reducing the risk of
inconsistencies across modules.

---

## 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/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)
- [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/devGuide/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/devGuide/DeveloperGuide.md#6-testing)
for more details.
2025-08-20 15:38:21 +01:00
Ludy ab7cef5a97 feat(common,core,proprietary): remove unused injections, enhance type safety, and improve test mocks (#4213)
# Description of Changes

This PR introduces several refactorings and minor enhancements across
the `common`, `core`, and `proprietary` modules:

- **Dependency Injection Cleanup**
- Removed unused constructor-injected dependencies (e.g.,
`FileOrUploadService`, `ApplicationProperties`, redundant `@Autowired`
annotations).
  - Simplified constructors to only require actively used dependencies.

- **Model Enhancements**
- Added `@NoArgsConstructor` to `FileInfo`, `PdfMetadata`, and
`SignatureFile` to improve serialization/deserialization support.

- **Service Improvements**
- Improved `JobExecutorService` content type retrieval by assigning
`MediaType` to a variable before conversion.
- Enhanced `KeyPersistenceService` with type-safe
`.filter(JwtVerificationKey.class::isInstance)`.
- Annotated `decodePublicKey` in `KeyPersistenceService` with
`@Override` for clarity.

- **Controller & API Changes**
- Updated `AdminSettingsController` to use
`TypeReference<Map<String,Object>>` for safer conversion.
- Improved long log and description strings with consistent formatting.

- **Testing Updates**
- Replaced `.lenient()` mock settings with
`.defaultAnswer(RETURNS_DEFAULTS)` for `FileToPdf` static mocks.
- Used `ArgumentMatchers.<TypeReference<List<BookmarkItem>>>any()` in
`EditTableOfContentsControllerTest` for type safety.
- Updated `UserServiceTest` default `AuthenticationType` from `SSO` to
`OAUTH2`.

- **Formatting**
  - Broke up long log/debug lines for better readability.
  - Removed redundant `@SuppressWarnings` where type safety was ensured.

These changes aim to make the codebase leaner, more type-safe, and
maintainable, while improving test reliability.

---

## 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/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)
- [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/devGuide/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/devGuide/DeveloperGuide.md#6-testing)
for more details.
2025-08-20 15:36:39 +01:00
Ludy c10474fd30 fix(h2): refine SQL condition check for custom database flag (#4216)
# Description of Changes

- Refactored `H2SQLCondition.matches` to use `env.getProperty` with
proper default values and types.
- Adjusted logic to only return `false` when a custom database is
enabled and datasource type is not `h2`.
- Simplified environment variable handling for better readability and
robustness.

---

## 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/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)
- [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/devGuide/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/devGuide/DeveloperGuide.md#6-testing)
for more details.
2025-08-20 15:35:24 +01:00
dependabot[bot] 246a59a794 build(deps): bump github/codeql-action from 3.29.8 to 3.29.10 (#4231)
Bumps [github/codeql-action](https://github.com/github/codeql-action)
from 3.29.8 to 3.29.10.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/github/codeql-action/releases">github/codeql-action's
releases</a>.</em></p>
<blockquote>
<h2>v3.29.10</h2>
<h1>CodeQL Action Changelog</h1>
<p>See the <a
href="https://github.com/github/codeql-action/releases">releases
page</a> for the relevant changes to the CodeQL CLI and language
packs.</p>
<h2>3.29.10 - 18 Aug 2025</h2>
<p>No user facing changes.</p>
<p>See the full <a
href="https://github.com/github/codeql-action/blob/v3.29.10/CHANGELOG.md">CHANGELOG.md</a>
for more information.</p>
<h2>v3.29.9</h2>
<h1>CodeQL Action Changelog</h1>
<p>See the <a
href="https://github.com/github/codeql-action/releases">releases
page</a> for the relevant changes to the CodeQL CLI and language
packs.</p>
<h2>3.29.9 - 12 Aug 2025</h2>
<p>No user facing changes.</p>
<p>See the full <a
href="https://github.com/github/codeql-action/blob/v3.29.9/CHANGELOG.md">CHANGELOG.md</a>
for more information.</p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/github/codeql-action/blob/main/CHANGELOG.md">github/codeql-action's
changelog</a>.</em></p>
<blockquote>
<h1>CodeQL Action Changelog</h1>
<p>See the <a
href="https://github.com/github/codeql-action/releases">releases
page</a> for the relevant changes to the CodeQL CLI and language
packs.</p>
<h2>[UNRELEASED]</h2>
<p>No user facing changes.</p>
<h2>3.29.10 - 18 Aug 2025</h2>
<p>No user facing changes.</p>
<h2>3.29.9 - 12 Aug 2025</h2>
<p>No user facing changes.</p>
<h2>3.29.8 - 08 Aug 2025</h2>
<ul>
<li>Fix an issue where the Action would autodetect unsupported languages
such as HTML. <a
href="https://redirect.github.com/github/codeql-action/pull/3015">#3015</a></li>
</ul>
<h2>3.29.7 - 07 Aug 2025</h2>
<p>This release rolls back 3.29.6 to address issues with language
autodetection. It is identical to 3.29.5.</p>
<h2>3.29.6 - 07 Aug 2025</h2>
<ul>
<li>The <code>cleanup-level</code> input to the <code>analyze</code>
Action is now deprecated. The CodeQL Action has written a limited amount
of intermediate results to the database since version 2.2.5, and now
automatically manages cleanup. <a
href="https://redirect.github.com/github/codeql-action/pull/2999">#2999</a></li>
<li>Update default CodeQL bundle version to 2.22.3. <a
href="https://redirect.github.com/github/codeql-action/pull/3000">#3000</a></li>
</ul>
<h2>3.29.5 - 29 Jul 2025</h2>
<ul>
<li>Update default CodeQL bundle version to 2.22.2. <a
href="https://redirect.github.com/github/codeql-action/pull/2986">#2986</a></li>
</ul>
<h2>3.29.4 - 23 Jul 2025</h2>
<p>No user facing changes.</p>
<h2>3.29.3 - 21 Jul 2025</h2>
<p>No user facing changes.</p>
<h2>3.29.2 - 30 Jun 2025</h2>
<ul>
<li>Experimental: When the <code>quality-queries</code> input for the
<code>init</code> action is provided with an argument, separate
<code>.quality.sarif</code> files are produced and uploaded for each
language with the results of the specified queries. Do not use this in
production as it is part of an internal experiment and subject to change
at any time. <a
href="https://redirect.github.com/github/codeql-action/pull/2935">#2935</a></li>
</ul>
<h2>3.29.1 - 27 Jun 2025</h2>
<ul>
<li>Fix bug in PR analysis where user-provided <code>include</code>
query filter fails to exclude non-included queries. <a
href="https://redirect.github.com/github/codeql-action/pull/2938">#2938</a></li>
<li>Update default CodeQL bundle version to 2.22.1. <a
href="https://redirect.github.com/github/codeql-action/pull/2950">#2950</a></li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/github/codeql-action/commit/96f518a34f7a870018057716cc4d7a5c014bd61c"><code>96f518a</code></a>
Merge pull request <a
href="https://redirect.github.com/github/codeql-action/issues/3042">#3042</a>
from github/update-v3.29.10-6ec994ecb</li>
<li><a
href="https://github.com/github/codeql-action/commit/57a1c6b3e7be038f5eeeeb5323255e363f4b0100"><code>57a1c6b</code></a>
Update changelog for v3.29.10</li>
<li><a
href="https://github.com/github/codeql-action/commit/6ec994ecba29cf3cf0724e281b919d68714895ce"><code>6ec994e</code></a>
Merge pull request <a
href="https://redirect.github.com/github/codeql-action/issues/3039">#3039</a>
from github/mbg/remove-cpp-bmn-check</li>
<li><a
href="https://github.com/github/codeql-action/commit/3f00c7c1e1cf5d62a6dcd81509929718baa53e5f"><code>3f00c7c</code></a>
Remove unused C++ BMN FF</li>
<li><a
href="https://github.com/github/codeql-action/commit/141ee4abd8937999bf5108d222dd9f553490f3a8"><code>141ee4a</code></a>
Remove C++ BMN FF check that is no longer used</li>
<li><a
href="https://github.com/github/codeql-action/commit/233052189b8c862bfaf875fb02c115f54d2b9286"><code>2330521</code></a>
Merge pull request <a
href="https://redirect.github.com/github/codeql-action/issues/3037">#3037</a>
from github/henrymercer/failed-upload-logs</li>
<li><a
href="https://github.com/github/codeql-action/commit/3966569d06c954a63fdb79944f148b2f8b4ceed8"><code>3966569</code></a>
Merge pull request <a
href="https://redirect.github.com/github/codeql-action/issues/3035">#3035</a>
from github/henrymercer/fix-cleanup-info</li>
<li><a
href="https://github.com/github/codeql-action/commit/f7bd70c7faab9b863a52c058f145ec121b391925"><code>f7bd70c</code></a>
Merge branch 'main' into henrymercer/failed-upload-logs</li>
<li><a
href="https://github.com/github/codeql-action/commit/75151c27826716b79222a4d1ddac714dc37eff65"><code>75151c2</code></a>
Merge branch 'main' into henrymercer/fix-cleanup-info</li>
<li><a
href="https://github.com/github/codeql-action/commit/4ff91f10807d53419e564e2484e7045e207584b9"><code>4ff91f1</code></a>
Merge pull request <a
href="https://redirect.github.com/github/codeql-action/issues/3036">#3036</a>
from github/mbg/ci/gradle9</li>
<li>Additional commits viewable in <a
href="https://github.com/github/codeql-action/compare/76621b61decf072c1cee8dd1ce2d2a82d33c17ed...96f518a34f7a870018057716cc4d7a5c014bd61c">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=github/codeql-action&package-manager=github_actions&previous-version=3.29.8&new-version=3.29.10)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-20 15:34:26 +01:00
dependabot[bot] 12d4e26aa3 build(deps): bump jwtVersion from 0.12.6 to 0.12.7 (#4229)
Bumps `jwtVersion` from 0.12.6 to 0.12.7.
Updates `io.jsonwebtoken:jjwt-api` from 0.12.6 to 0.12.7
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/jwtk/jjwt/releases">io.jsonwebtoken:jjwt-api's
releases</a>.</em></p>
<blockquote>
<h2>0.12.7</h2>
<p>This patch release:</p>
<ul>
<li>
<p>Adds a new Maven BOM! This is useful for multi-module projects. See
<a href="https://redirect.github.com/jwtk/jjwt/issues/967">Issue
967</a>.</p>
</li>
<li>
<p>Allows the <code>JwtParserBuilder</code> to have empty nested
algorithm collections, effectively disabling the parser's associated
feature:</p>
<ul>
<li>Emptying the <code>zip()</code> nested collection disables JWT
decompression.</li>
<li>Emptying the <code>sig()</code> nested collection disables JWS
mac/signature verification (i.e. all JWSs will be
unsupported/rejected).</li>
<li>Emptying either the <code>enc()</code> or <code>key()</code> nested
collections disables JWE decryption (i.e. all JWEs will be
unsupported/rejected)</li>
</ul>
<p>See <a href="https://redirect.github.com/jwtk/jjwt/issues/996">Issue
996</a>.</p>
</li>
<li>
<p>Fixes <a href="https://redirect.github.com/jwtk/jjwt/issues/961">bug
961</a> where <code>JwtParserBuilder</code> nested collection builders
were not correctly replacing algorithms with the same id.</p>
</li>
<li>
<p>Ensures a <code>JwkSet</code>'s <code>keys</code> collection is no
longer entirely secret/redacted by default. This was an overzealous
default that was unnecessarily restrictive; the <code>keys</code>
collection itself should always be public, and each individual key
within should determine which fields should be redacted when printed.
See <a href="https://redirect.github.com/jwtk/jjwt/issues/976">Issue
976</a>.</p>
</li>
<li>
<p>Improves performance slightly by ensuring all <code>jjwt-api</code>
utility methods that create <code>*Builder</code> instances
(<code>Jwts.builder()</code>, <code>Jwts.parserBuilder()</code>,
<code>Jwks.builder()</code>, etc) no longer use reflection.</p>
<p>Instead,<code>static</code> factories are created via reflection only
once during initial <code>jjwt-api</code> classloading, and then
<code>*Builder</code>s are created via standard instantiation using the
<code>new</code> operator thereafter. This also benefits certain
environments that may not have ideal <code>ClassLoader</code>
implementations (e.g. Tomcat in some cases).</p>
<p><strong>NOTE: because this changes which classes are loaded via
reflection, any environments that must explicitly reference reflective
class names (e.g. GraalVM applications) will need to be updated to
reflect the new factory class names</strong>.</p>
<p>See <a href="https://redirect.github.com/jwtk/jjwt/issues/988">Issue
988</a>.</p>
</li>
<li>
<p>Upgrades the Gson dependency to <code>2.11.0</code></p>
</li>
<li>
<p>Upgrades the BouncyCastle dependency to <code>1.78.1</code></p>
</li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/sigpwned"><code>@​sigpwned</code></a>
made their first contribution in <a
href="https://redirect.github.com/jwtk/jjwt/pull/968">jwtk/jjwt#968</a></li>
<li><a
href="https://github.com/TheMrMilchmann"><code>@​TheMrMilchmann</code></a>
made their first contribution in <a
href="https://redirect.github.com/jwtk/jjwt/pull/979">jwtk/jjwt#979</a></li>
<li><a href="https://github.com/atanasg"><code>@​atanasg</code></a> made
their first contribution in <a
href="https://redirect.github.com/jwtk/jjwt/pull/974">jwtk/jjwt#974</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/jwtk/jjwt/compare/0.12.6...0.12.7">https://github.com/jwtk/jjwt/compare/0.12.6...0.12.7</a></p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/jwtk/jjwt/blob/master/CHANGELOG.md">io.jsonwebtoken:jjwt-api's
changelog</a>.</em></p>
<blockquote>
<h3>0.12.7</h3>
<p>This patch release:</p>
<ul>
<li>
<p>Adds a new Maven BOM, useful for multi-module projects. See <a
href="https://redirect.github.com/jwtk/jjwt/issues/967">Issue
967</a>.</p>
</li>
<li>
<p>Allows the <code>JwtParserBuilder</code> to have empty nested
algorithm collections, effectively disabling the parser's associated
feature:</p>
<ul>
<li>Emptying the <code>zip()</code> nested collection disables JWT
decompression.</li>
<li>Emptying the <code>sig()</code> nested collection disables JWS
mac/signature verification (i.e. all JWSs will be
unsupported/rejected).</li>
<li>Emptying either the <code>enc()</code> or <code>key()</code> nested
collections disables JWE decryption (i.e. all JWEs will be
unsupported/rejected)</li>
</ul>
<p>See <a href="https://redirect.github.com/jwtk/jjwt/issues/996">Issue
996</a>.</p>
</li>
<li>
<p>Fixes <a href="https://redirect.github.com/jwtk/jjwt/issues/961">bug
961</a> where <code>JwtParserBuilder</code> nested collection builders
were not correctly replacing algorithms with the same id.</p>
</li>
<li>
<p>Ensures a <code>JwkSet</code>'s <code>keys</code> collection is no
longer entirely secret/redacted by default. This was an overzealous
default that was unnecessarily restrictive; the <code>keys</code>
collection itself should always be public, and each individual key
within should determine which fields should be redacted when printed.
See <a href="https://redirect.github.com/jwtk/jjwt/issues/976">Issue
976</a>.</p>
</li>
<li>
<p>Improves performance slightly by ensuring all <code>jjwt-api</code>
utility methods that create <code>*Builder</code> instances
(<code>Jwts.builder()</code>, <code>Jwts.parserBuilder()</code>,
<code>Jwks.builder()</code>, etc) no longer use reflection.</p>
<p>Instead,<code>static</code> factories are created via reflection only
once during initial <code>jjwt-api</code> classloading, and then
<code>*Builder</code>s are created via standard instantiation using the
<code>new</code> operator thereafter. This also benefits certain
environments that may not have ideal <code>ClassLoader</code>
implementations (e.g. Tomcat in some cases).</p>
<p><strong>NOTE: because this changes which classes are loaded via
reflection, any environments that must explicitly reference reflective
class names (e.g. GraalVM applications) will need to be updated to
reflect the new factory class names</strong>.</p>
<p>See <a href="https://redirect.github.com/jwtk/jjwt/issues/988">Issue
988</a>.</p>
</li>
<li>
<p>Upgrades the Gson dependency to <code>2.11.0</code></p>
</li>
<li>
<p>Upgrades the BouncyCastle dependency to <code>1.78.1</code></p>
</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/jwtk/jjwt/commit/77aeda012c4e31b86fb66acf43a67775c6fa3142"><code>77aeda0</code></a>
[maven-release-plugin] prepare release 0.12.7</li>
<li><a
href="https://github.com/jwtk/jjwt/commit/47d966f8e93734cf35fc19f5c1a9e5cc4abe624b"><code>47d966f</code></a>
Testing latest sonatype central publishing guidelines</li>
<li><a
href="https://github.com/jwtk/jjwt/commit/22ca29fe8849b11d2793bfcf2825ef692f2c19b2"><code>22ca29f</code></a>
[maven-release-plugin] rollback the release of 0.12.7</li>
<li><a
href="https://github.com/jwtk/jjwt/commit/0487f9b49f10f37b7ad5b4e664f3e9b9a25e4a1c"><code>0487f9b</code></a>
[maven-release-plugin] prepare for next development iteration</li>
<li><a
href="https://github.com/jwtk/jjwt/commit/4329125bac91880cb852983b1475465c30a1d819"><code>4329125</code></a>
[maven-release-plugin] prepare release 0.12.7</li>
<li><a
href="https://github.com/jwtk/jjwt/commit/0ddc51421240a9832f38c9afd966429c6d1aeb19"><code>0ddc514</code></a>
- Ensured JJWT_RELEASE_VERSION placeholders reference 0.12.7</li>
<li><a
href="https://github.com/jwtk/jjwt/commit/efed1cf56f9b9715e60eaac7fda6b2c4b62410b9"><code>efed1cf</code></a>
Updated 0.12.7 change list</li>
<li><a
href="https://github.com/jwtk/jjwt/commit/ca27b122b7f44f3bdd4cd4f636d084f38cc3b3c8"><code>ca27b12</code></a>
Resolves <a
href="https://redirect.github.com/jwtk/jjwt/issues/1010">#1010</a> (<a
href="https://redirect.github.com/jwtk/jjwt/issues/1011">#1011</a>)</li>
<li><a
href="https://github.com/jwtk/jjwt/commit/55c7b9adef88328f59534f232060830c34f25478"><code>55c7b9a</code></a>
Resolves <a
href="https://redirect.github.com/jwtk/jjwt/issues/771">#771</a> (<a
href="https://redirect.github.com/jwtk/jjwt/issues/1009">#1009</a>)</li>
<li><a
href="https://github.com/jwtk/jjwt/commit/6e9c6a5a825c5ec38f90006f48cc1f8640a6d82e"><code>6e9c6a5</code></a>
Bump org.bouncycastle:bcpkix-jdk18on from 1.78 to 1.78.1 (<a
href="https://redirect.github.com/jwtk/jjwt/issues/1008">#1008</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/jwtk/jjwt/compare/0.12.6...0.12.7">compare
view</a></li>
</ul>
</details>
<br />

Updates `io.jsonwebtoken:jjwt-impl` from 0.12.6 to 0.12.7
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/jwtk/jjwt/releases">io.jsonwebtoken:jjwt-impl's
releases</a>.</em></p>
<blockquote>
<h2>0.12.7</h2>
<p>This patch release:</p>
<ul>
<li>
<p>Adds a new Maven BOM! This is useful for multi-module projects. See
<a href="https://redirect.github.com/jwtk/jjwt/issues/967">Issue
967</a>.</p>
</li>
<li>
<p>Allows the <code>JwtParserBuilder</code> to have empty nested
algorithm collections, effectively disabling the parser's associated
feature:</p>
<ul>
<li>Emptying the <code>zip()</code> nested collection disables JWT
decompression.</li>
<li>Emptying the <code>sig()</code> nested collection disables JWS
mac/signature verification (i.e. all JWSs will be
unsupported/rejected).</li>
<li>Emptying either the <code>enc()</code> or <code>key()</code> nested
collections disables JWE decryption (i.e. all JWEs will be
unsupported/rejected)</li>
</ul>
<p>See <a href="https://redirect.github.com/jwtk/jjwt/issues/996">Issue
996</a>.</p>
</li>
<li>
<p>Fixes <a href="https://redirect.github.com/jwtk/jjwt/issues/961">bug
961</a> where <code>JwtParserBuilder</code> nested collection builders
were not correctly replacing algorithms with the same id.</p>
</li>
<li>
<p>Ensures a <code>JwkSet</code>'s <code>keys</code> collection is no
longer entirely secret/redacted by default. This was an overzealous
default that was unnecessarily restrictive; the <code>keys</code>
collection itself should always be public, and each individual key
within should determine which fields should be redacted when printed.
See <a href="https://redirect.github.com/jwtk/jjwt/issues/976">Issue
976</a>.</p>
</li>
<li>
<p>Improves performance slightly by ensuring all <code>jjwt-api</code>
utility methods that create <code>*Builder</code> instances
(<code>Jwts.builder()</code>, <code>Jwts.parserBuilder()</code>,
<code>Jwks.builder()</code>, etc) no longer use reflection.</p>
<p>Instead,<code>static</code> factories are created via reflection only
once during initial <code>jjwt-api</code> classloading, and then
<code>*Builder</code>s are created via standard instantiation using the
<code>new</code> operator thereafter. This also benefits certain
environments that may not have ideal <code>ClassLoader</code>
implementations (e.g. Tomcat in some cases).</p>
<p><strong>NOTE: because this changes which classes are loaded via
reflection, any environments that must explicitly reference reflective
class names (e.g. GraalVM applications) will need to be updated to
reflect the new factory class names</strong>.</p>
<p>See <a href="https://redirect.github.com/jwtk/jjwt/issues/988">Issue
988</a>.</p>
</li>
<li>
<p>Upgrades the Gson dependency to <code>2.11.0</code></p>
</li>
<li>
<p>Upgrades the BouncyCastle dependency to <code>1.78.1</code></p>
</li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/sigpwned"><code>@​sigpwned</code></a>
made their first contribution in <a
href="https://redirect.github.com/jwtk/jjwt/pull/968">jwtk/jjwt#968</a></li>
<li><a
href="https://github.com/TheMrMilchmann"><code>@​TheMrMilchmann</code></a>
made their first contribution in <a
href="https://redirect.github.com/jwtk/jjwt/pull/979">jwtk/jjwt#979</a></li>
<li><a href="https://github.com/atanasg"><code>@​atanasg</code></a> made
their first contribution in <a
href="https://redirect.github.com/jwtk/jjwt/pull/974">jwtk/jjwt#974</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/jwtk/jjwt/compare/0.12.6...0.12.7">https://github.com/jwtk/jjwt/compare/0.12.6...0.12.7</a></p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/jwtk/jjwt/blob/master/CHANGELOG.md">io.jsonwebtoken:jjwt-impl's
changelog</a>.</em></p>
<blockquote>
<h3>0.12.7</h3>
<p>This patch release:</p>
<ul>
<li>
<p>Adds a new Maven BOM, useful for multi-module projects. See <a
href="https://redirect.github.com/jwtk/jjwt/issues/967">Issue
967</a>.</p>
</li>
<li>
<p>Allows the <code>JwtParserBuilder</code> to have empty nested
algorithm collections, effectively disabling the parser's associated
feature:</p>
<ul>
<li>Emptying the <code>zip()</code> nested collection disables JWT
decompression.</li>
<li>Emptying the <code>sig()</code> nested collection disables JWS
mac/signature verification (i.e. all JWSs will be
unsupported/rejected).</li>
<li>Emptying either the <code>enc()</code> or <code>key()</code> nested
collections disables JWE decryption (i.e. all JWEs will be
unsupported/rejected)</li>
</ul>
<p>See <a href="https://redirect.github.com/jwtk/jjwt/issues/996">Issue
996</a>.</p>
</li>
<li>
<p>Fixes <a href="https://redirect.github.com/jwtk/jjwt/issues/961">bug
961</a> where <code>JwtParserBuilder</code> nested collection builders
were not correctly replacing algorithms with the same id.</p>
</li>
<li>
<p>Ensures a <code>JwkSet</code>'s <code>keys</code> collection is no
longer entirely secret/redacted by default. This was an overzealous
default that was unnecessarily restrictive; the <code>keys</code>
collection itself should always be public, and each individual key
within should determine which fields should be redacted when printed.
See <a href="https://redirect.github.com/jwtk/jjwt/issues/976">Issue
976</a>.</p>
</li>
<li>
<p>Improves performance slightly by ensuring all <code>jjwt-api</code>
utility methods that create <code>*Builder</code> instances
(<code>Jwts.builder()</code>, <code>Jwts.parserBuilder()</code>,
<code>Jwks.builder()</code>, etc) no longer use reflection.</p>
<p>Instead,<code>static</code> factories are created via reflection only
once during initial <code>jjwt-api</code> classloading, and then
<code>*Builder</code>s are created via standard instantiation using the
<code>new</code> operator thereafter. This also benefits certain
environments that may not have ideal <code>ClassLoader</code>
implementations (e.g. Tomcat in some cases).</p>
<p><strong>NOTE: because this changes which classes are loaded via
reflection, any environments that must explicitly reference reflective
class names (e.g. GraalVM applications) will need to be updated to
reflect the new factory class names</strong>.</p>
<p>See <a href="https://redirect.github.com/jwtk/jjwt/issues/988">Issue
988</a>.</p>
</li>
<li>
<p>Upgrades the Gson dependency to <code>2.11.0</code></p>
</li>
<li>
<p>Upgrades the BouncyCastle dependency to <code>1.78.1</code></p>
</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/jwtk/jjwt/commit/77aeda012c4e31b86fb66acf43a67775c6fa3142"><code>77aeda0</code></a>
[maven-release-plugin] prepare release 0.12.7</li>
<li><a
href="https://github.com/jwtk/jjwt/commit/47d966f8e93734cf35fc19f5c1a9e5cc4abe624b"><code>47d966f</code></a>
Testing latest sonatype central publishing guidelines</li>
<li><a
href="https://github.com/jwtk/jjwt/commit/22ca29fe8849b11d2793bfcf2825ef692f2c19b2"><code>22ca29f</code></a>
[maven-release-plugin] rollback the release of 0.12.7</li>
<li><a
href="https://github.com/jwtk/jjwt/commit/0487f9b49f10f37b7ad5b4e664f3e9b9a25e4a1c"><code>0487f9b</code></a>
[maven-release-plugin] prepare for next development iteration</li>
<li><a
href="https://github.com/jwtk/jjwt/commit/4329125bac91880cb852983b1475465c30a1d819"><code>4329125</code></a>
[maven-release-plugin] prepare release 0.12.7</li>
<li><a
href="https://github.com/jwtk/jjwt/commit/0ddc51421240a9832f38c9afd966429c6d1aeb19"><code>0ddc514</code></a>
- Ensured JJWT_RELEASE_VERSION placeholders reference 0.12.7</li>
<li><a
href="https://github.com/jwtk/jjwt/commit/efed1cf56f9b9715e60eaac7fda6b2c4b62410b9"><code>efed1cf</code></a>
Updated 0.12.7 change list</li>
<li><a
href="https://github.com/jwtk/jjwt/commit/ca27b122b7f44f3bdd4cd4f636d084f38cc3b3c8"><code>ca27b12</code></a>
Resolves <a
href="https://redirect.github.com/jwtk/jjwt/issues/1010">#1010</a> (<a
href="https://redirect.github.com/jwtk/jjwt/issues/1011">#1011</a>)</li>
<li><a
href="https://github.com/jwtk/jjwt/commit/55c7b9adef88328f59534f232060830c34f25478"><code>55c7b9a</code></a>
Resolves <a
href="https://redirect.github.com/jwtk/jjwt/issues/771">#771</a> (<a
href="https://redirect.github.com/jwtk/jjwt/issues/1009">#1009</a>)</li>
<li><a
href="https://github.com/jwtk/jjwt/commit/6e9c6a5a825c5ec38f90006f48cc1f8640a6d82e"><code>6e9c6a5</code></a>
Bump org.bouncycastle:bcpkix-jdk18on from 1.78 to 1.78.1 (<a
href="https://redirect.github.com/jwtk/jjwt/issues/1008">#1008</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/jwtk/jjwt/compare/0.12.6...0.12.7">compare
view</a></li>
</ul>
</details>
<br />

Updates `io.jsonwebtoken:jjwt-jackson` from 0.12.6 to 0.12.7


Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-20 15:34:11 +01:00
dependabot[bot] fbee4b99e4 build(deps): bump actions/dependency-review-action from 4.7.1 to 4.7.2 (#4230)
Bumps
[actions/dependency-review-action](https://github.com/actions/dependency-review-action)
from 4.7.1 to 4.7.2.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/actions/dependency-review-action/releases">actions/dependency-review-action's
releases</a>.</em></p>
<blockquote>
<h2>4.7.2</h2>
<h2>What's Changed</h2>
<ul>
<li>Add Missing Languages to CodeQL Advanced Configuration by <a
href="https://github.com/KyFaSt"><code>@​KyFaSt</code></a> in <a
href="https://redirect.github.com/actions/dependency-review-action/pull/945">actions/dependency-review-action#945</a></li>
<li>Deprecate deny lists by <a
href="https://github.com/claire153"><code>@​claire153</code></a> in <a
href="https://redirect.github.com/actions/dependency-review-action/pull/958">actions/dependency-review-action#958</a></li>
<li>Address discrepancy between docs and reality by <a
href="https://github.com/ahpook"><code>@​ahpook</code></a> in <a
href="https://redirect.github.com/actions/dependency-review-action/pull/960">actions/dependency-review-action#960</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/KyFaSt"><code>@​KyFaSt</code></a> made
their first contribution in <a
href="https://redirect.github.com/actions/dependency-review-action/pull/945">actions/dependency-review-action#945</a></li>
<li><a href="https://github.com/claire153"><code>@​claire153</code></a>
made their first contribution in <a
href="https://redirect.github.com/actions/dependency-review-action/pull/958">actions/dependency-review-action#958</a></li>
<li><a href="https://github.com/ahpook"><code>@​ahpook</code></a> made
their first contribution in <a
href="https://redirect.github.com/actions/dependency-review-action/pull/960">actions/dependency-review-action#960</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/dependency-review-action/compare/v4...v4.7.2">https://github.com/actions/dependency-review-action/compare/v4...v4.7.2</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/actions/dependency-review-action/commit/bc41886e18ea39df68b1b1245f4184881938e050"><code>bc41886</code></a>
Cut 4.7.2 version release (<a
href="https://redirect.github.com/actions/dependency-review-action/issues/964">#964</a>)</li>
<li><a
href="https://github.com/actions/dependency-review-action/commit/1c73553e364351d71bdd9718e92c824e1d39aaf1"><code>1c73553</code></a>
Merge pull request <a
href="https://redirect.github.com/actions/dependency-review-action/issues/960">#960</a>
from ahpook/ahpook/address-docs-dashes</li>
<li><a
href="https://github.com/actions/dependency-review-action/commit/fac3d41a588e61d27618248093f9c9137e20527c"><code>fac3d41</code></a>
Bump the minor-updates group across 1 directory with 5 updates (<a
href="https://redirect.github.com/actions/dependency-review-action/issues/956">#956</a>)</li>
<li><a
href="https://github.com/actions/dependency-review-action/commit/d8073c4b76cb44bb87b02d4facf11c298317533b"><code>d8073c4</code></a>
Merge pull request <a
href="https://redirect.github.com/actions/dependency-review-action/issues/958">#958</a>
from actions/claire153/deprecate-deny-lists</li>
<li><a
href="https://github.com/actions/dependency-review-action/commit/77184c6339b69987ba61f2fd650e0facc7bd2637"><code>77184c6</code></a>
Fix tests</li>
<li><a
href="https://github.com/actions/dependency-review-action/commit/5558c35bb3e79ef0a0f2d9896a56060e24df9bea"><code>5558c35</code></a>
Address discrepancy between docs and reality</li>
<li><a
href="https://github.com/actions/dependency-review-action/commit/e85d57a50e73c596b97dac69d8b3ed1a110c8bbf"><code>e85d57a</code></a>
Remove test code</li>
<li><a
href="https://github.com/actions/dependency-review-action/commit/3eb62794c5d48f3f51627b823b3efad8c224aafb"><code>3eb6279</code></a>
Re-add test package. Only show warning in summary if option is used.
Update c...</li>
<li><a
href="https://github.com/actions/dependency-review-action/commit/7cf33ac2f2d46e957b8c2df562c806d68486ab80"><code>7cf33ac</code></a>
Remove test deny list</li>
<li><a
href="https://github.com/actions/dependency-review-action/commit/493bee056051bfd97929ad42f88aa2422bd19196"><code>493bee0</code></a>
Remove test package</li>
<li>Additional commits viewable in <a
href="https://github.com/actions/dependency-review-action/compare/da24556b548a50705dd671f47852072ea4c105d9...bc41886e18ea39df68b1b1245f4184881938e050">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/dependency-review-action&package-manager=github_actions&previous-version=4.7.1&new-version=4.7.2)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-20 15:33:56 +01:00
Ludy 28b1b96cfb feat(audit): introduce structured Audit API with export, stats, and cleanup endpoints (#4217)
# Description of Changes

- Added new REST-based `AuditDashboardController` under `/api/v1/audit`
with endpoints for:
  - Audit data retrieval with pagination (`/data`)
  - Statistics retrieval (`/stats`)
  - Export in CSV and JSON (`/export/csv`, `/export/json`)
  - Cleanup of audit events before a given date (`/cleanup/before`)
  - Retrieval of distinct audit event types (`/types`)
- Extracted web dashboard logic into `AuditDashboardWebController` (view
rendering only).
- Introduced new API models:
  - `AuditDataRequest`, `AuditDataResponse`
  - `AuditExportRequest`, `AuditDateExportRequest`
  - `AuditStatsResponse`
- Extended `PersistentAuditEventRepository` with richer query methods
(histograms, counts, top/latest events, distinct principals).
- Updated `dashboard.js` to use new API endpoints under `/api/v1/audit`.
- Enhanced authentication handlers and user endpoints with `@Audited`
annotations for login/logout/password change events.
- Cleaned up `LicenseKeyChecker` by removing unused `updateLicenseKey`
method.
- Moved admin-related controllers into `controller.api` namespace with
proper OpenAPI annotations (`@Operation`, `@Tag`).
- Improved `CleanUrlInterceptor` whitelist for new query parameters
(`days`, `date`).

---

## 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/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)
- [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/devGuide/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/devGuide/DeveloperGuide.md#6-testing)
for more details.
2025-08-18 12:03:57 +01:00
d23c2eaa30 feat: Auto-redact to support text removal on True PDFs/non-custom encoded PDFs, JUnit tests for RedactController, and TextFinder (#3936)
# Description of Changes

## Overview

This enhancement adds **true PDF text removal** to RedactController. It
changes auto-redaction from visual covering to actual text removal. The
feature removes text from True PDFs completely while keeping
compatibility with other PDF types.

## Features

### 1. True PDF Text Removal

- Removes text from PDF structure instead of just hiding it
- No impact to manual redaction or other types of PDFs (e.g.: to
searchable PDFs or custom encoded PDFs)

### 2. Advanced Content Stream Processing

#### How It Works (only high level overview)
- Token Processing: Breaks PDF content into small pieces for exact text
finding
- Font Tracking: Keeps track of fonts and formatting
- Text Operators: Finds PDF commands that show text (`Tj`, `TJ`, `'`,
`"`)
- Position Mapping: Maps text to exact locations for removal
- Rebuilds PDF: Rebuilds PDFs without the text, while keeping formatting
operators

#### No change for other types PDFs

- Because the iteration through the PDF for token/text removal and for
box placing are two separate completely methods
- This means when the there is custom encoded PDF the token/text removal
won't find any text to remove (because there is no logic for decoding
for, for now) but the box finding methods still reliably finds redacted
words and puts a box onto them. So no change.

### 3. Enhanced TextFinder Integration

#### Minor Improvements
- Page Grouping: Groups found text by page for faster processing

### JUnit tests for both of files.

- Added JUnit tests for both files. 
- Might need future improvement.

### TODOs

- Support for additional PDF types besides true PDFs (currently a WIP),
e.g.: searchable PDF/custom encoded PDF
- Feature to be expected in few weeks (best case scenario, and only if I
succeed), sadly that is significantly harder task so only true PDFs for
now

### UI

- No UI change for now

### Sample files:


[Free_Test_Data_500KB_PDF_redacted.pdf](https://github.com/user-attachments/files/21195841/Free_Test_Data_500KB_PDF_redacted.pdf)

[lorem-ipsum_redacted.pdf](https://github.com/user-attachments/files/21195842/lorem-ipsum_redacted.pdf)

[true-pdf-sample-1_redacted.pdf](https://github.com/user-attachments/files/21195843/true-pdf-sample-1_redacted.pdf)

[true-pdf-sample-2_redacted.pdf](https://github.com/user-attachments/files/21195844/true-pdf-sample-2_redacted.pdf)

[true-pdf-sample-3_redacted.pdf](https://github.com/user-attachments/files/21195845/true-pdf-sample-3_redacted.pdf)


Closes: does not actually close any issues, since it only works with
true PDFs

---

## 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/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)
- [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/devGuide/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/devGuide/DeveloperGuide.md#6-testing)
for more details.

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Anthony Stirling <77850077+Frooodle@users.noreply.github.com>
2025-08-13 22:52:06 +01:00
stirlingbot[bot] 12ad8211fe Update 3rd Party Licenses (#4184)
Auto-generated by stirlingbot[bot]

Signed-off-by: stirlingbot[bot] <stirlingbot[bot]@users.noreply.github.com>
Co-authored-by: stirlingbot[bot] <195170888+stirlingbot[bot]@users.noreply.github.com>
2025-08-11 14:18:27 +01:00
stirlingbot[bot] b41230db53 🤖 format everything with pre-commit by stirlingbot (#4175)
Auto-generated by [create-pull-request][1] with **stirlingbot**

[1]: https://github.com/peter-evans/create-pull-request

Signed-off-by: stirlingbot[bot] <stirlingbot[bot]@users.noreply.github.com>
Co-authored-by: stirlingbot[bot] <195170888+stirlingbot[bot]@users.noreply.github.com>
2025-08-11 14:14:41 +01:00
albanobattistella 8211fd8dc4 Update messages_it_IT.properties (#4183)
# 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)

### 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.
2025-08-11 14:13:58 +01:00
dependabot[bot] 0afbd148cd build(deps): bump edu.sc.seis.launch4j from 3.0.7 to 4.0.0 (#4182)
Bumps edu.sc.seis.launch4j from 3.0.7 to 4.0.0.


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=edu.sc.seis.launch4j&package-manager=gradle&previous-version=3.0.7&new-version=4.0.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-11 14:12:47 +01:00
dependabot[bot] 91b2f5da53 build(deps): bump actions/ai-inference from 1.2.7 to 1.2.8 (#4181)
[//]: # (dependabot-start)
⚠️  **Dependabot is rebasing this PR** ⚠️ 

Rebasing might not happen immediately, so don't worry if this takes some
time.

Note: if you make any changes to this PR yourself, they will take
precedence over the rebase.

---

[//]: # (dependabot-end)

Bumps [actions/ai-inference](https://github.com/actions/ai-inference)
from 1.2.7 to 1.2.8.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/actions/ai-inference/releases">actions/ai-inference's
releases</a>.</em></p>
<blockquote>
<h2>v1.2.8</h2>
<h2>What's Changed</h2>
<ul>
<li>Ensure MCP loops output the right response format by <a
href="https://github.com/sgoedecke"><code>@​sgoedecke</code></a> in <a
href="https://redirect.github.com/actions/ai-inference/pull/89">actions/ai-inference#89</a></li>
<li>Force exit once inference finishes by <a
href="https://github.com/sgoedecke"><code>@​sgoedecke</code></a> in <a
href="https://redirect.github.com/actions/ai-inference/pull/88">actions/ai-inference#88</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/ai-inference/compare/v1...v1.2.8">https://github.com/actions/ai-inference/compare/v1...v1.2.8</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/actions/ai-inference/commit/b81b2afb8390ee6839b494a404766bef6493c7d9"><code>b81b2af</code></a>
Merge pull request <a
href="https://redirect.github.com/actions/ai-inference/issues/88">#88</a>
from actions/sgoedecke/force-exit-once-inference-finishes</li>
<li><a
href="https://github.com/actions/ai-inference/commit/9133f813307a2b02458ed619b7c644316a378541"><code>9133f81</code></a>
package</li>
<li><a
href="https://github.com/actions/ai-inference/commit/7923b92ef8460464ee4eb8f8975a727234fd5509"><code>7923b92</code></a>
Merge pull request <a
href="https://redirect.github.com/actions/ai-inference/issues/89">#89</a>
from actions/sgoedecke/ensure-mcp-loops-output-desired...</li>
<li><a
href="https://github.com/actions/ai-inference/commit/e44da102bfb48b5f86362e4cc7a3550e4c4e2f20"><code>e44da10</code></a>
fixup format parsing</li>
<li><a
href="https://github.com/actions/ai-inference/commit/866ae2b5d7332a2710e5fa066d267fbff1850d38"><code>866ae2b</code></a>
Ensure MCP loops output the right response format</li>
<li><a
href="https://github.com/actions/ai-inference/commit/4685e0dcd41bc58f268df3c4bf86f5dfeca31fc7"><code>4685e0d</code></a>
Force exit once inference finishes in case we are holding any
connections open</li>
<li>See full diff in <a
href="https://github.com/actions/ai-inference/compare/0cbed4a10641c75090de5968e66d70eb4660f751...b81b2afb8390ee6839b494a404766bef6493c7d9">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/ai-inference&package-manager=github_actions&previous-version=1.2.7&new-version=1.2.8)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-11 14:09:47 +01:00
dependabot[bot] 1dd5e9c649 build(deps): bump actions/checkout from 4.2.2 to 4.3.0 (#4180)
[//]: # (dependabot-start)
⚠️  **Dependabot is rebasing this PR** ⚠️ 

Rebasing might not happen immediately, so don't worry if this takes some
time.

Note: if you make any changes to this PR yourself, they will take
precedence over the rebase.

---

[//]: # (dependabot-end)

Bumps [actions/checkout](https://github.com/actions/checkout) from 4.2.2
to 4.3.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/actions/checkout/releases">actions/checkout's
releases</a>.</em></p>
<blockquote>
<h2>v4.3.0</h2>
<h2>What's Changed</h2>
<ul>
<li>docs: update README.md by <a
href="https://github.com/motss"><code>@​motss</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1971">actions/checkout#1971</a></li>
<li>Add internal repos for checking out multiple repositories by <a
href="https://github.com/mouismail"><code>@​mouismail</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1977">actions/checkout#1977</a></li>
<li>Documentation update - add recommended permissions to Readme by <a
href="https://github.com/benwells"><code>@​benwells</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2043">actions/checkout#2043</a></li>
<li>Adjust positioning of user email note and permissions heading by <a
href="https://github.com/joshmgross"><code>@​joshmgross</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2044">actions/checkout#2044</a></li>
<li>Update README.md by <a
href="https://github.com/nebuk89"><code>@​nebuk89</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2194">actions/checkout#2194</a></li>
<li>Update CODEOWNERS for actions by <a
href="https://github.com/TingluoHuang"><code>@​TingluoHuang</code></a>
in <a
href="https://redirect.github.com/actions/checkout/pull/2224">actions/checkout#2224</a></li>
<li>Update package dependencies by <a
href="https://github.com/salmanmkc"><code>@​salmanmkc</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2236">actions/checkout#2236</a></li>
<li>Prepare release v4.3.0 by <a
href="https://github.com/salmanmkc"><code>@​salmanmkc</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2237">actions/checkout#2237</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/motss"><code>@​motss</code></a> made
their first contribution in <a
href="https://redirect.github.com/actions/checkout/pull/1971">actions/checkout#1971</a></li>
<li><a href="https://github.com/mouismail"><code>@​mouismail</code></a>
made their first contribution in <a
href="https://redirect.github.com/actions/checkout/pull/1977">actions/checkout#1977</a></li>
<li><a href="https://github.com/benwells"><code>@​benwells</code></a>
made their first contribution in <a
href="https://redirect.github.com/actions/checkout/pull/2043">actions/checkout#2043</a></li>
<li><a href="https://github.com/nebuk89"><code>@​nebuk89</code></a> made
their first contribution in <a
href="https://redirect.github.com/actions/checkout/pull/2194">actions/checkout#2194</a></li>
<li><a href="https://github.com/salmanmkc"><code>@​salmanmkc</code></a>
made their first contribution in <a
href="https://redirect.github.com/actions/checkout/pull/2236">actions/checkout#2236</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/checkout/compare/v4...v4.3.0">https://github.com/actions/checkout/compare/v4...v4.3.0</a></p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/actions/checkout/blob/main/CHANGELOG.md">actions/checkout's
changelog</a>.</em></p>
<blockquote>
<h1>Changelog</h1>
<h2>V4.3.0</h2>
<ul>
<li>docs: update README.md by <a
href="https://github.com/motss"><code>@​motss</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1971">actions/checkout#1971</a></li>
<li>Add internal repos for checking out multiple repositories by <a
href="https://github.com/mouismail"><code>@​mouismail</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1977">actions/checkout#1977</a></li>
<li>Documentation update - add recommended permissions to Readme by <a
href="https://github.com/benwells"><code>@​benwells</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2043">actions/checkout#2043</a></li>
<li>Adjust positioning of user email note and permissions heading by <a
href="https://github.com/joshmgross"><code>@​joshmgross</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2044">actions/checkout#2044</a></li>
<li>Update README.md by <a
href="https://github.com/nebuk89"><code>@​nebuk89</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2194">actions/checkout#2194</a></li>
<li>Update CODEOWNERS for actions by <a
href="https://github.com/TingluoHuang"><code>@​TingluoHuang</code></a>
in <a
href="https://redirect.github.com/actions/checkout/pull/2224">actions/checkout#2224</a></li>
<li>Update package dependencies by <a
href="https://github.com/salmanmkc"><code>@​salmanmkc</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2236">actions/checkout#2236</a></li>
</ul>
<h2>v4.2.2</h2>
<ul>
<li><code>url-helper.ts</code> now leverages well-known environment
variables by <a href="https://github.com/jww3"><code>@​jww3</code></a>
in <a
href="https://redirect.github.com/actions/checkout/pull/1941">actions/checkout#1941</a></li>
<li>Expand unit test coverage for <code>isGhes</code> by <a
href="https://github.com/jww3"><code>@​jww3</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1946">actions/checkout#1946</a></li>
</ul>
<h2>v4.2.1</h2>
<ul>
<li>Check out other refs/* by commit if provided, fall back to ref by <a
href="https://github.com/orhantoy"><code>@​orhantoy</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1924">actions/checkout#1924</a></li>
</ul>
<h2>v4.2.0</h2>
<ul>
<li>Add Ref and Commit outputs by <a
href="https://github.com/lucacome"><code>@​lucacome</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1180">actions/checkout#1180</a></li>
<li>Dependency updates by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>- <a
href="https://redirect.github.com/actions/checkout/pull/1777">actions/checkout#1777</a>,
<a
href="https://redirect.github.com/actions/checkout/pull/1872">actions/checkout#1872</a></li>
</ul>
<h2>v4.1.7</h2>
<ul>
<li>Bump the minor-npm-dependencies group across 1 directory with 4
updates by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1739">actions/checkout#1739</a></li>
<li>Bump actions/checkout from 3 to 4 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1697">actions/checkout#1697</a></li>
<li>Check out other refs/* by commit by <a
href="https://github.com/orhantoy"><code>@​orhantoy</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1774">actions/checkout#1774</a></li>
<li>Pin actions/checkout's own workflows to a known, good, stable
version. by <a href="https://github.com/jww3"><code>@​jww3</code></a> in
<a
href="https://redirect.github.com/actions/checkout/pull/1776">actions/checkout#1776</a></li>
</ul>
<h2>v4.1.6</h2>
<ul>
<li>Check platform to set archive extension appropriately by <a
href="https://github.com/cory-miller"><code>@​cory-miller</code></a> in
<a
href="https://redirect.github.com/actions/checkout/pull/1732">actions/checkout#1732</a></li>
</ul>
<h2>v4.1.5</h2>
<ul>
<li>Update NPM dependencies by <a
href="https://github.com/cory-miller"><code>@​cory-miller</code></a> in
<a
href="https://redirect.github.com/actions/checkout/pull/1703">actions/checkout#1703</a></li>
<li>Bump github/codeql-action from 2 to 3 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1694">actions/checkout#1694</a></li>
<li>Bump actions/setup-node from 1 to 4 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1696">actions/checkout#1696</a></li>
<li>Bump actions/upload-artifact from 2 to 4 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1695">actions/checkout#1695</a></li>
<li>README: Suggest <code>user.email</code> to be
<code>41898282+github-actions[bot]@users.noreply.github.com</code> by <a
href="https://github.com/cory-miller"><code>@​cory-miller</code></a> in
<a
href="https://redirect.github.com/actions/checkout/pull/1707">actions/checkout#1707</a></li>
</ul>
<h2>v4.1.4</h2>
<ul>
<li>Disable <code>extensions.worktreeConfig</code> when disabling
<code>sparse-checkout</code> by <a
href="https://github.com/jww3"><code>@​jww3</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1692">actions/checkout#1692</a></li>
<li>Add dependabot config by <a
href="https://github.com/cory-miller"><code>@​cory-miller</code></a> in
<a
href="https://redirect.github.com/actions/checkout/pull/1688">actions/checkout#1688</a></li>
<li>Bump the minor-actions-dependencies group with 2 updates by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1693">actions/checkout#1693</a></li>
<li>Bump word-wrap from 1.2.3 to 1.2.5 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1643">actions/checkout#1643</a></li>
</ul>
<h2>v4.1.3</h2>
<ul>
<li>Check git version before attempting to disable
<code>sparse-checkout</code> by <a
href="https://github.com/jww3"><code>@​jww3</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1656">actions/checkout#1656</a></li>
<li>Add SSH user parameter by <a
href="https://github.com/cory-miller"><code>@​cory-miller</code></a> in
<a
href="https://redirect.github.com/actions/checkout/pull/1685">actions/checkout#1685</a></li>
<li>Update <code>actions/checkout</code> version in
<code>update-main-version.yml</code> by <a
href="https://github.com/jww3"><code>@​jww3</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1650">actions/checkout#1650</a></li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/actions/checkout/commit/08eba0b27e820071cde6df949e0beb9ba4906955"><code>08eba0b</code></a>
Prepare release v4.3.0 (<a
href="https://redirect.github.com/actions/checkout/issues/2237">#2237</a>)</li>
<li><a
href="https://github.com/actions/checkout/commit/631c7dc4f80f88219c5ee78fee08c6b62fac8da1"><code>631c7dc</code></a>
Update package dependencies (<a
href="https://redirect.github.com/actions/checkout/issues/2236">#2236</a>)</li>
<li><a
href="https://github.com/actions/checkout/commit/8edcb1bdb4e267140fa742c62e395cd74f332709"><code>8edcb1b</code></a>
Update CODEOWNERS for actions (<a
href="https://redirect.github.com/actions/checkout/issues/2224">#2224</a>)</li>
<li><a
href="https://github.com/actions/checkout/commit/09d2acae674a48949e3602304ab46fd20ae0c42f"><code>09d2aca</code></a>
Update README.md (<a
href="https://redirect.github.com/actions/checkout/issues/2194">#2194</a>)</li>
<li><a
href="https://github.com/actions/checkout/commit/85e6279cec87321a52edac9c87bce653a07cf6c2"><code>85e6279</code></a>
Adjust positioning of user email note and permissions heading (<a
href="https://redirect.github.com/actions/checkout/issues/2044">#2044</a>)</li>
<li><a
href="https://github.com/actions/checkout/commit/009b9ae9e446ad8d9b8c809870b0fbcc5e03573e"><code>009b9ae</code></a>
Documentation update - add recommended permissions to Readme (<a
href="https://redirect.github.com/actions/checkout/issues/2043">#2043</a>)</li>
<li><a
href="https://github.com/actions/checkout/commit/cbb722410c2e876e24abbe8de2cc27693e501dcb"><code>cbb7224</code></a>
Update README.md (<a
href="https://redirect.github.com/actions/checkout/issues/1977">#1977</a>)</li>
<li><a
href="https://github.com/actions/checkout/commit/3b9b8c884f6b4bb4d5be2779c26374abadae0871"><code>3b9b8c8</code></a>
docs: update README.md (<a
href="https://redirect.github.com/actions/checkout/issues/1971">#1971</a>)</li>
<li>See full diff in <a
href="https://github.com/actions/checkout/compare/11bd71901bbe5b1630ceea73d27597364c9af683...08eba0b27e820071cde6df949e0beb9ba4906955">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/checkout&package-manager=github_actions&previous-version=4.2.2&new-version=4.3.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-11 14:09:30 +01:00
dependabot[bot] 2c293d2231 build(deps): bump actions/download-artifact from 4.3.0 to 5.0.0 (#4179)
Bumps
[actions/download-artifact](https://github.com/actions/download-artifact)
from 4.3.0 to 5.0.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/actions/download-artifact/releases">actions/download-artifact's
releases</a>.</em></p>
<blockquote>
<h2>v5.0.0</h2>
<h2>What's Changed</h2>
<ul>
<li>Update README.md by <a
href="https://github.com/nebuk89"><code>@​nebuk89</code></a> in <a
href="https://redirect.github.com/actions/download-artifact/pull/407">actions/download-artifact#407</a></li>
<li>BREAKING fix: inconsistent path behavior for single artifact
downloads by ID by <a
href="https://github.com/GrantBirki"><code>@​GrantBirki</code></a> in <a
href="https://redirect.github.com/actions/download-artifact/pull/416">actions/download-artifact#416</a></li>
</ul>
<h2>v5.0.0</h2>
<h3>🚨 Breaking Change</h3>
<p>This release fixes an inconsistency in path behavior for single
artifact downloads by ID. <strong>If you're downloading single artifacts
by ID, the output path may change.</strong></p>
<h4>What Changed</h4>
<p>Previously, <strong>single artifact downloads</strong> behaved
differently depending on how you specified the artifact:</p>
<ul>
<li><strong>By name</strong>: <code>name: my-artifact</code> → extracted
to <code>path/</code> (direct)</li>
<li><strong>By ID</strong>: <code>artifact-ids: 12345</code> → extracted
to <code>path/my-artifact/</code> (nested)</li>
</ul>
<p>Now both methods are consistent:</p>
<ul>
<li><strong>By name</strong>: <code>name: my-artifact</code> → extracted
to <code>path/</code> (unchanged)</li>
<li><strong>By ID</strong>: <code>artifact-ids: 12345</code> → extracted
to <code>path/</code> (fixed - now direct)</li>
</ul>
<h4>Migration Guide</h4>
<h5> No Action Needed If:</h5>
<ul>
<li>You download artifacts by <strong>name</strong></li>
<li>You download <strong>multiple</strong> artifacts by ID</li>
<li>You already use <code>merge-multiple: true</code> as a
workaround</li>
</ul>
<h5>⚠️ Action Required If:</h5>
<p>You download <strong>single artifacts by ID</strong> and your
workflows expect the nested directory structure.</p>
<p><strong>Before v5 (nested structure):</strong></p>
<pre lang="yaml"><code>- uses: actions/download-artifact@v4
  with:
    artifact-ids: 12345
    path: dist
# Files were in: dist/my-artifact/
</code></pre>
<blockquote>
<p>Where <code>my-artifact</code> is the name of the artifact you
previously uploaded</p>
</blockquote>
<p><strong>To maintain old behavior (if needed):</strong></p>
<pre lang="yaml"><code>&lt;/tr&gt;&lt;/table&gt; 
</code></pre>
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/actions/download-artifact/commit/634f93cb2916e3fdff6788551b99b062d0335ce0"><code>634f93c</code></a>
Merge pull request <a
href="https://redirect.github.com/actions/download-artifact/issues/416">#416</a>
from actions/single-artifact-id-download-path</li>
<li><a
href="https://github.com/actions/download-artifact/commit/b19ff4302770b82aa4694b63703b547756dacce6"><code>b19ff43</code></a>
refactor: resolve download path correctly in artifact download tests
(mainly ...</li>
<li><a
href="https://github.com/actions/download-artifact/commit/e262cbee4ab8c473c61c59a81ad8e9dc760e90db"><code>e262cbe</code></a>
bundle dist</li>
<li><a
href="https://github.com/actions/download-artifact/commit/bff23f9308ceb2f06d673043ea6311519be6a87b"><code>bff23f9</code></a>
update docs</li>
<li><a
href="https://github.com/actions/download-artifact/commit/fff8c148a8fdd56aa81fcb019f0b5f6c65700c4d"><code>fff8c14</code></a>
fix download path logic when downloading a single artifact by id</li>
<li><a
href="https://github.com/actions/download-artifact/commit/448e3f862ab3ef47aa50ff917776823c9946035b"><code>448e3f8</code></a>
Merge pull request <a
href="https://redirect.github.com/actions/download-artifact/issues/407">#407</a>
from actions/nebuk89-patch-1</li>
<li><a
href="https://github.com/actions/download-artifact/commit/47225c44b359a5155efdbbbc352041b3e249fb1b"><code>47225c4</code></a>
Update README.md</li>
<li>See full diff in <a
href="https://github.com/actions/download-artifact/compare/d3f86a106a0bac45b974a628896c90dbdf5c8093...634f93cb2916e3fdff6788551b99b062d0335ce0">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/download-artifact&package-manager=github_actions&previous-version=4.3.0&new-version=5.0.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-11 14:09:19 +01:00
dependabot[bot] 84142bb42a build(deps): bump github/codeql-action from 3.29.7 to 3.29.8 (#4178)
[//]: # (dependabot-start)
⚠️  **Dependabot is rebasing this PR** ⚠️ 

Rebasing might not happen immediately, so don't worry if this takes some
time.

Note: if you make any changes to this PR yourself, they will take
precedence over the rebase.

---

[//]: # (dependabot-end)

Bumps [github/codeql-action](https://github.com/github/codeql-action)
from 3.29.7 to 3.29.8.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/github/codeql-action/releases">github/codeql-action's
releases</a>.</em></p>
<blockquote>
<h2>v3.29.8</h2>
<h1>CodeQL Action Changelog</h1>
<p>See the <a
href="https://github.com/github/codeql-action/releases">releases
page</a> for the relevant changes to the CodeQL CLI and language
packs.</p>
<h2>3.29.8 - 08 Aug 2025</h2>
<ul>
<li>Fix an issue where the Action would autodetect unsupported languages
such as HTML. <a
href="https://redirect.github.com/github/codeql-action/pull/3015">#3015</a></li>
</ul>
<p>See the full <a
href="https://github.com/github/codeql-action/blob/v3.29.8/CHANGELOG.md">CHANGELOG.md</a>
for more information.</p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/github/codeql-action/blob/main/CHANGELOG.md">github/codeql-action's
changelog</a>.</em></p>
<blockquote>
<h1>CodeQL Action Changelog</h1>
<p>See the <a
href="https://github.com/github/codeql-action/releases">releases
page</a> for the relevant changes to the CodeQL CLI and language
packs.</p>
<h2>[UNRELEASED]</h2>
<p>No user facing changes.</p>
<h2>3.29.8 - 08 Aug 2025</h2>
<ul>
<li>Fix an issue where the Action would autodetect unsupported languages
such as HTML. <a
href="https://redirect.github.com/github/codeql-action/pull/3015">#3015</a></li>
</ul>
<h2>3.29.7 - 07 Aug 2025</h2>
<p>This release rolls back 3.29.6 to address issues with language
autodetection. It is identical to 3.29.5.</p>
<h2>3.29.6 - 07 Aug 2025</h2>
<ul>
<li>The <code>cleanup-level</code> input to the <code>analyze</code>
Action is now deprecated. The CodeQL Action has written a limited amount
of intermediate results to the database since version 2.2.5, and now
automatically manages cleanup. <a
href="https://redirect.github.com/github/codeql-action/pull/2999">#2999</a></li>
<li>Update default CodeQL bundle version to 2.22.3. <a
href="https://redirect.github.com/github/codeql-action/pull/3000">#3000</a></li>
</ul>
<h2>3.29.5 - 29 Jul 2025</h2>
<ul>
<li>Update default CodeQL bundle version to 2.22.2. <a
href="https://redirect.github.com/github/codeql-action/pull/2986">#2986</a></li>
</ul>
<h2>3.29.4 - 23 Jul 2025</h2>
<p>No user facing changes.</p>
<h2>3.29.3 - 21 Jul 2025</h2>
<p>No user facing changes.</p>
<h2>3.29.2 - 30 Jun 2025</h2>
<ul>
<li>Experimental: When the <code>quality-queries</code> input for the
<code>init</code> action is provided with an argument, separate
<code>.quality.sarif</code> files are produced and uploaded for each
language with the results of the specified queries. Do not use this in
production as it is part of an internal experiment and subject to change
at any time. <a
href="https://redirect.github.com/github/codeql-action/pull/2935">#2935</a></li>
</ul>
<h2>3.29.1 - 27 Jun 2025</h2>
<ul>
<li>Fix bug in PR analysis where user-provided <code>include</code>
query filter fails to exclude non-included queries. <a
href="https://redirect.github.com/github/codeql-action/pull/2938">#2938</a></li>
<li>Update default CodeQL bundle version to 2.22.1. <a
href="https://redirect.github.com/github/codeql-action/pull/2950">#2950</a></li>
</ul>
<h2>3.29.0 - 11 Jun 2025</h2>
<ul>
<li>Update default CodeQL bundle version to 2.22.0. <a
href="https://redirect.github.com/github/codeql-action/pull/2925">#2925</a></li>
<li>Bump minimum CodeQL bundle version to 2.16.6. <a
href="https://redirect.github.com/github/codeql-action/pull/2912">#2912</a></li>
</ul>
<h2>3.28.21 - 28 July 2025</h2>
<p>No user facing changes.</p>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/github/codeql-action/commit/76621b61decf072c1cee8dd1ce2d2a82d33c17ed"><code>76621b6</code></a>
Merge pull request <a
href="https://redirect.github.com/github/codeql-action/issues/3019">#3019</a>
from github/update-v3.29.8-679a40d33</li>
<li><a
href="https://github.com/github/codeql-action/commit/29ac3cefbb645d41622f6f9baa1415e06d73cf06"><code>29ac3ce</code></a>
Add release notes for 3.29.7</li>
<li><a
href="https://github.com/github/codeql-action/commit/737cfdebe687c6e720fb99761f23d89751c3b93a"><code>737cfde</code></a>
Update changelog for v3.29.8</li>
<li><a
href="https://github.com/github/codeql-action/commit/679a40d337fedd9b7318253dd72bfe7dc6d1886c"><code>679a40d</code></a>
Merge pull request <a
href="https://redirect.github.com/github/codeql-action/issues/3014">#3014</a>
from github/henrymercer/rebuild-dispatch</li>
<li><a
href="https://github.com/github/codeql-action/commit/6fe50b283a3d2e5533299f72d99216cd8815500f"><code>6fe50b2</code></a>
Merge pull request <a
href="https://redirect.github.com/github/codeql-action/issues/3015">#3015</a>
from github/henrymercer/language-autodetection-worka...</li>
<li><a
href="https://github.com/github/codeql-action/commit/6bc91d64f66d435200c8ba85c64878c3cbfad33b"><code>6bc91d6</code></a>
Add changelog note</li>
<li><a
href="https://github.com/github/codeql-action/commit/6b4fedca4f3428195d7ba1ca7c7404f9ea472911"><code>6b4fedc</code></a>
Bump Action patch version</li>
<li><a
href="https://github.com/github/codeql-action/commit/5794ffcb4ab0e87e4b8a8446ef048488303db295"><code>5794ffc</code></a>
Fix auto-detection of extractors that aren't languages</li>
<li><a
href="https://github.com/github/codeql-action/commit/bd62bf449cd8695f818546752cc8157693e1716c"><code>bd62bf4</code></a>
Finish in-progress merges</li>
<li><a
href="https://github.com/github/codeql-action/commit/2afb4e6f3c84ec0534284f2b47ae8206dcb401bf"><code>2afb4e6</code></a>
Avoid specifying branch unnecessarily</li>
<li>Additional commits viewable in <a
href="https://github.com/github/codeql-action/compare/51f77329afa6477de8c49fc9c7046c15b9a4e79d...76621b61decf072c1cee8dd1ce2d2a82d33c17ed">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=github/codeql-action&package-manager=github_actions&previous-version=3.29.7&new-version=3.29.8)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-11 14:09:09 +01:00
dependabot[bot] bb07eced6e build(deps): bump gradle/actions from 4.4.1 to 4.4.2 (#4177)
Bumps [gradle/actions](https://github.com/gradle/actions) from 4.4.1 to
4.4.2.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/gradle/actions/releases">gradle/actions's
releases</a>.</em></p>
<blockquote>
<h2>v4.4.2</h2>
<p>This patch release updates a bunch of dependency versions</p>
<h2>What's Changed</h2>
<ul>
<li>Bump github/codeql-action from 3.29.4 to 3.29.5 in the
github-actions group across 1 directory (<a
href="https://redirect.github.com/gradle/actions/pull/703">gradle/actions#703</a>)</li>
<li>Bumps the npm-dependencies group in /sources with 4 updates (<a
href="https://redirect.github.com/gradle/actions/pull/702">gradle/actions#702</a>)</li>
<li>Upgrade to gradle 9 in workflows and tests (<a
href="https://redirect.github.com/gradle/actions/pull/704">gradle/actions#704</a>)</li>
<li>Update known wrapper checksums (<a
href="https://redirect.github.com/gradle/actions/pull/701">gradle/actions#701</a>)</li>
<li>Bump Gradle Wrapper from 8.14.3 to 9.0.0 in
/.github/workflow-samples/gradle-plugin (<a
href="https://redirect.github.com/gradle/actions/pull/695">gradle/actions#695</a>)</li>
<li>Bump Gradle Wrapper from 8.14.3 to 9.0.0 in
/.github/workflow-samples/groovy-dsl (<a
href="https://redirect.github.com/gradle/actions/pull/696">gradle/actions#696</a>)</li>
<li>Bump Gradle Wrapper from 8.14.3 to 9.0.0 in
/.github/workflow-samples/java-toolchain (<a
href="https://redirect.github.com/gradle/actions/pull/697">gradle/actions#697</a>)</li>
<li>Bump com.fasterxml.jackson.dataformat:jackson-dataformat-smile from
2.19.1 to 2.19.2 in /sources/test/init-scripts in the gradle group
across 1 directory (<a
href="https://redirect.github.com/gradle/actions/pull/693">gradle/actions#693</a>)</li>
<li>Bump github/codeql-action from 3.29.0 to 3.29.4 in the
github-actions group across 1 directory (<a
href="https://redirect.github.com/gradle/actions/pull/691">gradle/actions#691</a>)</li>
<li>Bump the npm-dependencies group in /sources with 5 updates (<a
href="https://redirect.github.com/gradle/actions/pull/692">gradle/actions#692</a>)</li>
<li>Bump references to Develocity Gradle plugin from 4.0.2 to 4.1 (<a
href="https://redirect.github.com/gradle/actions/pull/685">gradle/actions#685</a>)</li>
<li>Bump the npm-dependencies group across 1 directory with 8 updates
(<a
href="https://redirect.github.com/gradle/actions/pull/684">gradle/actions#684</a>)</li>
<li>Run Gradle release candidate tests with JDK 17 (<a
href="https://redirect.github.com/gradle/actions/pull/690">gradle/actions#690</a>)</li>
<li>Update Develocity npm agent to version 1.0.1 (<a
href="https://redirect.github.com/gradle/actions/pull/687">gradle/actions#687</a>)</li>
<li>Update known wrapper checksums (<a
href="https://redirect.github.com/gradle/actions/pull/688">gradle/actions#688</a>)</li>
<li>Bump Gradle Wrapper from 8.14.2 to 8.14.3 in
/.github/workflow-samples/kotlin-dsl (<a
href="https://redirect.github.com/gradle/actions/pull/683">gradle/actions#683</a></li>
<li>Bump the github-actions group across 1 directory with 3 updates (<a
href="https://redirect.github.com/gradle/actions/pull/675">gradle/actions#675</a>)</li>
<li>Bump the gradle group across 3 directories with 2 updates (<a
href="https://redirect.github.com/gradle/actions/pull/674">gradle/actions#674</a>)</li>
<li>Bump Gradle Wrapper from 8.14.2 to 8.14.3 in
/sources/test/init-scripts (<a
href="https://redirect.github.com/gradle/actions/pull/679">gradle/actions#679</a>)</li>
<li>Bump Gradle Wrapper from 8.14.2 to 8.14.3 in
/.github/workflow-samples/java-toolchain (<a
href="https://redirect.github.com/gradle/actions/pull/682">gradle/actions#682</a>)</li>
<li>Bump Gradle Wrapper from 8.14.2 to 8.14.3 in
/.github/workflow-samples/groovy-dsl (<a
href="https://redirect.github.com/gradle/actions/pull/681">gradle/actions#681</a>)</li>
<li>Bump Gradle Wrapper from 8.14.2 to 8.14.3 in
/.github/workflow-samples/gradle-plugin (<a
href="https://redirect.github.com/gradle/actions/pull/680">gradle/actions#680</a>)</li>
<li>Update known wrapper checksums (<a
href="https://redirect.github.com/gradle/actions/pull/676">gradle/actions#676</a>)</li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/gradle/actions/compare/v4.4.1...v4.4.2">https://github.com/gradle/actions/compare/v4.4.1...v4.4.2</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/gradle/actions/commit/017a9effdb900e5b5b2fddfb590a105619dca3c3"><code>017a9ef</code></a>
Bump github/codeql-action from 3.29.4 to 3.29.5 in the github-actions
group a...</li>
<li><a
href="https://github.com/gradle/actions/commit/d5397cf4c822cff29ba7b79b2c9ed29917bbe84a"><code>d5397cf</code></a>
Merge branch 'main' into
dependabot/github_actions/github-actions-12d2e1d0cf</li>
<li><a
href="https://github.com/gradle/actions/commit/559dfbd266963f24dd17a76f3ce0f009a6c020ef"><code>559dfbd</code></a>
Bump the npm-dependencies group in /sources with 4 updates (<a
href="https://redirect.github.com/gradle/actions/issues/702">#702</a>)</li>
<li><a
href="https://github.com/gradle/actions/commit/075ee283cc5fba335ac5184eb48b40672919612a"><code>075ee28</code></a>
Merge branch 'main' into
dependabot/npm_and_yarn/sources/npm-dependencies-fda...</li>
<li><a
href="https://github.com/gradle/actions/commit/c3e68c5c72468b5662b0e325d727b1c1e6a14c16"><code>c3e68c5</code></a>
Upgrade to gradle 9 in workflows and tests (<a
href="https://redirect.github.com/gradle/actions/issues/704">#704</a>)</li>
<li><a
href="https://github.com/gradle/actions/commit/d7e674f97b03ec86a7d6f688bd66c45269b35bf1"><code>d7e674f</code></a>
Fix init script tests dependencies</li>
<li><a
href="https://github.com/gradle/actions/commit/3e6512898620556ad8848c4073e8279051eaf7db"><code>3e65128</code></a>
Upgrade init script tests to Gradle 9</li>
<li><a
href="https://github.com/gradle/actions/commit/896b9fa30994e16abfabdffea39f9bbffa8ade46"><code>896b9fa</code></a>
Run tests on Gradle release candidate and current with JDK 17 as
required sin...</li>
<li><a
href="https://github.com/gradle/actions/commit/431b3e39ba5839847f90c3917165b1f0b5b2d0fa"><code>431b3e3</code></a>
Bump github/codeql-action in the github-actions group across 1
directory</li>
<li><a
href="https://github.com/gradle/actions/commit/44c3664945acba910b91b10f41602a5caceb57df"><code>44c3664</code></a>
Bump the npm-dependencies group in /sources with 4 updates</li>
<li>Additional commits viewable in <a
href="https://github.com/gradle/actions/compare/ac638b010cf58a27ee6c972d7336334ccaf61c96...017a9effdb900e5b5b2fddfb590a105619dca3c3">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=gradle/actions&package-manager=github_actions&previous-version=4.4.1&new-version=4.4.2)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-11 14:08:52 +01:00
stirlingbot[bot] 901218cdb2 🌐 Sync Translations + Update README Progress Table (#4174)
### 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>
2025-08-11 12:29:51 +01:00
6699facc24 JWT Authentication (#3921)
This PR introduces JWT (JSON Web Token) authentication for Stirling-PDF,
allowing for stateless authentication capabilities alongside the
existing session-based authentication system.

### Key Features & Changes

  JWT Authentication System
- Core Service: JwtService.java - Token generation, validation, and
cookie management
- Authentication Filter: JwtAuthenticationFilter.java - Request
interceptor for JWT validation
- Key Management: KeyPersistenceService.java +
KeyPairCleanupService.java - RSA key rotation and persistence
  - Frontend: jwt-init.js - Client-side JWT handling and URL cleanup

  Security Integration
- SAML2: JwtSaml2AuthenticationRequestRepository.java - JWT-backed SAML
request storage
- OAuth2: Updated CustomAuthenticationSuccessHandler. java,
CustomOAuth2AuthenticationSuccessHandler.java &
CustomSaml2AuthenticationSuccessHandler.java for JWT integration
- Configuration: Enhanced SecurityConfiguration.java with JWT filter
chain

  Infrastructure
  - Caching: CacheConfig.java - Caffeine cache for JWT keys
  - Database: New JwtVerificationKey.java entity for key storage
- Error Handling: JwtAuthenticationEntryPoint.java for unauthorized
access

### Challenges Encountered

- Configured SecurityConfiguration to use either
`UsernamePasswordAuthenticationFilter` or `JWTAuthenticationFilter`
based on whether JWTs are enabled to prevent the former intercepting
requests while in stateless mode.
- Removed the `.defaultSuccessUrl("/")` from login configuration as its
inclusion was preventing overriding the use of the
`CustomAuthenticationSuccessHandler` and preventing proper
authentication flows.
---

## 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/devGuide/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/devGuide/HowToAddNewLanguage.md)
(if applicable)
- [x] I have performed a self-review of my own code
- [x] My changes generate no new warnings

### Documentation

- [x] 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)
- [x] 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)

### UI Changes (if applicable)

- [x] Screenshots or videos demonstrating the UI changes are attached
(e.g., as comments or direct attachments in the PR)
<img width="599" height="515" alt="Screenshot 2025-07-10 at 13 35 56"
src="https://github.com/user-attachments/assets/4126b752-ad0d-4ffa-b295-6714c43381e1"
/>

<img width="392" height="376" alt="Screenshot 2025-07-10 at 13 36 10"
src="https://github.com/user-attachments/assets/c681bc43-68ff-4934-8245-d544e2ad7b9c"
/>

<img width="1870" height="986" alt="eb750e8c3954fc47b2dd2e6e76ddb7d5"
src="https://github.com/user-attachments/assets/fca9b23d-b0b6-4884-8a26-98a441b641ef"
/>

<img width="1299" height="702" alt="Screenshot 2025-07-10 at 13 30 57"
src="https://github.com/user-attachments/assets/9415d8bf-fac4-4d38-8c3a-985d043d1076"
/>

### Testing (if applicable)

- [x] 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.

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Ludy <Ludy87@users.noreply.github.com>
Co-authored-by: EthanHealy01 <80844253+EthanHealy01@users.noreply.github.com>
Co-authored-by: Ethan <ethan@MacBook-Pro.local>
Co-authored-by: Anthony Stirling <77850077+Frooodle@users.noreply.github.com>
2025-08-11 12:27:42 +01:00
Ludy 74c92ef215 chore(labeler): add new 'v2' label and expand matching rules (#4172)
# Description of Changes

- **Added** a new `v2` label with `base-branch` targeting `V2`
- **Extended** the 'UI' label matching to include `frontend/**` files
- **Extended** the 'Scripts' label matching to include `docker/**` files
- **Removed** duplicate `devTools/.*` entry from 'Devtools' label
configuration

---

## 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/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
- [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/devGuide/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/devGuide/DeveloperGuide.md#6-testing)
for more details.
2025-08-11 10:26:57 +01:00
228 changed files with 24430 additions and 1856 deletions
+7 -1
View File
@@ -5,7 +5,13 @@
"Bash(mkdir:*)",
"Bash(./gradlew:*)",
"Bash(grep:*)",
"Bash(cat:*)"
"Bash(cat:*)",
"Bash(find:*)",
"Bash(grep:*)",
"Bash(rg:*)",
"Bash(strings:*)",
"Bash(pkill:*)",
"Bash(true)"
],
"deny": []
}
+7
View File
@@ -29,3 +29,10 @@ project: &project
- settings.gradle
- frontend/**
- docker/**
- testing/**
frontend: &frontend
- frontend/**
- .github/workflows/testdriver.yml
- testing/**
- docker/**
+5 -1
View File
@@ -46,6 +46,9 @@ labels:
- label: 'API'
title: '.*openapi.*|.*swagger.*|.*api.*'
- label: 'v2'
base-branch: 'V2'
- label: 'Translation'
files:
- 'app/core/src/main/resources/messages_[a-zA-Z_]{2}_[a-zA-Z_]{2,7}.properties'
@@ -62,6 +65,7 @@ labels:
- 'app/core/src/main/java/stirling/software/SPDF/controller/web/.*'
- 'app/core/src/main/java/stirling/software/SPDF/UI/.*'
- 'app/proprietary/src/main/java/stirling/software/proprietary/security/controller/web/.*'
- 'frontend/**'
- label: 'Java'
files:
@@ -120,6 +124,7 @@ labels:
- 'scripts/installFonts.sh'
- 'test.sh'
- 'test2.sh'
- 'docker/**'
- label: 'Devtools'
files:
@@ -131,7 +136,6 @@ labels:
- '.github/workflows/pre_commit.yml'
- 'devGuide/.*'
- 'devTools/.*'
- 'devTools/.*'
- label: 'Test'
files:
+1
View File
@@ -83,6 +83,7 @@
color: "DEDEDE"
- name: "v2"
color: "FFFF00"
description: "Issues or pull requests related to the v2 branch"
- name: "wontfix"
description: "This will not be worked on"
color: "FFFFFF"
+8
View File
@@ -0,0 +1,8 @@
pip
setuptools
WeasyPrint
pdf2image
pillow
unoserver
opencv-python-headless
pre-commit
+638
View File
@@ -0,0 +1,638 @@
#
# This file is autogenerated by pip-compile with Python 3.10
# by the following command:
#
# pip-compile --allow-unsafe --generate-hashes --output-file='.github\scripts\requirements_dev.txt' --strip-extras '.github\scripts\requirements_dev.in'
#
brotli==1.1.0 \
--hash=sha256:03d20af184290887bdea3f0f78c4f737d126c74dc2f3ccadf07e54ceca3bf208 \
--hash=sha256:0541e747cce78e24ea12d69176f6a7ddb690e62c425e01d31cc065e69ce55b48 \
--hash=sha256:069a121ac97412d1fe506da790b3e69f52254b9df4eb665cd42460c837193354 \
--hash=sha256:0737ddb3068957cf1b054899b0883830bb1fec522ec76b1098f9b6e0f02d9419 \
--hash=sha256:0b63b949ff929fbc2d6d3ce0e924c9b93c9785d877a21a1b678877ffbbc4423a \
--hash=sha256:0c6244521dda65ea562d5a69b9a26120769b7a9fb3db2fe9545935ed6735b128 \
--hash=sha256:11d00ed0a83fa22d29bc6b64ef636c4552ebafcef57154b4ddd132f5638fbd1c \
--hash=sha256:141bd4d93984070e097521ed07e2575b46f817d08f9fa42b16b9b5f27b5ac088 \
--hash=sha256:19c116e796420b0cee3da1ccec3b764ed2952ccfcc298b55a10e5610ad7885f9 \
--hash=sha256:1ab4fbee0b2d9098c74f3057b2bc055a8bd92ccf02f65944a241b4349229185a \
--hash=sha256:1ae56aca0402a0f9a3431cddda62ad71666ca9d4dc3a10a142b9dce2e3c0cda3 \
--hash=sha256:1b2c248cd517c222d89e74669a4adfa5577e06ab68771a529060cf5a156e9757 \
--hash=sha256:1e9a65b5736232e7a7f91ff3d02277f11d339bf34099a56cdab6a8b3410a02b2 \
--hash=sha256:224e57f6eac61cc449f498cc5f0e1725ba2071a3d4f48d5d9dffba42db196438 \
--hash=sha256:22fc2a8549ffe699bfba2256ab2ed0421a7b8fadff114a3d201794e45a9ff578 \
--hash=sha256:23032ae55523cc7bccb4f6a0bf368cd25ad9bcdcc1990b64a647e7bbcce9cb5b \
--hash=sha256:2333e30a5e00fe0fe55903c8832e08ee9c3b1382aacf4db26664a16528d51b4b \
--hash=sha256:2954c1c23f81c2eaf0b0717d9380bd348578a94161a65b3a2afc62c86467dd68 \
--hash=sha256:2a24c50840d89ded6c9a8fdc7b6ed3692ed4e86f1c4a4a938e1e92def92933e0 \
--hash=sha256:2de9d02f5bda03d27ede52e8cfe7b865b066fa49258cbab568720aa5be80a47d \
--hash=sha256:2feb1d960f760a575dbc5ab3b1c00504b24caaf6986e2dc2b01c09c87866a943 \
--hash=sha256:30924eb4c57903d5a7526b08ef4a584acc22ab1ffa085faceb521521d2de32dd \
--hash=sha256:316cc9b17edf613ac76b1f1f305d2a748f1b976b033b049a6ecdfd5612c70409 \
--hash=sha256:32d95b80260d79926f5fab3c41701dbb818fde1c9da590e77e571eefd14abe28 \
--hash=sha256:38025d9f30cf4634f8309c6874ef871b841eb3c347e90b0851f63d1ded5212da \
--hash=sha256:39da8adedf6942d76dc3e46653e52df937a3c4d6d18fdc94a7c29d263b1f5b50 \
--hash=sha256:3c0ef38c7a7014ffac184db9e04debe495d317cc9c6fb10071f7fefd93100a4f \
--hash=sha256:3d7954194c36e304e1523f55d7042c59dc53ec20dd4e9ea9d151f1b62b4415c0 \
--hash=sha256:3ee8a80d67a4334482d9712b8e83ca6b1d9bc7e351931252ebef5d8f7335a547 \
--hash=sha256:4093c631e96fdd49e0377a9c167bfd75b6d0bad2ace734c6eb20b348bc3ea180 \
--hash=sha256:43395e90523f9c23a3d5bdf004733246fba087f2948f87ab28015f12359ca6a0 \
--hash=sha256:43ce1b9935bfa1ede40028054d7f48b5469cd02733a365eec8a329ffd342915d \
--hash=sha256:4410f84b33374409552ac9b6903507cdb31cd30d2501fc5ca13d18f73548444a \
--hash=sha256:494994f807ba0b92092a163a0a283961369a65f6cbe01e8891132b7a320e61eb \
--hash=sha256:4d4a848d1837973bf0f4b5e54e3bec977d99be36a7895c61abb659301b02c112 \
--hash=sha256:4ed11165dd45ce798d99a136808a794a748d5dc38511303239d4e2363c0695dc \
--hash=sha256:4f3607b129417e111e30637af1b56f24f7a49e64763253bbc275c75fa887d4b2 \
--hash=sha256:510b5b1bfbe20e1a7b3baf5fed9e9451873559a976c1a78eebaa3b86c57b4265 \
--hash=sha256:524f35912131cc2cabb00edfd8d573b07f2d9f21fa824bd3fb19725a9cf06327 \
--hash=sha256:587ca6d3cef6e4e868102672d3bd9dc9698c309ba56d41c2b9c85bbb903cdb95 \
--hash=sha256:58d4b711689366d4a03ac7957ab8c28890415e267f9b6589969e74b6e42225ec \
--hash=sha256:5b3cc074004d968722f51e550b41a27be656ec48f8afaeeb45ebf65b561481dd \
--hash=sha256:5dab0844f2cf82be357a0eb11a9087f70c5430b2c241493fc122bb6f2bb0917c \
--hash=sha256:5e55da2c8724191e5b557f8e18943b1b4839b8efc3ef60d65985bcf6f587dd38 \
--hash=sha256:5eeb539606f18a0b232d4ba45adccde4125592f3f636a6182b4a8a436548b914 \
--hash=sha256:5f4d5ea15c9382135076d2fb28dde923352fe02951e66935a9efaac8f10e81b0 \
--hash=sha256:5fb2ce4b8045c78ebbc7b8f3c15062e435d47e7393cc57c25115cfd49883747a \
--hash=sha256:6172447e1b368dcbc458925e5ddaf9113477b0ed542df258d84fa28fc45ceea7 \
--hash=sha256:6967ced6730aed543b8673008b5a391c3b1076d834ca438bbd70635c73775368 \
--hash=sha256:6974f52a02321b36847cd19d1b8e381bf39939c21efd6ee2fc13a28b0d99348c \
--hash=sha256:6c3020404e0b5eefd7c9485ccf8393cfb75ec38ce75586e046573c9dc29967a0 \
--hash=sha256:6c6e0c425f22c1c719c42670d561ad682f7bfeeef918edea971a79ac5252437f \
--hash=sha256:70051525001750221daa10907c77830bc889cb6d865cc0b813d9db7fefc21451 \
--hash=sha256:7905193081db9bfa73b1219140b3d315831cbff0d8941f22da695832f0dd188f \
--hash=sha256:7bc37c4d6b87fb1017ea28c9508b36bbcb0c3d18b4260fcdf08b200c74a6aee8 \
--hash=sha256:7c4855522edb2e6ae7fdb58e07c3ba9111e7621a8956f481c68d5d979c93032e \
--hash=sha256:7e4c4629ddad63006efa0ef968c8e4751c5868ff0b1c5c40f76524e894c50248 \
--hash=sha256:7eedaa5d036d9336c95915035fb57422054014ebdeb6f3b42eac809928e40d0c \
--hash=sha256:7f4bf76817c14aa98cc6697ac02f3972cb8c3da93e9ef16b9c66573a68014f91 \
--hash=sha256:81de08ac11bcb85841e440c13611c00b67d3bf82698314928d0b676362546724 \
--hash=sha256:832436e59afb93e1836081a20f324cb185836c617659b07b129141a8426973c7 \
--hash=sha256:861bf317735688269936f755fa136a99d1ed526883859f86e41a5d43c61d8966 \
--hash=sha256:87a3044c3a35055527ac75e419dfa9f4f3667a1e887ee80360589eb8c90aabb9 \
--hash=sha256:890b5a14ce214389b2cc36ce82f3093f96f4cc730c1cffdbefff77a7c71f2a97 \
--hash=sha256:89f4988c7203739d48c6f806f1e87a1d96e0806d44f0fba61dba81392c9e474d \
--hash=sha256:8bf32b98b75c13ec7cf774164172683d6e7891088f6316e54425fde1efc276d5 \
--hash=sha256:8dadd1314583ec0bf2d1379f7008ad627cd6336625d6679cf2f8e67081b83acf \
--hash=sha256:901032ff242d479a0efa956d853d16875d42157f98951c0230f69e69f9c09bac \
--hash=sha256:9011560a466d2eb3f5a6e4929cf4a09be405c64154e12df0dd72713f6500e32b \
--hash=sha256:906bc3a79de8c4ae5b86d3d75a8b77e44404b0f4261714306e3ad248d8ab0951 \
--hash=sha256:919e32f147ae93a09fe064d77d5ebf4e35502a8df75c29fb05788528e330fe74 \
--hash=sha256:91d7cc2a76b5567591d12c01f019dd7afce6ba8cba6571187e21e2fc418ae648 \
--hash=sha256:929811df5462e182b13920da56c6e0284af407d1de637d8e536c5cd00a7daf60 \
--hash=sha256:949f3b7c29912693cee0afcf09acd6ebc04c57af949d9bf77d6101ebb61e388c \
--hash=sha256:a090ca607cbb6a34b0391776f0cb48062081f5f60ddcce5d11838e67a01928d1 \
--hash=sha256:a1fd8a29719ccce974d523580987b7f8229aeace506952fa9ce1d53a033873c8 \
--hash=sha256:a37b8f0391212d29b3a91a799c8e4a2855e0576911cdfb2515487e30e322253d \
--hash=sha256:a3daabb76a78f829cafc365531c972016e4aa8d5b4bf60660ad8ecee19df7ccc \
--hash=sha256:a469274ad18dc0e4d316eefa616d1d0c2ff9da369af19fa6f3daa4f09671fd61 \
--hash=sha256:a599669fd7c47233438a56936988a2478685e74854088ef5293802123b5b2460 \
--hash=sha256:a743e5a28af5f70f9c080380a5f908d4d21d40e8f0e0c8901604d15cfa9ba751 \
--hash=sha256:a77def80806c421b4b0af06f45d65a136e7ac0bdca3c09d9e2ea4e515367c7e9 \
--hash=sha256:a7e53012d2853a07a4a79c00643832161a910674a893d296c9f1259859a289d2 \
--hash=sha256:a93dde851926f4f2678e704fadeb39e16c35d8baebd5252c9fd94ce8ce68c4a0 \
--hash=sha256:aac0411d20e345dc0920bdec5548e438e999ff68d77564d5e9463a7ca9d3e7b1 \
--hash=sha256:ae15b066e5ad21366600ebec29a7ccbc86812ed267e4b28e860b8ca16a2bc474 \
--hash=sha256:aea440a510e14e818e67bfc4027880e2fb500c2ccb20ab21c7a7c8b5b4703d75 \
--hash=sha256:af6fa6817889314555aede9a919612b23739395ce767fe7fcbea9a80bf140fe5 \
--hash=sha256:b760c65308ff1e462f65d69c12e4ae085cff3b332d894637f6273a12a482d09f \
--hash=sha256:be36e3d172dc816333f33520154d708a2657ea63762ec16b62ece02ab5e4daf2 \
--hash=sha256:c247dd99d39e0338a604f8c2b3bc7061d5c2e9e2ac7ba9cc1be5a69cb6cd832f \
--hash=sha256:c5529b34c1c9d937168297f2c1fde7ebe9ebdd5e121297ff9c043bdb2ae3d6fb \
--hash=sha256:c8146669223164fc87a7e3de9f81e9423c67a79d6b3447994dfb9c95da16e2d6 \
--hash=sha256:c8fd5270e906eef71d4a8d19b7c6a43760c6abcfcc10c9101d14eb2357418de9 \
--hash=sha256:ca63e1890ede90b2e4454f9a65135a4d387a4585ff8282bb72964fab893f2111 \
--hash=sha256:caf9ee9a5775f3111642d33b86237b05808dafcd6268faa492250e9b78046eb2 \
--hash=sha256:cb1dac1770878ade83f2ccdf7d25e494f05c9165f5246b46a621cc849341dc01 \
--hash=sha256:cdad5b9014d83ca68c25d2e9444e28e967ef16e80f6b436918c700c117a85467 \
--hash=sha256:cdbc1fc1bc0bff1cef838eafe581b55bfbffaed4ed0318b724d0b71d4d377619 \
--hash=sha256:ceb64bbc6eac5a140ca649003756940f8d6a7c444a68af170b3187623b43bebf \
--hash=sha256:d0c5516f0aed654134a2fc936325cc2e642f8a0e096d075209672eb321cff408 \
--hash=sha256:d143fd47fad1db3d7c27a1b1d66162e855b5d50a89666af46e1679c496e8e579 \
--hash=sha256:d192f0f30804e55db0d0e0a35d83a9fead0e9a359a9ed0285dbacea60cc10a84 \
--hash=sha256:d2b35ca2c7f81d173d2fadc2f4f31e88cc5f7a39ae5b6db5513cf3383b0e0ec7 \
--hash=sha256:d342778ef319e1026af243ed0a07c97acf3bad33b9f29e7ae6a1f68fd083e90c \
--hash=sha256:d487f5432bf35b60ed625d7e1b448e2dc855422e87469e3f450aa5552b0eb284 \
--hash=sha256:d7702622a8b40c49bffb46e1e3ba2e81268d5c04a34f460978c6b5517a34dd52 \
--hash=sha256:db85ecf4e609a48f4b29055f1e144231b90edc90af7481aa731ba2d059226b1b \
--hash=sha256:de6551e370ef19f8de1807d0a9aa2cdfdce2e85ce88b122fe9f6b2b076837e59 \
--hash=sha256:e1140c64812cb9b06c922e77f1c26a75ec5e3f0fb2bf92cc8c58720dec276752 \
--hash=sha256:e4fe605b917c70283db7dfe5ada75e04561479075761a0b3866c081d035b01c1 \
--hash=sha256:e6a904cb26bfefc2f0a6f240bdf5233be78cd2488900a2f846f3c3ac8489ab80 \
--hash=sha256:e79e6520141d792237c70bcd7a3b122d00f2613769ae0cb61c52e89fd3443839 \
--hash=sha256:e84799f09591700a4154154cab9787452925578841a94321d5ee8fb9a9a328f0 \
--hash=sha256:e93dfc1a1165e385cc8239fab7c036fb2cd8093728cbd85097b284d7b99249a2 \
--hash=sha256:efa8b278894b14d6da122a72fefcebc28445f2d3f880ac59d46c90f4c13be9a3 \
--hash=sha256:f0d8a7a6b5983c2496e364b969f0e526647a06b075d034f3297dc66f3b360c64 \
--hash=sha256:f0db75f47be8b8abc8d9e31bc7aad0547ca26f24a54e6fd10231d623f183d089 \
--hash=sha256:f296c40e23065d0d6650c4aefe7470d2a25fffda489bcc3eb66083f3ac9f6643 \
--hash=sha256:f31859074d57b4639318523d6ffdca586ace54271a73ad23ad021acd807eb14b \
--hash=sha256:f66b5337fa213f1da0d9000bc8dc0cb5b896b726eefd9c6046f699b169c41b9e \
--hash=sha256:f733d788519c7e3e71f0855c96618720f5d3d60c3cb829d8bbb722dddce37985 \
--hash=sha256:fce1473f3ccc4187f75b4690cfc922628aed4d3dd013d047f95a9b3919a86596 \
--hash=sha256:fd5f17ff8f14003595ab414e45fce13d073e0762394f957182e69035c9f3d7c2 \
--hash=sha256:fdc3ff3bfccdc6b9cc7c342c03aa2400683f0cb891d46e94b64a197910dc4064
# via fonttools
cffi==1.17.1 \
--hash=sha256:045d61c734659cc045141be4bae381a41d89b741f795af1dd018bfb532fd0df8 \
--hash=sha256:0984a4925a435b1da406122d4d7968dd861c1385afe3b45ba82b750f229811e2 \
--hash=sha256:0e2b1fac190ae3ebfe37b979cc1ce69c81f4e4fe5746bb401dca63a9062cdaf1 \
--hash=sha256:0f048dcf80db46f0098ccac01132761580d28e28bc0f78ae0d58048063317e15 \
--hash=sha256:1257bdabf294dceb59f5e70c64a3e2f462c30c7ad68092d01bbbfb1c16b1ba36 \
--hash=sha256:1c39c6016c32bc48dd54561950ebd6836e1670f2ae46128f67cf49e789c52824 \
--hash=sha256:1d599671f396c4723d016dbddb72fe8e0397082b0a77a4fab8028923bec050e8 \
--hash=sha256:28b16024becceed8c6dfbc75629e27788d8a3f9030691a1dbf9821a128b22c36 \
--hash=sha256:2bb1a08b8008b281856e5971307cc386a8e9c5b625ac297e853d36da6efe9c17 \
--hash=sha256:30c5e0cb5ae493c04c8b42916e52ca38079f1b235c2f8ae5f4527b963c401caf \
--hash=sha256:31000ec67d4221a71bd3f67df918b1f88f676f1c3b535a7eb473255fdc0b83fc \
--hash=sha256:386c8bf53c502fff58903061338ce4f4950cbdcb23e2902d86c0f722b786bbe3 \
--hash=sha256:3edc8d958eb099c634dace3c7e16560ae474aa3803a5df240542b305d14e14ed \
--hash=sha256:45398b671ac6d70e67da8e4224a065cec6a93541bb7aebe1b198a61b58c7b702 \
--hash=sha256:46bf43160c1a35f7ec506d254e5c890f3c03648a4dbac12d624e4490a7046cd1 \
--hash=sha256:4ceb10419a9adf4460ea14cfd6bc43d08701f0835e979bf821052f1805850fe8 \
--hash=sha256:51392eae71afec0d0c8fb1a53b204dbb3bcabcb3c9b807eedf3e1e6ccf2de903 \
--hash=sha256:5da5719280082ac6bd9aa7becb3938dc9f9cbd57fac7d2871717b1feb0902ab6 \
--hash=sha256:610faea79c43e44c71e1ec53a554553fa22321b65fae24889706c0a84d4ad86d \
--hash=sha256:636062ea65bd0195bc012fea9321aca499c0504409f413dc88af450b57ffd03b \
--hash=sha256:6883e737d7d9e4899a8a695e00ec36bd4e5e4f18fabe0aca0efe0a4b44cdb13e \
--hash=sha256:6b8b4a92e1c65048ff98cfe1f735ef8f1ceb72e3d5f0c25fdb12087a23da22be \
--hash=sha256:6f17be4345073b0a7b8ea599688f692ac3ef23ce28e5df79c04de519dbc4912c \
--hash=sha256:706510fe141c86a69c8ddc029c7910003a17353970cff3b904ff0686a5927683 \
--hash=sha256:72e72408cad3d5419375fc87d289076ee319835bdfa2caad331e377589aebba9 \
--hash=sha256:733e99bc2df47476e3848417c5a4540522f234dfd4ef3ab7fafdf555b082ec0c \
--hash=sha256:7596d6620d3fa590f677e9ee430df2958d2d6d6de2feeae5b20e82c00b76fbf8 \
--hash=sha256:78122be759c3f8a014ce010908ae03364d00a1f81ab5c7f4a7a5120607ea56e1 \
--hash=sha256:805b4371bf7197c329fcb3ead37e710d1bca9da5d583f5073b799d5c5bd1eee4 \
--hash=sha256:85a950a4ac9c359340d5963966e3e0a94a676bd6245a4b55bc43949eee26a655 \
--hash=sha256:8f2cdc858323644ab277e9bb925ad72ae0e67f69e804f4898c070998d50b1a67 \
--hash=sha256:9755e4345d1ec879e3849e62222a18c7174d65a6a92d5b346b1863912168b595 \
--hash=sha256:98e3969bcff97cae1b2def8ba499ea3d6f31ddfdb7635374834cf89a1a08ecf0 \
--hash=sha256:a08d7e755f8ed21095a310a693525137cfe756ce62d066e53f502a83dc550f65 \
--hash=sha256:a1ed2dd2972641495a3ec98445e09766f077aee98a1c896dcb4ad0d303628e41 \
--hash=sha256:a24ed04c8ffd54b0729c07cee15a81d964e6fee0e3d4d342a27b020d22959dc6 \
--hash=sha256:a45e3c6913c5b87b3ff120dcdc03f6131fa0065027d0ed7ee6190736a74cd401 \
--hash=sha256:a9b15d491f3ad5d692e11f6b71f7857e7835eb677955c00cc0aefcd0669adaf6 \
--hash=sha256:ad9413ccdeda48c5afdae7e4fa2192157e991ff761e7ab8fdd8926f40b160cc3 \
--hash=sha256:b2ab587605f4ba0bf81dc0cb08a41bd1c0a5906bd59243d56bad7668a6fc6c16 \
--hash=sha256:b62ce867176a75d03a665bad002af8e6d54644fad99a3c70905c543130e39d93 \
--hash=sha256:c03e868a0b3bc35839ba98e74211ed2b05d2119be4e8a0f224fba9384f1fe02e \
--hash=sha256:c59d6e989d07460165cc5ad3c61f9fd8f1b4796eacbd81cee78957842b834af4 \
--hash=sha256:c7eac2ef9b63c79431bc4b25f1cd649d7f061a28808cbc6c47b534bd789ef964 \
--hash=sha256:c9c3d058ebabb74db66e431095118094d06abf53284d9c81f27300d0e0d8bc7c \
--hash=sha256:ca74b8dbe6e8e8263c0ffd60277de77dcee6c837a3d0881d8c1ead7268c9e576 \
--hash=sha256:caaf0640ef5f5517f49bc275eca1406b0ffa6aa184892812030f04c2abf589a0 \
--hash=sha256:cdf5ce3acdfd1661132f2a9c19cac174758dc2352bfe37d98aa7512c6b7178b3 \
--hash=sha256:d016c76bdd850f3c626af19b0542c9677ba156e4ee4fccfdd7848803533ef662 \
--hash=sha256:d01b12eeeb4427d3110de311e1774046ad344f5b1a7403101878976ecd7a10f3 \
--hash=sha256:d63afe322132c194cf832bfec0dc69a99fb9bb6bbd550f161a49e9e855cc78ff \
--hash=sha256:da95af8214998d77a98cc14e3a3bd00aa191526343078b530ceb0bd710fb48a5 \
--hash=sha256:dd398dbc6773384a17fe0d3e7eeb8d1a21c2200473ee6806bb5e6a8e62bb73dd \
--hash=sha256:de2ea4b5833625383e464549fec1bc395c1bdeeb5f25c4a3a82b5a8c756ec22f \
--hash=sha256:de55b766c7aa2e2a3092c51e0483d700341182f08e67c63630d5b6f200bb28e5 \
--hash=sha256:df8b1c11f177bc2313ec4b2d46baec87a5f3e71fc8b45dab2ee7cae86d9aba14 \
--hash=sha256:e03eab0a8677fa80d646b5ddece1cbeaf556c313dcfac435ba11f107ba117b5d \
--hash=sha256:e221cf152cff04059d011ee126477f0d9588303eb57e88923578ace7baad17f9 \
--hash=sha256:e31ae45bc2e29f6b2abd0de1cc3b9d5205aa847cafaecb8af1476a609a2f6eb7 \
--hash=sha256:edae79245293e15384b51f88b00613ba9f7198016a5948b5dddf4917d4d26382 \
--hash=sha256:f1e22e8c4419538cb197e4dd60acc919d7696e5ef98ee4da4e01d3f8cfa4cc5a \
--hash=sha256:f3a2b4222ce6b60e2e8b337bb9596923045681d71e5a082783484d845390938e \
--hash=sha256:f6a16c31041f09ead72d69f583767292f750d24913dadacf5756b966aacb3f1a \
--hash=sha256:f75c7ab1f9e4aca5414ed4d8e5c0e303a34f4421f8a0d47a4d019ceff0ab6af4 \
--hash=sha256:f79fc4fc25f1c8698ff97788206bb3c2598949bfe0fef03d299eb1b5356ada99 \
--hash=sha256:f7f5baafcc48261359e14bcd6d9bff6d4b28d9103847c9e136694cb0501aef87 \
--hash=sha256:fc48c783f9c87e60831201f2cce7f3b2e4846bf4d8728eabe54d60700b318a0b
# via weasyprint
cfgv==3.4.0 \
--hash=sha256:b7265b1f29fd3316bfcd2b330d63d024f2bfd8bcb8b0272f8e19a504856c48f9 \
--hash=sha256:e52591d4c5f5dead8e0f673fb16db7949d2cfb3f7da4582893288f0ded8fe560
# via pre-commit
cssselect2==0.8.0 \
--hash=sha256:46fc70ebc41ced7a32cd42d58b1884d72ade23d21e5a4eaaf022401c13f0e76e \
--hash=sha256:7674ffb954a3b46162392aee2a3a0aedb2e14ecf99fcc28644900f4e6e3e9d3a
# via weasyprint
distlib==0.4.0 \
--hash=sha256:9659f7d87e46584a30b5780e43ac7a2143098441670ff0a49d5f9034c54a6c16 \
--hash=sha256:feec40075be03a04501a973d81f633735b4b69f98b05450592310c0f401a4e0d
# via virtualenv
filelock==3.18.0 \
--hash=sha256:adbc88eabb99d2fec8c9c1b229b171f18afa655400173ddc653d5d01501fb9f2 \
--hash=sha256:c401f4f8377c4464e6db25fff06205fd89bdd83b65eb0488ed1b160f780e21de
# via virtualenv
fonttools==4.59.0 \
--hash=sha256:052444a5d0151878e87e3e512a1aa1a0ab35ee4c28afde0a778e23b0ace4a7de \
--hash=sha256:169b99a2553a227f7b5fea8d9ecd673aa258617f466b2abc6091fe4512a0dcd0 \
--hash=sha256:209b75943d158f610b78320eacb5539aa9e920bee2c775445b2846c65d20e19d \
--hash=sha256:21e606b2d38fed938dde871c5736822dd6bda7a4631b92e509a1f5cd1b90c5df \
--hash=sha256:241313683afd3baacb32a6bd124d0bce7404bc5280e12e291bae1b9bba28711d \
--hash=sha256:26731739daa23b872643f0e4072d5939960237d540c35c14e6a06d47d71ca8fe \
--hash=sha256:2e7cf8044ce2598bb87e44ba1d2c6e45d7a8decf56055b92906dc53f67c76d64 \
--hash=sha256:31003b6a10f70742a63126b80863ab48175fb8272a18ca0846c0482968f0588e \
--hash=sha256:332bfe685d1ac58ca8d62b8d6c71c2e52a6c64bc218dc8f7825c9ea51385aa01 \
--hash=sha256:37c377f7cb2ab2eca8a0b319c68146d34a339792f9420fca6cd49cf28d370705 \
--hash=sha256:37e01c6ec0c98599778c2e688350d624fa4770fbd6144551bd5e032f1199171c \
--hash=sha256:401b1941ce37e78b8fd119b419b617277c65ae9417742a63282257434fd68ea2 \
--hash=sha256:4536f2695fe5c1ffb528d84a35a7d3967e5558d2af58b4775e7ab1449d65767b \
--hash=sha256:4c908a7036f0f3677f8afa577bcd973e3e20ddd2f7c42a33208d18bee95cdb6f \
--hash=sha256:51ab1ff33c19e336c02dee1e9fd1abd974a4ca3d8f7eef2a104d0816a241ce97 \
--hash=sha256:524133c1be38445c5c0575eacea42dbd44374b310b1ffc4b60ff01d881fabb96 \
--hash=sha256:57bb7e26928573ee7c6504f54c05860d867fd35e675769f3ce01b52af38d48e2 \
--hash=sha256:60f6665579e909b618282f3c14fa0b80570fbf1ee0e67678b9a9d43aa5d67a37 \
--hash=sha256:62224a9bb85b4b66d1b46d45cbe43d71cbf8f527d332b177e3b96191ffbc1e64 \
--hash=sha256:6770d7da00f358183d8fd5c4615436189e4f683bdb6affb02cad3d221d7bb757 \
--hash=sha256:6801aeddb6acb2c42eafa45bc1cb98ba236871ae6f33f31e984670b749a8e58e \
--hash=sha256:70d6b3ceaa9cc5a6ac52884f3b3d9544e8e231e95b23f138bdb78e6d4dc0eae3 \
--hash=sha256:78813b49d749e1bb4db1c57f2d4d7e6db22c253cb0a86ad819f5dc197710d4b2 \
--hash=sha256:841b2186adce48903c0fef235421ae21549020eca942c1da773ac380b056ab3c \
--hash=sha256:84fc186980231a287b28560d3123bd255d3c6b6659828c642b4cf961e2b923d0 \
--hash=sha256:885bde7d26e5b40e15c47bd5def48b38cbd50830a65f98122a8fb90962af7cd1 \
--hash=sha256:8b4309a2775e4feee7356e63b163969a215d663399cce1b3d3b65e7ec2d9680e \
--hash=sha256:8d77f92438daeaddc05682f0f3dac90c5b9829bcac75b57e8ce09cb67786073c \
--hash=sha256:902425f5afe28572d65d2bf9c33edd5265c612ff82c69e6f83ea13eafc0dcbea \
--hash=sha256:9bcc1e77fbd1609198966ded6b2a9897bd6c6bcbd2287a2fc7d75f1a254179c5 \
--hash=sha256:a408c3c51358c89b29cfa5317cf11518b7ce5de1717abb55c5ae2d2921027de6 \
--hash=sha256:a9bf8adc9e1f3012edc8f09b08336272aec0c55bc677422273e21280db748f7c \
--hash=sha256:b818db35879d2edf7f46c7e729c700a0bce03b61b9412f5a7118406687cb151d \
--hash=sha256:b8974b2a266b54c96709bd5e239979cddfd2dbceed331aa567ea1d7c4a2202db \
--hash=sha256:be392ec3529e2f57faa28709d60723a763904f71a2b63aabe14fee6648fe3b14 \
--hash=sha256:d3972b13148c1d1fbc092b27678a33b3080d1ac0ca305742b0119b75f9e87e38 \
--hash=sha256:d40dcf533ca481355aa7b682e9e079f766f35715defa4929aeb5597f9604272e \
--hash=sha256:e93df708c69a193fc7987192f94df250f83f3851fda49413f02ba5dded639482 \
--hash=sha256:efd7e6660674e234e29937bc1481dceb7e0336bfae75b856b4fb272b5093c5d4 \
--hash=sha256:f9b3a78f69dcbd803cf2fb3f972779875b244c1115481dfbdd567b2c22b31f6b \
--hash=sha256:fa39475eaccb98f9199eccfda4298abaf35ae0caec676ffc25b3a5e224044464 \
--hash=sha256:fbce6dae41b692a5973d0f2158f782b9ad05babc2c2019a970a1094a23909b1b
# via weasyprint
identify==2.6.13 \
--hash=sha256:60381139b3ae39447482ecc406944190f690d4a2997f2584062089848361b33b \
--hash=sha256:da8d6c828e773620e13bfa86ea601c5a5310ba4bcd65edf378198b56a1f9fb32
# via pre-commit
nodeenv==1.9.1 \
--hash=sha256:6ec12890a2dab7946721edbfbcd91f3319c6ccc9aec47be7c7e6b7011ee6645f \
--hash=sha256:ba11c9782d29c27c70ffbdda2d7415098754709be8a7056d79a737cd901155c9
# via pre-commit
numpy==2.2.6 \
--hash=sha256:038613e9fb8c72b0a41f025a7e4c3f0b7a1b5d768ece4796b674c8f3fe13efff \
--hash=sha256:0678000bb9ac1475cd454c6b8c799206af8107e310843532b04d49649c717a47 \
--hash=sha256:0811bb762109d9708cca4d0b13c4f67146e3c3b7cf8d34018c722adb2d957c84 \
--hash=sha256:0b605b275d7bd0c640cad4e5d30fa701a8d59302e127e5f79138ad62762c3e3d \
--hash=sha256:0bca768cd85ae743b2affdc762d617eddf3bcf8724435498a1e80132d04879e6 \
--hash=sha256:1bc23a79bfabc5d056d106f9befb8d50c31ced2fbc70eedb8155aec74a45798f \
--hash=sha256:287cc3162b6f01463ccd86be154f284d0893d2b3ed7292439ea97eafa8170e0b \
--hash=sha256:37c0ca431f82cd5fa716eca9506aefcabc247fb27ba69c5062a6d3ade8cf8f49 \
--hash=sha256:37e990a01ae6ec7fe7fa1c26c55ecb672dd98b19c3d0e1d1f326fa13cb38d163 \
--hash=sha256:389d771b1623ec92636b0786bc4ae56abafad4a4c513d36a55dce14bd9ce8571 \
--hash=sha256:3d70692235e759f260c3d837193090014aebdf026dfd167834bcba43e30c2a42 \
--hash=sha256:41c5a21f4a04fa86436124d388f6ed60a9343a6f767fced1a8a71c3fbca038ff \
--hash=sha256:481b49095335f8eed42e39e8041327c05b0f6f4780488f61286ed3c01368d491 \
--hash=sha256:4eeaae00d789f66c7a25ac5f34b71a7035bb474e679f410e5e1a94deb24cf2d4 \
--hash=sha256:55a4d33fa519660d69614a9fad433be87e5252f4b03850642f88993f7b2ca566 \
--hash=sha256:5a6429d4be8ca66d889b7cf70f536a397dc45ba6faeb5f8c5427935d9592e9cf \
--hash=sha256:5bd4fc3ac8926b3819797a7c0e2631eb889b4118a9898c84f585a54d475b7e40 \
--hash=sha256:5beb72339d9d4fa36522fc63802f469b13cdbe4fdab4a288f0c441b74272ebfd \
--hash=sha256:6031dd6dfecc0cf9f668681a37648373bddd6421fff6c66ec1624eed0180ee06 \
--hash=sha256:71594f7c51a18e728451bb50cc60a3ce4e6538822731b2933209a1f3614e9282 \
--hash=sha256:74d4531beb257d2c3f4b261bfb0fc09e0f9ebb8842d82a7b4209415896adc680 \
--hash=sha256:7befc596a7dc9da8a337f79802ee8adb30a552a94f792b9c9d18c840055907db \
--hash=sha256:894b3a42502226a1cac872f840030665f33326fc3dac8e57c607905773cdcde3 \
--hash=sha256:8e41fd67c52b86603a91c1a505ebaef50b3314de0213461c7a6e99c9a3beff90 \
--hash=sha256:8e9ace4a37db23421249ed236fdcdd457d671e25146786dfc96835cd951aa7c1 \
--hash=sha256:8fc377d995680230e83241d8a96def29f204b5782f371c532579b4f20607a289 \
--hash=sha256:9551a499bf125c1d4f9e250377c1ee2eddd02e01eac6644c080162c0c51778ab \
--hash=sha256:b0544343a702fa80c95ad5d3d608ea3599dd54d4632df855e4c8d24eb6ecfa1c \
--hash=sha256:b093dd74e50a8cba3e873868d9e93a85b78e0daf2e98c6797566ad8044e8363d \
--hash=sha256:b412caa66f72040e6d268491a59f2c43bf03eb6c96dd8f0307829feb7fa2b6fb \
--hash=sha256:b4f13750ce79751586ae2eb824ba7e1e8dba64784086c98cdbbcc6a42112ce0d \
--hash=sha256:b64d8d4d17135e00c8e346e0a738deb17e754230d7e0810ac5012750bbd85a5a \
--hash=sha256:ba10f8411898fc418a521833e014a77d3ca01c15b0c6cdcce6a0d2897e6dbbdf \
--hash=sha256:bd48227a919f1bafbdda0583705e547892342c26fb127219d60a5c36882609d1 \
--hash=sha256:c1f9540be57940698ed329904db803cf7a402f3fc200bfe599334c9bd84a40b2 \
--hash=sha256:c820a93b0255bc360f53eca31a0e676fd1101f673dda8da93454a12e23fc5f7a \
--hash=sha256:ce47521a4754c8f4593837384bd3424880629f718d87c5d44f8ed763edd63543 \
--hash=sha256:d042d24c90c41b54fd506da306759e06e568864df8ec17ccc17e9e884634fd00 \
--hash=sha256:de749064336d37e340f640b05f24e9e3dd678c57318c7289d222a8a2f543e90c \
--hash=sha256:e1dda9c7e08dc141e0247a5b8f49cf05984955246a327d4c48bda16821947b2f \
--hash=sha256:e29554e2bef54a90aa5cc07da6ce955accb83f21ab5de01a62c8478897b264fd \
--hash=sha256:e3143e4451880bed956e706a3220b4e5cf6172ef05fcc397f6f36a550b1dd868 \
--hash=sha256:e8213002e427c69c45a52bbd94163084025f533a55a59d6f9c5b820774ef3303 \
--hash=sha256:efd28d4e9cd7d7a8d39074a4d44c63eda73401580c5c76acda2ce969e0a38e83 \
--hash=sha256:f0fd6321b839904e15c46e0d257fdd101dd7f530fe03fd6359c1ea63738703f3 \
--hash=sha256:f1372f041402e37e5e633e586f62aa53de2eac8d98cbfb822806ce4bbefcb74d \
--hash=sha256:f2618db89be1b4e05f7a1a847a9c1c0abd63e63a1607d892dd54668dd92faf87 \
--hash=sha256:f447e6acb680fd307f40d3da4852208af94afdfab89cf850986c3ca00562f4fa \
--hash=sha256:f92729c95468a2f4f15e9bb94c432a9229d0d50de67304399627a943201baa2f \
--hash=sha256:f9f1adb22318e121c5c69a09142811a201ef17ab257a1e66ca3025065b7f53ae \
--hash=sha256:fc0c5673685c508a142ca65209b4e79ed6740a4ed6b2267dbba90f34b0b3cfda \
--hash=sha256:fc7b73d02efb0e18c000e9ad8b83480dfcd5dfd11065997ed4c6747470ae8915 \
--hash=sha256:fd83c01228a688733f1ded5201c678f0c53ecc1006ffbc404db9f7a899ac6249 \
--hash=sha256:fe27749d33bb772c80dcd84ae7e8df2adc920ae8297400dabec45f0dedb3f6de \
--hash=sha256:fee4236c876c4e8369388054d02d0e9bb84821feb1a64dd59e137e6511a551f8
# via opencv-python-headless
opencv-python-headless==4.12.0.88 \
--hash=sha256:1e58d664809b3350c1123484dd441e1667cd7bed3086db1b9ea1b6f6cb20b50e \
--hash=sha256:236c8df54a90f4d02076e6f9c1cc763d794542e886c576a6fee46ec8ff75a7a9 \
--hash=sha256:365bb2e486b50feffc2d07a405b953a8f3e8eaa63865bc650034e5c71e7a5154 \
--hash=sha256:86b413bdd6c6bf497832e346cd5371995de148e579b9774f8eba686dee3f5528 \
--hash=sha256:aeb4b13ecb8b4a0beb2668ea07928160ea7c2cd2d9b5ef571bbee6bafe9cc8d0 \
--hash=sha256:cfdc017ddf2e59b6c2f53bc12d74b6b0be7ded4ec59083ea70763921af2b6c09 \
--hash=sha256:fde2cf5c51e4def5f2132d78e0c08f9c14783cd67356922182c6845b9af87dbd
# via -r .github\scripts\requirements_dev.in
pdf2image==1.17.0 \
--hash=sha256:eaa959bc116b420dd7ec415fcae49b98100dda3dd18cd2fdfa86d09f112f6d57 \
--hash=sha256:ecdd58d7afb810dffe21ef2b1bbc057ef434dabbac6c33778a38a3f7744a27e2
# via -r .github\scripts\requirements_dev.in
pillow==11.3.0 \
--hash=sha256:023f6d2d11784a465f09fd09a34b150ea4672e85fb3d05931d89f373ab14abb2 \
--hash=sha256:02a723e6bf909e7cea0dac1b0e0310be9d7650cd66222a5f1c571455c0a45214 \
--hash=sha256:040a5b691b0713e1f6cbe222e0f4f74cd233421e105850ae3b3c0ceda520f42e \
--hash=sha256:05f6ecbeff5005399bb48d198f098a9b4b6bdf27b8487c7f38ca16eeb070cd59 \
--hash=sha256:068d9c39a2d1b358eb9f245ce7ab1b5c3246c7c8c7d9ba58cfa5b43146c06e50 \
--hash=sha256:0743841cabd3dba6a83f38a92672cccbd69af56e3e91777b0ee7f4dba4385632 \
--hash=sha256:092c80c76635f5ecb10f3f83d76716165c96f5229addbd1ec2bdbbda7d496e06 \
--hash=sha256:0b275ff9b04df7b640c59ec5a3cb113eefd3795a8df80bac69646ef699c6981a \
--hash=sha256:0bce5c4fd0921f99d2e858dc4d4d64193407e1b99478bc5cacecba2311abde51 \
--hash=sha256:1019b04af07fc0163e2810167918cb5add8d74674b6267616021ab558dc98ced \
--hash=sha256:106064daa23a745510dabce1d84f29137a37224831d88eb4ce94bb187b1d7e5f \
--hash=sha256:118ca10c0d60b06d006be10a501fd6bbdfef559251ed31b794668ed569c87e12 \
--hash=sha256:13f87d581e71d9189ab21fe0efb5a23e9f28552d5be6979e84001d3b8505abe8 \
--hash=sha256:155658efb5e044669c08896c0c44231c5e9abcaadbc5cd3648df2f7c0b96b9a6 \
--hash=sha256:1904e1264881f682f02b7f8167935cce37bc97db457f8e7849dc3a6a52b99580 \
--hash=sha256:19d2ff547c75b8e3ff46f4d9ef969a06c30ab2d4263a9e287733aa8b2429ce8f \
--hash=sha256:1a992e86b0dd7aeb1f053cd506508c0999d710a8f07b4c791c63843fc6a807ac \
--hash=sha256:1b9c17fd4ace828b3003dfd1e30bff24863e0eb59b535e8f80194d9cc7ecf860 \
--hash=sha256:1c627742b539bba4309df89171356fcb3cc5a9178355b2727d1b74a6cf155fbd \
--hash=sha256:1cd110edf822773368b396281a2293aeb91c90a2db00d78ea43e7e861631b722 \
--hash=sha256:1f85acb69adf2aaee8b7da124efebbdb959a104db34d3a2cb0f3793dbae422a8 \
--hash=sha256:23cff760a9049c502721bdb743a7cb3e03365fafcdfc2ef9784610714166e5a4 \
--hash=sha256:2465a69cf967b8b49ee1b96d76718cd98c4e925414ead59fdf75cf0fd07df673 \
--hash=sha256:2a3117c06b8fb646639dce83694f2f9eac405472713fcb1ae887469c0d4f6788 \
--hash=sha256:2aceea54f957dd4448264f9bf40875da0415c83eb85f55069d89c0ed436e3542 \
--hash=sha256:2d6fcc902a24ac74495df63faad1884282239265c6839a0a6416d33faedfae7e \
--hash=sha256:30807c931ff7c095620fe04448e2c2fc673fcbb1ffe2a7da3fb39613489b1ddd \
--hash=sha256:30b7c02f3899d10f13d7a48163c8969e4e653f8b43416d23d13d1bbfdc93b9f8 \
--hash=sha256:3828ee7586cd0b2091b6209e5ad53e20d0649bbe87164a459d0676e035e8f523 \
--hash=sha256:3cee80663f29e3843b68199b9d6f4f54bd1d4a6b59bdd91bceefc51238bcb967 \
--hash=sha256:3e184b2f26ff146363dd07bde8b711833d7b0202e27d13540bfe2e35a323a809 \
--hash=sha256:41342b64afeba938edb034d122b2dda5db2139b9a4af999729ba8818e0056477 \
--hash=sha256:41742638139424703b4d01665b807c6468e23e699e8e90cffefe291c5832b027 \
--hash=sha256:4445fa62e15936a028672fd48c4c11a66d641d2c05726c7ec1f8ba6a572036ae \
--hash=sha256:45dfc51ac5975b938e9809451c51734124e73b04d0f0ac621649821a63852e7b \
--hash=sha256:465b9e8844e3c3519a983d58b80be3f668e2a7a5db97f2784e7079fbc9f9822c \
--hash=sha256:48d254f8a4c776de343051023eb61ffe818299eeac478da55227d96e241de53f \
--hash=sha256:4c834a3921375c48ee6b9624061076bc0a32a60b5532b322cc0ea64e639dd50e \
--hash=sha256:4c96f993ab8c98460cd0c001447bff6194403e8b1d7e149ade5f00594918128b \
--hash=sha256:504b6f59505f08ae014f724b6207ff6222662aab5cc9542577fb084ed0676ac7 \
--hash=sha256:527b37216b6ac3a12d7838dc3bd75208ec57c1c6d11ef01902266a5a0c14fc27 \
--hash=sha256:5418b53c0d59b3824d05e029669efa023bbef0f3e92e75ec8428f3799487f361 \
--hash=sha256:59a03cdf019efbfeeed910bf79c7c93255c3d54bc45898ac2a4140071b02b4ae \
--hash=sha256:5e05688ccef30ea69b9317a9ead994b93975104a677a36a8ed8106be9260aa6d \
--hash=sha256:6359a3bc43f57d5b375d1ad54a0074318a0844d11b76abccf478c37c986d3cfc \
--hash=sha256:643f189248837533073c405ec2f0bb250ba54598cf80e8c1e043381a60632f58 \
--hash=sha256:65dc69160114cdd0ca0f35cb434633c75e8e7fad4cf855177a05bf38678f73ad \
--hash=sha256:67172f2944ebba3d4a7b54f2e95c786a3a50c21b88456329314caaa28cda70f6 \
--hash=sha256:676b2815362456b5b3216b4fd5bd89d362100dc6f4945154ff172e206a22c024 \
--hash=sha256:6a418691000f2a418c9135a7cf0d797c1bb7d9a485e61fe8e7722845b95ef978 \
--hash=sha256:6abdbfd3aea42be05702a8dd98832329c167ee84400a1d1f61ab11437f1717eb \
--hash=sha256:6be31e3fc9a621e071bc17bb7de63b85cbe0bfae91bb0363c893cbe67247780d \
--hash=sha256:7107195ddc914f656c7fc8e4a5e1c25f32e9236ea3ea860f257b0436011fddd0 \
--hash=sha256:71f511f6b3b91dd543282477be45a033e4845a40278fa8dcdbfdb07109bf18f9 \
--hash=sha256:7859a4cc7c9295f5838015d8cc0a9c215b77e43d07a25e460f35cf516df8626f \
--hash=sha256:7966e38dcd0fa11ca390aed7c6f20454443581d758242023cf36fcb319b1a874 \
--hash=sha256:79ea0d14d3ebad43ec77ad5272e6ff9bba5b679ef73375ea760261207fa8e0aa \
--hash=sha256:7aee118e30a4cf54fdd873bd3a29de51e29105ab11f9aad8c32123f58c8f8081 \
--hash=sha256:7b161756381f0918e05e7cb8a371fff367e807770f8fe92ecb20d905d0e1c149 \
--hash=sha256:7c8ec7a017ad1bd562f93dbd8505763e688d388cde6e4a010ae1486916e713e6 \
--hash=sha256:7d1aa4de119a0ecac0a34a9c8bde33f34022e2e8f99104e47a3ca392fd60e37d \
--hash=sha256:7db51d222548ccfd274e4572fdbf3e810a5e66b00608862f947b163e613b67dd \
--hash=sha256:819931d25e57b513242859ce1876c58c59dc31587847bf74cfe06b2e0cb22d2f \
--hash=sha256:83e1b0161c9d148125083a35c1c5a89db5b7054834fd4387499e06552035236c \
--hash=sha256:857844335c95bea93fb39e0fa2726b4d9d758850b34075a7e3ff4f4fa3aa3b31 \
--hash=sha256:8797edc41f3e8536ae4b10897ee2f637235c94f27404cac7297f7b607dd0716e \
--hash=sha256:8924748b688aa210d79883357d102cd64690e56b923a186f35a82cbc10f997db \
--hash=sha256:89bd777bc6624fe4115e9fac3352c79ed60f3bb18651420635f26e643e3dd1f6 \
--hash=sha256:8dc70ca24c110503e16918a658b869019126ecfe03109b754c402daff12b3d9f \
--hash=sha256:91da1d88226663594e3f6b4b8c3c8d85bd504117d043740a8e0ec449087cc494 \
--hash=sha256:921bd305b10e82b4d1f5e802b6850677f965d8394203d182f078873851dada69 \
--hash=sha256:932c754c2d51ad2b2271fd01c3d121daaa35e27efae2a616f77bf164bc0b3e94 \
--hash=sha256:93efb0b4de7e340d99057415c749175e24c8864302369e05914682ba642e5d77 \
--hash=sha256:97afb3a00b65cc0804d1c7abddbf090a81eaac02768af58cbdcaaa0a931e0b6d \
--hash=sha256:97f07ed9f56a3b9b5f49d3661dc9607484e85c67e27f3e8be2c7d28ca032fec7 \
--hash=sha256:98a9afa7b9007c67ed84c57c9e0ad86a6000da96eaa638e4f8abe5b65ff83f0a \
--hash=sha256:9ab6ae226de48019caa8074894544af5b53a117ccb9d3b3dcb2871464c829438 \
--hash=sha256:9c412fddd1b77a75aa904615ebaa6001f169b26fd467b4be93aded278266b288 \
--hash=sha256:a1bc6ba083b145187f648b667e05a2534ecc4b9f2784c2cbe3089e44868f2b9b \
--hash=sha256:a418486160228f64dd9e9efcd132679b7a02a5f22c982c78b6fc7dab3fefb635 \
--hash=sha256:a4d336baed65d50d37b88ca5b60c0fa9d81e3a87d4a7930d3880d1624d5b31f3 \
--hash=sha256:a6444696fce635783440b7f7a9fc24b3ad10a9ea3f0ab66c5905be1c19ccf17d \
--hash=sha256:a7bc6e6fd0395bc052f16b1a8670859964dbd7003bd0af2ff08342eb6e442cfe \
--hash=sha256:b4b8f3efc8d530a1544e5962bd6b403d5f7fe8b9e08227c6b255f98ad82b4ba0 \
--hash=sha256:b5f56c3f344f2ccaf0dd875d3e180f631dc60a51b314295a3e681fe8cf851fbe \
--hash=sha256:be5463ac478b623b9dd3937afd7fb7ab3d79dd290a28e2b6df292dc75063eb8a \
--hash=sha256:c37d8ba9411d6003bba9e518db0db0c58a680ab9fe5179f040b0463644bc9805 \
--hash=sha256:c84d689db21a1c397d001aa08241044aa2069e7587b398c8cc63020390b1c1b8 \
--hash=sha256:c96d333dcf42d01f47b37e0979b6bd73ec91eae18614864622d9b87bbd5bbf36 \
--hash=sha256:cadc9e0ea0a2431124cde7e1697106471fc4c1da01530e679b2391c37d3fbb3a \
--hash=sha256:cc3e831b563b3114baac7ec2ee86819eb03caa1a2cef0b481a5675b59c4fe23b \
--hash=sha256:cd8ff254faf15591e724dc7c4ddb6bf4793efcbe13802a4ae3e863cd300b493e \
--hash=sha256:d000f46e2917c705e9fb93a3606ee4a819d1e3aa7a9b442f6444f07e77cf5e25 \
--hash=sha256:d9da3df5f9ea2a89b81bb6087177fb1f4d1c7146d583a3fe5c672c0d94e55e12 \
--hash=sha256:e5c5858ad8ec655450a7c7df532e9842cf8df7cc349df7225c60d5d348c8aada \
--hash=sha256:e67d793d180c9df62f1f40aee3accca4829d3794c95098887edc18af4b8b780c \
--hash=sha256:ea944117a7974ae78059fcc1800e5d3295172bb97035c0c1d9345fca1419da71 \
--hash=sha256:eb76541cba2f958032d79d143b98a3a6b3ea87f0959bbe256c0b5e416599fd5d \
--hash=sha256:ec1ee50470b0d050984394423d96325b744d55c701a439d2bd66089bff963d3c \
--hash=sha256:ee92f2fd10f4adc4b43d07ec5e779932b4eb3dbfbc34790ada5a6669bc095aa6 \
--hash=sha256:f0f5d8f4a08090c6d6d578351a2b91acf519a54986c055af27e7a93feae6d3f1 \
--hash=sha256:f1f182ebd2303acf8c380a54f615ec883322593320a9b00438eb842c1f37ae50 \
--hash=sha256:f8a5827f84d973d8636e9dc5764af4f0cf2318d26744b3d902931701b0d46653 \
--hash=sha256:f944255db153ebb2b19c51fe85dd99ef0ce494123f21b9db4877ffdfc5590c7c \
--hash=sha256:fdae223722da47b024b867c1ea0be64e0df702c5e0a60e27daad39bf960dd1e4 \
--hash=sha256:fe27fb049cdcca11f11a7bfda64043c37b30e6b91f10cb5bab275806c32f6ab3
# via
# -r .github\scripts\requirements_dev.in
# pdf2image
# weasyprint
platformdirs==4.3.8 \
--hash=sha256:3d512d96e16bcb959a814c9f348431070822a6496326a4be0911c40b5a74c2bc \
--hash=sha256:ff7059bb7eb1179e2685604f4aaf157cfd9535242bd23742eadc3c13542139b4
# via virtualenv
pre-commit==4.3.0 \
--hash=sha256:2b0747ad7e6e967169136edffee14c16e148a778a54e4f967921aa1ebf2308d8 \
--hash=sha256:499fe450cc9d42e9d58e606262795ecb64dd05438943c62b66f6a8673da30b16
# via -r .github\scripts\requirements_dev.in
pycparser==2.22 \
--hash=sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6 \
--hash=sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc
# via cffi
pydyf==0.11.0 \
--hash=sha256:0aaf9e2ebbe786ec7a78ec3fbffa4cdcecde53fd6f563221d53c6bc1328848a3 \
--hash=sha256:394dddf619cca9d0c55715e3c55ea121a9bf9cbc780cdc1201a2427917b86b64
# via weasyprint
pyphen==0.17.2 \
--hash=sha256:3a07fb017cb2341e1d9ff31b8634efb1ae4dc4b130468c7c39dd3d32e7c3affd \
--hash=sha256:f60647a9c9b30ec6c59910097af82bc5dd2d36576b918e44148d8b07ef3b4aa3
# via weasyprint
pyyaml==6.0.2 \
--hash=sha256:01179a4a8559ab5de078078f37e5c1a30d76bb88519906844fd7bdea1b7729ff \
--hash=sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48 \
--hash=sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086 \
--hash=sha256:0b69e4ce7a131fe56b7e4d770c67429700908fc0752af059838b1cfb41960e4e \
--hash=sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133 \
--hash=sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5 \
--hash=sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484 \
--hash=sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee \
--hash=sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5 \
--hash=sha256:23502f431948090f597378482b4812b0caae32c22213aecf3b55325e049a6c68 \
--hash=sha256:24471b829b3bf607e04e88d79542a9d48bb037c2267d7927a874e6c205ca7e9a \
--hash=sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf \
--hash=sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99 \
--hash=sha256:39693e1f8320ae4f43943590b49779ffb98acb81f788220ea932a6b6c51004d8 \
--hash=sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85 \
--hash=sha256:3b1fdb9dc17f5a7677423d508ab4f243a726dea51fa5e70992e59a7411c89d19 \
--hash=sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc \
--hash=sha256:43fa96a3ca0d6b1812e01ced1044a003533c47f6ee8aca31724f78e93ccc089a \
--hash=sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1 \
--hash=sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317 \
--hash=sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c \
--hash=sha256:6395c297d42274772abc367baaa79683958044e5d3835486c16da75d2a694631 \
--hash=sha256:688ba32a1cffef67fd2e9398a2efebaea461578b0923624778664cc1c914db5d \
--hash=sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652 \
--hash=sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5 \
--hash=sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e \
--hash=sha256:7c36280e6fb8385e520936c3cb3b8042851904eba0e58d277dca80a5cfed590b \
--hash=sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8 \
--hash=sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476 \
--hash=sha256:82d09873e40955485746739bcb8b4586983670466c23382c19cffecbf1fd8706 \
--hash=sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563 \
--hash=sha256:8824b5a04a04a047e72eea5cec3bc266db09e35de6bdfe34c9436ac5ee27d237 \
--hash=sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b \
--hash=sha256:9056c1ecd25795207ad294bcf39f2db3d845767be0ea6e6a34d856f006006083 \
--hash=sha256:936d68689298c36b53b29f23c6dbb74de12b4ac12ca6cfe0e047bedceea56180 \
--hash=sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425 \
--hash=sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e \
--hash=sha256:a8786accb172bd8afb8be14490a16625cbc387036876ab6ba70912730faf8e1f \
--hash=sha256:a9f8c2e67970f13b16084e04f134610fd1d374bf477b17ec1599185cf611d725 \
--hash=sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183 \
--hash=sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab \
--hash=sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774 \
--hash=sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725 \
--hash=sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e \
--hash=sha256:d7fded462629cfa4b685c5416b949ebad6cec74af5e2d42905d41e257e0869f5 \
--hash=sha256:d84a1718ee396f54f3a086ea0a66d8e552b2ab2017ef8b420e92edbc841c352d \
--hash=sha256:d8e03406cac8513435335dbab54c0d385e4a49e4945d2909a581c83647ca0290 \
--hash=sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44 \
--hash=sha256:ec031d5d2feb36d1d1a24380e4db6d43695f3748343d99434e6f5f9156aaa2ed \
--hash=sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4 \
--hash=sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba \
--hash=sha256:f753120cb8181e736c57ef7636e83f31b9c0d1722c516f7e86cf15b7aa57ff12 \
--hash=sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4
# via pre-commit
tinycss2==1.4.0 \
--hash=sha256:10c0972f6fc0fbee87c3edb76549357415e94548c1ae10ebccdea16fb404a9b7 \
--hash=sha256:3a49cf47b7675da0b15d0c6e1df8df4ebd96e9394bb905a5775adb0d884c5289
# via
# cssselect2
# weasyprint
tinyhtml5==2.0.0 \
--hash=sha256:086f998833da24c300c414d9fe81d9b368fd04cb9d2596a008421cbc705fcfcc \
--hash=sha256:13683277c5b176d070f82d099d977194b7a1e26815b016114f581a74bbfbf47e
# via weasyprint
unoserver==3.3.2 \
--hash=sha256:1eeb7467cf6b56b8eff3b576e2d1b2b2ff4e0eb2052e995ac80a1456de300639 \
--hash=sha256:87e144f903ee21951b2e06a97549450c13ed7eca5bcebad942d3352d4e882616
# via -r .github\scripts\requirements_dev.in
virtualenv==20.33.1 \
--hash=sha256:07c19bc66c11acab6a5958b815cbcee30891cd1c2ccf53785a28651a0d8d8a67 \
--hash=sha256:1b44478d9e261b3fb8baa5e74a0ca3bc0e05f21aa36167bf9cbf850e542765b8
# via pre-commit
weasyprint==66.0 \
--hash=sha256:82b0783b726fcd318e2c977dcdddca76515b30044bc7a830cc4fbe717582a6d0 \
--hash=sha256:da71dc87dc129ac9cffdc65e5477e90365ab9dbae45c744014ec1d06303dde40
# via -r .github\scripts\requirements_dev.in
webencodings==0.5.1 \
--hash=sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78 \
--hash=sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923
# via
# cssselect2
# tinycss2
# tinyhtml5
zopfli==0.2.3.post1 \
--hash=sha256:0aa5f90d6298bda02a95bc8dc8c3c19004d5a4e44bda00b67ca7431d857b4b54 \
--hash=sha256:0cc20b02a9531559945324c38302fd4ba763311632d0ec8a1a0aa9c10ea363e6 \
--hash=sha256:1d8cc06605519e82b16df090e17cb3990d1158861b2872c3117f1168777b81e4 \
--hash=sha256:1f990634fd5c5c8ced8edddd8bd45fab565123b4194d6841e01811292650acae \
--hash=sha256:2345e713260a350bea0b01a816a469ea356bc2d63d009a0d777691ecbbcf7493 \
--hash=sha256:2768c877f76c8a0e7519b1c86c93757f3c01492ddde55751e9988afb7eff64e1 \
--hash=sha256:29ea74e72ffa6e291b8c6f2504ce6c146b4fe990c724c1450eb8e4c27fd31431 \
--hash=sha256:34a99592f3d9eb6f737616b5bd74b48a589fdb3cb59a01a50d636ea81d6af272 \
--hash=sha256:3654bfc927bc478b1c3f3ff5056ed7b20a1a37fa108ca503256d0a699c03bbb1 \
--hash=sha256:3657e416ffb8f31d9d3424af12122bb251befae109f2e271d87d825c92fc5b7b \
--hash=sha256:37d011e92f7b9622742c905fdbed9920a1d0361df84142807ea2a528419dea7f \
--hash=sha256:3827170de28faf144992d3d4dcf8f3998fe3c8a6a6f4a08f1d42c2ec6119d2bb \
--hash=sha256:39e576f93576c5c223b41d9c780bbb91fd6db4babf3223d2a4fe7bf568e2b5a8 \
--hash=sha256:3a89277ed5f8c0fb2d0b46d669aa0633123aa7381f1f6118c12f15e0fb48f8ca \
--hash=sha256:3c163911f8bad94b3e1db0a572e7c28ba681a0c91d0002ea1e4fa9264c21ef17 \
--hash=sha256:3f0197b6aa6eb3086ae9e66d6dd86c4d502b6c68b0ec490496348ae8c05ecaef \
--hash=sha256:48dba9251060289101343110ab47c0756f66f809bb4d1ddbb6d5c7e7752115c5 \
--hash=sha256:4915a41375bdee4db749ecd07d985a0486eb688a6619f713b7bf6fbfd145e960 \
--hash=sha256:4c1226a7e2c7105ac31503a9bb97454743f55d88164d6d46bc138051b77f609b \
--hash=sha256:4e50ffac74842c1c1018b9b73875a0d0a877c066ab06bf7cccbaa84af97e754f \
--hash=sha256:518f1f4ed35dd69ce06b552f84e6d081f07c552b4c661c5312d950a0b764a58a \
--hash=sha256:5aad740b4d4fcbaaae4887823925166ffd062db3b248b3f432198fc287381d1a \
--hash=sha256:5f272186e03ad55e7af09ab78055535c201b1a0bcc2944edb1768298d9c483a4 \
--hash=sha256:5fcfc0dc2761e4fcc15ad5d273b4d58c2e8e059d3214a7390d4d3c8e2aee644e \
--hash=sha256:60db20f06c3d4c5934b16cfa62a2cc5c3f0686bffe0071ed7804d3c31ab1a04e \
--hash=sha256:615a8ac9dda265e9cc38b2a76c3142e4a9f30fea4a79c85f670850783bc6feb4 \
--hash=sha256:6482db9876c68faac2d20a96b566ffbf65ddaadd97b222e4e73641f4f8722fc4 \
--hash=sha256:6617fb10f9e4393b331941861d73afb119cd847e88e4974bdbe8068ceef3f73f \
--hash=sha256:676919fba7311125244eb0c4393679ac5fe856e5864a15d122bd815205369fa0 \
--hash=sha256:6c2d2bc8129707e34c51f9352c4636ca313b52350bbb7e04637c46c1818a2a70 \
--hash=sha256:71390dbd3fbf6ebea9a5d85ffed8c26ee1453ee09248e9b88486e30e0397b775 \
--hash=sha256:716cdbfc57bfd3d3e31a58e6246e8190e6849b7dbb7c4ce39ef8bbf0edb8f6d5 \
--hash=sha256:75a26a2307b10745a83b660c404416e984ee6fca515ec7f0765f69af3ce08072 \
--hash=sha256:7be5cc6732eb7b4df17305d8a7b293223f934a31783a874a01164703bc1be6cd \
--hash=sha256:7cce242b5df12b2b172489daf19c32e5577dd2fac659eb4b17f6a6efb446fd5c \
--hash=sha256:81c341d9bb87a6dbbb0d45d6e272aca80c7c97b4b210f9b6e233bf8b87242f29 \
--hash=sha256:89899641d4de97dbad8e0cde690040d078b6aea04066dacaab98e0b5a23573f2 \
--hash=sha256:8d5ab297d660b75c159190ce6d73035502310e40fd35170aed7d1a1aea7ddd65 \
--hash=sha256:8fbe5bcf10d01aab3513550f284c09fef32f342b36f56bfae2120a9c4d12c130 \
--hash=sha256:91a2327a4d7e77471fa4fbb26991c6de4a738c6fc6a33e09bb25f56a870a4b7b \
--hash=sha256:95a260cafd56b8fffa679918937401c80bb38e1681c448b988022e4c3610965d \
--hash=sha256:96484dc0f48be1c5d7ae9f38ed1ce41e3675fd506b27c11a6607f14b49101e99 \
--hash=sha256:9a6aec38a989bad7ddd1ef53f1265699e49e294d08231b5313d61293f3cd6237 \
--hash=sha256:9ba214f4f45bec195ee8559651154d3ac2932470b9d91c5715fc29c013349f8c \
--hash=sha256:9f4a7ec2770e6af05f5a02733fd3900f30a9cd58e5d6d3727e14c5bcd6e7d587 \
--hash=sha256:a1cf720896d2ce998bc8e051d4b4ce0d8bec007aab6243102e8e1d22a0b2fb3f \
--hash=sha256:a241a68581d34d67b40c425cce3d1fd211c092f99d9250947824ccba9f491949 \
--hash=sha256:a53b18797cdef27e019db595d66c4b077325afe2fd62145953275f53d84ce40c \
--hash=sha256:a82fc2dbebe6eb908b9c665e71496f8525c1bc4d2e3a7a7722ef2b128b6227c8 \
--hash=sha256:a86eb88e06bd87e1fff31dac878965c26b0c26db59ddcf78bb0379a954b120de \
--hash=sha256:aa588b21044f8a74e423d8c8a4c7fc9988501878aacced793467010039c50734 \
--hash=sha256:b05296e8bc88c92e2b21e0a9bae4740c1551ee613c1d93a51fd28a7a0b2b6fbb \
--hash=sha256:b0ec13f352ea5ae0fc91f98a48540512eed0767d0ec4f7f3cb92d92797983d18 \
--hash=sha256:b3df42f52502438ee973042cc551877d24619fa1cd38ef7b7e9ac74200daca8b \
--hash=sha256:b78008a69300d929ca2efeffec951b64a312e9a811e265ea4a907ab546d79fa6 \
--hash=sha256:b9026a21b6d41eb0e2e63f5bc1242c3fcc43ecb770963cda99a4307863dac12e \
--hash=sha256:bbe429fc50686bb2a2608a30843e36fbaa123462a5284f136c7d9e0145220bfd \
--hash=sha256:bfa1eb759e07d8b7aa7a310a2bc535e127ee70addf90dc8d4b946b593c3e51a8 \
--hash=sha256:c1e0ed5d84ffa2d677cc9582fc01e61dab2e7ef8b8996e055f0a76167b1b94df \
--hash=sha256:c4278d1873ce6e803e5d4f8d702fd3026bd67fca744aa98881324d1157ddf748 \
--hash=sha256:cac2b37ab21c2b36a10b685b1893ebd6b0f83ae26004838ac817680881576567 \
--hash=sha256:cbe6df25807227519debd1a57ab236f5f6bad441500e85b13903e51f93a43214 \
--hash=sha256:cd2c002f160502608dcc822ed2441a0f4509c52e86fcfd1a09e937278ed1ca14 \
--hash=sha256:e0137dd64a493ba6a4be37405cfd6febe650a98cc1e9dca8f6b8c63b1db11b41 \
--hash=sha256:e63d558847166543c2c9789e6f985400a520b7eacc4b99181668b2c3aeadd352 \
--hash=sha256:eb45a34f23da4f8bc712b6376ca5396914b0b7c09adbb001dad964eb7f3132f8 \
--hash=sha256:ecb7572df5372abce8073df078207d9d1749f20b8b136089916a4a0868d56051 \
--hash=sha256:f12000a6accdd4bf0a3fa6eaa1b1c7a7bc80af0a2edf3f89d770d3dcce1d0e22 \
--hash=sha256:f7d69c1a7168ad0e9cb864e8663acb232986a0c9c9cb9801f56bf6214f53a54d \
--hash=sha256:f815fcc2b2a457977724bad97fb4854022980f51ce7b136925e336b530545ae1 \
--hash=sha256:fc39f5c27f962ec8660d8d20c24762431131b5d8c672b44b0a54cf2b5bcde9b9
# via fonttools
# The following packages are considered to be unsafe in a requirements file:
pip==25.2 \
--hash=sha256:578283f006390f85bb6282dffb876454593d637f5d1be494b5202ce4877e71f2 \
--hash=sha256:6d67a2b4e7f14d8b31b8b52648866fa717f45a1eb70e83002f4331d07e953717
# via -r .github\scripts\requirements_dev.in
setuptools==80.9.0 \
--hash=sha256:062d34222ad13e0cc312a4c02d73f059e86a4acbfbdea8f8f76b28c99f306922 \
--hash=sha256:f36b47402ecde768dbfafc46e8e4207b4360c654f1f3bb84475f0a28628fb19c
# via -r .github\scripts\requirements_dev.in
+16 -12
View File
@@ -8,17 +8,17 @@ cfgv==3.4.0 \
--hash=sha256:b7265b1f29fd3316bfcd2b330d63d024f2bfd8bcb8b0272f8e19a504856c48f9 \
--hash=sha256:e52591d4c5f5dead8e0f673fb16db7949d2cfb3f7da4582893288f0ded8fe560
# via pre-commit
distlib==0.3.9 \
--hash=sha256:47f8c22fd27c27e25a65601af709b38e4f0a45ea4fc2e710f65755fa8caaaf87 \
--hash=sha256:a60f20dea646b8a33f3e7772f74dc0b2d0772d2837ee1342a00645c81edf9403
distlib==0.4.0 \
--hash=sha256:9659f7d87e46584a30b5780e43ac7a2143098441670ff0a49d5f9034c54a6c16 \
--hash=sha256:feec40075be03a04501a973d81f633735b4b69f98b05450592310c0f401a4e0d
# via virtualenv
filelock==3.18.0 \
--hash=sha256:adbc88eabb99d2fec8c9c1b229b171f18afa655400173ddc653d5d01501fb9f2 \
--hash=sha256:c401f4f8377c4464e6db25fff06205fd89bdd83b65eb0488ed1b160f780e21de
# via virtualenv
identify==2.6.12 \
--hash=sha256:ad9672d5a72e0d2ff7c5c8809b62dfa60458626352fb0eb7b55e69bdc45334a2 \
--hash=sha256:d8de45749f1efb108badef65ee8386f0f7bb19a7f26185f74de6367bffbaf0e6
identify==2.6.13 \
--hash=sha256:60381139b3ae39447482ecc406944190f690d4a2997f2584062089848361b33b \
--hash=sha256:da8d6c828e773620e13bfa86ea601c5a5310ba4bcd65edf378198b56a1f9fb32
# via pre-commit
nodeenv==1.9.1 \
--hash=sha256:6ec12890a2dab7946721edbfbcd91f3319c6ccc9aec47be7c7e6b7011ee6645f \
@@ -28,9 +28,9 @@ platformdirs==4.3.8 \
--hash=sha256:3d512d96e16bcb959a814c9f348431070822a6496326a4be0911c40b5a74c2bc \
--hash=sha256:ff7059bb7eb1179e2685604f4aaf157cfd9535242bd23742eadc3c13542139b4
# via virtualenv
pre-commit==4.2.0 \
--hash=sha256:601283b9757afd87d40c4c4a9b2b5de9637a8ea02eaff7adc2d0fb4e04841146 \
--hash=sha256:a009ca7205f1eb497d10b845e52c838a98b6cdd2102a6c8e4540e94ee75c58bd
pre-commit==4.3.0 \
--hash=sha256:2b0747ad7e6e967169136edffee14c16e148a778a54e4f967921aa1ebf2308d8 \
--hash=sha256:499fe450cc9d42e9d58e606262795ecb64dd05438943c62b66f6a8673da30b16
# via -r .github\scripts\requirements_pre_commit.in
pyyaml==6.0.2 \
--hash=sha256:01179a4a8559ab5de078078f37e5c1a30d76bb88519906844fd7bdea1b7729ff \
@@ -87,7 +87,11 @@ pyyaml==6.0.2 \
--hash=sha256:f753120cb8181e736c57ef7636e83f31b9c0d1722c516f7e86cf15b7aa57ff12 \
--hash=sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4
# via pre-commit
virtualenv==20.31.2 \
--hash=sha256:36efd0d9650ee985f0cad72065001e66d49a6f24eb44d98980f630686243cf11 \
--hash=sha256:e10c0a9d02835e592521be48b332b6caee6887f332c111aa79a09b9e79efc2af
typing-extensions==4.14.1 \
--hash=sha256:38b39f4aeeab64884ce9f74c94263ef78f3c22467c8724005483154c26648d36 \
--hash=sha256:d1e1e3b58374dc93031d6eda2420a48ea44a36c2b4766a4fdeb3710755731d76
# via virtualenv
virtualenv==20.34.0 \
--hash=sha256:341f5afa7eee943e4984a9207c025feedd768baff6753cd660c857ceb3e36026 \
--hash=sha256:44815b2c9dee7ed86e387b842a84f20b93f7f417f95886ca1996a72a4138eb1a
# via pre-commit
@@ -33,8 +33,6 @@ jobs:
)
outputs:
pr_number: ${{ steps.get-pr.outputs.pr_number }}
pr_repository: ${{ steps.get-pr-info.outputs.repository }}
pr_ref: ${{ steps.get-pr-info.outputs.ref }}
comment_id: ${{ github.event.comment.id }}
disable_security: ${{ steps.check-security-flag.outputs.disable_security }}
enable_pro: ${{ steps.check-pro-flag.outputs.enable_pro }}
@@ -46,7 +44,7 @@ jobs:
egress-policy: audit
- name: Checkout PR
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Setup GitHub App Bot
if: github.actor != 'dependabot[bot]'
@@ -66,29 +64,6 @@ jobs:
console.log(`PR Number: ${prNumber}`);
core.setOutput('pr_number', prNumber);
- name: Get PR repository and ref
id: get-pr-info
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
with:
script: |
const { owner, repo } = context.repo;
const prNumber = context.payload.issue.number;
const { data: pr } = await github.rest.pulls.get({
owner,
repo,
pull_number: prNumber,
});
// For forks, use the full repository name, for internal PRs use the current repo
const repository = pr.head.repo.fork ? pr.head.repo.full_name : `${owner}/${repo}`;
console.log(`PR Repository: ${repository}`);
console.log(`PR Branch: ${pr.head.ref}`);
core.setOutput('repository', repository);
core.setOutput('ref', pr.head.ref);
- name: Check for security/login flag
id: check-security-flag
env:
@@ -157,7 +132,7 @@ jobs:
egress-policy: audit
- name: Checkout PR
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Setup GitHub App Bot
if: github.actor != 'dependabot[bot]'
@@ -169,14 +144,13 @@ jobs:
private-key: ${{ secrets.GH_APP_PRIVATE_KEY }}
- name: Checkout PR
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
repository: ${{ needs.check-comment.outputs.pr_repository }}
ref: ${{ needs.check-comment.outputs.pr_ref }}
ref: refs/pull/${{ needs.check-comment.outputs.pr_number }}/merge
token: ${{ steps.setup-bot.outputs.token }}
- name: Set up JDK
uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4.7.1
uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v5.0.0
with:
java-version: "17"
distribution: "temurin"
+1 -1
View File
@@ -26,7 +26,7 @@ jobs:
egress-policy: audit
- name: Checkout PR
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Setup GitHub App Bot
if: github.actor != 'dependabot[bot]'
+2 -2
View File
@@ -23,7 +23,7 @@ jobs:
with:
egress-policy: audit
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
fetch-depth: 0
@@ -87,7 +87,7 @@ jobs:
- name: AI PR Title Analysis
if: steps.actor.outputs.is_repo_dev == 'true'
id: ai-title-analysis
uses: actions/ai-inference@0cbed4a10641c75090de5968e66d70eb4660f751 # v1.2.7
uses: actions/ai-inference@b81b2afb8390ee6839b494a404766bef6493c7d9 # v1.2.8
with:
model: openai/gpt-4o
system-prompt-file: ".github/config/system-prompt.txt"
+1 -1
View File
@@ -17,7 +17,7 @@ jobs:
with:
egress-policy: audit
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Setup GitHub App Bot
id: setup-bot
+22 -17
View File
@@ -34,7 +34,7 @@ jobs:
project: ${{ steps.changes.outputs.project }}
openapi: ${{ steps.changes.outputs.openapi }}
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Check for file changes
uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2
@@ -61,16 +61,16 @@ jobs:
egress-policy: audit
- name: Checkout repository
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Set up JDK ${{ matrix.jdk-version }}
uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4.7.1
uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v5.0.0
with:
java-version: ${{ matrix.jdk-version }}
distribution: "temurin"
- name: Setup Gradle
uses: gradle/actions/setup-gradle@ac638b010cf58a27ee6c972d7336334ccaf61c96 # v4.4.1
uses: gradle/actions/setup-gradle@017a9effdb900e5b5b2fddfb590a105619dca3c3 # v4.4.2
with:
gradle-version: 8.14
@@ -134,20 +134,22 @@ jobs:
egress-policy: audit
- name: Checkout repository
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Set up JDK 17
uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4.7.1
uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v5.0.0
with:
java-version: "17"
distribution: "temurin"
- name: Setup Gradle
uses: gradle/actions/setup-gradle@ac638b010cf58a27ee6c972d7336334ccaf61c96 # v4.4.1
uses: gradle/actions/setup-gradle@017a9effdb900e5b5b2fddfb590a105619dca3c3 # v4.4.2
- name: Generate OpenAPI documentation
run: ./gradlew :stirling-pdf:generateOpenApiDocs
env:
DISABLE_ADDITIONAL_FEATURES: true
- name: Upload OpenAPI Documentation
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
@@ -165,18 +167,21 @@ jobs:
egress-policy: audit
- name: Checkout repository
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Set up JDK 17
uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4.7.1
uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v5.0.0
with:
java-version: "17"
distribution: "temurin"
- name: check the licenses for compatibility
- name: Check licenses for compatibility
run: ./gradlew clean checkLicense
env:
DISABLE_ADDITIONAL_FEATURES: false
STIRLING_PDF_DESKTOP_UI: true
- name: FAILED - check the licenses for compatibility
- name: FAILED - Check licenses for compatibility
if: failure()
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
@@ -211,10 +216,10 @@ jobs:
egress-policy: audit
- name: Checkout Repository
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Set up Java 17
uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4.7.1
uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v5.0.0
with:
java-version: "17"
distribution: "temurin"
@@ -260,16 +265,16 @@ jobs:
egress-policy: audit
- name: Checkout Repository
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Set up JDK 17
uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4.7.1
uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v5.0.0
with:
java-version: "17"
distribution: "temurin"
- name: Set up Gradle
uses: gradle/actions/setup-gradle@ac638b010cf58a27ee6c972d7336334ccaf61c96 # v4.4.1
uses: gradle/actions/setup-gradle@017a9effdb900e5b5b2fddfb590a105619dca3c3 # v4.4.2
with:
gradle-version: 8.14
+1 -1
View File
@@ -35,7 +35,7 @@ jobs:
egress-policy: audit
- name: Checkout main branch first
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Setup GitHub App Bot
id: setup-bot
+2 -2
View File
@@ -22,6 +22,6 @@ jobs:
egress-policy: audit
- name: "Checkout Repository"
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: "Dependency Review"
uses: actions/dependency-review-action@da24556b548a50705dd671f47852072ea4c105d9 # v4.7.1
uses: actions/dependency-review-action@595b5aeba73380359d98a5e087f648dbb0edce1b # v4.7.3
+6 -3
View File
@@ -36,7 +36,7 @@ jobs:
egress-policy: audit
- name: Check out code
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
fetch-depth: 0
@@ -48,16 +48,19 @@ jobs:
private-key: ${{ secrets.GH_APP_PRIVATE_KEY }}
- name: Set up JDK 17
uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4.7.1
uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v5.0.0
with:
java-version: "17"
distribution: "temurin"
- name: Setup Gradle
uses: gradle/actions/setup-gradle@ac638b010cf58a27ee6c972d7336334ccaf61c96 # v4.4.1
uses: gradle/actions/setup-gradle@017a9effdb900e5b5b2fddfb590a105619dca3c3 # v4.4.2
- name: Check licenses for compatibility
run: ./gradlew clean checkLicense
env:
DISABLE_ADDITIONAL_FEATURES: false
STIRLING_PDF_DESKTOP_UI: true
- name: Upload artifact on failure
if: failure()
+1 -1
View File
@@ -20,7 +20,7 @@ jobs:
egress-policy: audit
- name: Check out the repository
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Run Labeler
uses: crazy-max/ghaction-github-labeler@24d110aa46a59976b8a7f35518cb7f14f434c916 # v5.3.0
+11 -11
View File
@@ -25,10 +25,10 @@ jobs:
with:
egress-policy: audit
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Set up JDK
uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4.7.1
uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v5.0.0
with:
distribution: 'temurin'
java-version: '21'
@@ -64,15 +64,15 @@ jobs:
with:
egress-policy: audit
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Set up JDK 21
uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4.7.1
uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v5.0.0
with:
java-version: "21"
distribution: "temurin"
- uses: gradle/actions/setup-gradle@ac638b010cf58a27ee6c972d7336334ccaf61c96 # v4.4.1
- uses: gradle/actions/setup-gradle@017a9effdb900e5b5b2fddfb590a105619dca3c3 # v4.4.2
with:
gradle-version: 8.14
@@ -115,7 +115,7 @@ jobs:
egress-policy: audit
- name: Download build artifacts
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.0.0
with:
name: stirling-${{ matrix.file_suffix }}binaries
@@ -152,15 +152,15 @@ jobs:
with:
egress-policy: audit
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Set up JDK 21
uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4.7.1
uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v5.0.0
with:
java-version: "21"
distribution: "temurin"
- uses: gradle/actions/setup-gradle@ac638b010cf58a27ee6c972d7336334ccaf61c96 # v4.4.1
- uses: gradle/actions/setup-gradle@017a9effdb900e5b5b2fddfb590a105619dca3c3 # v4.4.2
with:
gradle-version: 8.14
@@ -243,7 +243,7 @@ jobs:
egress-policy: audit
- name: Download build artifacts
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.0.0
with:
name: ${{ matrix.platform }}binaries
@@ -306,7 +306,7 @@ jobs:
egress-policy: audit
- name: Download signed artifacts
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.0.0
- name: Display structure of downloaded files
run: ls -R
- name: Upload binaries, attestations and signatures to Release and create GitHub Release
+2 -2
View File
@@ -22,7 +22,7 @@ jobs:
egress-policy: audit
- name: Checkout repository
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
fetch-depth: 0
@@ -48,7 +48,7 @@ jobs:
continue-on-error: true
- name: Set up JDK
uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4.7.1
uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v5.0.0
with:
java-version: 17
distribution: "temurin"
+3 -3
View File
@@ -34,15 +34,15 @@ jobs:
with:
egress-policy: audit
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Set up JDK 17
uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4.7.1
uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v5.0.0
with:
java-version: "17"
distribution: "temurin"
- uses: gradle/actions/setup-gradle@ac638b010cf58a27ee6c972d7336334ccaf61c96 # v4.4.1
- uses: gradle/actions/setup-gradle@017a9effdb900e5b5b2fddfb590a105619dca3c3 # v4.4.2
with:
gradle-version: 8.14
+5 -5
View File
@@ -27,15 +27,15 @@ jobs:
with:
egress-policy: audit
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Set up JDK 17
uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4.7.1
uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v5.0.0
with:
java-version: "17"
distribution: "temurin"
- uses: gradle/actions/setup-gradle@ac638b010cf58a27ee6c972d7336334ccaf61c96 # v4.4.1
- uses: gradle/actions/setup-gradle@017a9effdb900e5b5b2fddfb590a105619dca3c3 # v4.4.2
with:
gradle-version: 8.14
@@ -88,7 +88,7 @@ jobs:
egress-policy: audit
- name: Download build artifacts
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.0.0
with:
name: binaries${{ matrix.file_suffix }}
- name: Display structure of downloaded files
@@ -166,7 +166,7 @@ jobs:
egress-policy: audit
- name: Download signed artifacts
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.0.0
with:
name: signed${{ matrix.file_suffix }}
+2 -2
View File
@@ -39,7 +39,7 @@ jobs:
egress-policy: audit
- name: "Checkout code"
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
persist-credentials: false
@@ -74,6 +74,6 @@ jobs:
# Upload the results to GitHub's code scanning dashboard.
- name: "Upload to code-scanning"
uses: github/codeql-action/upload-sarif@51f77329afa6477de8c49fc9c7046c15b9a4e79d # v3.29.5
uses: github/codeql-action/upload-sarif@2d92b76c45b91eb80fc44c74ce3fce0ee94e8f9d # v3.29.5
with:
sarif_file: results.sarif
+2 -2
View File
@@ -34,12 +34,12 @@ jobs:
with:
egress-policy: audit
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
fetch-depth: 0
- name: Setup Gradle
uses: gradle/actions/setup-gradle@ac638b010cf58a27ee6c972d7336334ccaf61c96 # v4.4.1
uses: gradle/actions/setup-gradle@017a9effdb900e5b5b2fddfb590a105619dca3c3 # v4.4.2
- name: Build and analyze with Gradle
env:
+3 -3
View File
@@ -30,15 +30,15 @@ jobs:
with:
egress-policy: audit
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Set up JDK 17
uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4.7.1
uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v5.0.0
with:
java-version: "17"
distribution: "temurin"
- uses: gradle/actions/setup-gradle@ac638b010cf58a27ee6c972d7336334ccaf61c96 # v4.4.1
- uses: gradle/actions/setup-gradle@017a9effdb900e5b5b2fddfb590a105619dca3c3 # v4.4.2
- name: Generate Swagger documentation
run: ./gradlew :stirling-pdf:generateOpenApiDocs
+1 -1
View File
@@ -36,7 +36,7 @@ jobs:
with:
egress-policy: audit
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Setup GitHub App Bot
id: setup-bot
+26 -5
View File
@@ -29,16 +29,16 @@ jobs:
egress-policy: audit
- name: Checkout repository
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Set up JDK
uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4.7.1
uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v5.0.0
with:
java-version: '17'
distribution: 'temurin'
- name: Setup Gradle
uses: gradle/actions/setup-gradle@ac638b010cf58a27ee6c972d7336334ccaf61c96 # v4.4.1
uses: gradle/actions/setup-gradle@017a9effdb900e5b5b2fddfb590a105619dca3c3 # v4.4.2
with:
gradle-version: 8.14
@@ -116,8 +116,25 @@ jobs:
docker-compose up -d
EOF
files-changed:
if: always()
name: detect what files changed
runs-on: ubuntu-latest
timeout-minutes: 3
outputs:
frontend: ${{ steps.changes.outputs.frontend }}
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Check for file changes
uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2
id: changes
with:
filters: ".github/config/.files.yaml"
test:
needs: deploy
if: needs.files-changed.outputs.frontend == 'true'
needs: [deploy, files-changed]
runs-on: ubuntu-latest
steps:
@@ -126,18 +143,20 @@ jobs:
with:
egress-policy: audit
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Set up Node
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with:
cache: 'npm'
cache-dependency-path: frontend/package-lock.json
- name: Run TestDriver.ai
uses: testdriverai/action@f0d0f45fdd684db628baa843fe9313f3ca3a8aa8 #1.1.3
with:
key: ${{secrets.TESTDRIVER_API_KEY}}
prerun: |
cd frontend
npm install
npm run build
npm install dashcam-chrome --save
@@ -167,6 +186,7 @@ jobs:
sudo chmod 600 ../private.key
- name: Cleanup deployment
if: always()
run: |
ssh -i ../private.key -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null ${{ secrets.VPS_USERNAME }}@${{ secrets.VPS_HOST }} << EOF
cd /stirling/test-${{ github.sha }}
@@ -174,3 +194,4 @@ jobs:
cd /stirling
rm -rf test-${{ github.sha }}
EOF
continue-on-error: true # Ensure cleanup runs even if previous steps fail
+3
View File
@@ -200,3 +200,6 @@ id_ed25519.pub
# node_modules
node_modules/
# weasyPrint
**/LOCAL_APPDATA_FONTCONFIG_CACHE/**
+1 -1
View File
@@ -5,7 +5,7 @@
The newly introduced feature enhances the application with robust database backup and import capabilities. This feature is designed to ensure data integrity and provide a straightforward way to manage database backups. Here's how it works:
1. Automatic Backup Creation
- The system automatically creates a database backup every day at midnight. This ensures that there is always a recent backup available, minimizing the risk of data loss.
- The system automatically creates a database backup on a configurable schedule (default: daily at midnight via `system.databaseBackup.cron`). This ensures that there is always a recent backup available, minimizing the risk of data loss.
2. Manual Backup Export
- Admin actions that modify the user database trigger a manual export of the database. This keeps the backup up-to-date with the latest changes and provides an extra layer of data security.
3. Importing Database Backups
+2 -2
View File
@@ -34,10 +34,10 @@ ENV SETUPTOOLS_USE_DISTUTILS=local \
TMP=/tmp/stirling-pdf
# Installation der benötigten Python-Pakete
COPY .github/scripts/requirements_dev.txt /tmp/requirements_dev.txt
RUN python3 -m venv --system-site-packages /opt/venv \
&& . /opt/venv/bin/activate \
&& pip install --no-cache-dir --upgrade pip setuptools \
&& pip install --no-cache-dir WeasyPrint pdf2image pillow unoserver opencv-python-headless pre-commit
&& pip install --no-cache-dir --require-hashes -r /tmp/requirements_dev.txt
# Füge den venv-Pfad zur globalen PATH-Variable hinzu, damit die Tools verfügbar sind
ENV PATH="/opt/venv/bin:$PATH"
+7 -7
View File
@@ -120,14 +120,14 @@ Stirling-PDF currently supports 40 languages!
| Azerbaijani (Azərbaycan Dili) (az_AZ) | ![62%](https://geps.dev/progress/62) |
| Basque (Euskara) (eu_ES) | ![36%](https://geps.dev/progress/36) |
| Bulgarian (Български) (bg_BG) | ![68%](https://geps.dev/progress/68) |
| Catalan (Català) (ca_CA) | ![68%](https://geps.dev/progress/68) |
| Catalan (Català) (ca_CA) | ![67%](https://geps.dev/progress/67) |
| Croatian (Hrvatski) (hr_HR) | ![60%](https://geps.dev/progress/60) |
| Czech (Česky) (cs_CZ) | ![70%](https://geps.dev/progress/70) |
| Danish (Dansk) (da_DK) | ![61%](https://geps.dev/progress/61) |
| Dutch (Nederlands) (nl_NL) | ![60%](https://geps.dev/progress/60) |
| 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) | ![89%](https://geps.dev/progress/89) |
| French (Français) (fr_FR) | ![88%](https://geps.dev/progress/88) |
| German (Deutsch) (de_DE) | ![98%](https://geps.dev/progress/98) |
| Greek (Ελληνικά) (el_GR) | ![67%](https://geps.dev/progress/67) |
| Hindi (हिंदी) (hi_IN) | ![67%](https://geps.dev/progress/67) |
@@ -135,12 +135,12 @@ Stirling-PDF currently supports 40 languages!
| Indonesian (Bahasa Indonesia) (id_ID) | ![62%](https://geps.dev/progress/62) |
| Irish (Gaeilge) (ga_IE) | ![68%](https://geps.dev/progress/68) |
| Italian (Italiano) (it_IT) | ![98%](https://geps.dev/progress/98) |
| Japanese (日本語) (ja_JP) | ![93%](https://geps.dev/progress/93) |
| Japanese (日本語) (ja_JP) | ![92%](https://geps.dev/progress/92) |
| Korean (한국어) (ko_KR) | ![67%](https://geps.dev/progress/67) |
| Norwegian (Norsk) (no_NB) | ![66%](https://geps.dev/progress/66) |
| Persian (فارسی) (fa_IR) | ![64%](https://geps.dev/progress/64) |
| Polish (Polski) (pl_PL) | ![72%](https://geps.dev/progress/72) |
| Portuguese (Português) (pt_PT) | ![69%](https://geps.dev/progress/69) |
| Portuguese (Português) (pt_PT) | ![68%](https://geps.dev/progress/68) |
| Portuguese Brazilian (Português) (pt_BR) | ![76%](https://geps.dev/progress/76) |
| Romanian (Română) (ro_RO) | ![57%](https://geps.dev/progress/57) |
| Russian (Русский) (ru_RU) | ![88%](https://geps.dev/progress/88) |
@@ -152,9 +152,9 @@ Stirling-PDF currently supports 40 languages!
| Swedish (Svenska) (sv_SE) | ![65%](https://geps.dev/progress/65) |
| Thai (ไทย) (th_TH) | ![59%](https://geps.dev/progress/59) |
| Tibetan (བོད་ཡིག་) (bo_CN) | ![65%](https://geps.dev/progress/65) |
| Traditional Chinese (繁體中文) (zh_TW) | ![97%](https://geps.dev/progress/97) |
| Turkish (Türkçe) (tr_TR) | ![80%](https://geps.dev/progress/80) |
| Ukrainian (Українська) (uk_UA) | ![71%](https://geps.dev/progress/71) |
| Traditional Chinese (繁體中文) (zh_TW) | ![99%](https://geps.dev/progress/99) |
| Turkish (Türkçe) (tr_TR) | ![99%](https://geps.dev/progress/99) |
| Ukrainian (Українська) (uk_UA) | ![70%](https://geps.dev/progress/70) |
| Vietnamese (Tiếng Việt) (vi_VN) | ![57%](https://geps.dev/progress/57) |
| Malayalam (മലയാളം) (ml_IN) | ![73%](https://geps.dev/progress/73) |
+1
View File
File diff suppressed because one or more lines are too long
+2 -2
View File
@@ -39,7 +39,7 @@ dependencies {
api "org.apache.pdfbox:pdfbox:$pdfboxVersion"
api 'jakarta.servlet:jakarta.servlet-api:6.1.0'
api 'org.snakeyaml:snakeyaml-engine:2.10'
api "org.springdoc:springdoc-openapi-starter-webmvc-ui:2.8.9"
api 'jakarta.mail:jakarta.mail-api:2.1.3'
api "org.springdoc:springdoc-openapi-starter-webmvc-ui:2.8.12"
api 'jakarta.mail:jakarta.mail-api:2.1.4'
runtimeOnly 'org.eclipse.angus:angus-mail:2.0.4'
}
@@ -19,7 +19,6 @@ import lombok.extern.slf4j.Slf4j;
import stirling.software.common.annotations.AutoJobPostMapping;
import stirling.software.common.model.api.PDFFile;
import stirling.software.common.service.FileOrUploadService;
import stirling.software.common.service.FileStorage;
import stirling.software.common.service.JobExecutorService;
@@ -34,7 +33,6 @@ public class AutoJobAspect {
private final JobExecutorService jobExecutorService;
private final HttpServletRequest request;
private final FileOrUploadService fileOrUploadService;
private final FileStorage fileStorage;
@Around("@annotation(autoJobPostMapping)")
@@ -53,7 +51,8 @@ public class AutoJobAspect {
boolean trackProgress = autoJobPostMapping.trackProgress();
log.debug(
"AutoJobPostMapping execution with async={}, timeout={}, retryCount={}, trackProgress={}",
"AutoJobPostMapping execution with async={}, timeout={}, retryCount={},"
+ " trackProgress={}",
async,
timeout > 0 ? timeout : "default",
retryCount,
@@ -148,7 +147,8 @@ public class AutoJobAspect {
} catch (Throwable ex) {
lastException = ex;
log.error(
"AutoJobAspect caught exception during job execution (attempt {}/{}): {}",
"AutoJobAspect caught exception during job execution (attempt"
+ " {}/{}): {}",
currentAttempt,
maxRetries,
ex.getMessage(),
@@ -8,6 +8,7 @@ import java.util.List;
import java.util.Locale;
import java.util.Properties;
import java.util.function.Predicate;
import java.util.stream.Stream;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
@@ -51,6 +52,14 @@ public class AppConfig {
@Value("${server.port:8080}")
private String serverPort;
@Value("${v2}")
public boolean v2Enabled;
@Bean
public boolean v2Enabled() {
return v2Enabled;
}
@Bean
@ConditionalOnProperty(name = "system.customHTMLFiles", havingValue = "true")
public SpringTemplateEngine templateEngine(ResourceLoader resourceLoader) {
@@ -120,7 +129,7 @@ public class AppConfig {
public boolean rateLimit() {
String rateLimit = System.getProperty("rateLimit");
if (rateLimit == null) rateLimit = System.getenv("rateLimit");
return (rateLimit != null) ? Boolean.valueOf(rateLimit) : false;
return Boolean.parseBoolean(rateLimit);
}
@Bean(name = "RunningInDocker")
@@ -140,8 +149,8 @@ public class AppConfig {
if (!Files.exists(mountInfo)) {
return true;
}
try {
return Files.lines(mountInfo).anyMatch(line -> line.contains(" /configs "));
try (Stream<String> lines = Files.lines(mountInfo)) {
return lines.anyMatch(line -> line.contains(" /configs "));
} catch (IOException e) {
return false;
}
@@ -23,10 +23,30 @@ import stirling.software.common.util.YamlHelper;
@Slf4j
public class ConfigInitializer {
private static final int MIN_SETTINGS_FILE_LINES = 31;
public void ensureConfigExists() throws IOException, URISyntaxException {
// 1) If settings file doesn't exist, create from template
Path destPath = Paths.get(InstallationPathConfig.getSettingsPath());
if (Files.notExists(destPath)) {
boolean settingsFileExists = Files.exists(destPath);
long lineCount = settingsFileExists ? Files.readAllLines(destPath).size() : 0;
log.info("Current settings file line count: {}", lineCount);
if (!settingsFileExists || lineCount < MIN_SETTINGS_FILE_LINES) {
if (settingsFileExists) {
// move settings.yml to settings.yml.{timestamp}.bak
Path backupPath =
Paths.get(
InstallationPathConfig.getSettingsPath()
+ "."
+ System.currentTimeMillis()
+ ".bak");
Files.move(destPath, backupPath, StandardCopyOption.REPLACE_EXISTING);
log.info("Moved existing settings file to backup: {}", backupPath);
}
Files.createDirectories(destPath.getParent());
try (InputStream in =
getClass().getClassLoader().getResourceAsStream("settings.yml.template")) {
@@ -14,12 +14,17 @@ public class InstallationPathConfig {
private static final String CONFIG_PATH;
private static final String CUSTOM_FILES_PATH;
private static final String CLIENT_WEBUI_PATH;
private static final String SCRIPTS_PATH;
private static final String PIPELINE_PATH;
// Config paths
private static final String SETTINGS_PATH;
private static final String CUSTOM_SETTINGS_PATH;
private static final String SCRIPTS_PATH;
private static final String BACKUP_PATH;
// Backup paths
private static final String BACKUP_DB_PATH;
private static final String BACKUP_PRIVATE_KEY_PATH;
// Custom file paths
private static final String STATIC_PATH;
@@ -40,6 +45,11 @@ public class InstallationPathConfig {
SETTINGS_PATH = CONFIG_PATH + "settings.yml";
CUSTOM_SETTINGS_PATH = CONFIG_PATH + "custom_settings.yml";
SCRIPTS_PATH = CONFIG_PATH + "scripts" + File.separator;
BACKUP_PATH = CONFIG_PATH + "backup" + File.separator;
// Initialize backup paths
BACKUP_DB_PATH = BACKUP_PATH + "db" + File.separator;
BACKUP_PRIVATE_KEY_PATH = BACKUP_PATH + "keys" + File.separator;
// Initialize custom file paths
STATIC_PATH = CUSTOM_FILES_PATH + "static" + File.separator;
@@ -120,4 +130,12 @@ public class InstallationPathConfig {
public static String getSignaturesPath() {
return SIGNATURES_PATH;
}
public static String getPrivateKeyPath() {
return BACKUP_PRIVATE_KEY_PATH;
}
public static String getBackupPath() {
return BACKUP_DB_PATH;
}
}
@@ -41,6 +41,7 @@ import stirling.software.common.model.oauth2.GitHubProvider;
import stirling.software.common.model.oauth2.GoogleProvider;
import stirling.software.common.model.oauth2.KeycloakProvider;
import stirling.software.common.model.oauth2.Provider;
import stirling.software.common.service.SsrfProtectionService.SsrfProtectionLevel;
import stirling.software.common.util.ValidationUtils;
@Data
@@ -119,6 +120,7 @@ public class ApplicationProperties {
private long loginResetTimeMinutes;
private String loginMethod = "all";
private String customGlobalAPIKey;
private Jwt jwt = new Jwt();
public Boolean isAltLogin() {
return saml2.getEnabled() || oauth2.getEnabled();
@@ -298,6 +300,15 @@ public class ApplicationProperties {
}
}
}
@Data
public static class Jwt {
private boolean enableKeystore = true;
private boolean enableKeyRotation = false;
private boolean enableKeyCleanup = true;
private int keyRetentionDays = 7;
private boolean secureCookie;
}
}
@Data
@@ -318,12 +329,18 @@ public class ApplicationProperties {
private CustomPaths customPaths = new CustomPaths();
private String fileUploadLimit;
private TempFileManagement tempFileManagement = new TempFileManagement();
private DatabaseBackup databaseBackup = new DatabaseBackup();
public boolean isAnalyticsEnabled() {
return this.getEnableAnalytics() != null && this.getEnableAnalytics();
}
}
@Data
public static class DatabaseBackup {
private String cron = "0 0 0 * * ?"; // daily at midnight
}
@Data
public static class CustomPaths {
private Pipeline pipeline = new Pipeline();
@@ -380,7 +397,7 @@ public class ApplicationProperties {
@Data
public static class UrlSecurity {
private boolean enabled = true;
private String level = "MEDIUM"; // MAX, MEDIUM, OFF
private SsrfProtectionLevel level = SsrfProtectionLevel.MEDIUM; // MAX, MEDIUM, OFF
private List<String> allowedDomains = new ArrayList<>();
private List<String> blockedDomains = new ArrayList<>();
private List<String> internalTlds =
@@ -8,9 +8,11 @@ import java.util.Locale;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@AllArgsConstructor
@Data
@NoArgsConstructor
@AllArgsConstructor
public class FileInfo {
private static final DateTimeFormatter DATE_FORMATTER =
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
@@ -7,14 +7,14 @@ import java.io.Reader;
import org.thymeleaf.templateresource.ITemplateResource;
public class InputStreamTemplateResource implements ITemplateResource {
private InputStream inputStream;
private String characterEncoding;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
public InputStreamTemplateResource(InputStream inputStream, String characterEncoding) {
this.inputStream = inputStream;
this.characterEncoding = characterEncoding;
}
@RequiredArgsConstructor
@Getter
public class InputStreamTemplateResource implements ITemplateResource {
private final InputStream inputStream;
private final String characterEncoding;
@Override
public Reader reader() throws IOException {
@@ -2,11 +2,15 @@ package stirling.software.common.model;
import java.util.Calendar;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class PdfMetadata {
private String author;
private String producer;
@@ -252,8 +252,10 @@ public class JobExecutorService {
}
}
if (response.getHeaders().getContentType() != null) {
contentType = response.getHeaders().getContentType().toString();
MediaType mediaType = response.getHeaders().getContentType();
if (mediaType != null) {
contentType = mediaType.toString();
}
// Store byte array directly to disk
@@ -1,5 +1,7 @@
package stirling.software.common.service;
import java.net.Inet4Address;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.URI;
import java.net.UnknownHostException;
@@ -51,21 +53,17 @@ public class SsrfProtectionService {
SsrfProtectionLevel level = parseProtectionLevel(config.getLevel());
switch (level) {
case OFF:
return true;
case MAX:
return isMaxSecurityAllowed(trimmedUrl, config);
case MEDIUM:
return isMediumSecurityAllowed(trimmedUrl, config);
default:
return false;
}
return switch (level) {
case OFF -> true;
case MAX -> isMaxSecurityAllowed(trimmedUrl, config);
case MEDIUM -> isMediumSecurityAllowed(trimmedUrl, config);
default -> false;
};
}
private SsrfProtectionLevel parseProtectionLevel(String level) {
private SsrfProtectionLevel parseProtectionLevel(SsrfProtectionLevel level) {
try {
return SsrfProtectionLevel.valueOf(level.toUpperCase());
return SsrfProtectionLevel.valueOf(level.name());
} catch (IllegalArgumentException e) {
log.warn("Invalid SSRF protection level '{}', defaulting to MEDIUM", level);
return SsrfProtectionLevel.MEDIUM;
@@ -172,15 +170,62 @@ public class SsrfProtectionService {
}
private boolean isPrivateAddress(InetAddress address) {
return address.isSiteLocalAddress()
|| address.isAnyLocalAddress()
|| isPrivateIPv4Range(address.getHostAddress());
if (address.isAnyLocalAddress() || address.isLoopbackAddress()) {
return true;
}
if (address instanceof Inet4Address) {
return isPrivateIPv4Range(address.getHostAddress());
}
if (address instanceof Inet6Address addr6) {
if (addr6.isLinkLocalAddress() || addr6.isSiteLocalAddress()) {
return true;
}
byte[] bytes = addr6.getAddress();
if (isIpv4MappedAddress(bytes)) {
String ipv4 =
(bytes[12] & 0xff)
+ "."
+ (bytes[13] & 0xff)
+ "."
+ (bytes[14] & 0xff)
+ "."
+ (bytes[15] & 0xff);
return isPrivateIPv4Range(ipv4);
}
int firstByte = bytes[0] & 0xff;
// Check for IPv6 unique local addresses (fc00::/7)
if ((firstByte & 0xfe) == 0xfc) {
return true;
}
}
return false;
}
private boolean isIpv4MappedAddress(byte[] addr) {
if (addr.length != 16) {
return false;
}
for (int i = 0; i < 10; i++) {
if (addr[i] != 0) {
return false;
}
}
// For IPv4-mapped IPv6 addresses, bytes 10 and 11 must be 0xff (i.e., address is
// ::ffff:w.x.y.z)
return addr[10] == (byte) 0xff && addr[11] == (byte) 0xff;
}
private boolean isPrivateIPv4Range(String ip) {
// Includes RFC1918, loopback, link-local, and unspecified addresses
return ip.startsWith("10.")
|| ip.startsWith("192.168.")
|| (ip.startsWith("172.") && isInRange172(ip))
|| ip.startsWith("169.254.")
|| ip.startsWith("127.")
|| "0.0.0.0".equals(ip);
}
@@ -192,17 +237,31 @@ public class SsrfProtectionService {
int secondOctet = Integer.parseInt(parts[1]);
return secondOctet >= 16 && secondOctet <= 31;
} catch (NumberFormatException e) {
return false;
}
}
return false;
}
private boolean isCloudMetadataAddress(String ip) {
String normalizedIp = normalizeIpv4MappedAddress(ip);
// Cloud metadata endpoints for AWS, GCP, Azure, Oracle Cloud, and IBM Cloud
return ip.startsWith("169.254.169.254") // AWS/GCP/Azure
|| ip.startsWith("fd00:ec2::254") // AWS IPv6
|| ip.startsWith("169.254.169.253") // Oracle Cloud
|| ip.startsWith("169.254.169.250"); // IBM Cloud
return normalizedIp.startsWith("169.254.169.254") // AWS/GCP/Azure
|| normalizedIp.startsWith("fd00:ec2::254") // AWS IPv6
|| normalizedIp.startsWith("169.254.169.253") // Oracle Cloud
|| normalizedIp.startsWith("169.254.169.250"); // IBM Cloud
}
private String normalizeIpv4MappedAddress(String ip) {
if (ip == null) {
return "";
}
if (ip.startsWith("::ffff:")) {
return ip.substring(7);
}
int lastColon = ip.lastIndexOf(':');
if (lastColon >= 0 && ip.indexOf('.') > lastColon) {
return ip.substring(lastColon + 1);
}
return ip;
}
}
@@ -0,0 +1,301 @@
package stirling.software.common.util;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.file.Files;
import java.nio.file.Path;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
import java.util.LinkedHashMap;
import java.util.Locale;
import java.util.Map;
import java.util.zip.Adler32;
import java.util.zip.CRC32;
import java.util.zip.Checksum;
import lombok.experimental.UtilityClass;
@UtilityClass
public class ChecksumUtils {
/** Shared buffer size for streaming I/O. */
private static final int BUFFER_SIZE = 8192;
/** Mask to extract the lower 32 bits of a long value (unsigned int). */
private static final long UNSIGNED_32_BIT_MASK = 0xFFFFFFFFL;
/**
* Computes a checksum for the given file using the chosen algorithm and returns a lowercase hex
* string.
*
* <p>For digest algorithms (e.g., SHA-256, SHA-1, MD5), this returns the digest as hex. For
* 32-bit {@link Checksum} algorithms ("CRC32", "ADLER32"), this returns an 8-character
* lowercase hex string of the unsigned 32-bit value.
*
* @param path file to read
* @param algorithm algorithm name (case-insensitive). Special values: "CRC32", "ADLER32".
* @return hex string of the checksum
* @throws IOException if the file cannot be read
*/
public static String checksum(Path path, String algorithm) throws IOException {
try (InputStream is = Files.newInputStream(path)) {
return checksum(is, algorithm);
}
}
/**
* Computes a checksum for the given stream using the chosen algorithm and returns a lowercase
* hex string.
*
* <p><strong>Note:</strong> This method does <em>not</em> close the provided stream.
*
* @param is input stream (not closed by this method)
* @param algorithm algorithm name (case-insensitive). Special values: "CRC32", "ADLER32".
* @return hex string of the checksum
* @throws IOException if reading from the stream fails
*/
public static String checksum(InputStream is, String algorithm) throws IOException {
switch (algorithm.toUpperCase(Locale.ROOT)) {
case "CRC32":
return checksumChecksum(is, new CRC32());
case "ADLER32":
return checksumChecksum(is, new Adler32());
default:
return toHex(checksumBytes(is, algorithm));
}
}
/**
* Computes a checksum for the given file using the chosen algorithm and returns a Base64
* encoded string.
*
* <p>For digest algorithms this is the Base64 of the raw digest bytes. For 32-bit checksum
* algorithms ("CRC32", "ADLER32"), this is the Base64 of the 4-byte big-endian unsigned value.
*
* @param path file to read
* @param algorithm algorithm name (case-insensitive). Special values: "CRC32", "ADLER32".
* @return Base64-encoded checksum bytes
* @throws IOException if the file cannot be read
*/
public static String checksumBase64(Path path, String algorithm) throws IOException {
try (InputStream is = Files.newInputStream(path)) {
return checksumBase64(is, algorithm);
}
}
/**
* Computes a checksum for the given stream using the chosen algorithm and returns a Base64
* encoded string.
*
* <p><strong>Note:</strong> This method does <em>not</em> close the provided stream.
*
* @param is input stream (not closed by this method)
* @param algorithm algorithm name (case-insensitive). Special values: "CRC32", "ADLER32".
* @return Base64-encoded checksum bytes
* @throws IOException if reading from the stream fails
*/
public static String checksumBase64(InputStream is, String algorithm) throws IOException {
switch (algorithm.toUpperCase(Locale.ROOT)) {
case "CRC32":
return Base64.getEncoder().encodeToString(checksumChecksumBytes(is, new CRC32()));
case "ADLER32":
return Base64.getEncoder().encodeToString(checksumChecksumBytes(is, new Adler32()));
default:
return Base64.getEncoder().encodeToString(checksumBytes(is, algorithm));
}
}
/**
* Computes multiple checksums for the given file in a single pass over the data.
*
* <p>Returns a map from algorithm name to lowercase hex string. Order of results follows the
* order of the provided {@code algorithms}.
*
* @param path file to read
* @param algorithms algorithm names (case-insensitive). Special: "CRC32", "ADLER32".
* @return map of algorithm → hex string
* @throws IOException if the file cannot be read
*/
public static Map<String, String> checksums(Path path, String... algorithms)
throws IOException {
try (InputStream is = Files.newInputStream(path)) {
return checksums(is, algorithms);
}
}
/**
* Computes multiple checksums for the given stream in a single pass over the data.
*
* <p><strong>Note:</strong> This method does <em>not</em> close the provided stream.
*
* @param is input stream (not closed by this method)
* @param algorithms algorithm names (case-insensitive). Special: "CRC32", "ADLER32".
* @return map of algorithm → hex string
* @throws IOException if reading from the stream fails
*/
public static Map<String, String> checksums(InputStream is, String... algorithms)
throws IOException {
// Use LinkedHashMap to preserve the order of requested algorithms in the result.
Map<String, MessageDigest> digests = new LinkedHashMap<>();
Map<String, Checksum> checksums = new LinkedHashMap<>();
for (String algorithm : algorithms) {
String key = algorithm; // keep original key for output
switch (algorithm.toUpperCase(Locale.ROOT)) {
case "CRC32":
checksums.put(key, new CRC32());
break;
case "ADLER32":
checksums.put(key, new Adler32());
break;
default:
try {
// For MessageDigest, pass the original name (case-insensitive per JCA)
digests.put(key, MessageDigest.getInstance(algorithm));
} catch (NoSuchAlgorithmException e) {
throw new IllegalStateException("Unsupported algorithm: " + algorithm, e);
}
}
}
byte[] buffer = new byte[BUFFER_SIZE];
int read;
while ((read = is.read(buffer)) != -1) {
for (MessageDigest digest : digests.values()) {
digest.update(buffer, 0, read);
}
for (Checksum cs : checksums.values()) {
cs.update(buffer, 0, read);
}
}
Map<String, String> results = new LinkedHashMap<>();
for (Map.Entry<String, MessageDigest> entry : digests.entrySet()) {
results.put(entry.getKey(), toHex(entry.getValue().digest()));
}
for (Map.Entry<String, Checksum> entry : checksums.entrySet()) {
// Keep value as long and mask to ensure unsigned hex formatting.
long unsigned32 = entry.getValue().getValue() & UNSIGNED_32_BIT_MASK;
results.put(entry.getKey(), String.format("%08x", unsigned32));
}
return results;
}
/**
* Compares the checksum of a file with an expected hex string (case-insensitive).
*
* @param path file to read
* @param algorithm algorithm name (case-insensitive). Special: "CRC32", "ADLER32".
* @param expected expected hex string (case-insensitive)
* @return {@code true} if they match, otherwise {@code false}
* @throws IOException if the file cannot be read
*/
public static boolean matches(Path path, String algorithm, String expected) throws IOException {
try (InputStream is = Files.newInputStream(path)) {
return matches(is, algorithm, expected);
}
}
/**
* Compares the checksum of a stream with an expected hex string (case-insensitive).
*
* <p><strong>Note:</strong> This method does <em>not</em> close the provided stream.
*
* @param is input stream (not closed by this method)
* @param algorithm algorithm name (case-insensitive). Special: "CRC32", "ADLER32".
* @param expected expected hex string (case-insensitive)
* @return {@code true} if they match, otherwise {@code false}
* @throws IOException if reading from the stream fails
*/
public static boolean matches(InputStream is, String algorithm, String expected)
throws IOException {
return checksum(is, algorithm).equalsIgnoreCase(expected);
}
// ---------- Internal helpers ----------
/**
* Computes a MessageDigest over a stream and returns the raw digest bytes.
*
* @param is input stream (not closed)
* @param algorithm JCA MessageDigest algorithm (e.g., "SHA-256")
* @return raw digest bytes
* @throws IOException if reading fails
* @throws IllegalStateException if the algorithm is unsupported
*/
private static byte[] checksumBytes(InputStream is, String algorithm) throws IOException {
try {
MessageDigest digest = MessageDigest.getInstance(algorithm);
byte[] buffer = new byte[BUFFER_SIZE];
int read;
while ((read = is.read(buffer)) != -1) {
digest.update(buffer, 0, read);
}
return digest.digest();
} catch (NoSuchAlgorithmException e) {
// Keep the message explicit to aid debugging
throw new IllegalStateException("Unsupported algorithm: " + algorithm, e);
}
}
/**
* Computes a 32-bit {@link Checksum} over a stream and returns the lowercase 8-char hex of the
* unsigned 32-bit value.
*
* @param is input stream (not closed)
* @param checksum checksum implementation (CRC32, Adler32, etc.)
* @return 8-character lowercase hex (big-endian representation)
* @throws IOException if reading fails
*/
private static String checksumChecksum(InputStream is, Checksum checksum) throws IOException {
byte[] buffer = new byte[BUFFER_SIZE];
int read;
while ((read = is.read(buffer)) != -1) {
checksum.update(buffer, 0, read);
}
// Keep as long and mask to ensure correct unsigned representation.
long unsigned32 = checksum.getValue() & UNSIGNED_32_BIT_MASK;
return String.format("%08x", unsigned32);
}
/**
* Computes a 32-bit {@link Checksum} over a stream and returns the raw 4-byte big-endian
* representation of the unsigned 32-bit value.
*
* <p>Cast to int already truncates to the lower 32 bits; the sign is irrelevant because we
* serialize the bit pattern directly into 4 bytes.
*
* @param is input stream (not closed)
* @param checksum checksum implementation (CRC32, Adler32, etc.)
* @return 4 bytes (big-endian)
* @throws IOException if reading fails
*/
private static byte[] checksumChecksumBytes(InputStream is, Checksum checksum)
throws IOException {
byte[] buffer = new byte[BUFFER_SIZE];
int read;
while ((read = is.read(buffer)) != -1) {
checksum.update(buffer, 0, read);
}
// Cast keeps only the lower 32 bits; mask is unnecessary here.
int v = (int) checksum.getValue();
return ByteBuffer.allocate(4).order(ByteOrder.BIG_ENDIAN).putInt(v).array();
}
/**
* Converts bytes to a lowercase hex string.
*
* @param hash the byte array to convert
* @return the lowercase hex string
*/
private static String toHex(byte[] hash) {
StringBuilder sb = new StringBuilder(hash.length * 2);
for (byte b : hash) {
sb.append(String.format("%02x", b));
}
return sb.toString();
}
}
@@ -4,7 +4,6 @@ import org.owasp.html.AttributePolicy;
import org.owasp.html.HtmlPolicyBuilder;
import org.owasp.html.PolicyFactory;
import org.owasp.html.Sanitizers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import stirling.software.common.model.ApplicationProperties;
@@ -16,7 +15,6 @@ public class CustomHtmlSanitizer {
private final SsrfProtectionService ssrfProtectionService;
private final ApplicationProperties applicationProperties;
@Autowired
public CustomHtmlSanitizer(
SsrfProtectionService ssrfProtectionService,
ApplicationProperties applicationProperties) {
@@ -142,7 +142,8 @@ public class PdfUtils {
ImageType colorType,
boolean singleImage,
int DPI,
String filename)
String filename,
boolean includeAnnotations)
throws IOException, Exception {
// Validate and limit DPI to prevent excessive memory usage
@@ -163,6 +164,9 @@ public class PdfUtils {
try (PDDocument document = pdfDocumentFactory.load(inputStream)) {
PDFRenderer pdfRenderer = new PDFRenderer(document);
pdfRenderer.setSubsamplingAllowed(true);
if (!includeAnnotations) {
pdfRenderer.setAnnotationsFilter(annotation -> false);
}
int pageCount = document.getNumberOfPages();
// Create a ByteArrayOutputStream to save the image(s) to
@@ -15,6 +15,8 @@ import java.util.concurrent.TimeUnit;
import io.github.pixee.security.BoundedLineReader;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import stirling.software.common.model.ApplicationProperties;
@@ -303,6 +305,8 @@ public class ProcessExecutor {
OCR_MY_PDF
}
@Setter
@Getter
public class ProcessExecutorResult {
int rc;
String messages;
@@ -312,20 +316,5 @@ public class ProcessExecutor {
this.messages = messages;
}
public int getRc() {
return rc;
}
public void setRc(int rc) {
this.rc = rc;
}
public String getMessages() {
return messages;
}
public void setMessages(String messages) {
this.messages = messages;
}
}
}
@@ -14,8 +14,10 @@ public class RequestUriUtils {
|| requestURI.startsWith(contextPath + "/images/")
|| requestURI.startsWith(contextPath + "/public/")
|| requestURI.startsWith(contextPath + "/pdfjs/")
|| requestURI.startsWith(contextPath + "/pdfjs-legacy/")
|| requestURI.startsWith(contextPath + "/login")
|| requestURI.startsWith(contextPath + "/error")
|| requestURI.startsWith(contextPath + "/favicon")
|| requestURI.endsWith(".svg")
|| requestURI.endsWith(".png")
|| requestURI.endsWith(".ico")
@@ -4,6 +4,7 @@ import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
/**
@@ -14,6 +15,7 @@ import lombok.extern.slf4j.Slf4j;
public class TempFile implements AutoCloseable {
private final TempFileManager manager;
@Getter
private final File file;
public TempFile(TempFileManager manager, String suffix) throws IOException {
@@ -21,10 +23,6 @@ public class TempFile implements AutoCloseable {
this.file = manager.createTempFile(suffix);
}
public File getFile() {
return file;
}
public Path getPath() {
return file.toPath();
}
@@ -11,6 +11,7 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.stream.Collectors;
import lombok.Getter;
import org.springframework.stereotype.Component;
import lombok.extern.slf4j.Slf4j;
@@ -24,8 +25,22 @@ import lombok.extern.slf4j.Slf4j;
public class TempFileRegistry {
private final ConcurrentMap<Path, Instant> registeredFiles = new ConcurrentHashMap<>();
/**
* -- GETTER --
* Get all registered third-party temporary files.
*
* @return Set of third-party file paths
*/
@Getter
private final Set<Path> thirdPartyTempFiles =
Collections.newSetFromMap(new ConcurrentHashMap<>());
/**
* -- GETTER --
* Get all registered temporary directories.
*
* @return Set of temporary directory paths
*/
@Getter
private final Set<Path> tempDirectories = Collections.newSetFromMap(new ConcurrentHashMap<>());
/**
@@ -133,24 +148,6 @@ public class TempFileRegistry {
.collect(Collectors.toSet());
}
/**
* Get all registered third-party temporary files.
*
* @return Set of third-party file paths
*/
public Set<Path> getThirdPartyTempFiles() {
return thirdPartyTempFiles;
}
/**
* Get all registered temporary directories.
*
* @return Set of temporary directory paths
*/
public Set<Path> getTempDirectories() {
return tempDirectories;
}
/**
* Check if a file is registered in the registry.
*
@@ -29,7 +29,6 @@ import jakarta.servlet.http.HttpServletRequest;
import stirling.software.common.aop.AutoJobAspect;
import stirling.software.common.model.api.PDFFile;
import stirling.software.common.service.FileOrUploadService;
import stirling.software.common.service.FileStorage;
import stirling.software.common.service.JobExecutorService;
import stirling.software.common.service.JobQueue;
@@ -44,8 +43,6 @@ class AutoJobPostMappingIntegrationTest {
@Mock private HttpServletRequest request;
@Mock private FileOrUploadService fileOrUploadService;
@Mock private FileStorage fileStorage;
@Mock private ResourceMonitor resourceMonitor;
@@ -54,8 +51,7 @@ class AutoJobPostMappingIntegrationTest {
@BeforeEach
void setUp() {
autoJobAspect =
new AutoJobAspect(jobExecutorService, request, fileOrUploadService, fileStorage);
autoJobAspect = new AutoJobAspect(jobExecutorService, request, fileStorage);
}
@Mock private ProceedingJoinPoint joinPoint;
@@ -179,7 +179,7 @@ class ApplicationPropertiesLogicTest {
assertEquals(30, t.getOcrMyPdfTimeoutMinutes());
}
@Deprecated
@Deprecated(since = "0.45.0")
@Test
void enterprise_metadata_defaults() {
ApplicationProperties.EnterpriseEdition ee = new ApplicationProperties.EnterpriseEdition();
@@ -0,0 +1,111 @@
package stirling.software.common.model;
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.io.File;
import java.time.LocalDateTime;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;
public class FileInfoTest {
@ParameterizedTest(name = "{index}: fileSize={0}")
@CsvSource({
"0, '0 Bytes'",
"1023, '1023 Bytes'",
"1024, '1.00 KB'",
"1048575, '1024.00 KB'", // Do we really want this as result?
"1048576, '1.00 MB'",
"1073741823, '1024.00 MB'", // Do we really want this as result?
"1073741824, '1.00 GB'"
})
void testGetFormattedFileSize(long fileSize, String expectedFormattedSize) {
FileInfo fileInfo =
new FileInfo(
"example.txt",
File.separator
+ "path"
+ File.separator
+ "to"
+ File.separator
+ "example.txt",
LocalDateTime.now(),
fileSize,
LocalDateTime.now().minusDays(1));
assertEquals(expectedFormattedSize, fileInfo.getFormattedFileSize());
}
@Test
void testGetFilePathAsPath() {
FileInfo fileInfo =
new FileInfo(
"test.pdf",
File.separator + "tmp" + File.separator + "test.pdf",
LocalDateTime.now(),
1234,
LocalDateTime.now().minusDays(2));
assertEquals(
File.separator + "tmp" + File.separator + "test.pdf",
fileInfo.getFilePathAsPath().toString());
}
@Test
void testGetFormattedModificationDate() {
LocalDateTime modDate = LocalDateTime.of(2024, 6, 1, 15, 30, 45);
FileInfo fileInfo =
new FileInfo(
"file.txt",
File.separator + "file.txt",
modDate,
100,
LocalDateTime.of(2024, 5, 31, 10, 0, 0));
assertEquals("2024-06-01 15:30:45", fileInfo.getFormattedModificationDate());
}
@Test
void testGetFormattedCreationDate() {
LocalDateTime creationDate = LocalDateTime.of(2023, 12, 25, 8, 15, 0);
FileInfo fileInfo =
new FileInfo(
"holiday.txt",
File.separator + "holiday.txt",
LocalDateTime.of(2024, 1, 1, 0, 0, 0),
500,
creationDate);
assertEquals("2023-12-25 08:15:00", fileInfo.getFormattedCreationDate());
}
@Test
void testGettersAndSetters() {
LocalDateTime now = LocalDateTime.now();
FileInfo fileInfo =
new FileInfo(
"doc.pdf",
File.separator + "docs" + File.separator + "doc.pdf",
now,
2048,
now.minusDays(1));
// Test getters
assertEquals("doc.pdf", fileInfo.getFileName());
assertEquals(File.separator + "docs" + File.separator + "doc.pdf", fileInfo.getFilePath());
assertEquals(now, fileInfo.getModificationDate());
assertEquals(2048, fileInfo.getFileSize());
assertEquals(now.minusDays(1), fileInfo.getCreationDate());
// Test setters
fileInfo.setFileName("new.pdf");
fileInfo.setFilePath(File.separator + "new" + File.separator + "new.pdf");
fileInfo.setModificationDate(now.plusDays(1));
fileInfo.setFileSize(4096);
fileInfo.setCreationDate(now.minusDays(2));
assertEquals("new.pdf", fileInfo.getFileName());
assertEquals(File.separator + "new" + File.separator + "new.pdf", fileInfo.getFilePath());
assertEquals(now.plusDays(1), fileInfo.getModificationDate());
assertEquals(4096, fileInfo.getFileSize());
assertEquals(now.minusDays(2), fileInfo.getCreationDate());
}
}
@@ -0,0 +1,94 @@
package stirling.software.common.model;
import static org.junit.jupiter.api.Assertions.*;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.Reader;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.Arrays;
import org.junit.jupiter.api.Test;
public class InputStreamTemplateResourceTest {
@Test
void gettersReturnProvidedFields() {
byte[] data = {1, 2, 3};
InputStream is = new ByteArrayInputStream(data);
String encoding = "UTF-8";
InputStreamTemplateResource resource = new InputStreamTemplateResource(is, encoding);
assertSame(is, resource.getInputStream());
assertEquals(encoding, resource.getCharacterEncoding());
}
@Test
void fieldsAreFinal() throws NoSuchFieldException {
Field inputStreamField = InputStreamTemplateResource.class.getDeclaredField("inputStream");
Field characterEncodingField =
InputStreamTemplateResource.class.getDeclaredField("characterEncoding");
assertTrue(Modifier.isFinal(inputStreamField.getModifiers()));
assertTrue(Modifier.isFinal(characterEncodingField.getModifiers()));
}
@Test
void noSetterMethodsPresent() {
long setterCount =
Arrays.stream(InputStreamTemplateResource.class.getDeclaredMethods())
.filter(method -> method.getName().startsWith("set"))
.count();
assertEquals(0, setterCount, "InputStreamTemplateResource should not have setter methods");
}
@Test
void readerReturnsCorrectContent() throws Exception {
String content = "Hello, world!";
InputStream is = new ByteArrayInputStream(content.getBytes("UTF-8"));
InputStreamTemplateResource resource = new InputStreamTemplateResource(is, "UTF-8");
try (Reader reader = resource.reader()) {
char[] buffer = new char[content.length()];
int read = reader.read(buffer);
assertEquals(content.length(), read);
assertEquals(content, new String(buffer));
}
}
@Test
void relativeThrowsUnsupportedOperationException() {
InputStream is = new ByteArrayInputStream(new byte[0]);
InputStreamTemplateResource resource = new InputStreamTemplateResource(is, "UTF-8");
assertThrows(UnsupportedOperationException.class, () -> resource.relative("other"));
}
@Test
void getDescriptionReturnsExpectedString() {
InputStream is = new ByteArrayInputStream(new byte[0]);
InputStreamTemplateResource resource = new InputStreamTemplateResource(is, "UTF-8");
assertEquals("InputStream resource [Stream]", resource.getDescription());
}
@Test
void getBaseNameReturnsExpectedString() {
InputStream is = new ByteArrayInputStream(new byte[0]);
InputStreamTemplateResource resource = new InputStreamTemplateResource(is, "UTF-8");
assertEquals("streamResource", resource.getBaseName());
}
@Test
void existsReturnsTrueWhenInputStreamNotNull() {
InputStream is = new ByteArrayInputStream(new byte[0]);
InputStreamTemplateResource resource = new InputStreamTemplateResource(is, "UTF-8");
assertTrue(resource.exists());
}
@Test
void existsReturnsFalseWhenInputStreamIsNull() {
InputStreamTemplateResource resource = new InputStreamTemplateResource(null, "UTF-8");
assertFalse(resource.exists());
}
}
@@ -0,0 +1,66 @@
package stirling.software.common.util;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import org.junit.jupiter.api.Test;
public class ChecksumUtilsTest {
@Test
void computeChecksums_basic() throws Exception {
byte[] data = "hello".getBytes(StandardCharsets.UTF_8);
// MD5 (hex)
try (InputStream is = new ByteArrayInputStream(data)) {
assertEquals("5d41402abc4b2a76b9719d911017c592", ChecksumUtils.checksum(is, "MD5"));
}
// MD5 (Base64)
try (InputStream is = new ByteArrayInputStream(data)) {
assertEquals("XUFAKrxLKna5cZ2REBfFkg==", ChecksumUtils.checksumBase64(is, "MD5"));
}
// MD5 + CRC32 (hex map)
try (InputStream is = new ByteArrayInputStream(data)) {
Map<String, String> map = ChecksumUtils.checksums(is, "MD5", "CRC32");
assertEquals("5d41402abc4b2a76b9719d911017c592", map.get("MD5"));
assertEquals("3610a686", map.get("CRC32"));
}
}
@Test
void crc32_base64_bigEndianBytes_forHello() throws Exception {
// CRC32("hello") = 0x3610A686 → bytes: 36 10 A6 86 → Base64: "NhCmhg=="
byte[] data = "hello".getBytes(StandardCharsets.UTF_8);
try (InputStream is = new ByteArrayInputStream(data)) {
assertEquals("NhCmhg==", ChecksumUtils.checksumBase64(is, "CRC32"));
}
}
@Test
void crc32_unsignedFormatting_highBitSet() throws Exception {
// CRC32 of single zero byte (0x00) is 0xD202EF8D (>= 0x8000_0000)
byte[] data = new byte[] {0x00};
// Hex (unsigned, 8 chars, lowercase)
try (InputStream is = new ByteArrayInputStream(data)) {
assertEquals("d202ef8d", ChecksumUtils.checksum(is, "CRC32"));
}
// Base64 of the 4-byte big-endian representation
try (InputStream is = new ByteArrayInputStream(data)) {
assertEquals("0gLvjQ==", ChecksumUtils.checksumBase64(is, "CRC32"));
}
// matches(..) must be case-insensitive for hex
try (InputStream is = new ByteArrayInputStream("hello".getBytes(StandardCharsets.UTF_8))) {
assertTrue(ChecksumUtils.matches(is, "CRC32", "3610A686")); // uppercase expected
}
}
}
@@ -586,7 +586,10 @@ class EmlToPdfTest {
when(mockPdDocument.getNumberOfPages()).thenReturn(1);
try (MockedStatic<FileToPdf> fileToPdf =
mockStatic(FileToPdf.class, org.mockito.Mockito.withSettings().lenient())) {
mockStatic(
FileToPdf.class,
org.mockito.Mockito.withSettings()
.defaultAnswer(org.mockito.Answers.RETURNS_DEFAULTS))) {
fileToPdf
.when(
() ->
@@ -657,7 +660,10 @@ class EmlToPdfTest {
when(mockPdDocument.getNumberOfPages()).thenReturn(1);
try (MockedStatic<FileToPdf> fileToPdf =
mockStatic(FileToPdf.class, org.mockito.Mockito.withSettings().lenient())) {
mockStatic(
FileToPdf.class,
org.mockito.Mockito.withSettings()
.defaultAnswer(org.mockito.Answers.RETURNS_DEFAULTS))) {
fileToPdf
.when(
() ->
@@ -724,7 +730,10 @@ class EmlToPdfTest {
String errorMessage = "Conversion failed";
try (MockedStatic<FileToPdf> fileToPdf =
mockStatic(FileToPdf.class, org.mockito.Mockito.withSettings().lenient())) {
mockStatic(
FileToPdf.class,
org.mockito.Mockito.withSettings()
.defaultAnswer(org.mockito.Answers.RETURNS_DEFAULTS))) {
fileToPdf
.when(
() ->
@@ -1,35 +0,0 @@
package stirling.software.common.util;
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.time.LocalDateTime;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;
import stirling.software.common.model.FileInfo;
public class FileInfoTest {
@ParameterizedTest(name = "{index}: fileSize={0}")
@CsvSource({
"0, '0 Bytes'",
"1023, '1023 Bytes'",
"1024, '1.00 KB'",
"1048575, '1024.00 KB'", // Do we really want this as result?
"1048576, '1.00 MB'",
"1073741823, '1024.00 MB'", // Do we really want this as result?
"1073741824, '1.00 GB'"
})
void testGetFormattedFileSize(long fileSize, String expectedFormattedSize) {
FileInfo fileInfo =
new FileInfo(
"example.txt",
"/path/to/example.txt",
LocalDateTime.now(),
fileSize,
LocalDateTime.now().minusDays(1));
assertEquals(expectedFormattedSize, fileInfo.getFormattedFileSize());
}
}
+4
View File
@@ -170,6 +170,10 @@ out/
*.jks
*.asc
# test-cert
!**/test/resources/certs/test-cert.*
!**/test/resources/certs/test-key.*
# SSH Keys
*.pub
*.priv
+1 -6
View File
@@ -58,7 +58,7 @@ dependencies {
implementation 'commons-io:commons-io:2.20.0'
implementation "org.bouncycastle:bcprov-jdk18on:$bouncycastleVersion"
implementation "org.bouncycastle:bcpkix-jdk18on:$bouncycastleVersion"
implementation 'io.micrometer:micrometer-core:1.15.2'
implementation 'io.micrometer:micrometer-core:1.15.3'
implementation 'com.google.zxing:core:3.5.3'
implementation "org.commonmark:commonmark:$commonmarkVersion" // https://mvnrepository.com/artifact/org.commonmark/commonmark
implementation "org.commonmark:commonmark-ext-gfm-tables:$commonmarkVersion"
@@ -114,11 +114,6 @@ sourceSets {
}
test {
java {
if (System.getenv('DOCKER_ENABLE_SECURITY') == 'false' || System.getenv('DISABLE_ADDITIONAL_FEATURES') == 'true'
|| (project.hasProperty('DISABLE_ADDITIONAL_FEATURES')
&& System.getProperty('DISABLE_ADDITIONAL_FEATURES') == 'true')) {
exclude 'stirling/software/proprietary/security/**'
}
if (System.getenv('STIRLING_PDF_DESKTOP_UI') == 'false') {
exclude 'stirling/software/SPDF/UI/impl/**'
}
@@ -31,6 +31,8 @@ import java.security.cert.X509Certificate;
import java.util.Arrays;
import java.util.Enumeration;
import lombok.Getter;
import lombok.Setter;
import org.apache.pdfbox.pdmodel.interactive.digitalsignature.SignatureInterface;
import org.bouncycastle.cert.jcajce.JcaCertStore;
import org.bouncycastle.cms.CMSException;
@@ -44,8 +46,21 @@ import org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder;
public abstract class CreateSignatureBase implements SignatureInterface {
private PrivateKey privateKey;
@Getter
private Certificate[] certificateChain;
@Setter
private String tsaUrl;
/**
* Specifies whether the external signing scenario should be used.
* If set to {@code true}, external signing will be performed and
* {@link SignatureInterface} will be used for signing.
* If set to {@code false}, internal signing will be performed.
* <p>Default: {@code false}
*
* @param externalSigning {@code true} if external signing should be performed; {@code false} for internal signing
*/
@Setter
@Getter
private boolean externalSigning;
/**
@@ -97,18 +112,10 @@ public abstract class CreateSignatureBase implements SignatureInterface {
this.privateKey = privateKey;
}
public Certificate[] getCertificateChain() {
return certificateChain;
}
public final void setCertificateChain(final Certificate[] certificateChain) {
this.certificateChain = certificateChain;
}
public void setTsaUrl(String tsaUrl) {
this.tsaUrl = tsaUrl;
}
/**
* SignatureInterface sample implementation.
*
@@ -152,19 +159,4 @@ public abstract class CreateSignatureBase implements SignatureInterface {
}
}
public boolean isExternalSigning() {
return externalSigning;
}
/**
* Set if external signing scenario should be used. If {@code false}, SignatureInterface would
* be used for signing.
*
* <p>Default: {@code false}
*
* @param externalSigning {@code true} if external signing should be performed
*/
public void setExternalSigning(boolean externalSigning) {
this.externalSigning = externalSigning;
}
}
@@ -27,7 +27,6 @@ import stirling.software.SPDF.UI.WebBrowser;
import stirling.software.common.configuration.AppConfig;
import stirling.software.common.configuration.ConfigInitializer;
import stirling.software.common.configuration.InstallationPathConfig;
import stirling.software.common.model.ApplicationProperties;
import stirling.software.common.util.UrlUtils;
@Slf4j
@@ -46,17 +45,14 @@ public class SPDFApplication {
private final AppConfig appConfig;
private final Environment env;
private final ApplicationProperties applicationProperties;
private final WebBrowser webBrowser;
public SPDFApplication(
AppConfig appConfig,
Environment env,
ApplicationProperties applicationProperties,
@Autowired(required = false) WebBrowser webBrowser) {
this.appConfig = appConfig;
this.env = env;
this.applicationProperties = applicationProperties;
this.webBrowser = webBrowser;
}
@@ -20,6 +20,8 @@ public class CleanUrlInterceptor implements HandlerInterceptor {
"endpoints",
"logout",
"error",
"days",
"date",
"errorOAuth",
"file",
"messageType",
@@ -6,6 +6,7 @@ import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import lombok.Getter;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
@@ -19,6 +20,7 @@ public class EndpointConfiguration {
private static final String REMOVE_BLANKS = "remove-blanks";
private final ApplicationProperties applicationProperties;
@Getter
private Map<String, Boolean> endpointStatuses = new ConcurrentHashMap<>();
private Map<String, Set<String>> endpointGroups = new ConcurrentHashMap<>();
private Set<String> disabledGroups = new HashSet<>();
@@ -46,10 +48,6 @@ public class EndpointConfiguration {
endpointStatuses.put(endpoint, false);
}
public Map<String, Boolean> getEndpointStatuses() {
return endpointStatuses;
}
public boolean isEndpointEnabled(String endpoint) {
String original = endpoint;
if (endpoint.startsWith("/")) {
@@ -6,8 +6,6 @@ import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
@@ -18,11 +16,12 @@ import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@Component
@RequiredArgsConstructor
@Slf4j
public class EndpointInspector implements ApplicationListener<ContextRefreshedEvent> {
private static final Logger logger = LoggerFactory.getLogger(EndpointInspector.class);
private final ApplicationContext applicationContext;
private final Set<String> validGetEndpoints = new HashSet<>();
@@ -71,13 +70,13 @@ public class EndpointInspector implements ApplicationListener<ContextRefreshedEv
}
if (validGetEndpoints.isEmpty()) {
logger.warn("No endpoints discovered. Adding common endpoints as fallback.");
log.warn("No endpoints discovered. Adding common endpoints as fallback.");
validGetEndpoints.add("/");
validGetEndpoints.add("/api/**");
validGetEndpoints.add("/**");
}
} catch (Exception e) {
logger.error("Error discovering endpoints", e);
log.error("Error discovering endpoints", e);
}
}
@@ -203,10 +202,10 @@ public class EndpointInspector implements ApplicationListener<ContextRefreshedEv
private void logAllEndpoints() {
Set<String> sortedEndpoints = new TreeSet<>(validGetEndpoints);
logger.info("=== BEGIN: All discovered GET endpoints ===");
log.info("=== BEGIN: All discovered GET endpoints ===");
for (String endpoint : sortedEndpoints) {
logger.info("Endpoint: {}", endpoint);
log.info("Endpoint: {}", endpoint);
}
logger.info("=== END: All discovered GET endpoints ===");
log.info("=== END: All discovered GET endpoints ===");
}
}
@@ -6,6 +6,8 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import lombok.Getter;
import lombok.Setter;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.interactive.documentnavigation.outline.PDDocumentOutline;
@@ -234,33 +236,12 @@ public class EditTableOfContentsController {
}
// Inner class to represent bookmarks in JSON
@Setter
@Getter
public static class BookmarkItem {
private String title;
private int pageNumber;
private List<BookmarkItem> children = new ArrayList<>();
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public int getPageNumber() {
return pageNumber;
}
public void setPageNumber(int pageNumber) {
this.pageNumber = pageNumber;
}
public List<BookmarkItem> getChildren() {
return children;
}
public void setChildren(List<BookmarkItem> children) {
this.children = children;
}
}
}
@@ -66,6 +66,7 @@ public class ConvertImgPDFController {
String colorType = request.getColorType();
int dpi = request.getDpi();
String pageNumbers = request.getPageNumbers();
boolean includeAnnotations = Boolean.TRUE.equals(request.getIncludeAnnotations());
Path tempFile = null;
Path tempOutputDir = null;
Path tempPdfPath = null;
@@ -101,7 +102,8 @@ public class ConvertImgPDFController {
colorTypeResult,
singleImage,
dpi,
filename);
filename,
includeAnnotations);
if (result == null || result.length == 0) {
log.error("resultant bytes for {} is null, error converting ", filename);
}
@@ -5,10 +5,11 @@ import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.springframework.http.ResponseEntity;
@@ -23,7 +24,9 @@ import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import stirling.software.SPDF.config.EndpointConfiguration;
import stirling.software.common.configuration.RuntimePathConfig;
import stirling.software.common.model.api.GeneralFile;
import stirling.software.common.service.CustomPDFDocumentFactory;
@@ -36,59 +39,130 @@ import stirling.software.common.util.WebResponseUtils;
@Tag(name = "Convert", description = "Convert APIs")
@RequestMapping("/api/v1/convert")
@RequiredArgsConstructor
@Slf4j
public class ConvertOfficeController {
private final CustomPDFDocumentFactory pdfDocumentFactory;
private final RuntimePathConfig runtimePathConfig;
private final CustomHtmlSanitizer customHtmlSanitizer;
private final EndpointConfiguration endpointConfiguration;
private boolean isUnoconvertAvailable() {
return endpointConfiguration.isGroupEnabled("Unoconvert")
|| endpointConfiguration.isGroupEnabled("Python");
}
public File convertToPdf(MultipartFile inputFile) throws IOException, InterruptedException {
// Check for valid file extension
// Check for valid file extension and sanitize filename
String originalFilename = Filenames.toSimpleFileName(inputFile.getOriginalFilename());
if (originalFilename == null
|| !isValidFileExtension(FilenameUtils.getExtension(originalFilename))) {
throw new IllegalArgumentException("Invalid file extension");
if (originalFilename == null || originalFilename.isBlank()) {
throw new IllegalArgumentException("Missing original filename");
}
// Save the uploaded file to a temporary location
Path tempInputFile =
Files.createTempFile("input_", "." + FilenameUtils.getExtension(originalFilename));
// Check for valid file extension
String extension = FilenameUtils.getExtension(originalFilename);
if (extension == null || !isValidFileExtension(extension)) {
throw new IllegalArgumentException("Invalid file extension");
}
String extensionLower = extension.toLowerCase();
String baseName = FilenameUtils.getBaseName(originalFilename);
if (baseName == null || baseName.isBlank()) {
baseName = "input";
}
// create temporary working directory
Path workDir = Files.createTempDirectory("office2pdf_");
Path inputPath = workDir.resolve(baseName + "." + extensionLower);
Path outputPath = workDir.resolve(baseName + ".pdf");
// Check if the file is HTML and apply sanitization if needed
String fileExtension = FilenameUtils.getExtension(originalFilename).toLowerCase();
if ("html".equals(fileExtension) || "htm".equals(fileExtension)) {
if ("html".equals(extensionLower) || "htm".equals(extensionLower)) {
// Read and sanitize HTML content
String htmlContent = new String(inputFile.getBytes(), StandardCharsets.UTF_8);
String sanitizedHtml = customHtmlSanitizer.sanitize(htmlContent);
Files.write(tempInputFile, sanitizedHtml.getBytes(StandardCharsets.UTF_8));
Files.writeString(inputPath, sanitizedHtml, StandardCharsets.UTF_8);
} else {
inputFile.transferTo(tempInputFile);
// copy file content
Files.copy(inputFile.getInputStream(), inputPath, StandardCopyOption.REPLACE_EXISTING);
}
// Prepare the output file path
Path tempOutputFile = Files.createTempFile("output_", ".pdf");
try {
// Run the LibreOffice command
List<String> command =
new ArrayList<>(
Arrays.asList(
runtimePathConfig.getUnoConvertPath(),
"--port",
"2003",
"--convert-to",
"pdf",
tempInputFile.toString(),
tempOutputFile.toString()));
ProcessExecutorResult returnCode =
ProcessExecutor.getInstance(ProcessExecutor.Processes.LIBRE_OFFICE)
.runCommandWithOutputHandling(command);
ProcessExecutorResult result;
// Run Unoconvert command
if (isUnoconvertAvailable()) {
// Unoconvert: schreibe direkt in outputPath innerhalb des workDir
List<String> command = new ArrayList<>();
command.add(runtimePathConfig.getUnoConvertPath());
command.add("--port");
command.add("2003");
command.add("--convert-to");
command.add("pdf");
command.add(inputPath.toString());
command.add(outputPath.toString());
// Read the converted PDF file
return tempOutputFile.toFile();
result =
ProcessExecutor.getInstance(ProcessExecutor.Processes.LIBRE_OFFICE)
.runCommandWithOutputHandling(command);
} // Run soffice command
else {
List<String> command = new ArrayList<>();
command.add("soffice");
command.add("--headless");
command.add("--nologo");
command.add("--convert-to");
command.add("pdf:writer_pdf_Export");
command.add("--outdir");
command.add(workDir.toString());
command.add(inputPath.toString());
result =
ProcessExecutor.getInstance(ProcessExecutor.Processes.LIBRE_OFFICE)
.runCommandWithOutputHandling(command);
}
// Check the result
if (result == null) {
throw new IllegalStateException("Converter returned no result");
}
if (result.getRc() != 0) {
throw new IllegalStateException("Conversion failed (exit " + result.getRc() + ")");
}
if (!Files.exists(outputPath)) {
// Some LibreOffice versions may deviate with exotic names as a fallback, we try
// to find any .pdf in the workDir
try (var stream = Files.list(workDir)) {
Path fallback =
stream.filter(
p ->
p.getFileName()
.toString()
.toLowerCase()
.endsWith(".pdf"))
.findFirst()
.orElse(null);
if (fallback == null) {
throw new IllegalStateException("No PDF produced.");
}
// Move the found PDF to the expected outputPath
Files.move(fallback, outputPath, StandardCopyOption.REPLACE_EXISTING);
}
}
// Check if the output file is empty
if (Files.size(outputPath) == 0L) {
throw new IllegalStateException("Produced PDF is empty");
}
return outputPath.toFile();
} finally {
// Clean up the temporary files
if (tempInputFile != null) Files.deleteIfExists(tempInputFile);
try {
Files.deleteIfExists(inputPath);
} catch (IOException e) {
log.warn("Failed to delete temp input file: {}", inputPath, e);
}
}
}
@@ -119,7 +193,9 @@ public class ConvertOfficeController {
.replaceFirst("[.][^.]+$", "")
+ "_convertedToPDF.pdf");
} finally {
if (file != null) file.delete();
if (file != null && file.getParent() != null) {
FileUtils.deleteDirectory(file.getParentFile());
}
}
}
}
@@ -1,17 +1,21 @@
package stirling.software.SPDF.controller.api.converters;
import java.io.IOException;
import java.net.URI;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;
import org.springframework.web.util.UriComponentsBuilder;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
@@ -23,7 +27,6 @@ import stirling.software.SPDF.model.api.converters.UrlToPdfRequest;
import stirling.software.common.configuration.RuntimePathConfig;
import stirling.software.common.model.ApplicationProperties;
import stirling.software.common.service.CustomPDFDocumentFactory;
import stirling.software.common.util.ExceptionUtils;
import stirling.software.common.util.GeneralUtils;
import stirling.software.common.util.ProcessExecutor;
import stirling.software.common.util.ProcessExecutor.ProcessExecutorResult;
@@ -46,24 +49,43 @@ public class ConvertWebsiteToPDF {
description =
"This endpoint fetches content from a URL and converts it to a PDF format."
+ " Input:N/A Output:PDF Type:SISO")
public ResponseEntity<byte[]> urlToPdf(@ModelAttribute UrlToPdfRequest request)
public ResponseEntity<?> urlToPdf(@ModelAttribute UrlToPdfRequest request)
throws IOException, InterruptedException {
String URL = request.getUrlInput();
UriComponentsBuilder uriComponentsBuilder =
ServletUriComponentsBuilder.fromCurrentContextPath().path("/url-to-pdf");
URI location = null;
HttpStatus status = HttpStatus.SEE_OTHER;
if (!applicationProperties.getSystem().getEnableUrlToPDF()) {
throw ExceptionUtils.createIllegalArgumentException(
"error.endpointDisabled", "This endpoint has been disabled by the admin");
}
location =
uriComponentsBuilder
.queryParam("error", "error.endpointDisabled")
.build()
.toUri();
} else
// Validate the URL format
if (!URL.matches("^https?://.*") || !GeneralUtils.isValidURL(URL)) {
throw ExceptionUtils.createInvalidArgumentException(
"URL", "provided format is invalid");
}
location =
uriComponentsBuilder
.queryParam("error", "error.invalidUrlFormat")
.build()
.toUri();
} else
// validate the URL is reachable
if (!GeneralUtils.isURLReachable(URL)) {
throw ExceptionUtils.createIllegalArgumentException(
"error.urlNotReachable", "URL is not reachable, please provide a valid URL");
location =
uriComponentsBuilder
.queryParam("error", "error.urlNotReachable")
.build()
.toUri();
}
if (location != null) {
log.info("Redirecting to: {}", location.toString());
return ResponseEntity.status(status).location(location).build();
}
Path tempOutputFile = null;
@@ -1,8 +1,10 @@
package stirling.software.SPDF.controller.api.misc;
import java.awt.Color;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.List;
import java.util.Locale;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
@@ -54,24 +56,27 @@ public class PageNumbersController {
String customText = request.getCustomText();
float fontSize = request.getFontSize();
String fontType = request.getFontType();
String fontColor = request.getFontColor();
Color color = Color.BLACK;
if (fontColor != null && !fontColor.trim().isEmpty()) {
try {
color = Color.decode(fontColor);
} catch (NumberFormatException e) {
color = Color.BLACK;
}
}
PDDocument document = pdfDocumentFactory.load(file);
float marginFactor;
switch (customMargin.toLowerCase()) {
case "small":
marginFactor = 0.02f;
break;
case "large":
marginFactor = 0.05f;
break;
case "x-large":
marginFactor = 0.075f;
break;
case "medium":
default:
marginFactor = 0.035f;
break;
}
float marginFactor =
switch (customMargin == null ? "" : customMargin.toLowerCase(Locale.ROOT)) {
case "small" -> 0.02f;
case "large" -> 0.05f;
case "x-large" -> 0.075f;
case "medium" -> 0.035f;
default -> 0.035f;
};
if (pagesToNumber == null || pagesToNumber.isEmpty()) {
pagesToNumber = "all";
@@ -79,9 +84,17 @@ public class PageNumbersController {
if (customText == null || customText.isEmpty()) {
customText = "{n}";
}
final String baseFilename =
Filenames.toSimpleFileName(file.getOriginalFilename())
.replaceFirst("[.][^.]+$", "");
List<Integer> pagesToNumberList =
GeneralUtils.parsePageList(pagesToNumber.split(","), document.getNumberOfPages());
// Clamp position to 1..9 (1 = top-left, 9 = bottom-right)
int pos = Math.max(1, Math.min(9, position));
for (int i : pagesToNumberList) {
PDPage page = document.getPage(i);
PDRectangle pageSize = page.getMediaBox();
@@ -90,70 +103,62 @@ public class PageNumbersController {
customText
.replace("{n}", String.valueOf(pageNumber))
.replace("{total}", String.valueOf(document.getNumberOfPages()))
.replace(
"{filename}",
Filenames.toSimpleFileName(file.getOriginalFilename())
.replaceFirst("[.][^.]+$", ""));
.replace("{filename}", baseFilename);
PDType1Font currentFont =
switch (fontType.toLowerCase()) {
switch (fontType == null ? "" : fontType.toLowerCase(Locale.ROOT)) {
case "courier" -> new PDType1Font(Standard14Fonts.FontName.COURIER);
case "times" -> new PDType1Font(Standard14Fonts.FontName.TIMES_ROMAN);
default -> new PDType1Font(Standard14Fonts.FontName.HELVETICA);
};
float x, y;
// Text dimensions and font metrics
float textWidth = currentFont.getStringWidth(text) / 1000f * fontSize;
float ascent = currentFont.getFontDescriptor().getAscent() / 1000f * fontSize;
float descent = currentFont.getFontDescriptor().getDescent() / 1000f * fontSize;
if (position == 5) {
// Calculate text width and font metrics
float textWidth = currentFont.getStringWidth(text) / 1000 * fontSize;
// Derive column/row in range 1..3 (1 = left/top, 2 = center/middle, 3 = right/bottom)
int col = ((pos - 1) % 3) + 1; // 1 = left, 2 = center, 3 = right
int row = ((pos - 1) / 3) + 1; // 1 = top, 2 = middle, 3 = bottom
float ascent = currentFont.getFontDescriptor().getAscent() / 1000 * fontSize;
float descent = currentFont.getFontDescriptor().getDescent() / 1000 * fontSize;
// Anchor coordinates with margin
float leftX = pageSize.getLowerLeftX() + marginFactor * pageSize.getWidth();
float midX = pageSize.getLowerLeftX() + pageSize.getWidth() / 2f;
float rightX = pageSize.getUpperRightX() - marginFactor * pageSize.getWidth();
float centerX = pageSize.getLowerLeftX() + (pageSize.getWidth() / 2);
float centerY = pageSize.getLowerLeftY() + (pageSize.getHeight() / 2);
float botY = pageSize.getLowerLeftY() + marginFactor * pageSize.getHeight();
float midY = pageSize.getLowerLeftY() + pageSize.getHeight() / 2f;
float topY = pageSize.getUpperRightY() - marginFactor * pageSize.getHeight();
x = centerX - (textWidth / 2);
y = centerY - (ascent + descent) / 2;
} else {
int xGroup = (position - 1) % 3;
int yGroup = 2 - (position - 1) / 3;
// Horizontal alignment: left = anchor, center = centered, right = right-aligned
float x =
switch (col) {
case 1 -> leftX;
case 2 -> midX - textWidth / 2f;
default -> rightX - textWidth;
};
x =
switch (xGroup) {
case 0 ->
pageSize.getLowerLeftX()
+ marginFactor * pageSize.getWidth(); // left
case 1 ->
pageSize.getLowerLeftX() + (pageSize.getWidth() / 2); // center
default ->
pageSize.getUpperRightX()
- marginFactor * pageSize.getWidth(); // right
};
// Vertical alignment (baseline!):
// top = align text top at topY,
// middle = optical middle using ascent/descent,
// bottom = baseline at botY
float y =
switch (row) {
case 1 -> topY - ascent;
case 2 -> midY - (ascent + descent) / 2f;
default -> botY;
};
y =
switch (yGroup) {
case 0 ->
pageSize.getLowerLeftY()
+ marginFactor * pageSize.getHeight(); // bottom
case 1 ->
pageSize.getLowerLeftY() + (pageSize.getHeight() / 2); // middle
default ->
pageSize.getUpperRightY()
- marginFactor * pageSize.getHeight(); // top
};
}
PDPageContentStream contentStream =
try (PDPageContentStream contentStream =
new PDPageContentStream(
document, page, PDPageContentStream.AppendMode.APPEND, true, true);
contentStream.beginText();
contentStream.setFont(currentFont, fontSize);
contentStream.newLineAtOffset(x, y);
contentStream.showText(text);
contentStream.endText();
contentStream.close();
document, page, PDPageContentStream.AppendMode.APPEND, true, true)) {
contentStream.beginText();
contentStream.setFont(currentFont, fontSize);
contentStream.setNonStrokingColor(color);
contentStream.newLineAtOffset(x, y);
contentStream.showText(text);
contentStream.endText();
}
pageNumber++;
}
@@ -2,6 +2,7 @@ package stirling.software.SPDF.controller.api.misc;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.beans.PropertyEditorSupport;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
@@ -25,6 +26,8 @@ import org.apache.pdfbox.pdmodel.graphics.state.PDExtendedGraphicsState;
import org.apache.pdfbox.util.Matrix;
import org.springframework.core.io.ClassPathResource;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
@@ -52,6 +55,24 @@ public class StampController {
private final CustomPDFDocumentFactory pdfDocumentFactory;
private final TempFileManager tempFileManager;
/**
* Initialize data binder for multipart file uploads.
* This method registers a custom editor for MultipartFile to handle file uploads.
* It sets the MultipartFile to null if the uploaded file is empty.
* This is necessary to avoid binding errors when the file is not present.
*/
@InitBinder
public void initBinder(WebDataBinder binder) {
binder.registerCustomEditor(
MultipartFile.class,
new PropertyEditorSupport() {
@Override
public void setAsText(String text) throws IllegalArgumentException {
setValue(null);
}
});
}
@PostMapping(consumes = "multipart/form-data", value = "/add-stamp")
@Operation(
summary = "Add stamp to a PDF file",
@@ -91,25 +112,14 @@ public class StampController {
float overrideY = request.getOverrideY(); // New field for Y override
String customColor = request.getCustomColor();
float marginFactor;
switch (request.getCustomMargin().toLowerCase()) {
case "small":
marginFactor = 0.02f;
break;
case "medium":
marginFactor = 0.035f;
break;
case "large":
marginFactor = 0.05f;
break;
case "x-large":
marginFactor = 0.075f;
break;
default:
marginFactor = 0.035f;
break;
}
float marginFactor =
switch (request.getCustomMargin().toLowerCase()) {
case "small" -> 0.02f;
case "medium" -> 0.035f;
case "large" -> 0.05f;
case "x-large" -> 0.075f;
default -> 0.035f;
};
// Load the input PDF
PDDocument document = pdfDocumentFactory.load(pdfFile);
@@ -185,27 +195,16 @@ public class StampController {
throws IOException {
String resourceDir = "";
PDFont font = new PDType1Font(Standard14Fonts.FontName.HELVETICA);
switch (alphabet) {
case "arabic":
resourceDir = "static/fonts/NotoSansArabic-Regular.ttf";
break;
case "japanese":
resourceDir = "static/fonts/Meiryo.ttf";
break;
case "korean":
resourceDir = "static/fonts/malgun.ttf";
break;
case "chinese":
resourceDir = "static/fonts/SimSun.ttf";
break;
case "thai":
resourceDir = "static/fonts/NotoSansThai-Regular.ttf";
break;
case "roman":
default:
resourceDir = "static/fonts/NotoSans-Regular.ttf";
break;
}
resourceDir =
switch (alphabet) {
case "arabic" -> "static/fonts/NotoSansArabic-Regular.ttf";
case "japanese" -> "static/fonts/Meiryo.ttf";
case "korean" -> "static/fonts/malgun.ttf";
case "chinese" -> "static/fonts/SimSun.ttf";
case "thai" -> "static/fonts/NotoSansThai-Regular.ttf";
case "roman" -> "static/fonts/NotoSans-Regular.ttf";
default -> "static/fonts/NotoSans-Regular.ttf";
};
if (!"".equals(resourceDir)) {
ClassPathResource classPathResource = new ClassPathResource(resourceDir);
@@ -327,30 +326,30 @@ public class StampController {
throws IOException {
float actualWidth =
(text != null) ? calculateTextWidth(text, font, fontSize) : contentWidth;
switch (position % 3) {
return switch (position % 3) {
case 1: // Left
return pageSize.getLowerLeftX() + margin;
yield pageSize.getLowerLeftX() + margin;
case 2: // Center
return (pageSize.getWidth() - actualWidth) / 2;
yield (pageSize.getWidth() - actualWidth) / 2;
case 0: // Right
return pageSize.getUpperRightX() - actualWidth - margin;
yield pageSize.getUpperRightX() - actualWidth - margin;
default:
return 0;
}
yield 0;
};
}
private float calculatePositionY(
PDRectangle pageSize, int position, float height, float margin) {
switch ((position - 1) / 3) {
return switch ((position - 1) / 3) {
case 0: // Top
return pageSize.getUpperRightY() - height - margin;
yield pageSize.getUpperRightY() - height - margin;
case 1: // Middle
return (pageSize.getHeight() - height) / 2;
yield (pageSize.getHeight() - height) / 2;
case 2: // Bottom
return pageSize.getLowerLeftY() + margin;
yield pageSize.getLowerLeftY() + margin;
default:
return 0;
}
yield 0;
};
}
private float calculateTextWidth(String text, PDFont font, float fontSize) throws IOException {
@@ -7,7 +7,6 @@ import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
@@ -106,7 +105,7 @@ public class PipelineProcessor {
Map<String, Object> parameters = pipelineOperation.getParameters();
List<String> inputFileTypes = apiDocService.getExtensionTypes(false, operation);
if (inputFileTypes == null) {
inputFileTypes = new ArrayList<String>(Arrays.asList("ALL"));
inputFileTypes = new ArrayList<>(List.of("ALL"));
}
if (!apiDocService.isValidOperation(operation, parameters)) {
@@ -186,6 +186,7 @@ public class CertSignController {
"alias", privateKey, password.toCharArray(), new Certificate[] {cert});
break;
case "PKCS12":
case "PFX":
ks = KeyStore.getInstance("PKCS12");
ks.load(p12File.getInputStream(), password.toCharArray());
break;
@@ -9,6 +9,8 @@ import java.nio.file.Paths;
import java.util.*;
import java.util.stream.Stream;
import lombok.Getter;
import lombok.Setter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
@@ -317,6 +319,8 @@ public class GeneralWebController {
return "remove-image-pdf";
}
@Setter
@Getter
public class FontResource {
private String name;
@@ -331,28 +335,5 @@ public class GeneralWebController {
this.type = getFormatFromExtension(extension);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getExtension() {
return extension;
}
public void setExtension(String extension) {
this.extension = extension;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}
}
@@ -4,6 +4,8 @@ import java.time.Duration;
import java.time.LocalDateTime;
import java.util.*;
import lombok.Getter;
import lombok.Setter;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
@@ -362,6 +364,8 @@ public class MetricsController {
return String.format("%dd %dh %dm %ds", days, hours, minutes, seconds);
}
@Setter
@Getter
public static class EndpointCount {
private String endpoint;
@@ -373,20 +377,5 @@ public class MetricsController {
this.count = count;
}
public String getEndpoint() {
return endpoint;
}
public void setEndpoint(String endpoint) {
this.endpoint = endpoint;
}
public double getCount() {
return count;
}
public void setCount(double count) {
this.count = count;
}
}
}
@@ -4,10 +4,12 @@ import java.util.HashMap;
import java.util.Map;
import com.fasterxml.jackson.databind.JsonNode;
import lombok.Getter;
public class ApiEndpoint {
private final String name;
private Map<String, JsonNode> parameters;
@Getter
private final String description;
public ApiEndpoint(String name, JsonNode postNode) {
@@ -31,10 +33,6 @@ public class ApiEndpoint {
return true;
}
public String getDescription() {
return description;
}
@Override
public String toString() {
return "ApiEndpoint [name=" + name + ", parameters=" + parameters + "]";
@@ -2,8 +2,10 @@ package stirling.software.SPDF.model;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class SignatureFile {
private String fileName;
@@ -39,4 +39,9 @@ public class ConvertToImageRequest extends PDFWithPageNums {
defaultValue = "300",
requiredMode = Schema.RequiredMode.REQUIRED)
private Integer dpi;
@Schema(
description = "Include annotations such as comments in the output image(s)",
defaultValue = "false")
private Boolean includeAnnotations;
}
@@ -32,6 +32,13 @@ public class AddPageNumbersRequest extends PDFWithPageNums {
requiredMode = RequiredMode.REQUIRED)
private String fontType;
@Schema(
description = "Hex colour for page numbers (e.g. #FF0000)",
example = "#000000",
defaultValue = "#000000",
requiredMode = RequiredMode.NOT_REQUIRED)
private String fontColor;
@Schema(
description =
"Position: 1-9 representing positions on the page (1=top-left, 2=top-center,"
@@ -79,10 +79,6 @@ public class ScannerEffectRequest {
@Schema(description = "Whether advanced settings are enabled", example = "false")
private boolean advancedEnabled = false;
public boolean isAdvancedEnabled() {
return advancedEnabled;
}
public int getQualityValue() {
return switch (quality) {
case low -> 30;
@@ -15,20 +15,25 @@ public class SignPDFWithCertRequest extends PDFFile {
@Schema(
description = "The type of the digital certificate",
allowableValues = {"PEM", "PKCS12", "JKS"},
allowableValues = {"PEM", "PKCS12", "PFX", "JKS"},
requiredMode = Schema.RequiredMode.REQUIRED)
private String certType;
@Schema(
description =
"The private key for the digital certificate (required for PEM type"
+ " certificates)")
+ " certificates, supports .pem, .der, or .key files)")
private MultipartFile privateKeyFile;
@Schema(description = "The digital certificate (required for PEM type certificates)")
@Schema(
description =
"The digital certificate (required for PEM type certificates, supports"
+ " .pem, .der, .crt, or .cer files)")
private MultipartFile certFile;
@Schema(description = "The PKCS12 keystore file (required for PKCS12 type certificates)")
@Schema(
description =
"The PKCS12/PFX keystore file (required for PKCS12 or PFX type certificates)")
private MultipartFile p12File;
@Schema(description = "The JKS keystore file (Java Key Store)")
@@ -6,7 +6,8 @@ import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.pdfbox.pdmodel.PDDocument;
import lombok.Getter;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.text.PDFTextStripper;
import org.apache.pdfbox.text.TextPosition;
@@ -17,91 +18,200 @@ import stirling.software.SPDF.model.PDFText;
@Slf4j
public class TextFinder extends PDFTextStripper {
private final String searchText;
private final String searchTerm;
private final boolean useRegex;
private final boolean wholeWordSearch;
private final List<PDFText> textOccurrences = new ArrayList<>();
@Getter
private final List<PDFText> foundTexts = new ArrayList<>();
public TextFinder(String searchText, boolean useRegex, boolean wholeWordSearch)
private final List<TextPosition> pageTextPositions = new ArrayList<>();
private final StringBuilder pageTextBuilder = new StringBuilder();
public TextFinder(String searchTerm, boolean useRegex, boolean wholeWordSearch)
throws IOException {
this.searchText = searchText.toLowerCase();
this.searchTerm = searchTerm;
this.useRegex = useRegex;
this.wholeWordSearch = wholeWordSearch;
setSortByPosition(true);
this.setWordSeparator(" ");
}
private List<MatchInfo> findOccurrencesInText(String searchText, String content) {
List<MatchInfo> matches = new ArrayList<>();
Pattern pattern;
if (useRegex) {
// Use regex-based search
pattern =
wholeWordSearch
? Pattern.compile("\\b" + searchText + "\\b")
: Pattern.compile(searchText);
} else {
// Use normal text search
pattern =
wholeWordSearch
? Pattern.compile("\\b" + Pattern.quote(searchText) + "\\b")
: Pattern.compile(Pattern.quote(searchText));
}
Matcher matcher = pattern.matcher(content);
while (matcher.find()) {
matches.add(new MatchInfo(matcher.start(), matcher.end() - matcher.start()));
}
return matches;
@Override
protected void startPage(PDPage page) throws IOException {
super.startPage(page);
pageTextPositions.clear();
pageTextBuilder.setLength(0);
}
@Override
protected void writeString(String text, List<TextPosition> textPositions) {
for (MatchInfo match : findOccurrencesInText(searchText, text.toLowerCase())) {
int index = match.startIndex;
if (index + match.matchLength <= textPositions.size()) {
// Initial values based on the first character
TextPosition first = textPositions.get(index);
float minX = first.getX();
float minY = first.getY();
float maxX = first.getX() + first.getWidth();
float maxY = first.getY() + first.getHeight();
pageTextBuilder.append(text);
pageTextPositions.addAll(textPositions);
}
// Loop over the rest of the characters and adjust bounding box values
for (int i = index; i < index + match.matchLength; i++) {
TextPosition position = textPositions.get(i);
minX = Math.min(minX, position.getX());
minY = Math.min(minY, position.getY());
maxX = Math.max(maxX, position.getX() + position.getWidth());
maxY = Math.max(maxY, position.getY() + position.getHeight());
}
@Override
protected void writeWordSeparator() {
pageTextBuilder.append(getWordSeparator());
pageTextPositions.add(null); // Placeholder for separator
}
textOccurrences.add(
new PDFText(getCurrentPageNo() - 1, minX, minY, maxX, maxY, text));
@Override
protected void writeLineSeparator() {
pageTextBuilder.append(getLineSeparator());
pageTextPositions.add(null); // Placeholder for separator
}
@Override
protected void endPage(PDPage page) throws IOException {
String text = pageTextBuilder.toString();
if (text.isEmpty() || this.searchTerm == null || this.searchTerm.isEmpty()) {
super.endPage(page);
return;
}
String processedSearchTerm = this.searchTerm.trim();
if (processedSearchTerm.isEmpty()) {
super.endPage(page);
return;
}
String regex = this.useRegex ? processedSearchTerm : "\\Q" + processedSearchTerm + "\\E";
if (this.wholeWordSearch) {
if (processedSearchTerm.length() == 1
&& Character.isDigit(processedSearchTerm.charAt(0))) {
regex = "(?<![\\w])(?<!\\d[\\.,])" + regex + "(?![\\w])(?![\\.,]\\d)";
} else if (processedSearchTerm.length() == 1) {
regex = "(?<![\\w])" + regex + "(?![\\w])";
} else {
regex = "\\b" + regex + "\\b";
}
}
}
public List<PDFText> getTextLocations(PDDocument document) throws Exception {
this.getText(document);
Pattern pattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE);
Matcher matcher = pattern.matcher(text);
log.debug(
"Found "
+ textOccurrences.size()
+ " occurrences of '"
+ searchText
+ "' in the document.");
"Searching for '{}' in page {} with regex '{}' (wholeWord: {}, useRegex: {})",
processedSearchTerm,
getCurrentPageNo(),
regex,
wholeWordSearch,
useRegex);
return textOccurrences;
int matchCount = 0;
while (matcher.find()) {
matchCount++;
int matchStart = matcher.start();
int matchEnd = matcher.end();
log.debug(
"Found match #{} at positions {}-{}: '{}'",
matchCount,
matchStart,
matchEnd,
matcher.group());
float minX = Float.MAX_VALUE;
float minY = Float.MAX_VALUE;
float maxX = Float.MIN_VALUE;
float maxY = Float.MIN_VALUE;
boolean foundPosition = false;
for (int i = matchStart; i < matchEnd; i++) {
if (i >= pageTextPositions.size()) {
log.debug(
"Position index {} exceeds available positions ({})",
i,
pageTextPositions.size());
continue;
}
TextPosition pos = pageTextPositions.get(i);
if (pos != null) {
foundPosition = true;
minX = Math.min(minX, pos.getX());
maxX = Math.max(maxX, pos.getX() + pos.getWidth());
minY = Math.min(minY, pos.getY() - pos.getHeight());
maxY = Math.max(maxY, pos.getY());
}
}
if (!foundPosition && matchStart < pageTextPositions.size()) {
log.debug(
"Attempting to find nearby positions for match at {}-{}",
matchStart,
matchEnd);
for (int i = Math.max(0, matchStart - 5);
i < Math.min(pageTextPositions.size(), matchEnd + 5);
i++) {
TextPosition pos = pageTextPositions.get(i);
if (pos != null) {
foundPosition = true;
minX = Math.min(minX, pos.getX());
maxX = Math.max(maxX, pos.getX() + pos.getWidth());
minY = Math.min(minY, pos.getY() - pos.getHeight());
maxY = Math.max(maxY, pos.getY());
break;
}
}
}
if (foundPosition) {
foundTexts.add(
new PDFText(
this.getCurrentPageNo() - 1,
minX,
minY,
maxX,
maxY,
matcher.group()));
log.debug(
"Added PDFText for match: page={}, bounds=({},{},{},{}), text='{}'",
getCurrentPageNo() - 1,
minX,
minY,
maxX,
maxY,
matcher.group());
} else {
log.warn(
"Found text match '{}' but no valid position data at {}-{}",
matcher.group(),
matchStart,
matchEnd);
}
}
log.debug(
"Page {} search complete: found {} matches for '{}'",
getCurrentPageNo(),
matchCount,
processedSearchTerm);
super.endPage(page);
}
private class MatchInfo {
int startIndex;
int matchLength;
public String getDebugInfo() {
StringBuilder debug = new StringBuilder();
debug.append("Extracted text length: ").append(pageTextBuilder.length()).append("\n");
debug.append("Position count: ").append(pageTextPositions.size()).append("\n");
debug.append("Text content: '")
.append(pageTextBuilder.toString().replace("\n", "\\n").replace("\r", "\\r"))
.append("'\n");
MatchInfo(int startIndex, int matchLength) {
this.startIndex = startIndex;
this.matchLength = matchLength;
String text = pageTextBuilder.toString();
for (int i = 0; i < Math.min(text.length(), 50); i++) {
char c = text.charAt(i);
TextPosition pos = i < pageTextPositions.size() ? pageTextPositions.get(i) : null;
debug.append(
String.format(
" [%d] '%c' (0x%02X) -> %s\n",
i,
c,
(int) c,
pos != null
? String.format("(%.1f,%.1f)", pos.getX(), pos.getY())
: "null"));
}
return debug.toString();
}
}
@@ -53,7 +53,7 @@ public class ApiDocService {
public List<String> getExtensionTypes(boolean output, String operationName) {
if (outputToFileTypes.size() == 0) {
outputToFileTypes.put("PDF", Arrays.asList("pdf"));
outputToFileTypes.put("PDF", List.of("pdf"));
outputToFileTypes.put(
"IMAGE",
Arrays.asList(
@@ -63,10 +63,10 @@ public class ApiDocService {
"ZIP",
Arrays.asList("zip", "rar", "7z", "tar", "gz", "bz2", "xz", "lz", "lzma", "z"));
outputToFileTypes.put("WORD", Arrays.asList("doc", "docx", "odt", "rtf"));
outputToFileTypes.put("CSV", Arrays.asList("csv"));
outputToFileTypes.put("CSV", List.of("csv"));
outputToFileTypes.put("JS", Arrays.asList("js", "jsx"));
outputToFileTypes.put("HTML", Arrays.asList("html", "htm", "xhtml"));
outputToFileTypes.put("JSON", Arrays.asList("json"));
outputToFileTypes.put("JSON", List.of("json"));
outputToFileTypes.put("TXT", Arrays.asList("txt", "text", "md", "markdown"));
outputToFileTypes.put("PPT", Arrays.asList("ppt", "pptx", "odp"));
outputToFileTypes.put("XML", Arrays.asList("xml", "xsd", "xsl"));
@@ -77,7 +77,7 @@ public class CertificateValidationService {
try {
CertPathValidator validator = CertPathValidator.getInstance("PKIX");
CertificateFactory cf = CertificateFactory.getInstance("X.509");
List<X509Certificate> certList = Arrays.asList(cert);
List<X509Certificate> certList = Collections.singletonList(cert);
CertPath certPath = cf.generateCertPath(certList);
Set<TrustAnchor> anchors = new HashSet<>();
@@ -4,8 +4,6 @@ import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
@@ -13,15 +11,15 @@ import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.search.Search;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import stirling.software.SPDF.config.EndpointInspector;
import stirling.software.common.service.PostHogService;
@Service
@RequiredArgsConstructor
@Slf4j
public class MetricsAggregatorService {
private static final Logger logger = LoggerFactory.getLogger(MetricsAggregatorService.class);
private final MeterRegistry meterRegistry;
private final PostHogService postHogService;
private final EndpointInspector endpointInspector;
@@ -66,7 +64,7 @@ public class MetricsAggregatorService {
if ("GET".equals(method)
&& validateGetEndpoints
&& !endpointInspector.isValidGetEndpoint(uri)) {
logger.debug("Skipping invalid GET endpoint: {}", uri);
log.debug("Skipping invalid GET endpoint: {}", uri);
return;
}
@@ -77,7 +75,7 @@ public class MetricsAggregatorService {
double lastCount = lastSentMetrics.getOrDefault(key, 0.0);
double difference = currentCount - lastCount;
if (difference > 0) {
logger.debug("{}, {}", key, difference);
log.debug("{}, {}", key, difference);
metrics.put(key, difference);
lastSentMetrics.put(key, currentCount);
}
@@ -0,0 +1,351 @@
package stirling.software.SPDF.utils.text;
import java.io.IOException;
import org.apache.pdfbox.pdmodel.font.PDFont;
import org.apache.pdfbox.pdmodel.font.PDSimpleFont;
import org.apache.pdfbox.pdmodel.font.encoding.DictionaryEncoding;
import org.apache.pdfbox.pdmodel.font.encoding.Encoding;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class TextEncodingHelper {
public static boolean canEncodeCharacters(PDFont font, String text) {
if (font == null || text == null || text.isEmpty()) {
return false;
}
try {
// Step 1: Primary check - full-string encoding (permissive for "good" cases)
byte[] encoded = font.encode(text);
if (encoded.length > 0) {
log.debug(
"Text '{}' has good full-string encoding for font {} - permissively allowing",
text,
font.getName() != null ? font.getName() : "Unknown");
return true;
}
// Step 2: Smart array-based fallback for TJ operator-style text
log.debug(
"Full encoding failed for '{}' - using array-based fallback for font {}",
text,
font.getName() != null ? font.getName() : "Unknown");
return validateAsCodePointArray(font, text);
} catch (IOException | IllegalArgumentException e) {
log.debug(
"Encoding exception for text '{}' with font {} - trying array fallback: {}",
text,
font.getName() != null ? font.getName() : "Unknown",
e.getMessage());
if (isFontSubset(font.getName()) || hasCustomEncoding(font)) {
return validateAsCodePointArray(font, text);
}
return false; // Non-subset fonts with encoding exceptions are likely problematic
}
}
private static boolean validateAsCodePointArray(PDFont font, String text) {
int totalCodePoints = 0;
int successfulCodePoints = 0;
// Iterate through code points (handles surrogates correctly per Unicode docs)
for (int i = 0; i < text.length(); ) {
int codePoint = text.codePointAt(i);
String charStr = new String(Character.toChars(codePoint));
totalCodePoints++;
try {
// Test encoding for this code point
byte[] charEncoded = font.encode(charStr);
if (charEncoded.length > 0) {
float charWidth = font.getStringWidth(charStr);
if (charWidth >= 0) {
successfulCodePoints++;
log.debug(
"Code point '{}' (U+{}) encoded successfully",
charStr,
Integer.toHexString(codePoint).toUpperCase());
} else {
log.debug(
"Code point '{}' (U+{}) has invalid width: {}",
charStr,
Integer.toHexString(codePoint).toUpperCase(),
charWidth);
}
} else {
log.debug(
"Code point '{}' (U+{}) encoding failed - empty result",
charStr,
Integer.toHexString(codePoint).toUpperCase());
}
} catch (IOException | IllegalArgumentException e) {
log.debug(
"Code point '{}' (U+{}) validation failed: {}",
charStr,
Integer.toHexString(codePoint).toUpperCase(),
e.getMessage());
}
i += Character.charCount(codePoint); // Handle surrogates properly
}
double successRate =
totalCodePoints > 0 ? (double) successfulCodePoints / totalCodePoints : 0;
boolean isAcceptable = successRate >= 0.95;
log.debug(
"Array validation for '{}': {}/{} code points successful ({:.1f}%) - {}",
text,
successfulCodePoints,
totalCodePoints,
successRate * 100,
isAcceptable ? "ALLOWING" : "rejecting");
return isAcceptable;
}
public static boolean isTextSegmentRemovable(PDFont font, String text) {
if (font == null || text == null || text.isEmpty()) {
return false;
}
// Log the attempt
log.debug(
"Evaluating text segment for removal: '{}' with font {}",
text,
font.getName() != null ? font.getName() : "Unknown Font");
if (isSimpleCharacter(text)) {
try {
font.encode(text);
font.getStringWidth(text);
log.debug(
"Text '{}' is a simple character and passed validation - allowing removal",
text);
return true;
} catch (Exception e) {
log.debug(
"Simple character '{}' failed basic validation with font {}: {}",
text,
font.getName() != null ? font.getName() : "Unknown",
e.getMessage());
return false;
}
}
// For complex text, require comprehensive validation
return isTextFullyRemovable(font, text);
}
public static boolean isTextFullyRemovable(PDFont font, String text) {
if (font == null || text == null || text.isEmpty()) {
return false;
}
try {
// Check 1: Verify encoding capability using new smart approach
if (!canEncodeCharacters(font, text)) {
log.debug(
"Text '{}' failed encoding validation for font {}",
text,
font.getName() != null ? font.getName() : "Unknown");
return false;
}
// Check 2: Validate width calculation capability
float width = font.getStringWidth(text);
if (width < 0) { // Allow zero width (invisible chars) but reject negative (invalid)
log.debug(
"Text '{}' has invalid width {} for font {}",
text,
width,
font.getName() != null ? font.getName() : "Unknown");
return false; // Invalid metrics prevent accurate removal
}
// Check 3: Verify font descriptor completeness for redaction area calculation
if (font.getFontDescriptor() == null) {
log.debug(
"Missing font descriptor for font {}",
font.getName() != null ? font.getName() : "Unknown");
return false;
}
// Check 4: Test bounding box calculation for redaction area
try {
font.getFontDescriptor().getFontBoundingBox();
} catch (IllegalArgumentException e) {
log.debug(
"Font bounding box unavailable for font {}: {}",
font.getName() != null ? font.getName() : "Unknown",
e.getMessage());
return false;
}
log.debug(
"Text '{}' passed comprehensive validation for font {}",
text,
font.getName() != null ? font.getName() : "Unknown");
return true;
} catch (IOException e) {
log.debug(
"Text '{}' failed validation for font {} due to IO error: {}",
text,
font.getName() != null ? font.getName() : "Unknown",
e.getMessage());
return false;
} catch (IllegalArgumentException e) {
log.debug(
"Text '{}' failed validation for font {} due to argument error: {}",
text,
font.getName() != null ? font.getName() : "Unknown",
e.getMessage());
return false;
}
}
private static boolean isSimpleCharacter(String text) {
if (text == null || text.isEmpty()) {
return false;
}
if (text.length() > 20) {
return false;
}
for (int i = 0; i < text.length(); i++) {
char c = text.charAt(i);
// Allow letters, digits, and whitespace (most common cases)
if (Character.isLetterOrDigit(c) || Character.isWhitespace(c)) {
continue;
}
// Allow common ASCII punctuation
if (c >= 32 && c <= 126 && ".,!?;:()-[]{}\"'/@#$%&*+=<>|\\~`".indexOf(c) >= 0) {
continue;
}
return false;
}
return true;
}
public static boolean hasCustomEncoding(PDFont font) {
try {
if (font instanceof PDSimpleFont simpleFont) {
try {
Encoding encoding = simpleFont.getEncoding();
if (encoding != null) {
// Check for dictionary-based custom encodings
if (encoding instanceof DictionaryEncoding) {
log.debug("Font {} uses DictionaryEncoding (custom)", font.getName());
return true;
}
String encodingName = encoding.getClass().getSimpleName();
if (encodingName.contains("Custom")
|| encodingName.contains("Dictionary")) {
log.debug(
"Font {} uses custom encoding: {}",
font.getName(),
encodingName);
return true;
}
}
} catch (Exception e) {
log.debug(
"Encoding detection failed for font {}: {}",
font.getName(),
e.getMessage());
return true; // Assume custom if detection fails
}
}
if (font instanceof org.apache.pdfbox.pdmodel.font.PDType0Font) {
log.debug(
"Font {} is Type0 (CID) - generally uses standard CMaps",
font.getName() != null ? font.getName() : "Unknown");
return false;
}
log.debug(
"Font {} type {} - assuming standard encoding",
font.getName() != null ? font.getName() : "Unknown",
font.getClass().getSimpleName());
return false;
} catch (IllegalArgumentException e) {
log.debug(
"Custom encoding detection failed for font {}: {}",
font.getName() != null ? font.getName() : "Unknown",
e.getMessage());
return false; // Be forgiving on detection failure
}
}
public static boolean fontSupportsCharacter(PDFont font, String character) {
if (font == null || character == null || character.isEmpty()) {
return false;
}
try {
byte[] encoded = font.encode(character);
if (encoded.length == 0) {
return false;
}
float width = font.getStringWidth(character);
return width > 0;
} catch (IOException | IllegalArgumentException e) {
log.debug(
"Character '{}' not supported by font {}: {}",
character,
font.getName() != null ? font.getName() : "Unknown",
e.getMessage());
return false;
}
}
public static boolean isFontSubset(String fontName) {
if (fontName == null) {
return false;
}
return fontName.matches("^[A-Z]{6}\\+.*");
}
public static boolean canCalculateBasicWidths(PDFont font) {
try {
float spaceWidth = font.getStringWidth(" ");
if (spaceWidth <= 0) {
return false;
}
String[] testChars = {"a", "A", "0", ".", "e", "!"};
for (String ch : testChars) {
try {
float width = font.getStringWidth(ch);
if (width > 0) {
return true;
}
} catch (IOException | IllegalArgumentException e) {
}
}
return false; // Can't calculate width for any test characters
} catch (IOException | IllegalArgumentException e) {
return false; // Font failed basic width calculation
}
}
}
@@ -0,0 +1,140 @@
package stirling.software.SPDF.utils.text;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.regex.Pattern;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDResources;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class TextFinderUtils {
public static boolean validateFontReliability(org.apache.pdfbox.pdmodel.font.PDFont font) {
if (font == null) {
return false;
}
if (font.isDamaged()) {
log.debug(
"Font {} is marked as damaged - using TextEncodingHelper validation",
font.getName());
}
if (TextEncodingHelper.canCalculateBasicWidths(font)) {
log.debug(
"Font {} passed basic width calculations - considering reliable",
font.getName());
return true;
}
String[] basicTests = {"1", "2", "3", "a", "A", "e", "E", " "};
int workingChars = 0;
for (String testChar : basicTests) {
if (TextEncodingHelper.canEncodeCharacters(font, testChar)) {
workingChars++;
}
}
if (workingChars > 0) {
log.debug(
"Font {} can process {}/{} basic characters - considering reliable",
font.getName(),
workingChars,
basicTests.length);
return true;
}
log.debug("Font {} failed all basic tests - considering unreliable", font.getName());
return false;
}
public static List<Pattern> createOptimizedSearchPatterns(
Set<String> searchTerms, boolean useRegex, boolean wholeWordSearch) {
List<Pattern> patterns = new ArrayList<>();
for (String term : searchTerms) {
if (term == null || term.trim().isEmpty()) {
continue;
}
try {
String patternString = useRegex ? term.trim() : Pattern.quote(term.trim());
if (wholeWordSearch) {
patternString = applyWordBoundaries(term.trim(), patternString);
}
Pattern pattern =
Pattern.compile(
patternString, Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE);
patterns.add(pattern);
log.debug("Created search pattern: '{}' -> '{}'", term.trim(), patternString);
} catch (Exception e) {
log.warn("Failed to create pattern for term '{}': {}", term, e.getMessage());
}
}
return patterns;
}
private static String applyWordBoundaries(String originalTerm, String patternString) {
if (originalTerm.length() == 1 && Character.isDigit(originalTerm.charAt(0))) {
return "(?<![\\w])" + patternString + "(?![\\w])";
} else if (originalTerm.length() == 1) {
return "(?<![\\w])" + patternString + "(?![\\w])";
} else {
return "\\b" + patternString + "\\b";
}
}
public static boolean hasProblematicFonts(PDPage page) {
if (page == null) {
return false;
}
try {
PDResources resources = page.getResources();
if (resources == null) {
return false;
}
int totalFonts = 0;
int completelyUnusableFonts = 0;
for (org.apache.pdfbox.cos.COSName fontName : resources.getFontNames()) {
try {
org.apache.pdfbox.pdmodel.font.PDFont font = resources.getFont(fontName);
if (font != null) {
totalFonts++;
if (!validateFontReliability(font)) {
completelyUnusableFonts++;
}
}
} catch (Exception e) {
log.debug("Font loading failed for {}: {}", fontName.getName(), e.getMessage());
totalFonts++;
}
}
boolean hasProblems = totalFonts > 0 && (completelyUnusableFonts * 2 > totalFonts);
log.debug(
"Page font analysis: {}/{} fonts are completely unusable - page {} problematic",
completelyUnusableFonts,
totalFonts,
hasProblems ? "IS" : "is NOT");
return hasProblems;
} catch (Exception e) {
log.warn("Font analysis failed for page: {}", e.getMessage());
return false; // Be permissive if analysis fails
}
}
}
@@ -0,0 +1,136 @@
package stirling.software.SPDF.utils.text;
import org.apache.pdfbox.pdmodel.common.PDRectangle;
import org.apache.pdfbox.pdmodel.font.PDFont;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class WidthCalculator {
private static final int FONT_SCALE_FACTOR = 1000;
public static float calculateAccurateWidth(PDFont font, String text, float fontSize) {
if (font == null || text == null || text.isEmpty() || fontSize <= 0) {
return 0;
}
if (!TextEncodingHelper.canEncodeCharacters(font, text)) {
log.debug(
"Text cannot be encoded by font {}, using fallback width calculation",
font.getName());
return calculateFallbackWidth(font, text, fontSize);
}
try {
float rawWidth = font.getStringWidth(text);
float scaledWidth = (rawWidth / FONT_SCALE_FACTOR) * fontSize;
log.debug(
"Direct width calculation successful for font {}: {} -> {}",
font.getName(),
rawWidth,
scaledWidth);
return scaledWidth;
} catch (Exception e) {
log.debug(
"Direct width calculation failed for font {}: {}",
font.getName(),
e.getMessage());
return calculateWidthWithCharacterIteration(font, text, fontSize);
}
}
private static float calculateWidthWithCharacterIteration(
PDFont font, String text, float fontSize) {
try {
float totalWidth = 0;
for (int i = 0; i < text.length(); i++) {
String character = text.substring(i, i + 1);
try {
byte[] encoded = font.encode(character);
if (encoded.length > 0) {
int glyphCode = encoded[0] & 0xFF;
float glyphWidth = font.getWidth(glyphCode);
if (glyphWidth == 0) {
try {
glyphWidth = font.getWidthFromFont(glyphCode);
} catch (Exception e2) {
glyphWidth = font.getAverageFontWidth();
}
}
totalWidth += (glyphWidth / FONT_SCALE_FACTOR) * fontSize;
} else {
totalWidth += (font.getAverageFontWidth() / FONT_SCALE_FACTOR) * fontSize;
}
} catch (Exception e2) {
totalWidth += (font.getAverageFontWidth() / FONT_SCALE_FACTOR) * fontSize;
}
}
log.debug("Character iteration width calculation: {}", totalWidth);
return totalWidth;
} catch (Exception e) {
log.debug("Character iteration failed: {}", e.getMessage());
return calculateFallbackWidth(font, text, fontSize);
}
}
private static float calculateFallbackWidth(PDFont font, String text, float fontSize) {
try {
if (font.getFontDescriptor() != null
&& font.getFontDescriptor().getFontBoundingBox() != null) {
PDRectangle bbox = font.getFontDescriptor().getFontBoundingBox();
float avgCharWidth =
bbox.getWidth() / FONT_SCALE_FACTOR * 0.6f; // Conservative estimate
float fallbackWidth = text.length() * avgCharWidth * fontSize;
log.debug("Bounding box fallback width: {}", fallbackWidth);
return fallbackWidth;
}
float avgWidth = font.getAverageFontWidth();
float fallbackWidth = (text.length() * avgWidth / FONT_SCALE_FACTOR) * fontSize;
log.debug("Average width fallback: {}", fallbackWidth);
return fallbackWidth;
} catch (Exception e) {
float conservativeWidth = text.length() * 0.5f * fontSize;
log.debug(
"Conservative fallback width for font {}: {}",
font.getName(),
conservativeWidth);
return conservativeWidth;
}
}
public static boolean isWidthCalculationReliable(PDFont font) {
if (font == null) {
return false;
}
if (font.isDamaged()) {
log.debug("Font {} is damaged", font.getName());
return false;
}
if (!TextEncodingHelper.canCalculateBasicWidths(font)) {
log.debug("Font {} cannot perform basic width calculations", font.getName());
return false;
}
if (TextEncodingHelper.hasCustomEncoding(font)) {
log.debug("Font {} has custom encoding", font.getName());
return false;
}
return true;
}
}
@@ -10,8 +10,12 @@ import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
@@ -27,6 +31,8 @@ import stirling.software.common.service.TaskManager;
@RestController
@RequiredArgsConstructor
@Slf4j
@RequestMapping("/api/v1/general")
@Tag(name = "Job Management", description = "Job Management API")
public class JobController {
private final TaskManager taskManager;
@@ -40,7 +46,8 @@ public class JobController {
* @param jobId The job ID
* @return The job result
*/
@GetMapping("/api/v1/general/job/{jobId}")
@GetMapping("/job/{jobId}")
@Operation(summary = "Get job status")
public ResponseEntity<?> getJobStatus(@PathVariable("jobId") String jobId) {
JobResult result = taskManager.getJobResult(jobId);
if (result == null) {
@@ -68,7 +75,8 @@ public class JobController {
* @param jobId The job ID
* @return The job result
*/
@GetMapping("/api/v1/general/job/{jobId}/result")
@GetMapping("/job/{jobId}/result")
@Operation(summary = "Get job result")
public ResponseEntity<?> getJobResult(@PathVariable("jobId") String jobId) {
JobResult result = taskManager.getJobResult(jobId);
if (result == null) {
@@ -130,7 +138,8 @@ public class JobController {
* @param jobId The job ID
* @return Response indicating whether the job was cancelled
*/
@DeleteMapping("/api/v1/general/job/{jobId}")
@DeleteMapping("/job/{jobId}")
@Operation(summary = "Cancel a job")
public ResponseEntity<?> cancelJob(@PathVariable("jobId") String jobId) {
log.debug("Request to cancel job: {}", jobId);
@@ -197,7 +206,8 @@ public class JobController {
* @param jobId The job ID
* @return List of files for the job
*/
@GetMapping("/api/v1/general/job/{jobId}/result/files")
@GetMapping("/job/{jobId}/result/files")
@Operation(summary = "Get job result files")
public ResponseEntity<?> getJobFiles(@PathVariable("jobId") String jobId) {
JobResult result = taskManager.getJobResult(jobId);
if (result == null) {
@@ -226,7 +236,8 @@ public class JobController {
* @param fileId The file ID
* @return The file metadata
*/
@GetMapping("/api/v1/general/files/{fileId}/metadata")
@GetMapping("/files/{fileId}/metadata")
@Operation(summary = "Get file metadata")
public ResponseEntity<?> getFileMetadata(@PathVariable("fileId") String fileId) {
try {
// Verify file exists
@@ -266,7 +277,8 @@ public class JobController {
* @param fileId The file ID
* @return The file content
*/
@GetMapping("/api/v1/general/files/{fileId}")
@GetMapping("/files/{fileId}")
@Operation(summary = "Download a file")
public ResponseEntity<?> downloadFile(@PathVariable("fileId") String fileId) {
try {
// Verify file exists
@@ -5,7 +5,7 @@ logging.level.org.eclipse.jetty=WARN
#logging.level.org.springframework.security.saml2=TRACE
#logging.level.org.springframework.security=DEBUG
#logging.level.org.opensaml=DEBUG
#logging.level.stirling.software.SPDF.config.security: DEBUG
#logging.level.stirling.software.proprietary.security=DEBUG
logging.level.com.zaxxer.hikari=WARN
spring.jpa.open-in-view=false
server.forward-headers-strategy=NATIVE
@@ -47,4 +47,7 @@ posthog.host=https://eu.i.posthog.com
spring.main.allow-bean-definition-overriding=true
# Set up a consistent temporary directory location
java.io.tmpdir=${stirling.tempfiles.directory:${java.io.tmpdir}/stirling-pdf}
java.io.tmpdir=${stirling.tempfiles.directory:${java.io.tmpdir}/stirling-pdf}
# V2 features
v2=false
@@ -193,6 +193,7 @@ error.fileFormatRequired=File must be in {0} format
error.invalidFormat=Invalid {0} format: {1}
error.endpointDisabled=This endpoint has been disabled by the admin
error.urlNotReachable=URL is not reachable, please provide a valid URL
error.invalidUrlFormat=Invalid URL format provided. The provided format is invalid.
# DPI and image rendering messages - used by frontend for dynamic translation
# Backend sends: [TRANSLATE:messageKey:arg1,arg2] English message
@@ -908,6 +909,7 @@ login.alreadyLoggedIn=لقد تسجل دخولًا إلى
login.alreadyLoggedIn2=أجهزة أخرى. يرجى تسجيل الخروج من الأجهزة وحاول مرة أخرى.
login.toManySessions=لديك عدة جلسات نشطة
login.logoutMessage=You have been logged out.
login.invalidInResponseTo=The requested SAML response is invalid or has expired. Please contact the administrator.
#auto-redact
autoRedact.title=حجب تلقائي
@@ -1080,7 +1082,7 @@ addPageNumbers.selectText.5=الصفحات المراد ترقيمها
addPageNumbers.selectText.6=نص مخصص
addPageNumbers.customTextDesc=نص مخصص
addPageNumbers.numberPagesDesc=أي الصفحات المراد ترقيمها، الافتراضي 'الكل'، يقبل أيضًا 1-5 أو 2,5,9 إلخ
addPageNumbers.customNumberDesc=الافتراضي هو {n}، يقبل أيضًا 'الصفحة {n} من {total}'، 'نص-{n}'، '{filename}-{n}
addPageNumbers.customNumberDesc=الافتراضي هو {n}، يقبل أيضًا 'الصفحة {n} من {total}'، 'نص-{n}'، '{filename}-{n}'
addPageNumbers.submit=إضافة أرقام الصفحات
@@ -1438,6 +1440,7 @@ pdfToImage.dpi=DPI (The server limit is {0} dpi)
pdfToImage.submit=تحويل
pdfToImage.info=Python غير مثبت. مطلوب لتحويل WebP.
pdfToImage.placeholder=(مثال: 1,2,8 أو 4,7,12-16 أو 2n-1)
pdfToImage.includeAnnotations=Include annotations (comments, highlights etc.)
#addPassword
@@ -193,6 +193,7 @@ error.fileFormatRequired=File must be in {0} format
error.invalidFormat=Invalid {0} format: {1}
error.endpointDisabled=This endpoint has been disabled by the admin
error.urlNotReachable=URL is not reachable, please provide a valid URL
error.invalidUrlFormat=Invalid URL format provided. The provided format is invalid.
# DPI and image rendering messages - used by frontend for dynamic translation
# Backend sends: [TRANSLATE:messageKey:arg1,arg2] English message
@@ -908,6 +909,7 @@ login.alreadyLoggedIn=Siz artıq daxil olmusunuz
login.alreadyLoggedIn2=cihazlar. Zəhmət olmasa, cihazlardan çıxış edin və yenidən cəhd edin.
login.toManySessions=Həddindən artıq aktiv sessiyanız var
login.logoutMessage=You have been logged out.
login.invalidInResponseTo=The requested SAML response is invalid or has expired. Please contact the administrator.
#auto-redact
autoRedact.title=Avtomatik Gizlətmə
@@ -1080,7 +1082,7 @@ addPageNumbers.selectText.5=Səhifələrə nömrə əlavə edin
addPageNumbers.selectText.6=Fərdi Mətn
addPageNumbers.customTextDesc=Fərdi Mətn
addPageNumbers.numberPagesDesc=Hansı səhifələrin nömrələnəcəyini seçin, default 'all', və ya 1-5, 2,5,9 kimi yazılış qəbul olunur
addPageNumbers.customNumberDesc=Defolt olaraq {n}, və ya 'Page {n} of {total}', 'Text-{n}', '{filename}-{n}
addPageNumbers.customNumberDesc=Defolt olaraq {n}, və ya 'Page {n} of {total}', 'Text-{n}', '{filename}-{n}'
addPageNumbers.submit=Səhifə Nömrələri əlavə edin
@@ -1438,6 +1440,7 @@ pdfToImage.dpi=DPI (The server limit is {0} dpi)
pdfToImage.submit=Çevir
pdfToImage.info=Python Yüklü Deyil.WebP Çevirməsi Üçün Vacibdir
pdfToImage.placeholder=(məsələn, 1,2,8 və ya 4,7,12-16 və ya 2n-1)
pdfToImage.includeAnnotations=Include annotations (comments, highlights etc.)
#addPassword
@@ -193,6 +193,7 @@ error.fileFormatRequired=File must be in {0} format
error.invalidFormat=Invalid {0} format: {1}
error.endpointDisabled=This endpoint has been disabled by the admin
error.urlNotReachable=URL is not reachable, please provide a valid URL
error.invalidUrlFormat=Invalid URL format provided. The provided format is invalid.
# DPI and image rendering messages - used by frontend for dynamic translation
# Backend sends: [TRANSLATE:messageKey:arg1,arg2] English message
@@ -908,6 +909,7 @@ login.alreadyLoggedIn=Вече сте влезли в
login.alreadyLoggedIn2=устройства. Моля, излезте от устройствата и опитайте отново.
login.toManySessions=Имате твърде много активни сесии
login.logoutMessage=You have been logged out.
login.invalidInResponseTo=The requested SAML response is invalid or has expired. Please contact the administrator.
#auto-redact
autoRedact.title=Автоматично редактиране
@@ -1080,7 +1082,7 @@ addPageNumbers.selectText.5=Страници към номер
addPageNumbers.selectText.6=Персонализиран текст
addPageNumbers.customTextDesc=Персонализиран текст
addPageNumbers.numberPagesDesc=Кои страници да номерирате, по подразбиране 'всички', също приема 1-5 или 2,5,9 и т.н.
addPageNumbers.customNumberDesc=По подразбиране е {n}, също приема 'Страница {n} от {total}', 'Текст-{n}', '{filename}-{n}
addPageNumbers.customNumberDesc=По подразбиране е {n}, също приема 'Страница {n} от {total}', 'Текст-{n}', '{filename}-{n}'
addPageNumbers.submit=Добавяне на номера на страници
@@ -1438,6 +1440,7 @@ pdfToImage.dpi=DPI (The server limit is {0} dpi)
pdfToImage.submit=Преобразуване
pdfToImage.info=Python не е инсталиран. Изисква се за конвертиране на WebP.
pdfToImage.placeholder=(e.g. 1,2,8 or 4,7,12-16 or 2n-1)
pdfToImage.includeAnnotations=Include annotations (comments, highlights etc.)
#addPassword
@@ -193,6 +193,7 @@ error.fileFormatRequired=File must be in {0} format
error.invalidFormat=Invalid {0} format: {1}
error.endpointDisabled=This endpoint has been disabled by the admin
error.urlNotReachable=URL is not reachable, please provide a valid URL
error.invalidUrlFormat=Invalid URL format provided. The provided format is invalid.
# DPI and image rendering messages - used by frontend for dynamic translation
# Backend sends: [TRANSLATE:messageKey:arg1,arg2] English message
@@ -908,6 +909,7 @@ login.alreadyLoggedIn=ཁྱེད་རང་
login.alreadyLoggedIn2=སྒྲིག་ཆས་ནང་ནང་འཛུལ་བྱས་ཟིན། སྒྲིག་ཆས་ནས་ཕྱིར་འཐེན་བྱས་ནས་ཡང་བསྐྱར་ཚོད་ལྟ་བྱེད་རོགས།
login.toManySessions=ཁྱེད་ལ་འཛུལ་ཞུགས་བྱས་པའི་གནས་སྐབས་མང་དྲགས་འདུག
login.logoutMessage=You have been logged out.
login.invalidInResponseTo=The requested SAML response is invalid or has expired. Please contact the administrator.
#auto-redact
autoRedact.title=རང་འགུལ་སྒྲིབ་སྲུང་།
@@ -1438,6 +1440,7 @@ pdfToImage.dpi=DPI (The server limit is {0} dpi)
pdfToImage.submit=བསྒྱུར་བ།
pdfToImage.info=Python སྒྲིག་འཇུག་བྱས་མི་འདུག WebP བསྒྱུར་བར་དགོས་མཁོ་ཡིན།
pdfToImage.placeholder=(དཔེར་ན། 1,2,8 ཡང་ན་ 4,7,12-16 ཡང་ན་ 2n-1)
pdfToImage.includeAnnotations=Include annotations (comments, highlights etc.)
#addPassword
@@ -193,6 +193,7 @@ error.fileFormatRequired=File must be in {0} format
error.invalidFormat=Invalid {0} format: {1}
error.endpointDisabled=This endpoint has been disabled by the admin
error.urlNotReachable=URL is not reachable, please provide a valid URL
error.invalidUrlFormat=Invalid URL format provided. The provided format is invalid.
# DPI and image rendering messages - used by frontend for dynamic translation
# Backend sends: [TRANSLATE:messageKey:arg1,arg2] English message
@@ -908,6 +909,7 @@ login.alreadyLoggedIn=Ja has iniciat sessió a
login.alreadyLoggedIn2=dispositius. Si us plau, tanca la sessió en els dispositius i torna-ho a intentar.
login.toManySessions=Tens massa sessions actives
login.logoutMessage=You have been logged out.
login.invalidInResponseTo=The requested SAML response is invalid or has expired. Please contact the administrator.
#auto-redact
autoRedact.title=Redacció Automàtica
@@ -1438,6 +1440,7 @@ pdfToImage.dpi=DPI (The server limit is {0} dpi)
pdfToImage.submit=Converteix
pdfToImage.info=Python no està instal·lat. És necessari per a la conversió a WebP.
pdfToImage.placeholder=(p. ex. 1,2,8 o 4,7,12-16 o 2n-1)
pdfToImage.includeAnnotations=Include annotations (comments, highlights etc.)
#addPassword
@@ -193,6 +193,7 @@ error.fileFormatRequired=File must be in {0} format
error.invalidFormat=Invalid {0} format: {1}
error.endpointDisabled=This endpoint has been disabled by the admin
error.urlNotReachable=URL is not reachable, please provide a valid URL
error.invalidUrlFormat=Invalid URL format provided. The provided format is invalid.
# DPI and image rendering messages - used by frontend for dynamic translation
# Backend sends: [TRANSLATE:messageKey:arg1,arg2] English message
@@ -908,6 +909,7 @@ login.alreadyLoggedIn=Již jste přihlášeni na
login.alreadyLoggedIn2=zařízeních. Odhlaste se prosím z těchto zařízení a zkuste to znovu.
login.toManySessions=Máte příliš mnoho aktivních relací
login.logoutMessage=You have been logged out.
login.invalidInResponseTo=The requested SAML response is invalid or has expired. Please contact the administrator.
#auto-redact
autoRedact.title=Automatické začernění
@@ -1438,6 +1440,7 @@ pdfToImage.dpi=DPI (The server limit is {0} dpi)
pdfToImage.submit=Převést
pdfToImage.info=Python není nainstalován. Vyžadován pro konverzi do WebP.
pdfToImage.placeholder=(např. 1,2,8 nebo 4,7,12-16 nebo 2n-1)
pdfToImage.includeAnnotations=Include annotations (comments, highlights etc.)
#addPassword
@@ -193,6 +193,7 @@ error.fileFormatRequired=File must be in {0} format
error.invalidFormat=Invalid {0} format: {1}
error.endpointDisabled=This endpoint has been disabled by the admin
error.urlNotReachable=URL is not reachable, please provide a valid URL
error.invalidUrlFormat=Invalid URL format provided. The provided format is invalid.
# DPI and image rendering messages - used by frontend for dynamic translation
# Backend sends: [TRANSLATE:messageKey:arg1,arg2] English message
@@ -908,6 +909,7 @@ login.alreadyLoggedIn=Du er allerede logget ind på
login.alreadyLoggedIn2=enheder. Log ud af disse enheder og prøv igen.
login.toManySessions=Du har for mange aktive sessoner
login.logoutMessage=You have been logged out.
login.invalidInResponseTo=The requested SAML response is invalid or has expired. Please contact the administrator.
#auto-redact
autoRedact.title=Auto Rediger
@@ -1080,7 +1082,7 @@ addPageNumbers.selectText.5=Sider at nummerere
addPageNumbers.selectText.6=Brugerdefineret Tekst
addPageNumbers.customTextDesc=Brugerdefineret Tekst
addPageNumbers.numberPagesDesc=Hvilke sider der skal nummereres, standard 'alle', accepterer også 1-5 eller 2,5,9 osv.
addPageNumbers.customNumberDesc=Standard er {n}, accepterer også 'Side {n} af {total}', 'Tekst-{n}', '{filnavn}-{n}
addPageNumbers.customNumberDesc=Standard er {n}, accepterer også 'Side {n} af {total}', 'Tekst-{n}', '{filename}-{n}'
addPageNumbers.submit=Tilføj Sidenumre
@@ -1438,6 +1440,7 @@ pdfToImage.dpi=DPI (The server limit is {0} dpi)
pdfToImage.submit=Konvertér
pdfToImage.info=Python er ikke installeret. Påkrævet for WebP-konvertering.
pdfToImage.placeholder=(f.eks. 1,2,8 eller 4,7,12-16 eller 2n-1)
pdfToImage.includeAnnotations=Include annotations (comments, highlights etc.)
#addPassword
@@ -193,6 +193,7 @@ error.fileFormatRequired=Die Datei muss im Format {0} vorliegen.
error.invalidFormat=Ungültiges {0}-Format: {1}
error.endpointDisabled=Dieser Endpunkt wurde vom Administrator deaktiviert.
error.urlNotReachable=Die URL ist nicht erreichbar, bitte geben Sie eine gültige URL an.
error.invalidUrlFormat=Invalid URL format provided. The provided format is invalid.
# DPI and image rendering messages - used by frontend for dynamic translation
# Backend sends: [TRANSLATE:messageKey:arg1,arg2] English message
@@ -908,6 +909,7 @@ login.alreadyLoggedIn=Sie sind bereits an
login.alreadyLoggedIn2=Geräten angemeldet. Bitte melden Sie sich dort ab und versuchen es dann erneut.
login.toManySessions=Sie haben zu viele aktive Sitzungen
login.logoutMessage=Sie wurden erfolgreich abgemeldet.
login.invalidInResponseTo=The requested SAML response is invalid or has expired. Please contact the administrator.
#auto-redact
autoRedact.title=Automatisch zensieren/schwärzen
@@ -1438,6 +1440,7 @@ pdfToImage.dpi=DPI (The server limit is {0} dpi)
pdfToImage.submit=Umwandeln
pdfToImage.info=Python ist nicht installiert. Erforderlich für die WebP-Konvertierung.
pdfToImage.placeholder=(z.B. 1,2,8 oder 4,7,12-16 oder 2n-1)
pdfToImage.includeAnnotations=Include annotations (comments, highlights etc.)
#addPassword
@@ -193,6 +193,7 @@ error.fileFormatRequired=File must be in {0} format
error.invalidFormat=Invalid {0} format: {1}
error.endpointDisabled=This endpoint has been disabled by the admin
error.urlNotReachable=URL is not reachable, please provide a valid URL
error.invalidUrlFormat=Invalid URL format provided. The provided format is invalid.
# DPI and image rendering messages - used by frontend for dynamic translation
# Backend sends: [TRANSLATE:messageKey:arg1,arg2] English message
@@ -908,6 +909,7 @@ login.alreadyLoggedIn=Είστε ήδη συνδεδεμένοι σε
login.alreadyLoggedIn2=συσκευές. Παρακαλώ αποσυνδεθείτε από τις συσκευές και προσπαθήστε ξανά.
login.toManySessions=Έχετε πάρα πολλές ενεργές συνεδρίες
login.logoutMessage=You have been logged out.
login.invalidInResponseTo=The requested SAML response is invalid or has expired. Please contact the administrator.
#auto-redact
autoRedact.title=Αυτόματη απόκρυψη
@@ -1080,7 +1082,7 @@ addPageNumbers.selectText.5=Σελίδες προς αρίθμηση
addPageNumbers.selectText.6=Προσαρμοσμένο κείμενο
addPageNumbers.customTextDesc=Προσαρμοσμένο κείμενο
addPageNumbers.numberPagesDesc=Ποιες σελίδες να αριθμηθούν, προεπιλογή 'all', δέχεται επίσης 1-5 ή 2,5,9 κλπ
addPageNumbers.customNumberDesc=Προεπιλογή σε {n}, δέχεται επίσης 'Σελίδα {n} από {total}', 'Κείμενο-{n}', '{filename}-{n}
addPageNumbers.customNumberDesc=Προεπιλογή σε {n}, δέχεται επίσης 'Σελίδα {n} από {total}', 'Κείμενο-{n}', '{filename}-{n}'
addPageNumbers.submit=Προσθήκη αριθμών σελίδων
@@ -1438,6 +1440,7 @@ pdfToImage.dpi=DPI (The server limit is {0} dpi)
pdfToImage.submit=Μετατροπή
pdfToImage.info=Η Python δεν είναι εγκατεστημένη. Απαιτείται για μετατροπή WebP.
pdfToImage.placeholder=(π.χ. 1,2,8 ή 4,7,12-16 ή 2n-1)
pdfToImage.includeAnnotations=Include annotations (comments, highlights etc.)
#addPassword
@@ -137,6 +137,7 @@ lang.yor=Yoruba
addPageNumbers.fontSize=Font Size
addPageNumbers.fontName=Font Name
addPageNumbers.fontColor=Font Colour
pdfPrompt=Select PDF(s)
multiPdfPrompt=Select PDFs (2+)
multiPdfDropPrompt=Select (or drag & drop) all PDFs you require
@@ -193,6 +194,7 @@ error.fileFormatRequired=File must be in {0} format
error.invalidFormat=Invalid {0} format: {1}
error.endpointDisabled=This endpoint has been disabled by the admin
error.urlNotReachable=URL is not reachable, please provide a valid URL
error.invalidUrlFormat=Invalid URL format provided. The provided format is invalid.
# DPI and image rendering messages - used by frontend for dynamic translation
# Backend sends: [TRANSLATE:messageKey:arg1,arg2] English message
@@ -893,7 +895,7 @@ login.rememberme=Remember me
login.invalid=Invalid username or password.
login.locked=Your account has been locked.
login.signinTitle=Please sign in
login.ssoSignIn=Login via Single Sign-on
login.ssoSignIn=Login via Single Sign-On
login.oAuth2AutoCreateDisabled=OAUTH2 Auto-Create User Disabled
login.oAuth2AdminBlockedUser=Registration or logging in of non-registered users is currently blocked. Please contact the administrator.
login.oauth2RequestNotFound=Authorization request not found
@@ -908,6 +910,7 @@ login.alreadyLoggedIn=You are already logged in to
login.alreadyLoggedIn2=devices. Please log out of the devices and try again.
login.toManySessions=You have too many active sessions
login.logoutMessage=You have been logged out.
login.invalidInResponseTo=The requested SAML response is invalid or has expired. Please contact the administrator.
#auto-redact
autoRedact.title=Auto Redact
@@ -1080,7 +1083,7 @@ addPageNumbers.selectText.5=Pages to Number
addPageNumbers.selectText.6=Custom Text
addPageNumbers.customTextDesc=Custom Text
addPageNumbers.numberPagesDesc=Which pages to number, default 'all', also accepts 1-5 or 2,5,9 etc
addPageNumbers.customNumberDesc=Defaults to {n}, also accepts 'Page {n} of {total}', 'Text-{n}', '{filename}-{n}
addPageNumbers.customNumberDesc=Defaults to {n}, also accepts 'Page {n} of {total}', 'Text-{n}', '{filename}-{n}'
addPageNumbers.submit=Add Page Numbers
@@ -1438,6 +1441,7 @@ pdfToImage.dpi=DPI (The server limit is {0} dpi)
pdfToImage.submit=Convert
pdfToImage.info=Python is not installed. Required for WebP conversion.
pdfToImage.placeholder=(e.g. 1,2,8 or 4,7,12-16 or 2n-1)
pdfToImage.includeAnnotations=Include annotations (comments, highlights etc.)
#addPassword
@@ -193,6 +193,7 @@ error.fileFormatRequired=File must be in {0} format
error.invalidFormat=Invalid {0} format: {1}
error.endpointDisabled=This endpoint has been disabled by the admin
error.urlNotReachable=URL is not reachable, please provide a valid URL
error.invalidUrlFormat=Invalid URL format provided. The provided format is invalid.
# DPI and image rendering messages - used by frontend for dynamic translation
# Backend sends: [TRANSLATE:messageKey:arg1,arg2] English message
@@ -908,6 +909,7 @@ login.alreadyLoggedIn=You are already logged in to
login.alreadyLoggedIn2=devices. Please log out of the devices and try again.
login.toManySessions=You have too many active sessions
login.logoutMessage=You have been logged out.
login.invalidInResponseTo=The requested SAML response is invalid or has expired. Please contact the administrator.
#auto-redact
autoRedact.title=Auto Redact
@@ -1080,7 +1082,7 @@ addPageNumbers.selectText.5=Pages to Number
addPageNumbers.selectText.6=Custom Text
addPageNumbers.customTextDesc=Custom Text
addPageNumbers.numberPagesDesc=Which pages to number, default 'all', also accepts 1-5 or 2,5,9 etc
addPageNumbers.customNumberDesc=Defaults to {n}, also accepts 'Page {n} of {total}', 'Text-{n}', '{filename}-{n}
addPageNumbers.customNumberDesc=Defaults to {n}, also accepts 'Page {n} of {total}', 'Text-{n}', '{filename}-{n}'
addPageNumbers.submit=Add Page Numbers
@@ -1438,6 +1440,7 @@ pdfToImage.dpi=DPI (The server limit is {0} dpi)
pdfToImage.submit=Convert
pdfToImage.info=Python is not installed. Required for WebP conversion.
pdfToImage.placeholder=(e.g. 1,2,8 or 4,7,12-16 or 2n-1)
pdfToImage.includeAnnotations=Include annotations (comments, highlights etc.)
#addPassword
@@ -193,6 +193,7 @@ error.fileFormatRequired=File must be in {0} format
error.invalidFormat=Invalid {0} format: {1}
error.endpointDisabled=This endpoint has been disabled by the admin
error.urlNotReachable=URL is not reachable, please provide a valid URL
error.invalidUrlFormat=Invalid URL format provided. The provided format is invalid.
# DPI and image rendering messages - used by frontend for dynamic translation
# Backend sends: [TRANSLATE:messageKey:arg1,arg2] English message
@@ -908,6 +909,7 @@ login.alreadyLoggedIn=Ya ha iniciado sesión en
login.alreadyLoggedIn2=dispositivos. Cierre sesión en los dispositivos y vuelva a intentarlo.
login.toManySessions=Tiene demasiadas sesiones activas
login.logoutMessage=You have been logged out.
login.invalidInResponseTo=The requested SAML response is invalid or has expired. Please contact the administrator.
#auto-redact
autoRedact.title=Auto Censurar Texto
@@ -1080,7 +1082,7 @@ addPageNumbers.selectText.5=Páginas a numerar
addPageNumbers.selectText.6=Texto personalizado
addPageNumbers.customTextDesc=Texto personalizado
addPageNumbers.numberPagesDesc=Qué páginas numerar, por defecto 'todas', también acepta 1-5 o 2,5,9 etc
addPageNumbers.customNumberDesc=Por defecto a {n}, también acepta 'Página {n} de {total}', 'Texto-{n}', '{filename}-{n}
addPageNumbers.customNumberDesc=Por defecto a {n}, también acepta 'Página {n} de {total}', 'Texto-{n}', '{filename}-{n}'
addPageNumbers.submit=Añadir Números de Página
@@ -1438,6 +1440,7 @@ pdfToImage.dpi=DPI (The server limit is {0} dpi)
pdfToImage.submit=Convertir
pdfToImage.info=Python no está instalado. Se requiere para la conversión WebP.
pdfToImage.placeholder=(por ejemplo 1,2,8 o 4,7,12-16 o 2n-1)
pdfToImage.includeAnnotations=Include annotations (comments, highlights etc.)
#addPassword

Some files were not shown because too many files have changed in this diff Show More