## PR: Certificate Pre-Validation for Document Signing
### Problem
When a participant uploaded a certificate to sign a document, there was
no validation at submission time. If the certificate had the wrong
password, was expired, or was incompatible with the signing algorithm,
the error only surfaced during **finalization** — potentially days
later, after all other participants had signed. At that point the
session is stuck with no way to recover.
Additionally, `buildKeystore` in the finalization service only
recognised `"P12"` as a cert type, causing a `400 Invalid certificate
type: PKCS12` error when the **owner** signed using the standard
`PKCS12` identifier.
---
### What this PR does
#### Backend — Certificate pre-validation service
Adds `CertificateSubmissionValidator`, which validates a keystore before
it is stored by:
1. Loading the keystore with the provided password (catches wrong
password / corrupt file)
2. Checking the certificate's validity dates (catches expired and
not-yet-valid certs)
3. Test-signing a blank PDF using the same `PdfSigningService` code path
as finalization (catches algorithm incompatibilities)
This runs on both the participant submission endpoint
(`WorkflowParticipantController`) and the owner signing endpoint
(`SigningSessionController`), so both flows are protected.
#### Backend — Bug fix
`SigningFinalizationService.buildKeystore` now accepts `"PKCS12"` and
`"PFX"` as aliases for `"P12"`, consistent with how the validator
already handles them. This fixes a `400` error when the owner signed
using the `PKCS12` cert type.
#### Frontend — Real-time validation feedback
`ParticipantView` gains a debounced validation call (600ms) triggered
whenever the cert file or password changes. The UI shows:
- A spinner while validating
- Green "Certificate valid until [date] · [subject name]" on success
- Red error message on failure (wrong password, expired, not yet valid)
- The submit button is disabled while validation is in flight
#### Tests — Three layers
| Layer | File | Coverage |
|---|---|---|
| Service unit | `CertificateSubmissionValidatorTest` | 11 tests — valid
P12/JKS, wrong password, corrupt bytes, expired, not-yet-valid, signing
failure, cert type aliases |
| Controller unit | `WorkflowParticipantValidateCertificateTest` | 4
tests — valid cert, invalid cert, missing file, invalid token |
| Controller integration | `CertificateValidationIntegrationTest` | 6
tests — real `.p12`/`.jks` files through the full controller → validator
stack |
| Frontend E2E | `CertificateValidationE2E.spec.ts` | 7 Playwright tests
— all feedback states, button behaviour, SERVER type bypass |
#### CI
- **PR**: Playwright runs on chromium when frontend files change (~2-3
min)
- **Nightly / on-demand**: All three browsers (chromium, firefox,
webkit) at 2 AM UTC, also manually triggerable via `workflow_dispatch`
# Description of Changes
Previously, `VITE_*` environment variables were scattered across the
codebase with hardcoded fallback values inline (e.g.
`import.meta.env.VITE_STRIPE_KEY || 'pk_live_...'`). This made it
unclear which variables
were required, what they were for, and caused real keys to be silently
used in builds where they hadn't been explicitly configured.
## What's changed
I've added `frontend/.env.example` and `frontend/.env.desktop.example`,
which declare every `VITE_*` variable the app uses, with comments
explaining each one and sensible defaults where applicable. These
are the source of truth for what's required.
I've added a setup script which runs before `npm run dev`, `build`,
`tauri-dev`, and all `tauri-build*` commands. It:
- Creates your local `.env` / `.env.desktop` from the example files on
first run, so you don't need to do anything manually
- Errors if you're missing keys that the example defines (e.g. after
pulling changes that added a new variable). These can either be
manually-set env vars, or in your `.env` file (env vars take precedence
over `.env` file vars when running)
- Warns if you have `VITE_*` variables set in your environment that
aren't listed in any example file
I've removed all `|| 'hardcoded-value'` defaults from source files
because they are not necessary in this system, as all variables must be
explicitly set (they can be set to `VITE_ENV_VAR=`, just as long as the
variable actually exists). I think this system will make it really
obvious exactly what you need to set and what's actually running in the
code.
I've added a test that checks that every `import.meta.env.VITE_*`
reference found in source is present in at least one example file, so
new variables can't be added without being documented.
## For contributors
New contributors shouldn't need to do anything - `npm run dev` will
create your `.env` automatically.
If you already have a `.env` file in the `frontend/` folder, you may
well need to update it to make the system happy. Here's an example
output from running `npm run dev` with an old `.env` file:
```
$ npm run dev
> [email protected] dev
> npm run prep && vite
> [email protected] prep
> tsx scripts/setup-env.ts && npm run generate-icons
setup-env: see frontend/README.md#environment-variables for documentation
setup-env: .env is missing keys from config/.env.example:
VITE_GOOGLE_DRIVE_CLIENT_ID
VITE_GOOGLE_DRIVE_API_KEY
VITE_GOOGLE_DRIVE_APP_ID
VITE_PUBLIC_POSTHOG_KEY
VITE_PUBLIC_POSTHOG_HOST
Add them manually or delete your local file to re-copy from the example.
setup-env: the following VITE_ vars are set but not listed in any example file:
VITE_DEV_BYPASS_AUTH
Add them to config/.env.example or config/.env.desktop.example if they are required.
```
If you add a new `VITE_*` variable to the codebase, add it to the
appropriate `frontend/config/.env.example` file or the test will fail.
### Motivation
- Allow operators to configure a pipeline base directory and multiple
watched folders so the pipeline can monitor several directories and
subdirectories concurrently.
- Ensure scanning traverses subdirectories while skipping internal
processing folders (e.g. `processing`) and preserve existing behavior
for finished/output paths.
- Expose the new options in the server `settings.yml.template` and the
admin UI so paths can be edited from the web console.
### Description
- Added new `pipelineDir` and `watchedFoldersDirs` fields to
`ApplicationProperties.CustomPaths.Pipeline` and kept backward
compatibility with `watchedFoldersDir`
(app/common/src/main/java/stirling/software/common/model/ApplicationProperties.java).
- Resolved pipeline base and multiple watched folder paths in
`RuntimePathConfig` and exposed `getPipelineWatchedFoldersPaths()`
(app/common/src/main/java/stirling/software/common/configuration/RuntimePathConfig.java).
- Updated `FileMonitor` to accept and register multiple root paths
instead of a single root
(app/common/src/main/java/stirling/software/common/util/FileMonitor.java).
- Updated `PipelineDirectoryProcessor` to iterate all configured watched
roots and to walk subdirectories while ignoring `processing` dirs
(app/core/src/main/java/stirling/software/SPDF/controller/api/pipeline/PipelineDirectoryProcessor.java).
- Exposed the new settings in `settings.yml.template` and the admin UI,
including a multi-line `Textarea` to edit `watchedFoldersDirs`
(app/core/src/main/resources/settings.yml.template,
frontend/src/proprietary/components/shared/config/configSections/AdminGeneralSection.tsx).
- Adjusted unit test setup to account for list-based watched folders
(app/common/src/test/java/stirling/software/common/util/FileMonitorTest.java).
### Testing
- Ran formatting and build checks with `./gradlew spotlessApply` and
`./gradlew build` using Java 21 via
`JAVA_HOME=/root/.local/share/mise/installs/java/21.0.2
PATH=/root/.local/share/mise/installs/java/21.0.2/bin:$PATH ./gradlew
...`, but both runs failed due to Gradle plugin resolution being blocked
in this environment (plugin portal/network 403), so full
compilation/formatting could not complete.
- Confirmed the code compiles locally was not possible here; unit test
`FileMonitorTest` was updated to use the new API but was not executed
due to the blocked build.
- Changes were committed (`Support multiple pipeline watch directories`)
and the repository diff contains the listed file modifications.
------
[Codex
Task](https://chatgpt.com/codex/tasks/task_b_69741ecd17c883288d8085a63ccd66f4)
# Description of Changes
## What was changed
- Updated several Mantine `label` compositions in
`AdminSecuritySection.tsx` to avoid invalid HTML nesting that can
trigger React hydration errors (e.g., a `<div>` rendered inside a
`<p>`).
- Changed `Group` used inside `NumberInput` / `Select` labels to render
as an inline element via `component="span"`.
- Added `name` attributes to multiple form controls (`Switch`, `Select`,
`NumberInput`, `Textarea`) to satisfy browser/autofill recommendations
and improve form field identification.
## Why the change was made
- Fixes the runtime warning/error:
- `In HTML, <div> cannot be a descendant of <p>. This will cause a
hydration error.`
- Caused by block-level wrappers inside Mantine `Text`/`p` label
rendering.
- Addresses the browser audit warning:
- `A form field element should have an id or name attribute`
- Adding stable `name` attributes improves autofill behavior and form
accessibility tooling.
---
## 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.
# Description of Changes
This pull request introduces several improvements and new features
across the authentication and admin data APIs, with a particular focus
on multi-factor authentication (MFA) support and better handling of user
settings. The changes include integrating MFA status into account data
responses, masking sensitive user settings in admin views, and
refactoring code to use more robust user creation methods. Additionally,
there are minor code cleanups and consistency improvements.
### Multi-factor Authentication (MFA) Integration
* Added `mfaEnabled` and `mfaRequired` fields to the `AccountData`
response, populated using the new `MfaService`, to provide clients with
MFA status information for users.
[[1]](diffhunk://#diff-2ead183708656f2c6894b28457623820c83b1ed4b0814533caa0e8f0dd6fbcd1R430-R431)
[[2]](diffhunk://#diff-2ead183708656f2c6894b28457623820c83b1ed4b0814533caa0e8f0dd6fbcd1R72)
[[3]](diffhunk://#diff-2ead183708656f2c6894b28457623820c83b1ed4b0814533caa0e8f0dd6fbcd1L83-R86)
[[4]](diffhunk://#diff-2ead183708656f2c6894b28457623820c83b1ed4b0814533caa0e8f0dd6fbcd1R98)
[[5]](diffhunk://#diff-2ead183708656f2c6894b28457623820c83b1ed4b0814533caa0e8f0dd6fbcd1R574-R575)
### User Settings Handling and Security
* Admin settings API now returns user settings for each user, with the
`mfaSecret` field masked to protect sensitive information. This is
achieved by fetching settings via `findByIdWithSettings` and
copying/masking the relevant field before returning.
[[1]](diffhunk://#diff-2ead183708656f2c6894b28457623820c83b1ed4b0814533caa0e8f0dd6fbcd1R252-R259)
[[2]](diffhunk://#diff-2ead183708656f2c6894b28457623820c83b1ed4b0814533caa0e8f0dd6fbcd1L302-R322)
[[3]](diffhunk://#diff-2ead183708656f2c6894b28457623820c83b1ed4b0814533caa0e8f0dd6fbcd1R378)
[[4]](diffhunk://#diff-2ead183708656f2c6894b28457623820c83b1ed4b0814533caa0e8f0dd6fbcd1R563)
### Refactoring and Code Consistency
* Refactored user creation in `InitialSecuritySetup` to use the
`SaveUserRequest` builder and `saveUserCore` for better maintainability
and clarity, replacing direct calls to `saveUser`.
[[1]](diffhunk://#diff-0c7960a6283a07c4905ac9785b2820b412574c9f86918ada30caba0356d34850R22)
[[2]](diffhunk://#diff-0c7960a6283a07c4905ac9785b2820b412574c9f86918ada30caba0356d34850L116-R124)
[[3]](diffhunk://#diff-0c7960a6283a07c4905ac9785b2820b412574c9f86918ada30caba0356d34850L130-R144)
[[4]](diffhunk://#diff-0c7960a6283a07c4905ac9785b2820b412574c9f86918ada30caba0356d34850L140-R160)
* Standardized checks for internal team membership by comparing with
`TeamService.INTERNAL_TEAM_NAME` on the left side for consistency.
[[1]](diffhunk://#diff-2ead183708656f2c6894b28457623820c83b1ed4b0814533caa0e8f0dd6fbcd1L267-R273)
[[2]](diffhunk://#diff-2ead183708656f2c6894b28457623820c83b1ed4b0814533caa0e8f0dd6fbcd1L332-R351)
[[3]](diffhunk://#diff-2ead183708656f2c6894b28457623820c83b1ed4b0814533caa0e8f0dd6fbcd1L421-R443)
[[4]](diffhunk://#diff-2ead183708656f2c6894b28457623820c83b1ed4b0814533caa0e8f0dd6fbcd1L449-R471)
[[5]](diffhunk://#diff-2ead183708656f2c6894b28457623820c83b1ed4b0814533caa0e8f0dd6fbcd1L462-R485)
### API and DTO Changes
* Changed the login API to accept `UsernameAndPassMfa` instead of
`UsernameAndPass`, paving the way for MFA code support in authentication
requests.
[[1]](diffhunk://#diff-9ca4f9246abe79368552264e2e18d7ed039e084c70c0794eb02cfd1b75fbd8a8L30-R41)
[[2]](diffhunk://#diff-9ca4f9246abe79368552264e2e18d7ed039e084c70c0794eb02cfd1b75fbd8a8L61-R71)
* Updated import statements and controller dependencies to include new
DTOs and services related to MFA.
[[1]](diffhunk://#diff-9ca4f9246abe79368552264e2e18d7ed039e084c70c0794eb02cfd1b75fbd8a8L14-R19)
[[2]](diffhunk://#diff-9ca4f9246abe79368552264e2e18d7ed039e084c70c0794eb02cfd1b75fbd8a8R56-R57)
These updates improve security, prepare the system for MFA rollout, and
make admin and authentication APIs more robust and informative.
---
## 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.
---------
Co-authored-by: Copilot <[email protected]>
## Summary
- show demo data for audit and usage sections when enterprise licensing
is unavailable
- add enterprise-required banner messaging and reuse demo content
instead of erroring
- update translations for the new enterprise notice
## Testing
- Not run (not requested)
------
[Codex
Task](https://chatgpt.com/codex/tasks/task_b_693af73ad9248328885eb8bb81ccf51a)
# Description of Changes
This PR introduces comprehensive database backup and restore management
for embedded H2 databases directly within the admin UI, along with a
corrected backend condition for H2 detection.
### What was changed
- Fixed `H2SQLCondition` logic so embedded H2 is correctly detected when
custom databases are disabled.
- Updated and expanded unit tests to reflect the corrected H2 enablement
behavior.
- Added a new **Backups & Restore** section to the Admin Database
settings UI.
- Implemented UI features to:
- Create H2 database backups
- List available backup files with metadata
- Download, import, and delete existing backups
- Upload and import `.sql` backup files with a confirmation code safety
step
- Added a new frontend service (`databaseManagementService`) to
encapsulate database management API calls.
- Extended English (en-GB) translations for all new database backup and
restore UI elements.
### Why the change was made
- Embedded H2 is the default database when no custom database is
configured, but this was not consistently reflected in backend
conditions.
- Administrators need a safe, UI-driven way to manage H2 backups without
manual filesystem access.
- The new UI improves operability, safety (confirmation code on import),
and transparency (version and status badges).
<img width="1920" height="1080" alt="image"
src="https://github.com/user-attachments/assets/15869b9c-fa86-4b31-ac9b-8e6424138b73"
/>
<img width="1920" height="1032" alt="image"
src="https://github.com/user-attachments/assets/8668dc07-0384-40f0-91e1-c6973c1ce535"
/>
Closes#5515
---
## 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.
# Description of Changes
### What was changed
- Added new admin-only API endpoints to:
- List installed tessdata OCR languages
- Fetch available tessdata languages from the official Tesseract
repository
- Download selected tessdata language files directly into the configured
tessdata directory
- Implemented server-side validation, safe language name handling, and
directory writability checks.
- Extended the Admin Advanced Settings UI to:
- Display installed tessdata languages
- Show available remote languages not yet installed
- Allow selecting and downloading additional languages via a
multi-select UI
- Gracefully fall back to manual download links when the tessdata
directory is not writable
- Added new i18n strings for all related UI states (loading, success,
error, permission warnings).
### Why the change was made
- Managing OCR languages previously required manual filesystem
interaction.
- This change improves usability for administrators by enabling in-app
management of tessdata languages while maintaining security constraints.
- The writable directory check and manual fallback ensure compatibility
with restricted or containerized environments.
<img width="1282" height="832" alt="image"
src="https://github.com/user-attachments/assets/aa958730-0ffb-4fd6-9af8-87c527a476e4"
/>
---
## 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.
---------
Co-authored-by: Copilot <[email protected]>
# Description of Changes
This pull request introduces Telegram bot integration to the
application, enabling users to send files via Telegram for processing
through the pipeline. The main changes add configuration options,
dependency management, and a new service for handling Telegram
interactions.
**Telegram bot integration:**
* Added a new `TelegramPipelineBot` service (`TelegramPipelineBot.java`)
that listens for incoming Telegram messages, downloads attached files or
photos, places them in a pipeline inbox folder, waits for processing
results, and sends the output files back to the user. The service
includes error handling and status messaging.
* Introduced a `TelegramBotConfig` configuration class to initialize and
register the Telegram bot only when enabled via application properties.
* Added a new `Telegram` configuration section to
`ApplicationProperties` and the `settings.yml.template`, supporting
options like enabling/disabling the bot, bot token/username, pipeline
folder, processing timeout, and polling interval.
[[1]](diffhunk://#diff-1c357db0a3e88cf5bedd4a5852415fadad83b8b3b9eb56e67059d8b9d8b10702R63)
[[2]](diffhunk://#diff-1c357db0a3e88cf5bedd4a5852415fadad83b8b3b9eb56e67059d8b9d8b10702R580-R589)
[[3]](diffhunk://#diff-12f23603ae35319a3ea08f91b6340d5d935216941fda2e69d2df1b6cd22a63f2R108-R115)
**Dependency management:**
* Added the `org.telegram:telegrambots` library to the project
dependencies to support Telegram bot functionality.
---
## 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.
---------
Co-authored-by: Copilot <[email protected]>
Co-authored-by: Anthony Stirling <[email protected]>
# Description of Changes
```console
index-DsORDqQQ.js:124 \n [TauriHttpClient] Network error: \n{url: 'http://localhost:8080/api/v1/admin/settings', method: 'PUT', errorType: 'ERR_NETWORK', originalMessage: `Failed to execute 'close' on 'ReadableStreamDefaul…cted token 'S', "Successful"... is not valid JSON`, stack: `SyntaxError: Unexpected token 'S', "Successful"...…lback (<anonymous>:284:7)\n at <anonymous>:1:28`}\nerrorType\n: \n"ERR_NETWORK"\nmethod\n: \n"PUT"\noriginalMessage\n: \n"Failed to execute 'close' on 'ReadableStreamDefaultController': Unexpected token 'S', \"Successful\"... is not valid JSON"\nstack\n: \n"SyntaxError: Unexpected token 'S', \"Successful\"... is not valid JSON\n at A.onmessage (http://tauri.localhost/assets/index-DsORDqQQ.js:124:22714)\n at http://tauri.localhost/assets/index-DsORDqQQ.js:124:20748\n at <anonymous>:272:26\n at Object.runCallback (<anonymous>:284:7)\n at <anonymous>:1:28"\nurl\n: \n"http://localhost:8080/api/v1/admin/settings"
index-DXbk7lbS.js:124 \n [TauriHttpClient] Network error: \n{url: 'http://localhost:8080/api/v1/user/get-api-key', method: 'POST', errorType: 'ERR_NETWORK', originalMessage: `Failed to execute 'close' on 'ReadableStreamDefaul…cted token 'a', "a72f6b26-1"... is not valid JSON`, stack: `SyntaxError: Unexpected token 'a', "a72f6b26-1"...…lback (<anonymous>:284:7)\n at <anonymous>:1:28`}\nerrorType\n: \n"ERR_NETWORK"\nmethod\n: \n"POST"\noriginalMessage\n: \n"Failed to execute 'close' on 'ReadableStreamDefaultController': Unexpected token 'a', \"a72f6b26-1\"... is not valid JSON"\nstack\n: \n"SyntaxError: Unexpected token 'a', \"a72f6b26-1\"... is not valid JSON\n at A.onmessage (http://tauri.localhost/assets/index-DXbk7lbS.js:124:22714)\n at http://tauri.localhost/assets/index-DXbk7lbS.js:124:20748\n at <anonymous>:272:26\n at Object.runCallback (<anonymous>:284:7)\n at <anonymous>:1:28"\nurl\n: \n"http://localhost:8080/api/v1/user/get-api-key"
```
This pull request fixes a self-hosting issue where the Tauri HTTP client
fails with `Unexpected token ... is not valid JSON` because certain API
endpoints returned plain text responses.
## What was changed
- Updated `AdminSettingsController`:
- Changed `updateSettings` and `updateSettingsSection` to return
structured JSON objects instead of raw strings.
- Standardized success and error payloads using a `Map<String, Object>`
with keys like `message` and `error`.
- Updated `UserController`:
- Changed `/api/v1/user/get-api-key` and `/api/v1/user/update-api-key`
to return JSON objects (`{ "apiKey": "..." }`) and JSON error objects
instead of plain text.
## Why the change was made
- The Tauri client expects JSON responses and attempts to parse them.
Returning plain strings like `"Successful..."` or an API key string
causes JSON parsing to fail, resulting in network errors on self-hosted
setups.
---
## 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.
---------
Co-authored-by: James Brunton <[email protected]>
# Description of Changes
This pull request improves the handling of provider settings in the
`ProviderCard` component to ensure settings are always in sync with the
latest values from `settings.yml`, and enhances how default values are
initialized for provider fields. It also updates the usage of
`ProviderCard` in the admin connections section to explicitly pass
provider settings.
**Provider settings synchronization and initialization:**
* Added a `useEffect` in `ProviderCard` to keep `localSettings` in sync
with incoming `settings` prop, ensuring that changes from `settings.yml`
are reflected in the UI.
* Improved default value initialization in `ProviderCard`: when opening
an unconfigured provider, it now merges defaults with any existing
values from `settings.yml`, rather than overwriting them.
**Integration with AdminConnectionsSection:**
* Updated `AdminConnectionsSection` to explicitly pass provider settings
to `ProviderCard` via the `settings` prop, ensuring the component always
receives the correct configuration.
---
## 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.
## Summary
- hide password and username update controls for SSO accounts and show a
managed-account notice
- prevent account update handlers from calling APIs when the user
authenticates via SSO
- expose authenticationType on the user session model and add
translations for new SSO messaging
## Testing
- not run (not requested)
------
[Codex
Task](https://chatgpt.com/codex/tasks/task_b_693ae8144148832888ecf128e66cd3ca)
Also added `enableDesktopInstallSlide` flag in `settings.yml` to hide
the download for desktop page in the onboarding.
---------
Co-authored-by: James Brunton <[email protected]>
## Summary
- restrict supported languages to the validated list from app-config
instead of always adding an extra fallback
- set the effective fallback locale to the preferred configured language
and switch away from disallowed selections automatically
## Testing
- ./gradlew build
------
[Codex
Task](https://chatgpt.com/codex/tasks/task_b_6930529bc6c08328a1ce05f7d1316e27)
## Summary
- add backend support for admins to reset user passwords and optionally
email notifications when SMTP is enabled
- surface mail capability in admin settings data for the UI
- add a shared change-password modal hooked into People and Team user
actions with random password generation and email options
## Testing
- not run (not requested)
------
[Codex
Task](https://chatgpt.com/codex/tasks/task_b_6934b978fe3c83289b5b95dec79b3d38)
---------
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>