- {t('admin.settings.general.customPaths.pipeline.watchedFoldersDir.label', 'Watched Folders Directory')}
-
+ {t('admin.settings.general.customPaths.pipeline.pipelineDir.label', 'Pipeline Directory')}
+
}
- description={t('admin.settings.general.customPaths.pipeline.watchedFoldersDir.description', 'Directory where pipeline monitors for incoming PDFs (leave empty for default: /pipeline/watchedFolders)')}
- value={settings.customPaths?.pipeline?.watchedFoldersDir || ''}
+ description={t('admin.settings.general.customPaths.pipeline.pipelineDir.description', 'Base directory for pipeline resources (leave empty for default: /pipeline)')}
+ value={settings.customPaths?.pipeline?.pipelineDir || ''}
onChange={(e) => setSettings({
...settings,
customPaths: {
...settings.customPaths,
pipeline: {
...settings.customPaths?.pipeline,
- watchedFoldersDir: e.target.value
+ pipelineDir: e.target.value
}
}
})}
- placeholder="/pipeline/watchedFolders"
+ placeholder="/pipeline"
disabled={!loginEnabled}
/>
+
+
Date: Sat, 31 Jan 2026 22:00:07 +0100
Subject: [PATCH 5/6] Pin GitHub Actions and add runner hardening (#5628)
# Description of Changes
---
## Checklist
### General
- [ ] I have read the [Contribution
Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md)
- [ ] I have read the [Stirling-PDF Developer
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/DeveloperGuide.md)
(if applicable)
- [ ] I have read the [How to add new languages to
Stirling-PDF](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md)
(if applicable)
- [ ] I have performed a self-review of my own code
- [ ] My changes generate no new warnings
### Documentation
- [ ] I have updated relevant docs on [Stirling-PDF's doc
repo](https://github.com/Stirling-Tools/Stirling-Tools.github.io/blob/main/docs/)
(if functionality has heavily changed)
- [ ] I have read the section [Add New Translation
Tags](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md#add-new-translation-tags)
(for new translation tags only)
### Translations (if applicable)
- [ ] I ran
[`scripts/counter_translation.py`](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/docs/counter_translation.md)
### UI Changes (if applicable)
- [ ] Screenshots or videos demonstrating the UI changes are attached
(e.g., as comments or direct attachments in the PR)
### Testing (if applicable)
- [ ] I have tested my changes locally. Refer to the [Testing
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/DeveloperGuide.md#6-testing)
for more details.
---
.github/workflows/multiOSReleases.yml | 10 +++++-----
.github/workflows/tauri-build.yml | 18 ++++++++++++++----
.github/workflows/testdriver.yml | 5 +++++
3 files changed, 24 insertions(+), 9 deletions(-)
diff --git a/.github/workflows/multiOSReleases.yml b/.github/workflows/multiOSReleases.yml
index 81152ed3b0..af23ec1d6e 100644
--- a/.github/workflows/multiOSReleases.yml
+++ b/.github/workflows/multiOSReleases.yml
@@ -130,7 +130,7 @@ jobs:
- name: Setup Node.js
if: matrix.variant.build_frontend == true
- uses: actions/setup-node@v4
+ uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with:
node-version: 22
cache: "npm"
@@ -185,14 +185,14 @@ jobs:
sudo apt-get install -y libgtk-3-dev libwebkit2gtk-4.0-dev libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelf libjavascriptcoregtk-4.0-dev libsoup2.4-dev libjavascriptcoregtk-4.1-dev libsoup-3.0-dev
- name: Setup Node.js
- uses: actions/setup-node@v4
+ uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with:
node-version: 22
cache: "npm"
cache-dependency-path: frontend/package-lock.json
- name: Setup Rust
- uses: dtolnay/rust-toolchain@stable
+ uses: dtolnay/rust-toolchain@4be9e76fd7c4901c61fb841f559994984270fce7 # stable
with:
toolchain: stable
targets: ${{ (matrix.platform == 'macos-15' || matrix.platform == 'macos-15-intel') && 'aarch64-apple-darwin,x86_64-apple-darwin' || '' }}
@@ -291,7 +291,7 @@ jobs:
- name: Setup DigiCert KeyLocker
id: digicert-setup
if: ${{ matrix.platform == 'windows-latest' && env.SM_API_KEY != '' && (github.event_name == 'release' || github.ref == 'refs/heads/V2-master') }}
- uses: digicert/ssm-code-signing@v1.1.0
+ uses: digicert/ssm-code-signing@9476ceec3ea1c63298d4403b983e1ccf2556ff4c # v1.1.0
env:
SM_API_KEY: ${{ secrets.SM_API_KEY }}
SM_CLIENT_CERT_FILE_B64: ${{ secrets.SM_CLIENT_CERT_FILE_B64 }}
@@ -399,7 +399,7 @@ jobs:
echo "Certificate imported successfully."
- name: Build Tauri app
- uses: tauri-apps/tauri-action@v0
+ uses: tauri-apps/tauri-action@51a9f1156b33df106d827c3a78f8f894946c5faa # v0.5.25
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }}
diff --git a/.github/workflows/tauri-build.yml b/.github/workflows/tauri-build.yml
index f021eb0e46..af31fb4ecb 100644
--- a/.github/workflows/tauri-build.yml
+++ b/.github/workflows/tauri-build.yml
@@ -33,6 +33,11 @@ jobs:
outputs:
matrix: ${{ steps.set-matrix.outputs.matrix }}
steps:
+ - name: Harden the runner (Audit all outbound calls)
+ uses: step-security/harden-runner@20cf305ff2072d973412fa9b1e3a4f227bda3c76 # v2.14.0
+ with:
+ egress-policy: audit
+
- name: Determine build matrix
id: set-matrix
run: |
@@ -81,14 +86,14 @@ jobs:
sudo apt-get install -y libgtk-3-dev libwebkit2gtk-4.0-dev libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelf libjavascriptcoregtk-4.0-dev libsoup2.4-dev libjavascriptcoregtk-4.1-dev libsoup-3.0-dev
- name: Setup Node.js
- uses: actions/setup-node@v4
+ uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with:
node-version: 22
cache: "npm"
cache-dependency-path: frontend/package-lock.json
- name: Setup Rust
- uses: dtolnay/rust-toolchain@stable
+ uses: dtolnay/rust-toolchain@4be9e76fd7c4901c61fb841f559994984270fce7 # stable
with:
toolchain: stable
targets: ${{ (matrix.platform == 'macos-15' || matrix.platform == 'macos-15-intel') && 'aarch64-apple-darwin,x86_64-apple-darwin' || '' }}
@@ -188,7 +193,7 @@ jobs:
- name: Setup DigiCert KeyLocker
id: digicert-setup
if: ${{ matrix.platform == 'windows-latest' && env.SM_API_KEY != '' && github.ref == 'refs/heads/main' }}
- uses: digicert/ssm-code-signing@v1.1.0
+ uses: digicert/ssm-code-signing@9476ceec3ea1c63298d4403b983e1ccf2556ff4c # v1.1.0
env:
SM_API_KEY: ${{ secrets.SM_API_KEY }}
SM_CLIENT_CERT_FILE_B64: ${{ secrets.SM_CLIENT_CERT_FILE_B64 }}
@@ -307,7 +312,7 @@ jobs:
ls -la /usr/bin/hd* || echo "No hd* tools found"
- name: Build Tauri app
- uses: tauri-apps/tauri-action@v0
+ uses: tauri-apps/tauri-action@51a9f1156b33df106d827c3a78f8f894946c5faa # v0.5.25
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }}
@@ -639,6 +644,11 @@ jobs:
runs-on: ubuntu-latest
if: always()
steps:
+ - name: Harden the runner (Audit all outbound calls)
+ uses: step-security/harden-runner@20cf305ff2072d973412fa9b1e3a4f227bda3c76 # v2.14.0
+ with:
+ egress-policy: audit
+
- name: Report build results
run: |
if [ "${{ needs.build.result }}" = "success" ]; then
diff --git a/.github/workflows/testdriver.yml b/.github/workflows/testdriver.yml
index 3e06d7ec16..0e09b3acd1 100644
--- a/.github/workflows/testdriver.yml
+++ b/.github/workflows/testdriver.yml
@@ -128,6 +128,11 @@ jobs:
outputs:
frontend: ${{ steps.changes.outputs.frontend }}
steps:
+ - name: Harden the runner (Audit all outbound calls)
+ uses: step-security/harden-runner@20cf305ff2072d973412fa9b1e3a4f227bda3c76 # v2.14.0
+ with:
+ egress-policy: audit
+
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- name: Check for file changes
From 79bc62a5d24edd701d403ab54fdd9a623c152ed3 Mon Sep 17 00:00:00 2001
From: mrober01
Date: Mon, 2 Feb 2026 02:42:33 -0800
Subject: [PATCH 6/6] =?UTF-8?q?update=20to=20add=20optional=20Zero=20Paddi?=
=?UTF-8?q?ng=20to=20page=20numbers=20(Bates=20Stamping).=E2=80=A6=20(#561?=
=?UTF-8?q?2)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
… Useful in legal and other professional fields to have page numbers
written with padded 0s of a fixed width. This is also known as bates
stamping.
# Description of Changes
---
## 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
- [ ] I have updated relevant docs on [Stirling-PDF's doc
repo](https://github.com/Stirling-Tools/Stirling-Tools.github.io/blob/main/docs/)
(if functionality has heavily changed)
- [ ] I have read the section [Add New Translation
Tags](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md#add-new-translation-tags)
(for new translation tags only)
### Translations (if applicable)
- [ ] I ran
[`scripts/counter_translation.py`](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/docs/counter_translation.md)
### UI Changes (if applicable)
- [ ] Screenshots or videos demonstrating the UI changes are attached
(e.g., as comments or direct attachments in the PR)
### Testing (if applicable)
- [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: Anthony Stirling <77850077+Frooodle@users.noreply.github.com>
---
.../controller/api/misc/PageNumbersController.java | 11 ++++++++++-
.../SPDF/model/api/misc/AddPageNumbersRequest.java | 7 +++++++
frontend/public/locales/en-GB/translation.toml | 3 +++
.../AddPageNumbersAppearanceSettings.tsx | 10 ++++++++++
.../addPageNumbers/useAddPageNumbersOperation.ts | 1 +
.../addPageNumbers/useAddPageNumbersParameters.ts | 3 +++
6 files changed, 34 insertions(+), 1 deletion(-)
diff --git a/app/core/src/main/java/stirling/software/SPDF/controller/api/misc/PageNumbersController.java b/app/core/src/main/java/stirling/software/SPDF/controller/api/misc/PageNumbersController.java
index 41cbe7328e..6d0d05a28d 100644
--- a/app/core/src/main/java/stirling/software/SPDF/controller/api/misc/PageNumbersController.java
+++ b/app/core/src/main/java/stirling/software/SPDF/controller/api/misc/PageNumbersController.java
@@ -52,9 +52,17 @@ public class PageNumbersController {
int pageNumber = request.getStartingNumber();
String pagesToNumber = request.getPagesToNumber();
String customText = request.getCustomText();
+ int zeroPad = request.getZeroPad();
float fontSize = request.getFontSize();
String fontType = request.getFontType();
String fontColor = request.getFontColor();
+ // compute padded number string where requested
+ String formatN;
+ if (zeroPad > 0) {
+ formatN = String.format("%%0%dd", Math.max(0, zeroPad));
+ } else {
+ formatN = "%d";
+ }
Color color = Color.BLACK;
if (fontColor != null && !fontColor.trim().isEmpty()) {
@@ -93,9 +101,10 @@ public class PageNumbersController {
PDPage page = document.getPage(i);
PDRectangle pageSize = page.getMediaBox();
+ String nFormatted = String.format(formatN, pageNumber);
String text =
customText
- .replace("{n}", String.valueOf(pageNumber))
+ .replace("{n}", nFormatted)
.replace("{total}", String.valueOf(document.getNumberOfPages()))
.replace(
"{filename}",
diff --git a/app/core/src/main/java/stirling/software/SPDF/model/api/misc/AddPageNumbersRequest.java b/app/core/src/main/java/stirling/software/SPDF/model/api/misc/AddPageNumbersRequest.java
index 3e116742d3..c4b9074659 100644
--- a/app/core/src/main/java/stirling/software/SPDF/model/api/misc/AddPageNumbersRequest.java
+++ b/app/core/src/main/java/stirling/software/SPDF/model/api/misc/AddPageNumbersRequest.java
@@ -39,6 +39,13 @@ public class AddPageNumbersRequest extends PDFWithPageNums {
requiredMode = RequiredMode.NOT_REQUIRED)
private String fontColor;
+ @Schema(
+ description = "Zero-padding width for page numbers (Bates Stamping). Set to 0 to disable padding",
+ minimum = "0",
+ defaultValue = "0",
+ requiredMode = RequiredMode.NOT_REQUIRED)
+ private int zeroPad = 0;
+
@Schema(
description =
"Position: 1-9 representing positions on the page (1=top-left, 2=top-center,"
diff --git a/frontend/public/locales/en-GB/translation.toml b/frontend/public/locales/en-GB/translation.toml
index 2bb1b12f9a..a0077e1842 100644
--- a/frontend/public/locales/en-GB/translation.toml
+++ b/frontend/public/locales/en-GB/translation.toml
@@ -219,6 +219,9 @@ pagesAndStarting = "Pages & Starting Number"
positionAndPages = "Position & Pages"
preview = "Position Selection"
previewDisclaimer = "Preview is approximate. Final output may vary due to PDF font metrics."
+zeroPad = "Zero‑pad Width (Bates Stamping)"
+zeroPadTooltip = "Zero‑pad (Bates Stamp) page numbers to this width (e.g., 3 ⇒ 001). Set 0 to disable."
+
[addPageNumbers.selectText]
1 = "Select PDF file:"
diff --git a/frontend/src/core/components/tools/addPageNumbers/AddPageNumbersAppearanceSettings.tsx b/frontend/src/core/components/tools/addPageNumbers/AddPageNumbersAppearanceSettings.tsx
index 6ff03ede69..0ff9690d8d 100644
--- a/frontend/src/core/components/tools/addPageNumbers/AddPageNumbersAppearanceSettings.tsx
+++ b/frontend/src/core/components/tools/addPageNumbers/AddPageNumbersAppearanceSettings.tsx
@@ -49,6 +49,16 @@ const AddPageNumbersAppearanceSettings = ({
/>
+ 001). Set 0 to disable.')}>
+ onParameterChange('zeroPad', typeof v === 'number' ? v : 0)}
+ min={0}
+ disabled={disabled}
+ />
+
+