mirror of
https://github.com/Frooodle/Stirling-PDF.git
synced 2025-09-12 17:52:13 +02:00
Merge branch 'Stirling-Tools:main' into main
This commit is contained in:
commit
30aa5d4612
18
.github/labeler-config.yml
vendored
18
.github/labeler-config.yml
vendored
@ -27,18 +27,34 @@ Back End:
|
||||
|
||||
Security:
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: 'src/main/java/stirling/software/SPDF/config/interfaces/DatabaseInterface.java'
|
||||
- any-glob-to-any-file: 'src/main/java/stirling/software/SPDF/config/security/**/*'
|
||||
- any-glob-to-any-file: 'src/main/java/stirling/software/SPDF/controller/api/DatabaseController.java'
|
||||
- any-glob-to-any-file: 'src/main/java/stirling/software/SPDF/controller/api/EmailController.java'
|
||||
- any-glob-to-any-file: 'src/main/java/stirling/software/SPDF/controller/api/H2SQLController.java'
|
||||
- any-glob-to-any-file: 'src/main/java/stirling/software/SPDF/controller/web/AccountWebController.java'
|
||||
- any-glob-to-any-file: 'src/main/java/stirling/software/SPDF/controller/web/DatabaseWebController.java'
|
||||
- any-glob-to-any-file: 'src/main/java/stirling/software/SPDF/controller/api/UserController.java'
|
||||
- any-glob-to-any-file: 'src/main/java/stirling/software/SPDF/model/api/Email.java'
|
||||
- any-glob-to-any-file: 'src/main/java/stirling/software/SPDF/model/exception/BackupNotFoundException.java'
|
||||
- any-glob-to-any-file: 'src/main/java/stirling/software/SPDF/model/exception/NoProviderFoundExceptionjava'
|
||||
- any-glob-to-any-file: 'src/main/java/stirling/software/SPDF/model/provider/**/*'
|
||||
- any-glob-to-any-file: 'src/main/java/stirling/software/SPDF/model/AuthenticationType.java'
|
||||
- any-glob-to-any-file: 'src/main/java/stirling/software/SPDF/model/BackupNotFoundException.java'
|
||||
- any-glob-to-any-file: 'src/main/java/stirling/software/SPDF/model/ApiKeyAuthenticationToken.java'
|
||||
- any-glob-to-any-file: 'src/main/java/stirling/software/SPDF/model/AttemptCounter.java'
|
||||
- any-glob-to-any-file: 'src/main/java/stirling/software/SPDF/model/Authority.java'
|
||||
- any-glob-to-any-file: 'src/main/java/stirling/software/SPDF/model/PersistentLogin.java'
|
||||
- any-glob-to-any-file: 'src/main/java/stirling/software/SPDF/model/SessionEntity.java'
|
||||
- any-glob-to-any-file: 'scripts/download-security-jar.sh'
|
||||
- any-glob-to-any-file: '.github/workflows/dependency-review.yml'
|
||||
- any-glob-to-any-file: '.github/workflows/scorecards.yml'
|
||||
|
||||
API:
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: 'src/main/java/stirling/software/SPDF/config/OpenApiConfig.java'
|
||||
- any-glob-to-any-file: 'src/main/java/stirling/software/SPDF/controller/web/MetricsController.java'
|
||||
- any-glob-to-any-file: 'src/main/java/stirling/software/SPDF/controller/api/**/*'
|
||||
- any-glob-to-any-file: 'src/main/java/stirling/software/SPDF/model/api/**/*'
|
||||
- any-glob-to-any-file: 'scripts/png_to_webp.py'
|
||||
- any-glob-to-any-file: 'split_photos.py'
|
||||
- any-glob-to-any-file: '.github/workflows/swagger.yml'
|
||||
|
10
.github/workflows/PR-Demo-Comment-with-react.yml
vendored
10
.github/workflows/PR-Demo-Comment-with-react.yml
vendored
@ -41,14 +41,14 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
|
||||
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
# Generate GitHub App token
|
||||
- name: Generate GitHub App Token
|
||||
id: generate-token
|
||||
uses: actions/create-github-app-token@3ff1caaa28b64c9cc276ce0a02e2ff584f3900c5 # v2.0.2
|
||||
uses: actions/create-github-app-token@df432ceedc7162793a195dd1713ff69aefc7379e # v2.0.6
|
||||
with:
|
||||
app-id: ${{ secrets.GH_APP_ID }}
|
||||
private-key: ${{ secrets.GH_APP_PRIVATE_KEY }}
|
||||
@ -129,13 +129,13 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
|
||||
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
- name: Generate GitHub App Token
|
||||
id: generate-token
|
||||
uses: actions/create-github-app-token@3ff1caaa28b64c9cc276ce0a02e2ff584f3900c5 # v2.0.2
|
||||
uses: actions/create-github-app-token@df432ceedc7162793a195dd1713ff69aefc7379e # v2.0.6
|
||||
with:
|
||||
app-id: ${{ secrets.GH_APP_ID }}
|
||||
private-key: ${{ secrets.GH_APP_PRIVATE_KEY }}
|
||||
@ -180,7 +180,7 @@ jobs:
|
||||
password: ${{ secrets.DOCKER_HUB_API }}
|
||||
|
||||
- name: Build and push PR-specific image
|
||||
uses: docker/build-push-action@471d1dc4e07e5cdedd4c2171150001c434f0b7a4 # v6.15.0
|
||||
uses: docker/build-push-action@14487ce63c7a62a4a324b0bfb37086795e31c6c1 # v6.16.0
|
||||
with:
|
||||
context: .
|
||||
file: ./Dockerfile
|
||||
|
2
.github/workflows/PR-Demo-cleanup.yml
vendored
2
.github/workflows/PR-Demo-cleanup.yml
vendored
@ -21,7 +21,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
|
||||
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
|
2
.github/workflows/auto-labeler.yml
vendored
2
.github/workflows/auto-labeler.yml
vendored
@ -13,7 +13,7 @@ jobs:
|
||||
pull-requests: write
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
|
||||
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
|
8
.github/workflows/build.yml
vendored
8
.github/workflows/build.yml
vendored
@ -24,7 +24,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
|
||||
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
@ -62,7 +62,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
|
||||
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
@ -106,7 +106,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
|
||||
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
@ -128,7 +128,7 @@ jobs:
|
||||
sudo chmod +x /usr/local/bin/docker-compose
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@8d9ed9ac5c53483de85588cdf95a591a75ab9f55 # v5.5.0
|
||||
uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
|
||||
with:
|
||||
python-version: "3.12"
|
||||
cache: 'pip' # caching pip dependencies
|
||||
|
4
.github/workflows/check_properties.yml
vendored
4
.github/workflows/check_properties.yml
vendored
@ -18,7 +18,7 @@ jobs:
|
||||
pull-requests: write
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
|
||||
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
@ -26,7 +26,7 @@ jobs:
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@8d9ed9ac5c53483de85588cdf95a591a75ab9f55 # v5.5.0
|
||||
uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
|
||||
with:
|
||||
python-version: "3.12"
|
||||
|
||||
|
2
.github/workflows/dependency-review.yml
vendored
2
.github/workflows/dependency-review.yml
vendored
@ -17,7 +17,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
|
||||
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
|
4
.github/workflows/licenses-update.yml
vendored
4
.github/workflows/licenses-update.yml
vendored
@ -18,13 +18,13 @@ jobs:
|
||||
pull-requests: write
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
|
||||
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
- name: Generate GitHub App Token
|
||||
id: generate-token
|
||||
uses: actions/create-github-app-token@3ff1caaa28b64c9cc276ce0a02e2ff584f3900c5 # v2.0.2
|
||||
uses: actions/create-github-app-token@df432ceedc7162793a195dd1713ff69aefc7379e # v2.0.6
|
||||
with:
|
||||
app-id: ${{ secrets.GH_APP_ID }}
|
||||
private-key: ${{ secrets.GH_APP_PRIVATE_KEY }}
|
||||
|
2
.github/workflows/manage-label.yml
vendored
2
.github/workflows/manage-label.yml
vendored
@ -15,7 +15,7 @@ jobs:
|
||||
issues: write
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
|
||||
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
|
38
.github/workflows/multiOSReleases.yml
vendored
38
.github/workflows/multiOSReleases.yml
vendored
@ -2,13 +2,13 @@ name: Test Installers Build
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
release:
|
||||
types: [created]
|
||||
inputs:
|
||||
test_mode:
|
||||
description: "Run in test mode (skips release step)"
|
||||
description: "Run in test mode (skip release step)"
|
||||
required: false
|
||||
default: "false"
|
||||
release:
|
||||
types: [created]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
@ -21,7 +21,7 @@ jobs:
|
||||
versionMac: ${{ steps.versionNumberMac.outputs.versionNumberMac }}
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
|
||||
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
@ -56,7 +56,7 @@ jobs:
|
||||
file_suffix: ""
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
|
||||
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
@ -70,7 +70,7 @@ jobs:
|
||||
|
||||
- uses: gradle/actions/setup-gradle@06832c7b30a0129d7fb559bcc6e43d26f6374244 # v4.3.1
|
||||
with:
|
||||
gradle-version: 8.12
|
||||
gradle-version: 8.14
|
||||
|
||||
- name: Generate jar (With Security=${{ matrix.enable_security }})
|
||||
run: ./gradlew clean createExe
|
||||
@ -106,12 +106,12 @@ jobs:
|
||||
file_suffix: ""
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
|
||||
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
- name: Download build artifacts
|
||||
uses: actions/download-artifact@95815c38cf2ff2164869cbab79da8d1f422bc89e # v4.2.1
|
||||
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
|
||||
with:
|
||||
name: stirling-${{ matrix.file_suffix }}binaries
|
||||
|
||||
@ -144,7 +144,7 @@ jobs:
|
||||
contents: write
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
|
||||
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
@ -158,7 +158,7 @@ jobs:
|
||||
|
||||
- uses: gradle/actions/setup-gradle@06832c7b30a0129d7fb559bcc6e43d26f6374244 # v4.3.1
|
||||
with:
|
||||
gradle-version: 8.12
|
||||
gradle-version: 8.14
|
||||
|
||||
# Install Windows dependencies
|
||||
- name: Install WiX Toolset
|
||||
@ -175,7 +175,7 @@ jobs:
|
||||
STIRLING_PDF_DESKTOP_UI: true
|
||||
BROWSER_OPEN: true
|
||||
|
||||
- name: ☕ Set up JDK (x86_64)
|
||||
- name: Set up JDK (x86_64)
|
||||
if: matrix.os == 'macos-latest'
|
||||
run: |
|
||||
curl -L -o jdk.tar.gz https://cdn.azul.com/zulu/bin/zulu17.56.15-ca-jdk17.0.14-macosx_x64.tar.gz
|
||||
@ -200,10 +200,10 @@ jobs:
|
||||
ls -lah ./build/jpackage/
|
||||
mkdir ./binaries
|
||||
if [ "${{ matrix.os }}" = "windows-latest" ]; then
|
||||
mv "./build/jpackage/Stirling-PDF-${{ needs.read_versions.outputs.version }}.exe" "./binaries/Stirling-PDF-win-installer.exe"
|
||||
mv "./build/jpackage/Stirling PDF-${{ needs.read_versions.outputs.version }}.exe" "./binaries/Stirling-PDF-win-installer.exe"
|
||||
elif [ "${{ matrix.os }}" = "macos-latest" ]; then
|
||||
mv "./build/jpackage/Stirling-PDF-${{ needs.read_versions.outputs.versionMac }}.dmg" "./binaries/Stirling-PDF-mac-installer.dmg"
|
||||
mv "./build/jpackage/x86_64/Stirling-PDF (x86_64)-${{ needs.read_versions.outputs.versionMac }}.dmg" "./binaries/Stirling-PDF-mac-x86_64-installer.dmg"
|
||||
mv "./build/jpackage/Stirling PDF-${{ needs.read_versions.outputs.versionMac }}.dmg" "./binaries/Stirling-PDF-mac-installer.dmg"
|
||||
mv "./build/jpackage/x86_64/Stirling PDF (x86_64)-${{ needs.read_versions.outputs.versionMac }}.dmg" "./binaries/Stirling-PDF-mac-x86_64-installer.dmg"
|
||||
else
|
||||
mv "./build/jpackage/stirling-pdf_${{ needs.read_versions.outputs.version }}-1_amd64.deb" "./binaries/Stirling-PDF-linux-installer.deb"
|
||||
fi
|
||||
@ -234,12 +234,12 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
|
||||
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
- name: Download build artifacts
|
||||
uses: actions/download-artifact@95815c38cf2ff2164869cbab79da8d1f422bc89e # v4.2.1
|
||||
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
|
||||
with:
|
||||
name: ${{ matrix.platform }}binaries
|
||||
|
||||
@ -248,7 +248,7 @@ jobs:
|
||||
|
||||
- name: Install Cosign
|
||||
if: matrix.os == 'windows-latest'
|
||||
uses: sigstore/cosign-installer@d7d6bc7722e3daa8354c50bcb52f4837da5e9b6a # v3.8.1
|
||||
uses: sigstore/cosign-installer@3454372f43399081ed03b604cb2d021dabca52bb # v3.8.2
|
||||
|
||||
- name: Generate key pair
|
||||
if: matrix.os == 'windows-latest'
|
||||
@ -297,12 +297,12 @@ jobs:
|
||||
contents: write
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
|
||||
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
- name: Download signed artifacts
|
||||
uses: actions/download-artifact@95815c38cf2ff2164869cbab79da8d1f422bc89e # v4.2.1
|
||||
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
|
||||
- name: Display structure of downloaded files
|
||||
run: ls -R
|
||||
- name: Upload binaries, attestations and signatures to Release and create GitHub Release
|
||||
|
6
.github/workflows/pre_commit.yml
vendored
6
.github/workflows/pre_commit.yml
vendored
@ -16,13 +16,13 @@ jobs:
|
||||
pull-requests: write
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
|
||||
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
- name: Generate GitHub App Token
|
||||
id: generate-token
|
||||
uses: actions/create-github-app-token@3ff1caaa28b64c9cc276ce0a02e2ff584f3900c5 # v2.0.2
|
||||
uses: actions/create-github-app-token@df432ceedc7162793a195dd1713ff69aefc7379e # v2.0.6
|
||||
with:
|
||||
app-id: ${{ secrets.GH_APP_ID }}
|
||||
private-key: ${{ secrets.GH_APP_PRIVATE_KEY }}
|
||||
@ -42,7 +42,7 @@ jobs:
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@8d9ed9ac5c53483de85588cdf95a591a75ab9f55 # v5.5.0
|
||||
uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
|
||||
with:
|
||||
python-version: 3.12
|
||||
cache: 'pip' # caching pip dependencies
|
||||
|
12
.github/workflows/push-docker.yml
vendored
12
.github/workflows/push-docker.yml
vendored
@ -18,7 +18,7 @@ jobs:
|
||||
id-token: write
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
|
||||
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
@ -32,7 +32,7 @@ jobs:
|
||||
|
||||
- uses: gradle/actions/setup-gradle@06832c7b30a0129d7fb559bcc6e43d26f6374244 # v4.3.1
|
||||
with:
|
||||
gradle-version: 8.12
|
||||
gradle-version: 8.14
|
||||
|
||||
- name: Run Gradle Command
|
||||
run: ./gradlew clean build
|
||||
@ -42,7 +42,7 @@ jobs:
|
||||
|
||||
- name: Install cosign
|
||||
if: github.ref == 'refs/heads/master'
|
||||
uses: sigstore/cosign-installer@d7d6bc7722e3daa8354c50bcb52f4837da5e9b6a # v3.8.1
|
||||
uses: sigstore/cosign-installer@3454372f43399081ed03b604cb2d021dabca52bb # v3.8.2
|
||||
with:
|
||||
cosign-release: "v2.4.1"
|
||||
|
||||
@ -90,7 +90,7 @@ jobs:
|
||||
|
||||
- name: Build and push main Dockerfile
|
||||
id: build-push-regular
|
||||
uses: docker/build-push-action@471d1dc4e07e5cdedd4c2171150001c434f0b7a4 # v6.15.0
|
||||
uses: docker/build-push-action@14487ce63c7a62a4a324b0bfb37086795e31c6c1 # v6.16.0
|
||||
with:
|
||||
builder: ${{ steps.buildx.outputs.name }}
|
||||
context: .
|
||||
@ -135,7 +135,7 @@ jobs:
|
||||
|
||||
- name: Build and push Dockerfile-ultra-lite
|
||||
id: build-push-lite
|
||||
uses: docker/build-push-action@471d1dc4e07e5cdedd4c2171150001c434f0b7a4 # v6.15.0
|
||||
uses: docker/build-push-action@14487ce63c7a62a4a324b0bfb37086795e31c6c1 # v6.16.0
|
||||
if: github.ref != 'refs/heads/main'
|
||||
with:
|
||||
context: .
|
||||
@ -166,7 +166,7 @@ jobs:
|
||||
|
||||
- name: Build and push main Dockerfile fat
|
||||
id: build-push-fat
|
||||
uses: docker/build-push-action@471d1dc4e07e5cdedd4c2171150001c434f0b7a4 # v6.15.0
|
||||
uses: docker/build-push-action@14487ce63c7a62a4a324b0bfb37086795e31c6c1 # v6.16.0
|
||||
if: github.ref != 'refs/heads/main'
|
||||
with:
|
||||
builder: ${{ steps.buildx.outputs.name }}
|
||||
|
14
.github/workflows/releaseArtifacts.yml
vendored
14
.github/workflows/releaseArtifacts.yml
vendored
@ -23,7 +23,7 @@ jobs:
|
||||
version: ${{ steps.versionNumber.outputs.versionNumber }}
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
|
||||
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
@ -37,7 +37,7 @@ jobs:
|
||||
|
||||
- uses: gradle/actions/setup-gradle@06832c7b30a0129d7fb559bcc6e43d26f6374244 # v4.3.1
|
||||
with:
|
||||
gradle-version: 8.12
|
||||
gradle-version: 8.14
|
||||
|
||||
- name: Generate jar (With Security=${{ matrix.enable_security }})
|
||||
run: ./gradlew clean createExe
|
||||
@ -83,19 +83,19 @@ jobs:
|
||||
file_suffix: ""
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
|
||||
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
- name: Download build artifacts
|
||||
uses: actions/download-artifact@95815c38cf2ff2164869cbab79da8d1f422bc89e # v4.2.1
|
||||
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
|
||||
with:
|
||||
name: binaries${{ matrix.file_suffix }}
|
||||
- name: Display structure of downloaded files
|
||||
run: ls -R
|
||||
|
||||
- name: Install Cosign
|
||||
uses: sigstore/cosign-installer@d7d6bc7722e3daa8354c50bcb52f4837da5e9b6a # v3.8.1
|
||||
uses: sigstore/cosign-installer@3454372f43399081ed03b604cb2d021dabca52bb # v3.8.2
|
||||
|
||||
- name: Generate key pair
|
||||
run: cosign generate-key-pair
|
||||
@ -161,12 +161,12 @@ jobs:
|
||||
file_suffix: ""
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
|
||||
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
- name: Download signed artifacts
|
||||
uses: actions/download-artifact@95815c38cf2ff2164869cbab79da8d1f422bc89e # v4.2.1
|
||||
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
|
||||
with:
|
||||
name: signed${{ matrix.file_suffix }}
|
||||
|
||||
|
4
.github/workflows/scorecards.yml
vendored
4
.github/workflows/scorecards.yml
vendored
@ -34,7 +34,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
|
||||
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
@ -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@45775bd8235c68ba998cffa5171334d58593da47 # v3.28.15
|
||||
uses: github/codeql-action/upload-sarif@60168efe1c415ce0f5521ea06d5c2062adbeed1b # v3.28.17
|
||||
with:
|
||||
sarif_file: results.sarif
|
||||
|
2
.github/workflows/sonarqube.yml
vendored
2
.github/workflows/sonarqube.yml
vendored
@ -18,7 +18,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
|
||||
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
|
2
.github/workflows/stale.yml
vendored
2
.github/workflows/stale.yml
vendored
@ -16,7 +16,7 @@ jobs:
|
||||
pull-requests: write
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
|
||||
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
|
2
.github/workflows/swagger.yml
vendored
2
.github/workflows/swagger.yml
vendored
@ -14,7 +14,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
|
||||
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
|
10
.github/workflows/sync_files.yml
vendored
10
.github/workflows/sync_files.yml
vendored
@ -24,13 +24,13 @@ jobs:
|
||||
committer: ${{ steps.committer.outputs.committer }}
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
|
||||
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
- name: Generate GitHub App Token
|
||||
id: generate-token
|
||||
uses: actions/create-github-app-token@3ff1caaa28b64c9cc276ce0a02e2ff584f3900c5 # v2.0.2
|
||||
uses: actions/create-github-app-token@df432ceedc7162793a195dd1713ff69aefc7379e # v2.0.6
|
||||
with:
|
||||
app-id: ${{ secrets.GH_APP_ID }}
|
||||
private-key: ${{ secrets.GH_APP_PRIVATE_KEY }}
|
||||
@ -57,13 +57,13 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
|
||||
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
- name: Generate GitHub App Token
|
||||
id: generate-token
|
||||
uses: actions/create-github-app-token@3ff1caaa28b64c9cc276ce0a02e2ff584f3900c5 # v2.0.2
|
||||
uses: actions/create-github-app-token@df432ceedc7162793a195dd1713ff69aefc7379e # v2.0.6
|
||||
with:
|
||||
app-id: ${{ vars.GH_APP_ID }}
|
||||
private-key: ${{ secrets.GH_APP_PRIVATE_KEY }}
|
||||
@ -71,7 +71,7 @@ jobs:
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@8d9ed9ac5c53483de85588cdf95a591a75ab9f55 # v5.5.0
|
||||
uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
|
||||
with:
|
||||
python-version: "3.12"
|
||||
cache: 'pip' # caching pip dependencies
|
||||
|
8
.github/workflows/testdriver.yml
vendored
8
.github/workflows/testdriver.yml
vendored
@ -12,7 +12,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
|
||||
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
@ -46,7 +46,7 @@ jobs:
|
||||
password: ${{ secrets.DOCKER_HUB_API }}
|
||||
|
||||
- name: Build and push test image
|
||||
uses: docker/build-push-action@471d1dc4e07e5cdedd4c2171150001c434f0b7a4 # v6.15.0
|
||||
uses: docker/build-push-action@14487ce63c7a62a4a324b0bfb37086795e31c6c1 # v6.16.0
|
||||
with:
|
||||
context: .
|
||||
file: ./Dockerfile
|
||||
@ -105,7 +105,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
|
||||
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
@ -134,7 +134,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
|
||||
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
|
@ -153,6 +153,7 @@ services:
|
||||
SYSTEM_MAXFILESIZE: "100"
|
||||
METRICS_ENABLED: "true"
|
||||
SYSTEM_GOOGLEVISIBILITY: "true"
|
||||
SHOW_SURVEY: "true"
|
||||
restart: on-failure:5
|
||||
```
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
# dockerfile.dev
|
||||
|
||||
# Basisimage: Gradle mit JDK 17 (Debian-basiert)
|
||||
FROM gradle:8.13-jdk17
|
||||
FROM gradle:8.14-jdk17
|
||||
|
||||
# Als Root-Benutzer arbeiten, um benötigte Pakete zu installieren
|
||||
USER root
|
||||
|
@ -1,5 +1,5 @@
|
||||
# Build the application
|
||||
FROM gradle:8.13-jdk21 AS build
|
||||
FROM gradle:8.14-jdk21 AS build
|
||||
|
||||
COPY build.gradle .
|
||||
COPY settings.gradle .
|
||||
|
44
README.md
44
README.md
@ -116,46 +116,46 @@ Stirling-PDF currently supports 39 languages!
|
||||
|
||||
| Language | Progress |
|
||||
| -------------------------------------------- | -------------------------------------- |
|
||||
| Arabic (العربية) (ar_AR) |  |
|
||||
| Azerbaijani (Azərbaycan Dili) (az_AZ) |  |
|
||||
| Arabic (العربية) (ar_AR) |  |
|
||||
| Azerbaijani (Azərbaycan Dili) (az_AZ) |  |
|
||||
| Basque (Euskara) (eu_ES) |  |
|
||||
| Bulgarian (Български) (bg_BG) |  |
|
||||
| Catalan (Català) (ca_CA) |  |
|
||||
| Bulgarian (Български) (bg_BG) |  |
|
||||
| Catalan (Català) (ca_CA) |  |
|
||||
| Croatian (Hrvatski) (hr_HR) |  |
|
||||
| Czech (Česky) (cs_CZ) |  |
|
||||
| Czech (Česky) (cs_CZ) |  |
|
||||
| Danish (Dansk) (da_DK) |  |
|
||||
| Dutch (Nederlands) (nl_NL) |  |
|
||||
| English (English) (en_GB) |  |
|
||||
| English (US) (en_US) |  |
|
||||
| French (Français) (fr_FR) |  |
|
||||
| German (Deutsch) (de_DE) |  |
|
||||
| French (Français) (fr_FR) |  |
|
||||
| German (Deutsch) (de_DE) |  |
|
||||
| Greek (Ελληνικά) (el_GR) |  |
|
||||
| Hindi (हिंदी) (hi_IN) |  |
|
||||
| Hungarian (Magyar) (hu_HU) |  |
|
||||
| Indonesian (Bahasa Indonesia) (id_ID) |  |
|
||||
| Irish (Gaeilge) (ga_IE) |  |
|
||||
| Hindi (हिंदी) (hi_IN) |  |
|
||||
| Hungarian (Magyar) (hu_HU) |  |
|
||||
| Indonesian (Bahasa Indonesia) (id_ID) |  |
|
||||
| Irish (Gaeilge) (ga_IE) |  |
|
||||
| Italian (Italiano) (it_IT) |  |
|
||||
| Japanese (日本語) (ja_JP) |  |
|
||||
| Japanese (日本語) (ja_JP) |  |
|
||||
| Korean (한국어) (ko_KR) |  |
|
||||
| Norwegian (Norsk) (no_NB) |  |
|
||||
| Persian (فارسی) (fa_IR) |  |
|
||||
| Polish (Polski) (pl_PL) |  |
|
||||
| Persian (فارسی) (fa_IR) |  |
|
||||
| Polish (Polski) (pl_PL) |  |
|
||||
| Portuguese (Português) (pt_PT) |  |
|
||||
| Portuguese Brazilian (Português) (pt_BR) |  |
|
||||
| Portuguese Brazilian (Português) (pt_BR) |  |
|
||||
| Romanian (Română) (ro_RO) |  |
|
||||
| Russian (Русский) (ru_RU) |  |
|
||||
| Russian (Русский) (ru_RU) |  |
|
||||
| Serbian Latin alphabet (Srpski) (sr_LATN_RS) |  |
|
||||
| Simplified Chinese (简体中文) (zh_CN) |  |
|
||||
| Slovakian (Slovensky) (sk_SK) |  |
|
||||
| Slovenian (Slovenščina) (sl_SI) |  |
|
||||
| Spanish (Español) (es_ES) |  |
|
||||
| Slovenian (Slovenščina) (sl_SI) |  |
|
||||
| Spanish (Español) (es_ES) |  |
|
||||
| Swedish (Svenska) (sv_SE) |  |
|
||||
| Thai (ไทย) (th_TH) |  |
|
||||
| Tibetan (བོད་ཡིག་) (zh_BO) |  |
|
||||
| Tibetan (བོད་ཡིག་) (zh_BO) |  |
|
||||
| Traditional Chinese (繁體中文) (zh_TW) |  |
|
||||
| Turkish (Türkçe) (tr_TR) |  |
|
||||
| Ukrainian (Українська) (uk_UA) |  |
|
||||
| Vietnamese (Tiếng Việt) (vi_VN) |  |
|
||||
| Turkish (Türkçe) (tr_TR) |  |
|
||||
| Ukrainian (Українська) (uk_UA) |  |
|
||||
| Vietnamese (Tiếng Việt) (vi_VN) |  |
|
||||
|
||||
|
||||
## Stirling PDF Enterprise
|
||||
|
91
build.gradle
91
build.gradle
@ -1,6 +1,6 @@
|
||||
plugins {
|
||||
id "java"
|
||||
id "org.springframework.boot" version "3.4.4"
|
||||
id "org.springframework.boot" version "3.4.5"
|
||||
id "io.spring.dependency-management" version "1.1.7"
|
||||
id "org.springdoc.openapi-gradle-plugin" version "1.9.0"
|
||||
id "io.swagger.swaggerhub" version "1.3.2"
|
||||
@ -18,18 +18,18 @@ import java.nio.file.Files
|
||||
import java.time.Year
|
||||
|
||||
ext {
|
||||
springBootVersion = "3.4.4"
|
||||
pdfboxVersion = "3.0.4"
|
||||
springBootVersion = "3.4.5"
|
||||
pdfboxVersion = "3.0.5"
|
||||
imageioVersion = "3.12.0"
|
||||
lombokVersion = "1.18.38"
|
||||
bouncycastleVersion = "1.80"
|
||||
springSecuritySamlVersion = "6.4.4"
|
||||
springSecuritySamlVersion = "6.4.5"
|
||||
openSamlVersion = "4.3.2"
|
||||
tempJrePath = null
|
||||
}
|
||||
|
||||
group = "stirling.software"
|
||||
version = "0.45.6"
|
||||
version = "0.46.0"
|
||||
|
||||
java {
|
||||
// 17 is lowest but we support and recommend 21
|
||||
@ -51,16 +51,20 @@ sourceSets {
|
||||
main {
|
||||
java {
|
||||
if (System.getenv("DOCKER_ENABLE_SECURITY") == "false") {
|
||||
exclude "stirling/software/SPDF/config/interfaces/DatabaseInterface.java"
|
||||
exclude "stirling/software/SPDF/config/security/**"
|
||||
exclude "stirling/software/SPDF/controller/api/DatabaseController.java"
|
||||
exclude "stirling/software/SPDF/controller/api/UserController.java"
|
||||
exclude "stirling/software/SPDF/controller/api/EmailController.java"
|
||||
exclude "stirling/software/SPDF/controller/api/H2SQLCondition.java"
|
||||
exclude "stirling/software/SPDF/controller/api/UserController.java"
|
||||
exclude "stirling/software/SPDF/controller/web/AccountWebController.java"
|
||||
exclude "stirling/software/SPDF/controller/web/DatabaseWebController.java"
|
||||
exclude "stirling/software/SPDF/model/api/Email.java"
|
||||
exclude "stirling/software/SPDF/model/ApiKeyAuthenticationToken.java"
|
||||
exclude "stirling/software/SPDF/model/AttemptCounter.java"
|
||||
exclude "stirling/software/SPDF/model/Authority.java"
|
||||
exclude "stirling/software/SPDF/model/BackupNotFoundException.java"
|
||||
exclude "stirling/software/SPDF/model/exception/BackupNotFoundException.java"
|
||||
exclude "stirling/software/SPDF/model/exception/NoProviderFoundException.java"
|
||||
exclude "stirling/software/SPDF/model/PersistentLogin.java"
|
||||
exclude "stirling/software/SPDF/model/SessionEntity.java"
|
||||
exclude "stirling/software/SPDF/model/User.java"
|
||||
@ -78,16 +82,8 @@ sourceSets {
|
||||
java {
|
||||
if (System.getenv("DOCKER_ENABLE_SECURITY") == "false") {
|
||||
exclude "stirling/software/SPDF/config/security/**"
|
||||
exclude "stirling/software/SPDF/controller/api/UserControllerTest.java"
|
||||
exclude "stirling/software/SPDF/controller/api/DatabaseControllerTest.java"
|
||||
exclude "stirling/software/SPDF/controller/web/AccountWebControllerTest.java"
|
||||
exclude "stirling/software/SPDF/controller/web/DatabaseWebControllerTest.java"
|
||||
exclude "stirling/software/SPDF/model/ApiKeyAuthenticationTokenTest.java"
|
||||
exclude "stirling/software/SPDF/model/AttemptCounterTest.java"
|
||||
exclude "stirling/software/SPDF/model/AuthorityTest.java"
|
||||
exclude "stirling/software/SPDF/model/PersistentLoginTest.java"
|
||||
exclude "stirling/software/SPDF/model/SessionEntityTest.java"
|
||||
exclude "stirling/software/SPDF/model/UserTest.java"
|
||||
exclude "stirling/software/SPDF/controller/api/EmailControllerTest.java"
|
||||
exclude "stirling/software/SPDF/repository/**"
|
||||
}
|
||||
|
||||
@ -116,10 +112,10 @@ jpackage {
|
||||
input = "build/libs"
|
||||
destination = "${projectDir}/build/jpackage"
|
||||
mainJar = "Stirling-PDF-${project.version}.jar"
|
||||
appName = "Stirling-PDF"
|
||||
appName = "Stirling PDF"
|
||||
appVersion = project.version
|
||||
// appVersion = "2005.45.1"
|
||||
vendor = "Stirling-Software"
|
||||
vendor = "Stirling PDF Inc"
|
||||
appDescription = "Stirling PDF - Your Local PDF Editor"
|
||||
icon = "src/main/resources/static/favicon.ico"
|
||||
verbose = true
|
||||
@ -151,7 +147,7 @@ jpackage {
|
||||
winShortcutPrompt = true // Lets user choose whether to create shortcuts
|
||||
winDirChooser = true // Allows users to choose installation directory
|
||||
winPerUserInstall = false
|
||||
winMenuGroup = "Stirling Software"
|
||||
winMenuGroup = "Stirling PDF"
|
||||
winUpgradeUuid = "2a43ed0c-b8c2-40cf-89e1-751129b87641" // Unique identifier for updates
|
||||
winHelpUrl = "https://github.com/Stirling-Tools/Stirling-PDF"
|
||||
winUpdateUrl = "https://github.com/Stirling-Tools/Stirling-PDF/releases"
|
||||
@ -164,8 +160,8 @@ jpackage {
|
||||
appVersion = getMacVersion(project.version.toString())
|
||||
icon = "src/main/resources/static/favicon.icns"
|
||||
type = "dmg"
|
||||
macPackageIdentifier = "Stirling-PDF"
|
||||
macPackageName = "Stirling-PDF"
|
||||
macPackageIdentifier = "Stirling PDF"
|
||||
macPackageName = "Stirling PDF"
|
||||
macAppCategory = "public.app-category.productivity"
|
||||
macSign = false // Enable signing
|
||||
macAppStore = false // Not targeting App Store initially
|
||||
@ -249,18 +245,32 @@ tasks.register('jpackageMacX64') {
|
||||
|
||||
def result = exec {
|
||||
commandLine 'jpackage',
|
||||
'--type', 'dmg',
|
||||
'--name', 'Stirling-PDF (x86_64)',
|
||||
'--input', 'build/libs',
|
||||
'--main-jar', "Stirling-PDF-${project.version}.jar",
|
||||
'--main-class', 'org.springframework.boot.loader.launch.JarLauncher',
|
||||
'--runtime-image', file(jrePath + "/zulu-17.jre/Contents/Home"),
|
||||
'--dest', 'build/jpackage/x86_64',
|
||||
'--icon', 'src/main/resources/static/favicon.icns',
|
||||
'--app-version', getMacVersion(project.version.toString()),
|
||||
'--mac-package-name', 'Stirling-PDF (x86_64)',
|
||||
'--mac-package-identifier', 'Stirling-PDF (x86_64)',
|
||||
'--mac-app-category', 'public.app-category.productivity'
|
||||
'--type', 'dmg',
|
||||
'--name', 'Stirling PDF (x86_64)',
|
||||
'--input', 'build/libs',
|
||||
'--main-jar', "Stirling-PDF-${project.version}.jar",
|
||||
'--main-class', 'org.springframework.boot.loader.launch.JarLauncher',
|
||||
'--runtime-image', file(jrePath + "/zulu-17.jre/Contents/Home"),
|
||||
'--dest', 'build/jpackage/x86_64',
|
||||
'--icon', 'src/main/resources/static/favicon.icns',
|
||||
'--app-version', getMacVersion(project.version.toString()),
|
||||
'--mac-package-name', 'Stirling PDF (x86_64)',
|
||||
'--mac-package-identifier', 'Stirling PDF (x86_64)',
|
||||
'--mac-app-category', 'public.app-category.productivity',
|
||||
|
||||
// Java options
|
||||
'--java-options', '-DBROWSER_OPEN=true',
|
||||
'--java-options', '-DSTIRLING_PDF_DESKTOP_UI=true',
|
||||
'--java-options', '-Djava.awt.headless=false',
|
||||
'--java-options', '-Dapple.awt.UIElement=true',
|
||||
'--java-options', '--add-opens=java.base/java.lang=ALL-UNNAMED',
|
||||
'--java-options', '--add-opens=java.desktop/java.awt.event=ALL-UNNAMED',
|
||||
'--java-options', '--add-opens=java.desktop/sun.awt=ALL-UNNAMED',
|
||||
'--java-options', '--add-opens=java.desktop/sun.awt.X11=ALL-UNNAMED',
|
||||
'--java-options', '--add-opens=java.desktop/sun.awt.windows=ALL-UNNAMED',
|
||||
'--java-options', '--add-opens=java.desktop/sun.lwawt=ALL-UNNAMED',
|
||||
'--java-options', '--add-opens=java.desktop/sun.lwawt.macosx=ALL-UNNAMED'
|
||||
|
||||
standardOutput = outputStream
|
||||
errorOutput = errorStream
|
||||
ignoreExitValue = true
|
||||
@ -390,7 +400,7 @@ sonar {
|
||||
// rules=['unused-dependency']
|
||||
// }
|
||||
tasks.wrapper {
|
||||
gradleVersion = "8.12"
|
||||
gradleVersion = "8.14"
|
||||
distributionType = Wrapper.DistributionType.ALL
|
||||
}
|
||||
//tasks.withType(JavaCompile) {
|
||||
@ -423,7 +433,7 @@ dependencies {
|
||||
}
|
||||
|
||||
//security updates
|
||||
implementation "org.springframework:spring-webmvc:6.2.5"
|
||||
implementation "org.springframework:spring-webmvc:6.2.6"
|
||||
|
||||
implementation("io.github.pixee:java-security-toolkit:1.2.1")
|
||||
|
||||
@ -445,9 +455,10 @@ dependencies {
|
||||
implementation "org.thymeleaf.extras:thymeleaf-extras-springsecurity5:3.1.3.RELEASE"
|
||||
implementation "org.springframework.boot:spring-boot-starter-data-jpa:$springBootVersion"
|
||||
implementation "org.springframework.boot:spring-boot-starter-oauth2-client:$springBootVersion"
|
||||
implementation "org.springframework.boot:spring-boot-starter-mail:$springBootVersion"
|
||||
|
||||
implementation "org.springframework.session:spring-session-core:3.4.2"
|
||||
implementation "org.springframework:spring-jdbc:6.2.5"
|
||||
implementation "org.springframework.session:spring-session-core:3.4.3"
|
||||
implementation "org.springframework:spring-jdbc:6.2.6"
|
||||
|
||||
implementation 'com.unboundid.product.scim2:scim2-sdk-client:2.3.5'
|
||||
// Don't upgrade h2database
|
||||
@ -492,11 +503,11 @@ dependencies {
|
||||
implementation "com.drewnoakes:metadata-extractor:2.19.0"
|
||||
|
||||
implementation "commons-io:commons-io:2.19.0"
|
||||
implementation "org.springdoc:springdoc-openapi-starter-webmvc-ui:2.2.0"
|
||||
implementation "org.springdoc:springdoc-openapi-starter-webmvc-ui:2.8.8"
|
||||
//general PDF
|
||||
|
||||
// https://mvnrepository.com/artifact/com.opencsv/opencsv
|
||||
implementation ("com.opencsv:opencsv:5.10")
|
||||
implementation ("com.opencsv:opencsv:5.11")
|
||||
|
||||
implementation ("org.apache.pdfbox:pdfbox:$pdfboxVersion")
|
||||
implementation "org.apache.pdfbox:preflight:$pdfboxVersion"
|
||||
@ -523,7 +534,7 @@ dependencies {
|
||||
implementation "org.commonmark:commonmark-ext-gfm-tables:0.24.0"
|
||||
// https://mvnrepository.com/artifact/com.bucket4j/bucket4j_jdk17
|
||||
implementation "com.bucket4j:bucket4j_jdk17-core:8.14.0"
|
||||
implementation "com.fathzer:javaluator:3.0.5"
|
||||
implementation "com.fathzer:javaluator:3.0.6"
|
||||
|
||||
implementation 'com.vladsch.flexmark:flexmark-html2md-converter:0.64.8'
|
||||
|
||||
|
@ -32,4 +32,5 @@ services:
|
||||
SYSTEM_MAXFILESIZE: "100"
|
||||
METRICS_ENABLED: "true"
|
||||
SYSTEM_GOOGLEVISIBILITY: "true"
|
||||
SHOW_SURVEY: "true"
|
||||
restart: on-failure:5
|
||||
|
@ -36,6 +36,7 @@ services:
|
||||
SYSTEM_DATASOURCE_CUSTOMDATABASEURL: "jdbc:postgresql://db:5432/stirling_pdf"
|
||||
SYSTEM_DATASOURCE_USERNAME: "admin"
|
||||
SYSTEM_DATASOURCE_PASSWORD: "stirling"
|
||||
SHOW_SURVEY: "true"
|
||||
restart: on-failure:5
|
||||
|
||||
db:
|
||||
|
@ -30,4 +30,5 @@ services:
|
||||
SYSTEM_MAXFILESIZE: "100"
|
||||
METRICS_ENABLED: "true"
|
||||
SYSTEM_GOOGLEVISIBILITY: "true"
|
||||
SHOW_SURVEY: "true"
|
||||
restart: on-failure:5
|
||||
|
@ -38,4 +38,5 @@ services:
|
||||
SYSTEM_MAXFILESIZE: "100"
|
||||
METRICS_ENABLED: "true"
|
||||
SYSTEM_GOOGLEVISIBILITY: "true"
|
||||
SHOW_SURVEY: "true"
|
||||
restart: on-failure:5
|
||||
|
@ -30,4 +30,5 @@ services:
|
||||
SYSTEM_MAXFILESIZE: "100"
|
||||
METRICS_ENABLED: "true"
|
||||
SYSTEM_GOOGLEVISIBILITY: "true"
|
||||
SHOW_SURVEY: "true"
|
||||
restart: on-failure:5
|
||||
|
@ -27,4 +27,5 @@ services:
|
||||
SYSTEM_MAXFILESIZE: "100"
|
||||
METRICS_ENABLED: "true"
|
||||
SYSTEM_GOOGLEVISIBILITY: "true"
|
||||
SHOW_SURVEY: "true"
|
||||
restart: on-failure:5
|
||||
|
@ -26,4 +26,5 @@ services:
|
||||
SYSTEM_MAXFILESIZE: "100"
|
||||
METRICS_ENABLED: "true"
|
||||
SYSTEM_GOOGLEVISIBILITY: "true"
|
||||
SHOW_SURVEY: "true"
|
||||
restart: on-failure:5
|
||||
|
@ -28,4 +28,5 @@ services:
|
||||
SYSTEM_MAXFILESIZE: "100"
|
||||
METRICS_ENABLED: "true"
|
||||
SYSTEM_GOOGLEVISIBILITY: "true"
|
||||
SHOW_SURVEY: "true"
|
||||
restart: on-failure:5
|
||||
|
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Binary file not shown.
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@ -1,6 +1,6 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-all.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14-all.zip
|
||||
networkTimeout=10000
|
||||
validateDistributionUrl=true
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
|
6
gradlew
vendored
6
gradlew
vendored
@ -114,7 +114,7 @@ case "$( uname )" in #(
|
||||
NONSTOP* ) nonstop=true ;;
|
||||
esac
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
CLASSPATH="\\\"\\\""
|
||||
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
@ -205,7 +205,7 @@ fi
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
|
||||
# Collect all arguments for the java command:
|
||||
# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
|
||||
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
|
||||
# and any embedded shellness will be escaped.
|
||||
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
|
||||
# treated as '${Hostname}' itself on the command line.
|
||||
@ -213,7 +213,7 @@ DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
set -- \
|
||||
"-Dorg.gradle.appname=$APP_BASE_NAME" \
|
||||
-classpath "$CLASSPATH" \
|
||||
org.gradle.wrapper.GradleWrapperMain \
|
||||
-jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \
|
||||
"$@"
|
||||
|
||||
# Stop when "xargs" is not available.
|
||||
|
4
gradlew.bat
vendored
4
gradlew.bat
vendored
@ -70,11 +70,11 @@ goto fail
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
set CLASSPATH=
|
||||
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %*
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
|
@ -56,6 +56,9 @@ ignore = [
|
||||
'validateSignature.cert.version',
|
||||
'validateSignature.status',
|
||||
'watermark.type.1',
|
||||
'endpointStatistics.top10',
|
||||
'endpointStatistics.top20',
|
||||
'cookieBanner.popUp.acceptAllBtn',
|
||||
]
|
||||
|
||||
[el_GR]
|
||||
|
@ -1 +1,5 @@
|
||||
plugins {
|
||||
// Apply the foojay-resolver plugin to allow automatic download of JDKs
|
||||
id 'org.gradle.toolchains.foojay-resolver-convention' version '0.10.0'
|
||||
}
|
||||
rootProject.name = 'Stirling-PDF'
|
||||
|
@ -9,7 +9,6 @@ import java.util.Base64;
|
||||
import org.bouncycastle.crypto.params.Ed25519PublicKeyParameters;
|
||||
import org.bouncycastle.crypto.signers.Ed25519Signer;
|
||||
import org.bouncycastle.util.encoders.Hex;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
@ -17,6 +16,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.posthog.java.shaded.org.json.JSONException;
|
||||
import com.posthog.java.shaded.org.json.JSONObject;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import stirling.software.SPDF.model.ApplicationProperties;
|
||||
@ -24,6 +24,7 @@ import stirling.software.SPDF.utils.GeneralUtils;
|
||||
|
||||
@Service
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
public class KeygenLicenseVerifier {
|
||||
|
||||
enum License {
|
||||
@ -47,40 +48,35 @@ public class KeygenLicenseVerifier {
|
||||
private static final ObjectMapper objectMapper = new ObjectMapper();
|
||||
private final ApplicationProperties applicationProperties;
|
||||
|
||||
@Autowired
|
||||
public KeygenLicenseVerifier(ApplicationProperties applicationProperties) {
|
||||
this.applicationProperties = applicationProperties;
|
||||
}
|
||||
|
||||
public License verifyLicense(String licenseKeyOrCert) {
|
||||
License license;
|
||||
License license;
|
||||
|
||||
if (isCertificateLicense(licenseKeyOrCert)) {
|
||||
log.info("Detected certificate-based license. Processing...");
|
||||
boolean isValid = verifyCertificateLicense(licenseKeyOrCert);
|
||||
if (isValid) {
|
||||
license = isEnterpriseLicense ? License.ENTERPRISE : License.PRO;
|
||||
} else {
|
||||
license = License.NORMAL;
|
||||
}
|
||||
} else if (isJWTLicense(licenseKeyOrCert)) {
|
||||
log.info("Detected JWT-style license key. Processing...");
|
||||
boolean isValid = verifyJWTLicense(licenseKeyOrCert);
|
||||
if (isValid) {
|
||||
license = isEnterpriseLicense ? License.ENTERPRISE : License.PRO;
|
||||
} else {
|
||||
license = License.NORMAL;
|
||||
}
|
||||
} else {
|
||||
log.info("Detected standard license key. Processing...");
|
||||
boolean isValid = verifyStandardLicense(licenseKeyOrCert);
|
||||
if (isValid) {
|
||||
license = isEnterpriseLicense ? License.ENTERPRISE : License.PRO;
|
||||
} else {
|
||||
license = License.NORMAL;
|
||||
}
|
||||
}
|
||||
return license;
|
||||
if (isCertificateLicense(licenseKeyOrCert)) {
|
||||
log.info("Detected certificate-based license. Processing...");
|
||||
boolean isValid = verifyCertificateLicense(licenseKeyOrCert);
|
||||
if (isValid) {
|
||||
license = isEnterpriseLicense ? License.ENTERPRISE : License.PRO;
|
||||
} else {
|
||||
license = License.NORMAL;
|
||||
}
|
||||
} else if (isJWTLicense(licenseKeyOrCert)) {
|
||||
log.info("Detected JWT-style license key. Processing...");
|
||||
boolean isValid = verifyJWTLicense(licenseKeyOrCert);
|
||||
if (isValid) {
|
||||
license = isEnterpriseLicense ? License.ENTERPRISE : License.PRO;
|
||||
} else {
|
||||
license = License.NORMAL;
|
||||
}
|
||||
} else {
|
||||
log.info("Detected standard license key. Processing...");
|
||||
boolean isValid = verifyStandardLicense(licenseKeyOrCert);
|
||||
if (isValid) {
|
||||
license = isEnterpriseLicense ? License.ENTERPRISE : License.PRO;
|
||||
} else {
|
||||
license = License.NORMAL;
|
||||
}
|
||||
}
|
||||
return license;
|
||||
}
|
||||
|
||||
private boolean isEnterpriseLicense = false;
|
||||
@ -123,7 +119,7 @@ public class KeygenLicenseVerifier {
|
||||
}
|
||||
|
||||
// Verify license file algorithm
|
||||
if (!algorithm.equals("base64+ed25519")) {
|
||||
if (!"base64+ed25519".equals(algorithm)) {
|
||||
log.error(
|
||||
"Unsupported algorithm: {}. Only base64+ed25519 is supported.", algorithm);
|
||||
return false;
|
||||
@ -193,8 +189,6 @@ public class KeygenLicenseVerifier {
|
||||
|
||||
private boolean processCertificateData(String certData) {
|
||||
try {
|
||||
|
||||
|
||||
JSONObject licenseData = new JSONObject(certData);
|
||||
JSONObject metaObj = licenseData.optJSONObject("meta");
|
||||
if (metaObj != null) {
|
||||
@ -208,7 +202,8 @@ public class KeygenLicenseVerifier {
|
||||
|
||||
if (issued.isAfter(now)) {
|
||||
log.error(
|
||||
"License file issued date is in the future. Please adjust system time or request a new license");
|
||||
"License file issued date is in the future. Please adjust system"
|
||||
+ " time or request a new license");
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -248,8 +243,8 @@ public class KeygenLicenseVerifier {
|
||||
// Check license status if available
|
||||
String status = attributesObj.optString("status", null);
|
||||
if (status != null
|
||||
&& !status.equals("ACTIVE")
|
||||
&& !status.equals("EXPIRING")) { // Accept "EXPIRING" status as valid
|
||||
&& !"ACTIVE".equals(status)
|
||||
&& !"EXPIRING".equals(status)) { // Accept "EXPIRING" status as valid
|
||||
log.error("License status is not active: {}", status);
|
||||
return false;
|
||||
}
|
||||
@ -273,7 +268,8 @@ public class KeygenLicenseVerifier {
|
||||
String[] parts = licenseData.split("\\.", 2);
|
||||
if (parts.length != 2) {
|
||||
log.error(
|
||||
"Invalid ED25519_SIGN license format. Expected format: key/payload.signature");
|
||||
"Invalid ED25519_SIGN license format. Expected format:"
|
||||
+ " key/payload.signature");
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -354,7 +350,7 @@ public class KeygenLicenseVerifier {
|
||||
|
||||
// Check expiry date
|
||||
String expiryStr = licenseObj.optString("expiry", null);
|
||||
if (expiryStr != null && !expiryStr.equals("null")) {
|
||||
if (expiryStr != null && !"null".equals(expiryStr)) {
|
||||
java.time.Instant expiry = java.time.Instant.parse(expiryStr);
|
||||
java.time.Instant now = java.time.Instant.now();
|
||||
|
||||
@ -390,19 +386,18 @@ public class KeygenLicenseVerifier {
|
||||
// Extract max users and isEnterprise from policy or metadata
|
||||
int users = policyObj.optInt("users", 0);
|
||||
isEnterpriseLicense = policyObj.optBoolean("isEnterprise", false);
|
||||
|
||||
|
||||
if (users > 0) {
|
||||
applicationProperties.getPremium().setMaxUsers(users);
|
||||
log.info("License allows for {} users", users);
|
||||
} else {
|
||||
// Try to get users from metadata if present
|
||||
Object metadataObj = policyObj.opt("metadata");
|
||||
if (metadataObj instanceof JSONObject) {
|
||||
JSONObject metadata = (JSONObject) metadataObj;
|
||||
if (metadataObj instanceof JSONObject metadata) {
|
||||
users = metadata.optInt("users", 1);
|
||||
applicationProperties.getPremium().setMaxUsers(users);
|
||||
log.info("License allows for {} users (from metadata)", users);
|
||||
|
||||
|
||||
// Check for isEnterprise flag in metadata
|
||||
isEnterpriseLicense = metadata.optBoolean("isEnterprise", false);
|
||||
} else {
|
||||
@ -411,7 +406,6 @@ public class KeygenLicenseVerifier {
|
||||
log.info("Using default of 1 user for license");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -438,7 +432,8 @@ public class KeygenLicenseVerifier {
|
||||
|| "NO_MACHINES".equals(code)
|
||||
|| "FINGERPRINT_SCOPE_MISMATCH".equals(code)) {
|
||||
log.info(
|
||||
"License not activated for this machine. Attempting to activate...");
|
||||
"License not activated for this machine. Attempting to"
|
||||
+ " activate...");
|
||||
boolean activated =
|
||||
activateMachine(licenseKey, licenseId, machineFingerprint);
|
||||
if (activated) {
|
||||
@ -507,16 +502,16 @@ public class KeygenLicenseVerifier {
|
||||
.path("users")
|
||||
.asInt(0);
|
||||
applicationProperties.getPremium().setMaxUsers(users);
|
||||
|
||||
|
||||
// Extract isEnterprise flag
|
||||
isEnterpriseLicense =
|
||||
isEnterpriseLicense =
|
||||
jsonResponse
|
||||
.path("data")
|
||||
.path("attributes")
|
||||
.path("metadata")
|
||||
.path("isEnterprise")
|
||||
.asBoolean(false);
|
||||
|
||||
|
||||
log.info(applicationProperties.toString());
|
||||
|
||||
} else {
|
||||
|
@ -5,7 +5,6 @@ import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@ -27,7 +26,6 @@ public class LicenseKeyChecker {
|
||||
|
||||
private License premiumEnabledResult = License.NORMAL;
|
||||
|
||||
@Autowired
|
||||
public LicenseKeyChecker(
|
||||
KeygenLicenseVerifier licenseService, ApplicationProperties applicationProperties) {
|
||||
this.licenseService = licenseService;
|
||||
|
@ -20,8 +20,7 @@ import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.io.ResourceLoader;
|
||||
import org.thymeleaf.spring6.SpringTemplateEngine;
|
||||
|
||||
import com.posthog.java.shaded.kotlin.text.Regex;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import stirling.software.SPDF.model.ApplicationProperties;
|
||||
@ -29,14 +28,11 @@ import stirling.software.SPDF.model.ApplicationProperties;
|
||||
@Configuration
|
||||
@Lazy
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
public class AppConfig {
|
||||
|
||||
private final ApplicationProperties applicationProperties;
|
||||
|
||||
public AppConfig(ApplicationProperties applicationProperties) {
|
||||
this.applicationProperties = applicationProperties;
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnProperty(name = "system.customHTMLFiles", havingValue = "true")
|
||||
public SpringTemplateEngine templateEngine(ResourceLoader resourceLoader) {
|
||||
|
@ -6,7 +6,6 @@ import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@ -24,7 +23,6 @@ public class EndpointConfiguration {
|
||||
private Map<String, Set<String>> endpointGroups = new ConcurrentHashMap<>();
|
||||
private final boolean runningProOrHigher;
|
||||
|
||||
@Autowired
|
||||
public EndpointConfiguration(
|
||||
ApplicationProperties applicationProperties,
|
||||
@Qualifier("runningProOrHigher") boolean runningProOrHigher) {
|
||||
@ -166,6 +164,7 @@ public class EndpointConfiguration {
|
||||
addEndpointToGroup("Other", "sign");
|
||||
addEndpointToGroup("Other", "flatten");
|
||||
addEndpointToGroup("Other", "repair");
|
||||
addEndpointToGroup("Other", "unlock-pdf-forms");
|
||||
addEndpointToGroup("Other", REMOVE_BLANKS);
|
||||
addEndpointToGroup("Other", "remove-annotations");
|
||||
addEndpointToGroup("Other", "compare");
|
||||
|
@ -8,7 +8,6 @@ import java.util.TreeSet;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.context.event.ContextRefreshedEvent;
|
||||
@ -18,7 +17,10 @@ import org.springframework.web.method.HandlerMethod;
|
||||
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class EndpointInspector implements ApplicationListener<ContextRefreshedEvent> {
|
||||
private static final Logger logger = LoggerFactory.getLogger(EndpointInspector.class);
|
||||
|
||||
@ -26,11 +28,6 @@ public class EndpointInspector implements ApplicationListener<ContextRefreshedEv
|
||||
private final Set<String> validGetEndpoints = new HashSet<>();
|
||||
private boolean endpointsDiscovered = false;
|
||||
|
||||
@Autowired
|
||||
public EndpointInspector(ApplicationContext applicationContext) {
|
||||
this.applicationContext = applicationContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onApplicationEvent(ContextRefreshedEvent event) {
|
||||
if (!endpointsDiscovered) {
|
||||
|
@ -6,18 +6,16 @@ import org.springframework.web.servlet.HandlerInterceptor;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
public class EndpointInterceptor implements HandlerInterceptor {
|
||||
|
||||
private final EndpointConfiguration endpointConfiguration;
|
||||
|
||||
public EndpointInterceptor(EndpointConfiguration endpointConfiguration) {
|
||||
this.endpointConfiguration = endpointConfiguration;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean preHandle(
|
||||
HttpServletRequest request, HttpServletResponse response, Object handler)
|
||||
|
@ -14,6 +14,7 @@ import io.micrometer.common.util.StringUtils;
|
||||
|
||||
import jakarta.annotation.PostConstruct;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import stirling.software.SPDF.model.ApplicationProperties;
|
||||
@ -22,14 +23,11 @@ import stirling.software.SPDF.utils.GeneralUtils;
|
||||
@Component
|
||||
@Slf4j
|
||||
@Order(Ordered.HIGHEST_PRECEDENCE + 1)
|
||||
@RequiredArgsConstructor
|
||||
public class InitialSetup {
|
||||
|
||||
private final ApplicationProperties applicationProperties;
|
||||
|
||||
public InitialSetup(ApplicationProperties applicationProperties) {
|
||||
this.applicationProperties = applicationProperties;
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
public void init() throws IOException {
|
||||
initUUIDKey();
|
||||
|
@ -10,17 +10,16 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;
|
||||
import org.springframework.web.servlet.i18n.SessionLocaleResolver;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import stirling.software.SPDF.model.ApplicationProperties;
|
||||
|
||||
@Configuration
|
||||
@RequiredArgsConstructor
|
||||
public class LocaleConfiguration implements WebMvcConfigurer {
|
||||
|
||||
private final ApplicationProperties applicationProperties;
|
||||
|
||||
public LocaleConfiguration(ApplicationProperties applicationProperties) {
|
||||
this.applicationProperties = applicationProperties;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addInterceptors(InterceptorRegistry registry) {
|
||||
registry.addInterceptor(localeChangeInterceptor());
|
||||
@ -52,7 +51,7 @@ public class LocaleConfiguration implements WebMvcConfigurer {
|
||||
defaultLocale = tempLocale;
|
||||
} else {
|
||||
System.err.println(
|
||||
"Invalid APP_LOCALE environment variable value. Falling back to default Locale.UK.");
|
||||
"Invalid SYSTEM_DEFAULTLOCALE environment variable value. Falling back to default en-GB.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,6 @@ package stirling.software.SPDF.config;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.filter.OncePerRequestFilter;
|
||||
|
||||
@ -15,18 +14,16 @@ import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import jakarta.servlet.http.HttpSession;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import stirling.software.SPDF.utils.RequestUriUtils;
|
||||
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class MetricsFilter extends OncePerRequestFilter {
|
||||
|
||||
private final MeterRegistry meterRegistry;
|
||||
|
||||
@Autowired
|
||||
public MetricsFilter(MeterRegistry meterRegistry) {
|
||||
this.meterRegistry = meterRegistry;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doFilterInternal(
|
||||
HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
|
||||
|
@ -9,16 +9,20 @@ import io.swagger.v3.oas.models.info.Info;
|
||||
import io.swagger.v3.oas.models.security.SecurityRequirement;
|
||||
import io.swagger.v3.oas.models.security.SecurityScheme;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import stirling.software.SPDF.model.ApplicationProperties;
|
||||
|
||||
@Configuration
|
||||
@RequiredArgsConstructor
|
||||
public class OpenApiConfig {
|
||||
|
||||
private final ApplicationProperties applicationProperties;
|
||||
|
||||
public OpenApiConfig(ApplicationProperties applicationProperties) {
|
||||
this.applicationProperties = applicationProperties;
|
||||
}
|
||||
private static final String DEFAULT_TITLE = "Stirling PDF API";
|
||||
private static final String DEFAULT_DESCRIPTION =
|
||||
"API documentation for all Server-Side processing.\n"
|
||||
+ "Please note some functionality might be UI only and missing from here.";
|
||||
|
||||
@Bean
|
||||
public OpenAPI customOpenAPI() {
|
||||
@ -27,29 +31,27 @@ public class OpenApiConfig {
|
||||
// default version if all else fails
|
||||
version = "1.0.0";
|
||||
}
|
||||
SecurityScheme apiKeyScheme =
|
||||
new SecurityScheme()
|
||||
.type(SecurityScheme.Type.APIKEY)
|
||||
.in(SecurityScheme.In.HEADER)
|
||||
.name("X-API-KEY");
|
||||
if (!applicationProperties.getSecurity().getEnableLogin()) {
|
||||
return new OpenAPI()
|
||||
.components(new Components())
|
||||
.info(
|
||||
new Info()
|
||||
.title("Stirling PDF API")
|
||||
.title(DEFAULT_TITLE)
|
||||
.version(version)
|
||||
.description(
|
||||
"API documentation for all Server-Side processing.\nPlease note some functionality might be UI only and missing from here."));
|
||||
.description(DEFAULT_DESCRIPTION));
|
||||
} else {
|
||||
SecurityScheme apiKeyScheme =
|
||||
new SecurityScheme()
|
||||
.type(SecurityScheme.Type.APIKEY)
|
||||
.in(SecurityScheme.In.HEADER)
|
||||
.name("X-API-KEY");
|
||||
return new OpenAPI()
|
||||
.components(new Components().addSecuritySchemes("apiKey", apiKeyScheme))
|
||||
.info(
|
||||
new Info()
|
||||
.title("Stirling PDF API")
|
||||
.title(DEFAULT_TITLE)
|
||||
.version(version)
|
||||
.description(
|
||||
"API documentation for all Server-Side processing.\nPlease note some functionality might be UI only and missing from here."))
|
||||
.description(DEFAULT_DESCRIPTION))
|
||||
.addSecurityItem(new SecurityRequirement().addList("apiKey"));
|
||||
}
|
||||
}
|
||||
|
@ -5,15 +5,14 @@ import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
@Configuration
|
||||
@RequiredArgsConstructor
|
||||
public class WebMvcConfig implements WebMvcConfigurer {
|
||||
|
||||
private final EndpointInterceptor endpointInterceptor;
|
||||
|
||||
public WebMvcConfig(EndpointInterceptor endpointInterceptor) {
|
||||
this.endpointInterceptor = endpointInterceptor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addInterceptors(InterceptorRegistry registry) {
|
||||
registry.addInterceptor(endpointInterceptor);
|
||||
|
@ -6,24 +6,21 @@ import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import stirling.software.SPDF.config.interfaces.ShowAdminInterface;
|
||||
import stirling.software.SPDF.model.ApplicationProperties;
|
||||
import stirling.software.SPDF.model.User;
|
||||
import stirling.software.SPDF.repository.UserRepository;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
class AppUpdateAuthService implements ShowAdminInterface {
|
||||
|
||||
private final UserRepository userRepository;
|
||||
|
||||
private final ApplicationProperties applicationProperties;
|
||||
|
||||
public AppUpdateAuthService(
|
||||
UserRepository userRepository, ApplicationProperties applicationProperties) {
|
||||
this.userRepository = userRepository;
|
||||
this.applicationProperties = applicationProperties;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getShowUpdateOnlyAdmins() {
|
||||
boolean showUpdate = applicationProperties.getSystem().isShowUpdate();
|
||||
@ -35,7 +32,7 @@ class AppUpdateAuthService implements ShowAdminInterface {
|
||||
if (authentication == null || !authentication.isAuthenticated()) {
|
||||
return !showUpdateOnlyAdmin;
|
||||
}
|
||||
if (authentication.getName().equalsIgnoreCase("anonymousUser")) {
|
||||
if ("anonymousUser".equalsIgnoreCase(authentication.getName())) {
|
||||
return !showUpdateOnlyAdmin;
|
||||
}
|
||||
Optional<User> user = userRepository.findByUsername(authentication.getName());
|
||||
|
@ -19,7 +19,7 @@ import com.coveo.saml.SamlException;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import stirling.software.SPDF.SPDFApplication;
|
||||
@ -32,7 +32,7 @@ import stirling.software.SPDF.model.provider.KeycloakProvider;
|
||||
import stirling.software.SPDF.utils.UrlUtils;
|
||||
|
||||
@Slf4j
|
||||
@AllArgsConstructor
|
||||
@RequiredArgsConstructor
|
||||
public class CustomLogoutSuccessHandler extends SimpleUrlLogoutSuccessHandler {
|
||||
|
||||
public static final String LOGOUT_PATH = "/login?logout=true";
|
||||
|
@ -11,23 +11,20 @@ import org.springframework.security.core.userdetails.UserDetailsService;
|
||||
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import stirling.software.SPDF.model.Authority;
|
||||
import stirling.software.SPDF.model.User;
|
||||
import stirling.software.SPDF.repository.UserRepository;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class CustomUserDetailsService implements UserDetailsService {
|
||||
|
||||
private final UserRepository userRepository;
|
||||
|
||||
private final LoginAttemptService loginAttemptService;
|
||||
|
||||
public CustomUserDetailsService(
|
||||
UserRepository userRepository, LoginAttemptService loginAttemptService) {
|
||||
this.userRepository = userRepository;
|
||||
this.loginAttemptService = loginAttemptService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
|
||||
User user =
|
||||
|
@ -7,8 +7,11 @@ import java.util.concurrent.atomic.AtomicInteger;
|
||||
import jakarta.servlet.*;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import stirling.software.SPDF.utils.RequestUriUtils;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public class IPRateLimitingFilter implements Filter {
|
||||
|
||||
private final ConcurrentHashMap<String, AtomicInteger> requestCounts =
|
||||
@ -17,11 +20,6 @@ public class IPRateLimitingFilter implements Filter {
|
||||
private final int maxRequests;
|
||||
private final int maxGetRequests;
|
||||
|
||||
public IPRateLimitingFilter(int maxRequests, int maxGetRequests) {
|
||||
this.maxRequests = maxRequests;
|
||||
this.maxGetRequests = maxGetRequests;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
|
||||
throws IOException, ServletException {
|
||||
|
@ -7,6 +7,7 @@ import org.springframework.stereotype.Component;
|
||||
|
||||
import jakarta.annotation.PostConstruct;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import stirling.software.SPDF.config.interfaces.DatabaseInterface;
|
||||
@ -16,6 +17,7 @@ import stirling.software.SPDF.model.exception.UnsupportedProviderException;
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class InitialSecuritySetup {
|
||||
|
||||
private final UserService userService;
|
||||
@ -24,15 +26,6 @@ public class InitialSecuritySetup {
|
||||
|
||||
private final DatabaseInterface databaseService;
|
||||
|
||||
public InitialSecuritySetup(
|
||||
UserService userService,
|
||||
ApplicationProperties applicationProperties,
|
||||
DatabaseInterface databaseService) {
|
||||
this.userService = userService;
|
||||
this.applicationProperties = applicationProperties;
|
||||
this.databaseService = databaseService;
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
try {
|
||||
|
@ -7,6 +7,7 @@ import org.springframework.stereotype.Service;
|
||||
|
||||
import jakarta.annotation.PostConstruct;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import stirling.software.SPDF.model.ApplicationProperties;
|
||||
@ -14,6 +15,7 @@ import stirling.software.SPDF.model.AttemptCounter;
|
||||
|
||||
@Service
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
public class LoginAttemptService {
|
||||
|
||||
private final ApplicationProperties applicationProperties;
|
||||
@ -26,10 +28,6 @@ public class LoginAttemptService {
|
||||
|
||||
private boolean isBlockedEnabled = true;
|
||||
|
||||
public LoginAttemptService(ApplicationProperties applicationProperties) {
|
||||
this.applicationProperties = applicationProperties;
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
MAX_ATTEMPT = applicationProperties.getSecurity().getLoginAttemptCount();
|
||||
|
@ -3,15 +3,14 @@ package stirling.software.SPDF.config.security;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class RateLimitResetScheduler {
|
||||
|
||||
private final IPRateLimitingFilter rateLimitingFilter;
|
||||
|
||||
public RateLimitResetScheduler(IPRateLimitingFilter rateLimitingFilter) {
|
||||
this.rateLimitingFilter = rateLimitingFilter;
|
||||
}
|
||||
|
||||
@Scheduled(cron = "0 0 0 * * MON") // At 00:00 every Monday TODO: configurable
|
||||
public void resetRateLimit() {
|
||||
rateLimitingFilter.resetRequestCounts();
|
||||
|
@ -121,7 +121,7 @@ public class UserBasedRateLimitingFilter extends OncePerRequestFilter {
|
||||
if (probe.isConsumed()) {
|
||||
response.setHeader(
|
||||
"X-Rate-Limit-Remaining",
|
||||
Newlines.stripAll(Long.toString(probe.getRemainingTokens())));
|
||||
stripNewlines(Newlines.stripAll(Long.toString(probe.getRemainingTokens()))));
|
||||
filterChain.doFilter(request, response);
|
||||
} else {
|
||||
long waitForRefill = probe.getNanosToWaitForRefill() / 1_000_000_000;
|
||||
@ -141,4 +141,8 @@ public class UserBasedRateLimitingFilter extends OncePerRequestFilter {
|
||||
.build();
|
||||
return Bucket.builder().addLimit(limit).build();
|
||||
}
|
||||
|
||||
private static String stripNewlines(final String s) {
|
||||
return s.replaceAll("[\n\r]", "");
|
||||
}
|
||||
}
|
||||
|
@ -19,6 +19,7 @@ import org.springframework.security.oauth2.core.user.OAuth2User;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import stirling.software.SPDF.config.interfaces.DatabaseInterface;
|
||||
@ -32,6 +33,7 @@ import stirling.software.SPDF.repository.UserRepository;
|
||||
|
||||
@Service
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
public class UserService implements UserServiceInterface {
|
||||
|
||||
private final UserRepository userRepository;
|
||||
@ -48,23 +50,6 @@ public class UserService implements UserServiceInterface {
|
||||
|
||||
private final ApplicationProperties applicationProperties;
|
||||
|
||||
public UserService(
|
||||
UserRepository userRepository,
|
||||
AuthorityRepository authorityRepository,
|
||||
PasswordEncoder passwordEncoder,
|
||||
MessageSource messageSource,
|
||||
SessionPersistentRegistry sessionRegistry,
|
||||
DatabaseInterface databaseService,
|
||||
ApplicationProperties applicationProperties) {
|
||||
this.userRepository = userRepository;
|
||||
this.authorityRepository = authorityRepository;
|
||||
this.passwordEncoder = passwordEncoder;
|
||||
this.messageSource = messageSource;
|
||||
this.sessionRegistry = sessionRegistry;
|
||||
this.databaseService = databaseService;
|
||||
this.applicationProperties = applicationProperties;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void migrateOauth2ToSSO() {
|
||||
userRepository
|
||||
@ -423,6 +408,8 @@ public class UserService implements UserServiceInterface {
|
||||
|
||||
if (principal instanceof UserDetails detailsUser) {
|
||||
return detailsUser.getUsername();
|
||||
} else if (principal instanceof stirling.software.SPDF.model.User domainUser) {
|
||||
return domainUser.getUsername();
|
||||
} else if (principal instanceof OAuth2User oAuth2User) {
|
||||
return oAuth2User.getAttribute(
|
||||
applicationProperties.getSecurity().getOauth2().getUseAsUsername());
|
||||
|
@ -240,8 +240,34 @@ public class DatabaseService implements DatabaseInterface {
|
||||
private boolean isH2Database() {
|
||||
ApplicationProperties.Datasource datasource =
|
||||
applicationProperties.getSystem().getDatasource();
|
||||
return !datasource.isEnableCustomDatabase()
|
||||
|| datasource.getType().equalsIgnoreCase(ApplicationProperties.Driver.H2.name());
|
||||
|
||||
boolean isTypeH2 =
|
||||
datasource.getType().equalsIgnoreCase(ApplicationProperties.Driver.H2.name());
|
||||
boolean isDBUrlH2 =
|
||||
datasource.getCustomDatabaseUrl().contains("h2")
|
||||
|| datasource.getCustomDatabaseUrl().contains("H2");
|
||||
boolean isCustomDatabase = datasource.isEnableCustomDatabase();
|
||||
|
||||
if (isCustomDatabase) {
|
||||
if (isTypeH2 && !isDBUrlH2) {
|
||||
log.warn(
|
||||
"Datasource type is H2, but the URL does not contain 'h2'. "
|
||||
+ "Please check your configuration.");
|
||||
throw new IllegalStateException(
|
||||
"Datasource type is H2, but the URL does not contain 'h2'. Please check"
|
||||
+ " your configuration.");
|
||||
} else if (!isTypeH2 && isDBUrlH2) {
|
||||
log.warn(
|
||||
"Datasource URL contains 'h2', but the type is not H2. "
|
||||
+ "Please check your configuration.");
|
||||
throw new IllegalStateException(
|
||||
"Datasource URL contains 'h2', but the type is not H2. Please check your"
|
||||
+ " configuration.");
|
||||
}
|
||||
}
|
||||
boolean isH2 = isTypeH2 && isDBUrlH2;
|
||||
|
||||
return !isCustomDatabase || isH2;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -6,20 +6,19 @@ import org.springframework.context.annotation.Conditional;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import stirling.software.SPDF.config.interfaces.DatabaseInterface;
|
||||
import stirling.software.SPDF.controller.api.H2SQLCondition;
|
||||
import stirling.software.SPDF.model.exception.UnsupportedProviderException;
|
||||
|
||||
@Component
|
||||
@Conditional(H2SQLCondition.class)
|
||||
@RequiredArgsConstructor
|
||||
public class ScheduledTasks {
|
||||
|
||||
private final DatabaseInterface databaseService;
|
||||
|
||||
public ScheduledTasks(DatabaseInterface databaseService) {
|
||||
this.databaseService = databaseService;
|
||||
}
|
||||
|
||||
@Scheduled(cron = "0 0 0 * * ?")
|
||||
public void performBackup() throws SQLException, UnsupportedProviderException {
|
||||
databaseService.exportDatabase();
|
||||
|
@ -0,0 +1,63 @@
|
||||
package stirling.software.SPDF.config.security.mail;
|
||||
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.mail.javamail.JavaMailSender;
|
||||
import org.springframework.mail.javamail.MimeMessageHelper;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import jakarta.mail.MessagingException;
|
||||
import jakarta.mail.internet.MimeMessage;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import stirling.software.SPDF.model.ApplicationProperties;
|
||||
import stirling.software.SPDF.model.api.Email;
|
||||
|
||||
/**
|
||||
* Service class responsible for sending emails, including those with attachments. It uses
|
||||
* JavaMailSender to send the email and is designed to handle both the message content and file
|
||||
* attachments.
|
||||
*/
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
@ConditionalOnProperty(value = "mail.enabled", havingValue = "true", matchIfMissing = false)
|
||||
public class EmailService {
|
||||
|
||||
private final JavaMailSender mailSender;
|
||||
private final ApplicationProperties applicationProperties;
|
||||
|
||||
/**
|
||||
* Sends an email with an attachment asynchronously. This method is annotated with @Async, which
|
||||
* means it will be executed asynchronously.
|
||||
*
|
||||
* @param email The Email object containing the recipient, subject, body, and file attachment.
|
||||
* @throws MessagingException If there is an issue with creating or sending the email.
|
||||
*/
|
||||
@Async
|
||||
public void sendEmailWithAttachment(Email email) throws MessagingException {
|
||||
ApplicationProperties.Mail mailProperties = applicationProperties.getMail();
|
||||
MultipartFile file = email.getFileInput();
|
||||
|
||||
// Creates a MimeMessage to represent the email
|
||||
MimeMessage message = mailSender.createMimeMessage();
|
||||
|
||||
// Helper class to set up the message content and attachments
|
||||
MimeMessageHelper helper = new MimeMessageHelper(message, true);
|
||||
|
||||
// Sets the recipient, subject, body, and sender email
|
||||
helper.addTo(email.getTo());
|
||||
helper.setSubject(email.getSubject());
|
||||
helper.setText(
|
||||
email.getBody(),
|
||||
true); // The "true" here indicates that the body contains HTML content.
|
||||
helper.setFrom(mailProperties.getFrom());
|
||||
|
||||
// Adds the attachment to the email
|
||||
helper.addAttachment(file.getOriginalFilename(), file);
|
||||
|
||||
// Sends the email via the configured mail sender
|
||||
mailSender.send(message);
|
||||
}
|
||||
}
|
@ -0,0 +1,54 @@
|
||||
package stirling.software.SPDF.config.security.mail;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.mail.javamail.JavaMailSender;
|
||||
import org.springframework.mail.javamail.JavaMailSenderImpl;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import stirling.software.SPDF.model.ApplicationProperties;
|
||||
|
||||
/**
|
||||
* This configuration class provides the JavaMailSender bean, which is used to send emails. It reads
|
||||
* email server settings from the configuration (ApplicationProperties) and configures the mail
|
||||
* client (JavaMailSender).
|
||||
*/
|
||||
@Configuration
|
||||
@Slf4j
|
||||
@AllArgsConstructor
|
||||
@ConditionalOnProperty(value = "mail.enabled", havingValue = "true", matchIfMissing = false)
|
||||
public class MailConfig {
|
||||
|
||||
private final ApplicationProperties applicationProperties;
|
||||
|
||||
@Bean
|
||||
public JavaMailSender javaMailSender() {
|
||||
|
||||
ApplicationProperties.Mail mailProperties = applicationProperties.getMail();
|
||||
|
||||
// Creates a new instance of JavaMailSenderImpl, which is a Spring implementation
|
||||
JavaMailSenderImpl mailSender = new JavaMailSenderImpl();
|
||||
mailSender.setHost(mailProperties.getHost());
|
||||
mailSender.setPort(mailProperties.getPort());
|
||||
mailSender.setUsername(mailProperties.getUsername());
|
||||
mailSender.setPassword(mailProperties.getPassword());
|
||||
mailSender.setDefaultEncoding("UTF-8");
|
||||
|
||||
// Retrieves the JavaMail properties to configure additional SMTP parameters
|
||||
Properties props = mailSender.getJavaMailProperties();
|
||||
|
||||
// Enables SMTP authentication
|
||||
props.put("mail.smtp.auth", "true");
|
||||
|
||||
// Enables STARTTLS to encrypt the connection if supported by the SMTP server
|
||||
props.put("mail.smtp.starttls.enable", "true");
|
||||
|
||||
// Returns the configured mail sender, ready to send emails
|
||||
return mailSender;
|
||||
}
|
||||
}
|
@ -15,6 +15,8 @@ import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import jakarta.servlet.http.HttpSession;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import stirling.software.SPDF.config.security.LoginAttemptService;
|
||||
import stirling.software.SPDF.config.security.UserService;
|
||||
import stirling.software.SPDF.model.ApplicationProperties;
|
||||
@ -23,6 +25,7 @@ import stirling.software.SPDF.model.AuthenticationType;
|
||||
import stirling.software.SPDF.model.exception.UnsupportedProviderException;
|
||||
import stirling.software.SPDF.utils.RequestUriUtils;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public class CustomOAuth2AuthenticationSuccessHandler
|
||||
extends SavedRequestAwareAuthenticationSuccessHandler {
|
||||
|
||||
@ -30,15 +33,6 @@ public class CustomOAuth2AuthenticationSuccessHandler
|
||||
private final ApplicationProperties applicationProperties;
|
||||
private final UserService userService;
|
||||
|
||||
public CustomOAuth2AuthenticationSuccessHandler(
|
||||
LoginAttemptService loginAttemptService,
|
||||
ApplicationProperties applicationProperties,
|
||||
UserService userService) {
|
||||
this.applicationProperties = applicationProperties;
|
||||
this.userService = userService;
|
||||
this.loginAttemptService = loginAttemptService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAuthenticationSuccess(
|
||||
HttpServletRequest request, HttpServletResponse response, Authentication authentication)
|
||||
|
@ -13,6 +13,7 @@ import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
||||
import org.springframework.security.saml2.provider.service.authentication.OpenSaml4AuthenticationProvider.ResponseToken;
|
||||
import org.springframework.security.saml2.provider.service.authentication.Saml2Authentication;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import stirling.software.SPDF.config.security.UserService;
|
||||
@ -20,15 +21,12 @@ import stirling.software.SPDF.model.User;
|
||||
|
||||
@Slf4j
|
||||
@ConditionalOnProperty(name = "security.saml2.enabled", havingValue = "true")
|
||||
@RequiredArgsConstructor
|
||||
public class CustomSaml2ResponseAuthenticationConverter
|
||||
implements Converter<ResponseToken, Saml2Authentication> {
|
||||
|
||||
private final UserService userService;
|
||||
|
||||
public CustomSaml2ResponseAuthenticationConverter(UserService userService) {
|
||||
this.userService = userService;
|
||||
}
|
||||
|
||||
private Map<String, List<Object>> extractAttributes(Assertion assertion) {
|
||||
Map<String, List<Object>> attributes = new HashMap<>();
|
||||
|
||||
|
@ -21,6 +21,7 @@ import org.springframework.security.saml2.provider.service.web.authentication.Op
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import stirling.software.SPDF.model.ApplicationProperties;
|
||||
@ -29,14 +30,11 @@ import stirling.software.SPDF.model.ApplicationProperties.Security.SAML2;
|
||||
@Configuration
|
||||
@Slf4j
|
||||
@ConditionalOnProperty(value = "security.saml2.enabled", havingValue = "true")
|
||||
@RequiredArgsConstructor
|
||||
public class SAML2Configuration {
|
||||
|
||||
private final ApplicationProperties applicationProperties;
|
||||
|
||||
public SAML2Configuration(ApplicationProperties applicationProperties) {
|
||||
this.applicationProperties = applicationProperties;
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnProperty(name = "security.saml2.enabled", havingValue = "true")
|
||||
public RelyingPartyRegistrationRepository relyingPartyRegistrations() throws Exception {
|
||||
|
@ -1,6 +1,5 @@
|
||||
package stirling.software.SPDF.config.security.session;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import jakarta.servlet.http.HttpSessionEvent;
|
||||
@ -14,7 +13,6 @@ public class CustomHttpSessionListener implements HttpSessionListener {
|
||||
|
||||
private SessionPersistentRegistry sessionPersistentRegistry;
|
||||
|
||||
@Autowired
|
||||
public CustomHttpSessionListener(SessionPersistentRegistry sessionPersistentRegistry) {
|
||||
super();
|
||||
this.sessionPersistentRegistry = sessionPersistentRegistry;
|
||||
|
@ -12,10 +12,13 @@ import org.springframework.stereotype.Component;
|
||||
|
||||
import jakarta.transaction.Transactional;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import stirling.software.SPDF.config.security.saml2.CustomSaml2AuthenticatedPrincipal;
|
||||
import stirling.software.SPDF.model.SessionEntity;
|
||||
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class SessionPersistentRegistry implements SessionRegistry {
|
||||
|
||||
private final SessionRepository sessionRepository;
|
||||
@ -23,10 +26,6 @@ public class SessionPersistentRegistry implements SessionRegistry {
|
||||
@Value("${server.servlet.session.timeout:30m}")
|
||||
private Duration defaultMaxInactiveInterval;
|
||||
|
||||
public SessionPersistentRegistry(SessionRepository sessionRepository) {
|
||||
this.sessionRepository = sessionRepository;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Object> getAllPrincipals() {
|
||||
List<SessionEntity> sessions = sessionRepository.findAll();
|
||||
|
@ -9,15 +9,14 @@ import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.security.core.session.SessionInformation;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class SessionScheduled {
|
||||
|
||||
private final SessionPersistentRegistry sessionPersistentRegistry;
|
||||
|
||||
public SessionScheduled(SessionPersistentRegistry sessionPersistentRegistry) {
|
||||
this.sessionPersistentRegistry = sessionPersistentRegistry;
|
||||
}
|
||||
|
||||
@Scheduled(cron = "0 0/5 * * * ?")
|
||||
public void expireSessions() {
|
||||
Instant now = Instant.now();
|
||||
|
@ -14,18 +14,17 @@ import io.swagger.v3.oas.annotations.Hidden;
|
||||
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import stirling.software.SPDF.service.LanguageService;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/js")
|
||||
@RequiredArgsConstructor
|
||||
public class AdditionalLanguageJsController {
|
||||
|
||||
private final LanguageService languageService;
|
||||
|
||||
public AdditionalLanguageJsController(LanguageService languageService) {
|
||||
this.languageService = languageService;
|
||||
}
|
||||
|
||||
@Hidden
|
||||
@GetMapping(value = "/additionalLanguageCode.js", produces = "application/javascript")
|
||||
public void generateAdditionalLanguageJs(HttpServletResponse response) throws IOException {
|
||||
|
@ -11,27 +11,24 @@ import org.apache.pdfbox.pdmodel.PDPageTree;
|
||||
import org.apache.pdfbox.pdmodel.encryption.PDEncryption;
|
||||
import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotation;
|
||||
import org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import stirling.software.SPDF.model.api.PDFFile;
|
||||
import stirling.software.SPDF.service.CustomPDFDocumentFactory;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api/v1/analysis")
|
||||
@Tag(name = "Analysis", description = "Analysis APIs")
|
||||
@RequiredArgsConstructor
|
||||
public class AnalysisController {
|
||||
|
||||
private final CustomPDFDocumentFactory pdfDocumentFactory;
|
||||
|
||||
@Autowired
|
||||
public AnalysisController(CustomPDFDocumentFactory pdfDocumentFactory) {
|
||||
this.pdfDocumentFactory = pdfDocumentFactory;
|
||||
}
|
||||
|
||||
@PostMapping(value = "/page-count", consumes = "multipart/form-data")
|
||||
@Operation(
|
||||
summary = "Get PDF page count",
|
||||
@ -62,7 +59,8 @@ public class AnalysisController {
|
||||
description = "Returns title, author, subject, etc. Input:PDF Output:JSON Type:SISO")
|
||||
public Map<String, String> getDocumentProperties(@ModelAttribute PDFFile file)
|
||||
throws IOException {
|
||||
try (PDDocument document = pdfDocumentFactory.load(file.getFileInput())) {
|
||||
// Load the document in read-only mode to prevent modifications and ensure the integrity of the original file.
|
||||
try (PDDocument document = pdfDocumentFactory.load(file.getFileInput(), true)) {
|
||||
PDDocumentInformation info = document.getDocumentInformation();
|
||||
Map<String, String> properties = new HashMap<>();
|
||||
properties.put("title", info.getTitle());
|
||||
|
@ -10,7 +10,6 @@ import org.apache.pdfbox.pdmodel.PDPageContentStream;
|
||||
import org.apache.pdfbox.pdmodel.PDPageContentStream.AppendMode;
|
||||
import org.apache.pdfbox.pdmodel.common.PDRectangle;
|
||||
import org.apache.pdfbox.pdmodel.graphics.form.PDFormXObject;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
@ -20,6 +19,8 @@ import org.springframework.web.bind.annotation.RestController;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import stirling.software.SPDF.model.api.general.CropPdfForm;
|
||||
import stirling.software.SPDF.service.CustomPDFDocumentFactory;
|
||||
import stirling.software.SPDF.utils.WebResponseUtils;
|
||||
@ -27,15 +28,11 @@ import stirling.software.SPDF.utils.WebResponseUtils;
|
||||
@RestController
|
||||
@RequestMapping("/api/v1/general")
|
||||
@Tag(name = "General", description = "General APIs")
|
||||
@RequiredArgsConstructor
|
||||
public class CropController {
|
||||
|
||||
private final CustomPDFDocumentFactory pdfDocumentFactory;
|
||||
|
||||
@Autowired
|
||||
public CropController(CustomPDFDocumentFactory pdfDocumentFactory) {
|
||||
this.pdfDocumentFactory = pdfDocumentFactory;
|
||||
}
|
||||
|
||||
@PostMapping(value = "/crop", consumes = "multipart/form-data")
|
||||
@Operation(
|
||||
summary = "Crops a PDF document",
|
||||
|
@ -24,6 +24,7 @@ import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import stirling.software.SPDF.config.security.database.DatabaseService;
|
||||
@ -34,14 +35,11 @@ import stirling.software.SPDF.config.security.database.DatabaseService;
|
||||
@PreAuthorize("hasRole('ROLE_ADMIN')")
|
||||
@Conditional(H2SQLCondition.class)
|
||||
@Tag(name = "Database", description = "Database APIs for backup, import, and management")
|
||||
@RequiredArgsConstructor
|
||||
public class DatabaseController {
|
||||
|
||||
private final DatabaseService databaseService;
|
||||
|
||||
public DatabaseController(DatabaseService databaseService) {
|
||||
this.databaseService = databaseService;
|
||||
}
|
||||
|
||||
@Operation(
|
||||
summary = "Import a database backup file",
|
||||
description = "Uploads and imports a database backup SQL file.")
|
||||
|
@ -0,0 +1,57 @@
|
||||
package stirling.software.SPDF.controller.api;
|
||||
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
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 io.swagger.v3.oas.annotations.tags.Tag;
|
||||
|
||||
import jakarta.mail.MessagingException;
|
||||
import jakarta.validation.Valid;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import stirling.software.SPDF.config.security.mail.EmailService;
|
||||
import stirling.software.SPDF.model.api.Email;
|
||||
|
||||
/**
|
||||
* Controller for handling email-related API requests. This controller exposes an endpoint for
|
||||
* sending emails with attachments.
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/api/v1/general")
|
||||
@RequiredArgsConstructor
|
||||
@Slf4j
|
||||
@Tag(name = "General", description = "General APIs")
|
||||
@ConditionalOnProperty(value = "mail.enabled", havingValue = "true", matchIfMissing = false)
|
||||
public class EmailController {
|
||||
private final EmailService emailService;
|
||||
|
||||
/**
|
||||
* Endpoint to send an email with an attachment. This method consumes a multipart/form-data
|
||||
* request containing the email details and attachment.
|
||||
*
|
||||
* @param email The Email object containing recipient address, subject, body, and file
|
||||
* attachment.
|
||||
* @return ResponseEntity with success or error message.
|
||||
*/
|
||||
@PostMapping(consumes = "multipart/form-data", value = "/send-email")
|
||||
public ResponseEntity<String> sendEmailWithAttachment(@Valid @ModelAttribute Email email) {
|
||||
try {
|
||||
// Calls the service to send the email with attachment
|
||||
emailService.sendEmailWithAttachment(email);
|
||||
return ResponseEntity.ok("Email sent successfully");
|
||||
} catch (MessagingException e) {
|
||||
// Catches any messaging exception (e.g., invalid email address, SMTP server issues)
|
||||
String errorMsg = "Failed to send email: " + e.getMessage();
|
||||
log.error(errorMsg, e); // Logging the detailed error
|
||||
// Returns an error response with status 500 (Internal Server Error)
|
||||
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(errorMsg);
|
||||
}
|
||||
}
|
||||
}
|
@ -18,7 +18,6 @@ import org.apache.pdfbox.pdmodel.PDPage;
|
||||
import org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm;
|
||||
import org.apache.pdfbox.pdmodel.interactive.form.PDField;
|
||||
import org.apache.pdfbox.pdmodel.interactive.form.PDSignatureField;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
@ -29,6 +28,7 @@ import org.springframework.web.multipart.MultipartFile;
|
||||
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.model.api.general.MergePdfsRequest;
|
||||
@ -40,15 +40,11 @@ import stirling.software.SPDF.utils.WebResponseUtils;
|
||||
@Slf4j
|
||||
@RequestMapping("/api/v1/general")
|
||||
@Tag(name = "General", description = "General APIs")
|
||||
@RequiredArgsConstructor
|
||||
public class MergeController {
|
||||
|
||||
private final CustomPDFDocumentFactory pdfDocumentFactory;
|
||||
|
||||
@Autowired
|
||||
public MergeController(CustomPDFDocumentFactory pdfDocumentFactory) {
|
||||
this.pdfDocumentFactory = pdfDocumentFactory;
|
||||
}
|
||||
|
||||
// Merges a list of PDDocument objects into a single PDDocument
|
||||
public PDDocument mergeDocuments(List<PDDocument> documents) throws IOException {
|
||||
PDDocument mergedDoc = pdfDocumentFactory.createNewDocument();
|
||||
|
@ -11,7 +11,6 @@ import org.apache.pdfbox.pdmodel.PDPageContentStream;
|
||||
import org.apache.pdfbox.pdmodel.common.PDRectangle;
|
||||
import org.apache.pdfbox.pdmodel.graphics.form.PDFormXObject;
|
||||
import org.apache.pdfbox.util.Matrix;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
@ -23,6 +22,8 @@ import io.github.pixee.security.Filenames;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import stirling.software.SPDF.model.api.general.MergeMultiplePagesRequest;
|
||||
import stirling.software.SPDF.service.CustomPDFDocumentFactory;
|
||||
import stirling.software.SPDF.utils.WebResponseUtils;
|
||||
@ -30,15 +31,11 @@ import stirling.software.SPDF.utils.WebResponseUtils;
|
||||
@RestController
|
||||
@RequestMapping("/api/v1/general")
|
||||
@Tag(name = "General", description = "General APIs")
|
||||
@RequiredArgsConstructor
|
||||
public class MultiPageLayoutController {
|
||||
|
||||
private final CustomPDFDocumentFactory pdfDocumentFactory;
|
||||
|
||||
@Autowired
|
||||
public MultiPageLayoutController(CustomPDFDocumentFactory pdfDocumentFactory) {
|
||||
this.pdfDocumentFactory = pdfDocumentFactory;
|
||||
}
|
||||
|
||||
@PostMapping(value = "/multi-page-layout", consumes = "multipart/form-data")
|
||||
@Operation(
|
||||
summary = "Merge multiple pages of a PDF document into a single page",
|
||||
|
@ -4,7 +4,6 @@ import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
@ -14,6 +13,8 @@ import org.springframework.web.bind.annotation.RestController;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import stirling.software.SPDF.model.api.PDFFile;
|
||||
import stirling.software.SPDF.service.CustomPDFDocumentFactory;
|
||||
import stirling.software.SPDF.service.PdfImageRemovalService;
|
||||
@ -26,6 +27,7 @@ import stirling.software.SPDF.utils.WebResponseUtils;
|
||||
@RestController
|
||||
@RequestMapping("/api/v1/general")
|
||||
@Tag(name = "General", description = "General APIs")
|
||||
@RequiredArgsConstructor
|
||||
public class PdfImageRemovalController {
|
||||
|
||||
// Service for removing images from PDFs
|
||||
@ -33,19 +35,6 @@ public class PdfImageRemovalController {
|
||||
|
||||
private final CustomPDFDocumentFactory pdfDocumentFactory;
|
||||
|
||||
/**
|
||||
* Constructor for dependency injection of PdfImageRemovalService.
|
||||
*
|
||||
* @param pdfImageRemovalService The service used for removing images from PDFs.
|
||||
*/
|
||||
@Autowired
|
||||
public PdfImageRemovalController(
|
||||
PdfImageRemovalService pdfImageRemovalService,
|
||||
CustomPDFDocumentFactory pdfDocumentFactory) {
|
||||
this.pdfImageRemovalService = pdfImageRemovalService;
|
||||
this.pdfDocumentFactory = pdfDocumentFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Endpoint to remove images from a PDF file.
|
||||
*
|
||||
|
@ -12,7 +12,6 @@ import java.util.Map;
|
||||
import org.apache.pdfbox.Loader;
|
||||
import org.apache.pdfbox.multipdf.Overlay;
|
||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||
@ -25,6 +24,8 @@ import io.github.pixee.security.Filenames;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import stirling.software.SPDF.model.api.general.OverlayPdfsRequest;
|
||||
import stirling.software.SPDF.service.CustomPDFDocumentFactory;
|
||||
import stirling.software.SPDF.utils.GeneralUtils;
|
||||
@ -33,15 +34,11 @@ import stirling.software.SPDF.utils.WebResponseUtils;
|
||||
@RestController
|
||||
@RequestMapping("/api/v1/general")
|
||||
@Tag(name = "General", description = "General APIs")
|
||||
@RequiredArgsConstructor
|
||||
public class PdfOverlayController {
|
||||
|
||||
private final CustomPDFDocumentFactory pdfDocumentFactory;
|
||||
|
||||
@Autowired
|
||||
public PdfOverlayController(CustomPDFDocumentFactory pdfDocumentFactory) {
|
||||
this.pdfDocumentFactory = pdfDocumentFactory;
|
||||
}
|
||||
|
||||
@PostMapping(value = "/overlay-pdfs", consumes = "multipart/form-data")
|
||||
@Operation(
|
||||
summary = "Overlay PDF files in various modes",
|
||||
|
@ -7,7 +7,6 @@ import java.util.List;
|
||||
|
||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||
import org.apache.pdfbox.pdmodel.PDPage;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
@ -19,6 +18,7 @@ import io.github.pixee.security.Filenames;
|
||||
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.model.SortTypes;
|
||||
@ -32,15 +32,11 @@ import stirling.software.SPDF.utils.WebResponseUtils;
|
||||
@RequestMapping("/api/v1/general")
|
||||
@Slf4j
|
||||
@Tag(name = "General", description = "General APIs")
|
||||
@RequiredArgsConstructor
|
||||
public class RearrangePagesPDFController {
|
||||
|
||||
private final CustomPDFDocumentFactory pdfDocumentFactory;
|
||||
|
||||
@Autowired
|
||||
public RearrangePagesPDFController(CustomPDFDocumentFactory pdfDocumentFactory) {
|
||||
this.pdfDocumentFactory = pdfDocumentFactory;
|
||||
}
|
||||
|
||||
@PostMapping(consumes = "multipart/form-data", value = "/remove-pages")
|
||||
@Operation(
|
||||
summary = "Remove pages from a PDF file",
|
||||
|
@ -5,7 +5,6 @@ import java.io.IOException;
|
||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||
import org.apache.pdfbox.pdmodel.PDPage;
|
||||
import org.apache.pdfbox.pdmodel.PDPageTree;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
@ -17,6 +16,8 @@ import io.github.pixee.security.Filenames;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import stirling.software.SPDF.model.api.general.RotatePDFRequest;
|
||||
import stirling.software.SPDF.service.CustomPDFDocumentFactory;
|
||||
import stirling.software.SPDF.utils.WebResponseUtils;
|
||||
@ -24,15 +25,11 @@ import stirling.software.SPDF.utils.WebResponseUtils;
|
||||
@RestController
|
||||
@RequestMapping("/api/v1/general")
|
||||
@Tag(name = "General", description = "General APIs")
|
||||
@RequiredArgsConstructor
|
||||
public class RotationController {
|
||||
|
||||
private final CustomPDFDocumentFactory pdfDocumentFactory;
|
||||
|
||||
@Autowired
|
||||
public RotationController(CustomPDFDocumentFactory pdfDocumentFactory) {
|
||||
this.pdfDocumentFactory = pdfDocumentFactory;
|
||||
}
|
||||
|
||||
@PostMapping(consumes = "multipart/form-data", value = "/rotate-pdf")
|
||||
@Operation(
|
||||
summary = "Rotate a PDF file",
|
||||
|
@ -12,7 +12,6 @@ import org.apache.pdfbox.pdmodel.PDPageContentStream;
|
||||
import org.apache.pdfbox.pdmodel.common.PDRectangle;
|
||||
import org.apache.pdfbox.pdmodel.graphics.form.PDFormXObject;
|
||||
import org.apache.pdfbox.util.Matrix;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
@ -24,6 +23,8 @@ import io.github.pixee.security.Filenames;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import stirling.software.SPDF.model.api.general.ScalePagesRequest;
|
||||
import stirling.software.SPDF.service.CustomPDFDocumentFactory;
|
||||
import stirling.software.SPDF.utils.WebResponseUtils;
|
||||
@ -31,15 +32,11 @@ import stirling.software.SPDF.utils.WebResponseUtils;
|
||||
@RestController
|
||||
@RequestMapping("/api/v1/general")
|
||||
@Tag(name = "General", description = "General APIs")
|
||||
@RequiredArgsConstructor
|
||||
public class ScalePagesController {
|
||||
|
||||
private final CustomPDFDocumentFactory pdfDocumentFactory;
|
||||
|
||||
@Autowired
|
||||
public ScalePagesController(CustomPDFDocumentFactory pdfDocumentFactory) {
|
||||
this.pdfDocumentFactory = pdfDocumentFactory;
|
||||
}
|
||||
|
||||
@PostMapping(value = "/scale-pages", consumes = "multipart/form-data")
|
||||
@Operation(
|
||||
summary = "Change the size of a PDF page/document",
|
||||
|
@ -14,6 +14,8 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import io.swagger.v3.oas.annotations.Hidden;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import stirling.software.SPDF.config.EndpointConfiguration;
|
||||
import stirling.software.SPDF.config.InstallationPathConfig;
|
||||
import stirling.software.SPDF.model.ApplicationProperties;
|
||||
@ -22,19 +24,13 @@ import stirling.software.SPDF.utils.GeneralUtils;
|
||||
@Controller
|
||||
@Tag(name = "Settings", description = "Settings APIs")
|
||||
@RequestMapping("/api/v1/settings")
|
||||
@RequiredArgsConstructor
|
||||
@Hidden
|
||||
public class SettingsController {
|
||||
|
||||
private final ApplicationProperties applicationProperties;
|
||||
private final EndpointConfiguration endpointConfiguration;
|
||||
|
||||
public SettingsController(
|
||||
ApplicationProperties applicationProperties,
|
||||
EndpointConfiguration endpointConfiguration) {
|
||||
this.applicationProperties = applicationProperties;
|
||||
this.endpointConfiguration = endpointConfiguration;
|
||||
}
|
||||
|
||||
@PostMapping("/update-enable-analytics")
|
||||
@Hidden
|
||||
public ResponseEntity<String> updateApiKey(@RequestBody Boolean enabled) throws IOException {
|
||||
|
@ -12,7 +12,6 @@ import java.util.zip.ZipOutputStream;
|
||||
|
||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||
import org.apache.pdfbox.pdmodel.PDPage;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||
@ -25,6 +24,7 @@ import io.github.pixee.security.Filenames;
|
||||
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.model.api.PDFWithPageNums;
|
||||
@ -35,15 +35,11 @@ import stirling.software.SPDF.utils.WebResponseUtils;
|
||||
@RequestMapping("/api/v1/general")
|
||||
@Slf4j
|
||||
@Tag(name = "General", description = "General APIs")
|
||||
@RequiredArgsConstructor
|
||||
public class SplitPDFController {
|
||||
|
||||
private final CustomPDFDocumentFactory pdfDocumentFactory;
|
||||
|
||||
@Autowired
|
||||
public SplitPDFController(CustomPDFDocumentFactory pdfDocumentFactory) {
|
||||
this.pdfDocumentFactory = pdfDocumentFactory;
|
||||
}
|
||||
|
||||
@PostMapping(consumes = "multipart/form-data", value = "/split-pages")
|
||||
@Operation(
|
||||
summary = "Split a PDF file into separate documents",
|
||||
|
@ -12,7 +12,6 @@ import org.apache.pdfbox.pdmodel.PDDocument;
|
||||
import org.apache.pdfbox.pdmodel.PDPage;
|
||||
import org.apache.pdfbox.pdmodel.interactive.documentnavigation.outline.PDDocumentOutline;
|
||||
import org.apache.pdfbox.pdmodel.interactive.documentnavigation.outline.PDOutlineItem;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||
@ -29,6 +28,7 @@ import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import stirling.software.SPDF.model.PdfMetadata;
|
||||
@ -41,19 +41,13 @@ import stirling.software.SPDF.utils.WebResponseUtils;
|
||||
@RequestMapping("/api/v1/general")
|
||||
@Slf4j
|
||||
@Tag(name = "General", description = "General APIs")
|
||||
@RequiredArgsConstructor
|
||||
public class SplitPdfByChaptersController {
|
||||
|
||||
private final PdfMetadataService pdfMetadataService;
|
||||
|
||||
private final CustomPDFDocumentFactory pdfDocumentFactory;
|
||||
|
||||
@Autowired
|
||||
public SplitPdfByChaptersController(
|
||||
PdfMetadataService pdfMetadataService, CustomPDFDocumentFactory pdfDocumentFactory) {
|
||||
this.pdfMetadataService = pdfMetadataService;
|
||||
this.pdfDocumentFactory = pdfDocumentFactory;
|
||||
}
|
||||
|
||||
private static List<Bookmark> extractOutlineItems(
|
||||
PDDocument sourceDocument,
|
||||
PDOutlineItem current,
|
||||
|
@ -17,7 +17,6 @@ import org.apache.pdfbox.pdmodel.PDPageContentStream.AppendMode;
|
||||
import org.apache.pdfbox.pdmodel.common.PDRectangle;
|
||||
import org.apache.pdfbox.pdmodel.graphics.form.PDFormXObject;
|
||||
import org.apache.pdfbox.util.Matrix;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||
@ -30,6 +29,8 @@ import io.github.pixee.security.Filenames;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import stirling.software.SPDF.model.api.SplitPdfBySectionsRequest;
|
||||
import stirling.software.SPDF.service.CustomPDFDocumentFactory;
|
||||
import stirling.software.SPDF.utils.WebResponseUtils;
|
||||
@ -37,15 +38,11 @@ import stirling.software.SPDF.utils.WebResponseUtils;
|
||||
@RestController
|
||||
@RequestMapping("/api/v1/general")
|
||||
@Tag(name = "General", description = "General APIs")
|
||||
@RequiredArgsConstructor
|
||||
public class SplitPdfBySectionsController {
|
||||
|
||||
private final CustomPDFDocumentFactory pdfDocumentFactory;
|
||||
|
||||
@Autowired
|
||||
public SplitPdfBySectionsController(CustomPDFDocumentFactory pdfDocumentFactory) {
|
||||
this.pdfDocumentFactory = pdfDocumentFactory;
|
||||
}
|
||||
|
||||
@PostMapping(value = "/split-pdf-by-sections", consumes = "multipart/form-data")
|
||||
@Operation(
|
||||
summary = "Split PDF pages into smaller sections",
|
||||
|
@ -9,7 +9,6 @@ import java.util.zip.ZipOutputStream;
|
||||
|
||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||
import org.apache.pdfbox.pdmodel.PDPage;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||
@ -22,6 +21,7 @@ import io.github.pixee.security.Filenames;
|
||||
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.model.api.general.SplitPdfBySizeOrCountRequest;
|
||||
@ -33,15 +33,11 @@ import stirling.software.SPDF.utils.WebResponseUtils;
|
||||
@RequestMapping("/api/v1/general")
|
||||
@Slf4j
|
||||
@Tag(name = "General", description = "General APIs")
|
||||
@RequiredArgsConstructor
|
||||
public class SplitPdfBySizeController {
|
||||
|
||||
private final CustomPDFDocumentFactory pdfDocumentFactory;
|
||||
|
||||
@Autowired
|
||||
public SplitPdfBySizeController(CustomPDFDocumentFactory pdfDocumentFactory) {
|
||||
this.pdfDocumentFactory = pdfDocumentFactory;
|
||||
}
|
||||
|
||||
@PostMapping(value = "/split-by-size-or-count", consumes = "multipart/form-data")
|
||||
@Operation(
|
||||
summary = "Auto split PDF pages into separate documents based on size or count",
|
||||
|
@ -10,7 +10,6 @@ import org.apache.pdfbox.pdmodel.PDPage;
|
||||
import org.apache.pdfbox.pdmodel.PDPageContentStream;
|
||||
import org.apache.pdfbox.pdmodel.common.PDRectangle;
|
||||
import org.apache.pdfbox.pdmodel.graphics.form.PDFormXObject;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
@ -20,6 +19,8 @@ import org.springframework.web.bind.annotation.RestController;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import stirling.software.SPDF.model.api.PDFFile;
|
||||
import stirling.software.SPDF.service.CustomPDFDocumentFactory;
|
||||
import stirling.software.SPDF.utils.WebResponseUtils;
|
||||
@ -27,15 +28,11 @@ import stirling.software.SPDF.utils.WebResponseUtils;
|
||||
@RestController
|
||||
@RequestMapping("/api/v1/general")
|
||||
@Tag(name = "General", description = "General APIs")
|
||||
@RequiredArgsConstructor
|
||||
public class ToSinglePageController {
|
||||
|
||||
private final CustomPDFDocumentFactory pdfDocumentFactory;
|
||||
|
||||
@Autowired
|
||||
public ToSinglePageController(CustomPDFDocumentFactory pdfDocumentFactory) {
|
||||
this.pdfDocumentFactory = pdfDocumentFactory;
|
||||
}
|
||||
|
||||
@PostMapping(consumes = "multipart/form-data", value = "/pdf-to-single-page")
|
||||
@Operation(
|
||||
summary = "Convert a multi-page PDF into a single long page PDF",
|
||||
|
@ -27,6 +27,7 @@ import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import stirling.software.SPDF.config.security.UserService;
|
||||
@ -43,6 +44,7 @@ import stirling.software.SPDF.model.exception.UnsupportedProviderException;
|
||||
@Tag(name = "User", description = "User APIs")
|
||||
@RequestMapping("/api/v1/user")
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
public class UserController {
|
||||
|
||||
private static final String LOGIN_MESSAGETYPE_CREDSUPDATED = "/login?messageType=credsUpdated";
|
||||
@ -50,15 +52,6 @@ public class UserController {
|
||||
private final SessionPersistentRegistry sessionRegistry;
|
||||
private final ApplicationProperties applicationProperties;
|
||||
|
||||
public UserController(
|
||||
UserService userService,
|
||||
SessionPersistentRegistry sessionRegistry,
|
||||
ApplicationProperties applicationProperties) {
|
||||
this.userService = userService;
|
||||
this.sessionRegistry = sessionRegistry;
|
||||
this.applicationProperties = applicationProperties;
|
||||
}
|
||||
|
||||
@PreAuthorize("!hasAuthority('ROLE_DEMO_USER')")
|
||||
@PostMapping("/register")
|
||||
public String register(@ModelAttribute UsernameAndPass requestModel, Model model)
|
||||
|
@ -1,6 +1,5 @@
|
||||
package stirling.software.SPDF.controller.api.converters;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
@ -12,6 +11,8 @@ import io.github.pixee.security.Filenames;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import stirling.software.SPDF.config.RuntimePathConfig;
|
||||
import stirling.software.SPDF.model.ApplicationProperties;
|
||||
import stirling.software.SPDF.model.api.converters.HTMLToPdfRequest;
|
||||
@ -22,6 +23,7 @@ import stirling.software.SPDF.utils.WebResponseUtils;
|
||||
@RestController
|
||||
@Tag(name = "Convert", description = "Convert APIs")
|
||||
@RequestMapping("/api/v1/convert")
|
||||
@RequiredArgsConstructor
|
||||
public class ConvertHtmlToPDF {
|
||||
|
||||
private final CustomPDFDocumentFactory pdfDocumentFactory;
|
||||
@ -30,17 +32,6 @@ public class ConvertHtmlToPDF {
|
||||
|
||||
private final RuntimePathConfig runtimePathConfig;
|
||||
|
||||
@Autowired
|
||||
public ConvertHtmlToPDF(
|
||||
CustomPDFDocumentFactory pdfDocumentFactory,
|
||||
ApplicationProperties applicationProperties,
|
||||
RuntimePathConfig runtimePathConfig) {
|
||||
this.pdfDocumentFactory = pdfDocumentFactory;
|
||||
|
||||
this.applicationProperties = applicationProperties;
|
||||
this.runtimePathConfig = runtimePathConfig;
|
||||
}
|
||||
|
||||
@PostMapping(consumes = "multipart/form-data", value = "/html/pdf")
|
||||
@Operation(
|
||||
summary = "Convert an HTML or ZIP (containing HTML and CSS) to PDF",
|
||||
|
@ -15,7 +15,6 @@ import org.apache.commons.io.FileUtils;
|
||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||
import org.apache.pdfbox.pdmodel.PDPage;
|
||||
import org.apache.pdfbox.rendering.ImageType;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||
@ -28,6 +27,7 @@ import io.github.pixee.security.Filenames;
|
||||
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.model.api.converters.ConvertToImageRequest;
|
||||
@ -40,15 +40,11 @@ import stirling.software.SPDF.utils.ProcessExecutor.ProcessExecutorResult;
|
||||
@RequestMapping("/api/v1/convert")
|
||||
@Slf4j
|
||||
@Tag(name = "Convert", description = "Convert APIs")
|
||||
@RequiredArgsConstructor
|
||||
public class ConvertImgPDFController {
|
||||
|
||||
private final CustomPDFDocumentFactory pdfDocumentFactory;
|
||||
|
||||
@Autowired
|
||||
public ConvertImgPDFController(CustomPDFDocumentFactory pdfDocumentFactory) {
|
||||
this.pdfDocumentFactory = pdfDocumentFactory;
|
||||
}
|
||||
|
||||
@PostMapping(consumes = "multipart/form-data", value = "/pdf/img")
|
||||
@Operation(
|
||||
summary = "Convert PDF to image(s)",
|
||||
|
@ -10,7 +10,6 @@ import org.commonmark.node.Node;
|
||||
import org.commonmark.parser.Parser;
|
||||
import org.commonmark.renderer.html.AttributeProvider;
|
||||
import org.commonmark.renderer.html.HtmlRenderer;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
@ -22,6 +21,8 @@ import io.github.pixee.security.Filenames;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import stirling.software.SPDF.config.RuntimePathConfig;
|
||||
import stirling.software.SPDF.model.ApplicationProperties;
|
||||
import stirling.software.SPDF.model.api.GeneralFile;
|
||||
@ -32,6 +33,7 @@ import stirling.software.SPDF.utils.WebResponseUtils;
|
||||
@RestController
|
||||
@Tag(name = "Convert", description = "Convert APIs")
|
||||
@RequestMapping("/api/v1/convert")
|
||||
@RequiredArgsConstructor
|
||||
public class ConvertMarkdownToPdf {
|
||||
|
||||
private final CustomPDFDocumentFactory pdfDocumentFactory;
|
||||
@ -39,17 +41,6 @@ public class ConvertMarkdownToPdf {
|
||||
private final ApplicationProperties applicationProperties;
|
||||
private final RuntimePathConfig runtimePathConfig;
|
||||
|
||||
@Autowired
|
||||
public ConvertMarkdownToPdf(
|
||||
CustomPDFDocumentFactory pdfDocumentFactory,
|
||||
ApplicationProperties applicationProperties,
|
||||
RuntimePathConfig runtimePathConfig) {
|
||||
this.pdfDocumentFactory = pdfDocumentFactory;
|
||||
|
||||
this.applicationProperties = applicationProperties;
|
||||
this.runtimePathConfig = runtimePathConfig;
|
||||
}
|
||||
|
||||
@PostMapping(consumes = "multipart/form-data", value = "/markdown/pdf")
|
||||
@Operation(
|
||||
summary = "Convert a Markdown file to PDF",
|
||||
|
@ -10,7 +10,6 @@ import java.util.List;
|
||||
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
@ -22,6 +21,8 @@ import io.github.pixee.security.Filenames;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import stirling.software.SPDF.config.RuntimePathConfig;
|
||||
import stirling.software.SPDF.model.api.GeneralFile;
|
||||
import stirling.software.SPDF.service.CustomPDFDocumentFactory;
|
||||
@ -32,18 +33,12 @@ import stirling.software.SPDF.utils.WebResponseUtils;
|
||||
@RestController
|
||||
@Tag(name = "Convert", description = "Convert APIs")
|
||||
@RequestMapping("/api/v1/convert")
|
||||
@RequiredArgsConstructor
|
||||
public class ConvertOfficeController {
|
||||
|
||||
private final CustomPDFDocumentFactory pdfDocumentFactory;
|
||||
private final RuntimePathConfig runtimePathConfig;
|
||||
|
||||
@Autowired
|
||||
public ConvertOfficeController(
|
||||
CustomPDFDocumentFactory pdfDocumentFactory, RuntimePathConfig runtimePathConfig) {
|
||||
this.pdfDocumentFactory = pdfDocumentFactory;
|
||||
this.runtimePathConfig = runtimePathConfig;
|
||||
}
|
||||
|
||||
public File convertToPdf(MultipartFile inputFile) throws IOException, InterruptedException {
|
||||
// Check for valid file extension
|
||||
String originalFilename = Filenames.toSimpleFileName(inputFile.getOriginalFilename());
|
||||
|
@ -4,7 +4,6 @@ import java.io.IOException;
|
||||
|
||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||
import org.apache.pdfbox.text.PDFTextStripper;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||
@ -17,6 +16,8 @@ import io.github.pixee.security.Filenames;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import stirling.software.SPDF.model.api.PDFFile;
|
||||
import stirling.software.SPDF.model.api.converters.PdfToPresentationRequest;
|
||||
import stirling.software.SPDF.model.api.converters.PdfToTextOrRTFRequest;
|
||||
@ -28,15 +29,11 @@ import stirling.software.SPDF.utils.WebResponseUtils;
|
||||
@RestController
|
||||
@RequestMapping("/api/v1/convert")
|
||||
@Tag(name = "Convert", description = "Convert APIs")
|
||||
@RequiredArgsConstructor
|
||||
public class ConvertPDFToOffice {
|
||||
|
||||
private final CustomPDFDocumentFactory pdfDocumentFactory;
|
||||
|
||||
@Autowired
|
||||
public ConvertPDFToOffice(CustomPDFDocumentFactory pdfDocumentFactory) {
|
||||
this.pdfDocumentFactory = pdfDocumentFactory;
|
||||
}
|
||||
|
||||
@PostMapping(consumes = "multipart/form-data", value = "/pdf/presentation")
|
||||
@Operation(
|
||||
summary = "Convert PDF to Presentation format",
|
||||
|
@ -7,7 +7,6 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
@ -17,6 +16,7 @@ import org.springframework.web.bind.annotation.RestController;
|
||||
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.RuntimePathConfig;
|
||||
@ -32,22 +32,13 @@ import stirling.software.SPDF.utils.WebResponseUtils;
|
||||
@Tag(name = "Convert", description = "Convert APIs")
|
||||
@Slf4j
|
||||
@RequestMapping("/api/v1/convert")
|
||||
@RequiredArgsConstructor
|
||||
public class ConvertWebsiteToPDF {
|
||||
|
||||
private final CustomPDFDocumentFactory pdfDocumentFactory;
|
||||
private final RuntimePathConfig runtimePathConfig;
|
||||
private final ApplicationProperties applicationProperties;
|
||||
|
||||
@Autowired
|
||||
public ConvertWebsiteToPDF(
|
||||
CustomPDFDocumentFactory pdfDocumentFactory,
|
||||
RuntimePathConfig runtimePathConfig,
|
||||
ApplicationProperties applicationProperties) {
|
||||
this.pdfDocumentFactory = pdfDocumentFactory;
|
||||
this.runtimePathConfig = runtimePathConfig;
|
||||
this.applicationProperties = applicationProperties;
|
||||
}
|
||||
|
||||
@PostMapping(consumes = "multipart/form-data", value = "/url/pdf")
|
||||
@Operation(
|
||||
summary = "Convert a URL to a PDF",
|
||||
|
@ -13,7 +13,6 @@ import java.util.zip.ZipOutputStream;
|
||||
import org.apache.commons.csv.CSVFormat;
|
||||
import org.apache.commons.csv.QuoteMode;
|
||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.ContentDisposition;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.MediaType;
|
||||
@ -26,6 +25,7 @@ import org.springframework.web.bind.annotation.RestController;
|
||||
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.model.api.PDFWithPageNums;
|
||||
@ -41,15 +41,11 @@ import technology.tabula.extractors.SpreadsheetExtractionAlgorithm;
|
||||
@RequestMapping("/api/v1/convert")
|
||||
@Tag(name = "Convert", description = "Convert APIs")
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
public class ExtractCSVController {
|
||||
|
||||
private final CustomPDFDocumentFactory pdfDocumentFactory;
|
||||
|
||||
@Autowired
|
||||
public ExtractCSVController(CustomPDFDocumentFactory pdfDocumentFactory) {
|
||||
this.pdfDocumentFactory = pdfDocumentFactory;
|
||||
}
|
||||
|
||||
@PostMapping(value = "/pdf/csv", consumes = "multipart/form-data")
|
||||
@Operation(
|
||||
summary = "Extracts a CSV document from a PDF",
|
||||
|
@ -5,7 +5,6 @@ import java.io.IOException;
|
||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||
import org.apache.pdfbox.pdmodel.PDPage;
|
||||
import org.apache.pdfbox.pdmodel.common.PDRectangle;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
@ -17,6 +16,8 @@ import io.github.pixee.security.Filenames;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import stirling.software.SPDF.model.api.PDFComparisonAndCount;
|
||||
import stirling.software.SPDF.model.api.PDFWithPageNums;
|
||||
import stirling.software.SPDF.model.api.filter.ContainsTextRequest;
|
||||
@ -30,15 +31,11 @@ import stirling.software.SPDF.utils.WebResponseUtils;
|
||||
@RestController
|
||||
@RequestMapping("/api/v1/filter")
|
||||
@Tag(name = "Filter", description = "Filter APIs")
|
||||
@RequiredArgsConstructor
|
||||
public class FilterController {
|
||||
|
||||
private final CustomPDFDocumentFactory pdfDocumentFactory;
|
||||
|
||||
@Autowired
|
||||
public FilterController(CustomPDFDocumentFactory pdfDocumentFactory) {
|
||||
this.pdfDocumentFactory = pdfDocumentFactory;
|
||||
}
|
||||
|
||||
@PostMapping(consumes = "multipart/form-data", value = "/filter-contains-text")
|
||||
@Operation(
|
||||
summary = "Checks if a PDF contains set text, returns true if does",
|
||||
|
@ -8,7 +8,6 @@ import java.util.List;
|
||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||
import org.apache.pdfbox.text.PDFTextStripper;
|
||||
import org.apache.pdfbox.text.TextPosition;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
@ -20,6 +19,7 @@ import io.github.pixee.security.Filenames;
|
||||
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.model.api.misc.ExtractHeaderRequest;
|
||||
@ -30,18 +30,14 @@ import stirling.software.SPDF.utils.WebResponseUtils;
|
||||
@RequestMapping("/api/v1/misc")
|
||||
@Slf4j
|
||||
@Tag(name = "Misc", description = "Miscellaneous APIs")
|
||||
@RequiredArgsConstructor
|
||||
public class AutoRenameController {
|
||||
|
||||
private static final float TITLE_FONT_SIZE_THRESHOLD = 20.0f;
|
||||
// private static final float TITLE_FONT_SIZE_THRESHOLD = 20.0f;
|
||||
private static final int LINE_LIMIT = 200;
|
||||
|
||||
private final CustomPDFDocumentFactory pdfDocumentFactory;
|
||||
|
||||
@Autowired
|
||||
public AutoRenameController(CustomPDFDocumentFactory pdfDocumentFactory) {
|
||||
this.pdfDocumentFactory = pdfDocumentFactory;
|
||||
}
|
||||
|
||||
@PostMapping(consumes = "multipart/form-data", value = "/auto-rename")
|
||||
@Operation(
|
||||
summary = "Extract header from PDF file",
|
||||
|
@ -16,7 +16,6 @@ import java.util.zip.ZipOutputStream;
|
||||
|
||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||
import org.apache.pdfbox.rendering.PDFRenderer;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||
@ -32,6 +31,7 @@ import io.github.pixee.security.Filenames;
|
||||
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.model.api.misc.AutoSplitPdfRequest;
|
||||
@ -42,6 +42,7 @@ import stirling.software.SPDF.utils.WebResponseUtils;
|
||||
@RequestMapping("/api/v1/misc")
|
||||
@Slf4j
|
||||
@Tag(name = "Misc", description = "Miscellaneous APIs")
|
||||
@RequiredArgsConstructor
|
||||
public class AutoSplitPdfController {
|
||||
|
||||
private static final Set<String> VALID_QR_CONTENTS =
|
||||
@ -53,11 +54,6 @@ public class AutoSplitPdfController {
|
||||
|
||||
private final CustomPDFDocumentFactory pdfDocumentFactory;
|
||||
|
||||
@Autowired
|
||||
public AutoSplitPdfController(CustomPDFDocumentFactory pdfDocumentFactory) {
|
||||
this.pdfDocumentFactory = pdfDocumentFactory;
|
||||
}
|
||||
|
||||
private static String decodeQRCode(BufferedImage bufferedImage) {
|
||||
LuminanceSource source;
|
||||
|
||||
|
@ -13,7 +13,6 @@ import org.apache.pdfbox.pdmodel.PDPage;
|
||||
import org.apache.pdfbox.pdmodel.PDPageTree;
|
||||
import org.apache.pdfbox.rendering.PDFRenderer;
|
||||
import org.apache.pdfbox.text.PDFTextStripper;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
@ -27,6 +26,7 @@ import io.github.pixee.security.Filenames;
|
||||
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.model.api.misc.RemoveBlankPagesRequest;
|
||||
@ -38,15 +38,11 @@ import stirling.software.SPDF.utils.WebResponseUtils;
|
||||
@RequestMapping("/api/v1/misc")
|
||||
@Slf4j
|
||||
@Tag(name = "Misc", description = "Miscellaneous APIs")
|
||||
@RequiredArgsConstructor
|
||||
public class BlankPageController {
|
||||
|
||||
private final CustomPDFDocumentFactory pdfDocumentFactory;
|
||||
|
||||
@Autowired
|
||||
public BlankPageController(CustomPDFDocumentFactory pdfDocumentFactory) {
|
||||
this.pdfDocumentFactory = pdfDocumentFactory;
|
||||
}
|
||||
|
||||
public static boolean isBlankImage(
|
||||
BufferedImage image, int threshold, double whitePercent, int blurSize) {
|
||||
if (image == null) {
|
||||
|
@ -10,7 +10,6 @@ import org.apache.pdfbox.cos.*;
|
||||
import org.apache.pdfbox.io.IOUtils;
|
||||
import org.apache.pdfbox.pdfwriter.compress.CompressParameters;
|
||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||
@ -22,6 +21,7 @@ import org.springframework.web.multipart.MultipartFile;
|
||||
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.model.api.PDFFile;
|
||||
@ -32,15 +32,11 @@ import stirling.software.SPDF.utils.WebResponseUtils;
|
||||
@RequestMapping("/api/v1/misc")
|
||||
@Slf4j
|
||||
@Tag(name = "Misc", description = "Miscellaneous APIs")
|
||||
@RequiredArgsConstructor
|
||||
public class DecompressPdfController {
|
||||
|
||||
private final CustomPDFDocumentFactory pdfDocumentFactory;
|
||||
|
||||
@Autowired
|
||||
public DecompressPdfController(CustomPDFDocumentFactory pdfDocumentFactory) {
|
||||
this.pdfDocumentFactory = pdfDocumentFactory;
|
||||
}
|
||||
|
||||
@PostMapping(value = "/decompress-pdf", consumes = "multipart/form-data")
|
||||
@Operation(
|
||||
summary = "Decompress PDF streams",
|
||||
|
@ -16,7 +16,6 @@ import javax.imageio.ImageIO;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||
import org.apache.pdfbox.rendering.PDFRenderer;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
@ -29,6 +28,7 @@ import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import io.swagger.v3.oas.annotations.parameters.RequestBody;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import stirling.software.SPDF.model.api.misc.ExtractImageScansRequest;
|
||||
@ -42,17 +42,13 @@ import stirling.software.SPDF.utils.WebResponseUtils;
|
||||
@RequestMapping("/api/v1/misc")
|
||||
@Slf4j
|
||||
@Tag(name = "Misc", description = "Miscellaneous APIs")
|
||||
@RequiredArgsConstructor
|
||||
public class ExtractImageScansController {
|
||||
|
||||
private static final String REPLACEFIRST = "[.][^.]+$";
|
||||
|
||||
private final CustomPDFDocumentFactory pdfDocumentFactory;
|
||||
|
||||
@Autowired
|
||||
public ExtractImageScansController(CustomPDFDocumentFactory pdfDocumentFactory) {
|
||||
this.pdfDocumentFactory = pdfDocumentFactory;
|
||||
}
|
||||
|
||||
@PostMapping(consumes = "multipart/form-data", value = "/extract-image-scans")
|
||||
@Operation(
|
||||
summary = "Extract image scans from an input file",
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user