Compare commits
16 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f7add727a6 | ||
|
|
cd947c2554 | ||
|
|
9422a30ebf | ||
|
|
ed273a6e92 | ||
|
|
0136c25e1d | ||
|
|
cf03bdc17b | ||
|
|
093b882141 | ||
|
|
46507f10b6 | ||
|
|
54fbf666fd | ||
|
|
faecaf1ee4 | ||
|
|
a062b36ee5 | ||
|
|
00b6d60309 | ||
|
|
1e0121b4d6 | ||
|
|
d7a3708a13 | ||
|
|
73ac17942f | ||
|
|
54e599a18b |
2
.github/labeler-config.yml
vendored
2
.github/labeler-config.yml
vendored
@@ -9,7 +9,6 @@ Front End:
|
|||||||
- any-glob-to-any-file: 'src/main/resources/templates/**/*'
|
- any-glob-to-any-file: 'src/main/resources/templates/**/*'
|
||||||
- any-glob-to-any-file: 'src/main/resources/static/**/*'
|
- any-glob-to-any-file: 'src/main/resources/static/**/*'
|
||||||
- any-glob-to-any-file: 'src/main/java/stirling/software/SPDF/controller/web/**'
|
- any-glob-to-any-file: 'src/main/java/stirling/software/SPDF/controller/web/**'
|
||||||
- any-glob-to-any-file: 'src/main/java/stirling/software/SPDF/UI/**/*'
|
|
||||||
|
|
||||||
Java:
|
Java:
|
||||||
- changed-files:
|
- changed-files:
|
||||||
@@ -30,7 +29,6 @@ Security:
|
|||||||
- any-glob-to-any-file: 'src/main/java/stirling/software/SPDF/config/security/**/*'
|
- any-glob-to-any-file: 'src/main/java/stirling/software/SPDF/config/security/**/*'
|
||||||
- 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/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/AuthenticationType.java'
|
||||||
- any-glob-to-any-file: 'src/main/java/stirling/software/SPDF/model/BackupNotFoundException.java'
|
|
||||||
- any-glob-to-any-file: 'scripts/download-security-jar.sh'
|
- 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/dependency-review.yml'
|
||||||
- any-glob-to-any-file: '.github/workflows/scorecards.yml'
|
- any-glob-to-any-file: '.github/workflows/scorecards.yml'
|
||||||
|
|||||||
3
.github/workflows/PR-Demo-Comment.yml
vendored
3
.github/workflows/PR-Demo-Comment.yml
vendored
@@ -26,8 +26,7 @@ jobs:
|
|||||||
github.event.comment.user.login == 'Ludy87' ||
|
github.event.comment.user.login == 'Ludy87' ||
|
||||||
github.event.comment.user.login == 'LaserKaspar' ||
|
github.event.comment.user.login == 'LaserKaspar' ||
|
||||||
github.event.comment.user.login == 'sbplat' ||
|
github.event.comment.user.login == 'sbplat' ||
|
||||||
github.event.comment.user.login == 'reecebrowne' ||
|
github.event.comment.user.login == 'reecebrowne'
|
||||||
github.event.comment.user.login == 'DarioGii'
|
|
||||||
)
|
)
|
||||||
outputs:
|
outputs:
|
||||||
pr_number: ${{ steps.get-pr.outputs.pr_number }}
|
pr_number: ${{ steps.get-pr.outputs.pr_number }}
|
||||||
|
|||||||
6
.github/workflows/build.yml
vendored
6
.github/workflows/build.yml
vendored
@@ -49,7 +49,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Upload Test Reports
|
- name: Upload Test Reports
|
||||||
if: always()
|
if: always()
|
||||||
uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: test-reports-jdk-${{ matrix.jdk-version }}
|
name: test-reports-jdk-${{ matrix.jdk-version }}
|
||||||
path: |
|
path: |
|
||||||
@@ -57,7 +57,7 @@ jobs:
|
|||||||
build/test-results/
|
build/test-results/
|
||||||
build/reports/problems/
|
build/reports/problems/
|
||||||
retention-days: 3
|
retention-days: 3
|
||||||
|
|
||||||
docker-compose-tests:
|
docker-compose-tests:
|
||||||
# if: github.event_name == 'push' && github.ref == 'refs/heads/main' ||
|
# if: github.event_name == 'push' && github.ref == 'refs/heads/main' ||
|
||||||
# (github.event_name == 'pull_request' &&
|
# (github.event_name == 'pull_request' &&
|
||||||
@@ -105,7 +105,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Pip requirements
|
- name: Pip requirements
|
||||||
run: |
|
run: |
|
||||||
pip install --require-hashes -r ./cucumber/requirements.txt
|
pip install -r ./cucumber/requirements.txt
|
||||||
|
|
||||||
- name: Run Docker Compose Tests
|
- name: Run Docker Compose Tests
|
||||||
run: |
|
run: |
|
||||||
|
|||||||
2
.github/workflows/check_properties.yml
vendored
2
.github/workflows/check_properties.yml
vendored
@@ -28,7 +28,7 @@ jobs:
|
|||||||
- name: Set up Python
|
- name: Set up Python
|
||||||
uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b # v5.3.0
|
uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b # v5.3.0
|
||||||
with:
|
with:
|
||||||
python-version: "3.12"
|
python-version: "3.x"
|
||||||
|
|
||||||
- name: Get PR data
|
- name: Get PR data
|
||||||
id: get-pr-data
|
id: get-pr-data
|
||||||
|
|||||||
2
.github/workflows/sync_files.yml
vendored
2
.github/workflows/sync_files.yml
vendored
@@ -28,7 +28,7 @@ jobs:
|
|||||||
- name: Set up Python
|
- name: Set up Python
|
||||||
uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b # v5.3.0
|
uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b # v5.3.0
|
||||||
with:
|
with:
|
||||||
python-version: "3.12"
|
python-version: "3.x"
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: pip install tomlkit
|
run: pip install tomlkit
|
||||||
- name: Sync README
|
- name: Sync README
|
||||||
|
|||||||
2
.github/workflows/update-translations.yml
vendored
2
.github/workflows/update-translations.yml
vendored
@@ -28,7 +28,7 @@ jobs:
|
|||||||
- name: Set up Python
|
- name: Set up Python
|
||||||
uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b # v5.3.0
|
uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b # v5.3.0
|
||||||
with:
|
with:
|
||||||
python-version: "3.12"
|
python-version: "3.x"
|
||||||
|
|
||||||
- name: Run Python script to check files
|
- name: Run Python script to check files
|
||||||
id: run-check
|
id: run-check
|
||||||
|
|||||||
74
README.md
74
README.md
@@ -14,9 +14,8 @@
|
|||||||
|
|
||||||
All files and PDFs exist either exclusively on the client side, reside in server memory only during task execution, or temporarily reside in a file solely for the execution of the task. Any file downloaded by the user will have been deleted from the server by that point.
|
All files and PDFs exist either exclusively on the client side, reside in server memory only during task execution, or temporarily reside in a file solely for the execution of the task. Any file downloaded by the user will have been deleted from the server by that point.
|
||||||
|
|
||||||
Homepage: [https://stirlingpdf.com](https://stirlingpdf.com)
|
|
||||||
|
|
||||||
All documentation available at [https://docs.stirlingpdf.com/](https://docs.stirlingpdf.com/)
|
All information available at [https://docs.stirlingpdf.com/](https://docs.stirlingpdf.com/)
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
@@ -117,45 +116,44 @@ Stirling-PDF currently supports 38 languages!
|
|||||||
|
|
||||||
| Language | Progress |
|
| Language | Progress |
|
||||||
| -------------------------------------------- | -------------------------------------- |
|
| -------------------------------------------- | -------------------------------------- |
|
||||||
| Arabic (العربية) (ar_AR) |  |
|
| Arabic (العربية) (ar_AR) |  |
|
||||||
| Azerbaijani (Azərbaycan Dili) (az_AZ) |  |
|
| Azerbaijani (Azərbaycan Dili) (az_AZ) |  |
|
||||||
| Basque (Euskara) (eu_ES) |  |
|
| Basque (Euskara) (eu_ES) |  |
|
||||||
| Bulgarian (Български) (bg_BG) |  |
|
| Bulgarian (Български) (bg_BG) |  |
|
||||||
| Catalan (Català) (ca_CA) |  |
|
| Catalan (Català) (ca_CA) |  |
|
||||||
| Croatian (Hrvatski) (hr_HR) |  |
|
| Croatian (Hrvatski) (hr_HR) |  |
|
||||||
| Czech (Česky) (cs_CZ) |  |
|
| Czech (Česky) (cs_CZ) |  |
|
||||||
| Danish (Dansk) (da_DK) |  |
|
| Danish (Dansk) (da_DK) |  |
|
||||||
| Dutch (Nederlands) (nl_NL) |  |
|
| Dutch (Nederlands) (nl_NL) |  |
|
||||||
| English (English) (en_GB) |  |
|
| English (English) (en_GB) |  |
|
||||||
| English (US) (en_US) |  |
|
| English (US) (en_US) |  |
|
||||||
| French (Français) (fr_FR) |  |
|
| French (Français) (fr_FR) |  |
|
||||||
| German (Deutsch) (de_DE) |  |
|
| German (Deutsch) (de_DE) |  |
|
||||||
| Greek (Ελληνικά) (el_GR) |  |
|
| Greek (Ελληνικά) (el_GR) |  |
|
||||||
| Hindi (हिंदी) (hi_IN) |  |
|
| Hindi (हिंदी) (hi_IN) |  |
|
||||||
| Hungarian (Magyar) (hu_HU) |  |
|
| Hungarian (Magyar) (hu_HU) |  |
|
||||||
| Indonesian (Bahasa Indonesia) (id_ID) |  |
|
| Indonesian (Bahasa Indonesia) (id_ID) |  |
|
||||||
| Irish (Gaeilge) (ga_IE) |  |
|
| Irish (Gaeilge) (ga_IE) |  |
|
||||||
| Italian (Italiano) (it_IT) |  |
|
| Italian (Italiano) (it_IT) |  |
|
||||||
| Japanese (日本語) (ja_JP) |  |
|
| Japanese (日本語) (ja_JP) |  |
|
||||||
| Korean (한국어) (ko_KR) |  |
|
| Korean (한국어) (ko_KR) |  |
|
||||||
| Norwegian (Norsk) (no_NB) |  |
|
| Norwegian (Norsk) (no_NB) |  |
|
||||||
| Persian (فارسی) (fa_IR) |  |
|
| Persian (فارسی) (fa_IR) |  |
|
||||||
| Polish (Polski) (pl_PL) |  |
|
| Polish (Polski) (pl_PL) |  |
|
||||||
| Portuguese (Português) (pt_PT) |  |
|
| Portuguese (Português) (pt_PT) |  |
|
||||||
| Portuguese Brazilian (Português) (pt_BR) |  |
|
| Portuguese Brazilian (Português) (pt_BR) |  |
|
||||||
| Romanian (Română) (ro_RO) |  |
|
| Romanian (Română) (ro_RO) |  |
|
||||||
| Russian (Русский) (ru_RU) |  |
|
| Russian (Русский) (ru_RU) |  |
|
||||||
| Serbian Latin alphabet (Srpski) (sr_LATN_RS) |  |
|
| Serbian Latin alphabet (Srpski) (sr_LATN_RS) |  |
|
||||||
| Simplified Chinese (简体中文) (zh_CN) |  |
|
| Simplified Chinese (简体中文) (zh_CN) |  |
|
||||||
| Slovakian (Slovensky) (sk_SK) |  |
|
| Slovakian (Slovensky) (sk_SK) |  |
|
||||||
| Spanish (Español) (es_ES) |  |
|
| Spanish (Español) (es_ES) |  |
|
||||||
| Swedish (Svenska) (sv_SE) |  |
|
| Swedish (Svenska) (sv_SE) |  |
|
||||||
| Thai (ไทย) (th_TH) |  |
|
| Thai (ไทย) (th_TH) |  |
|
||||||
| Tibetan (བོད་ཡིག་) (zh_BO) |  |
|
| Traditional Chinese (繁體中文) (zh_TW) |  |
|
||||||
| Traditional Chinese (繁體中文) (zh_TW) |  |
|
| Turkish (Türkçe) (tr_TR) |  |
|
||||||
| Turkish (Türkçe) (tr_TR) |  |
|
| Ukrainian (Українська) (uk_UA) |  |
|
||||||
| Ukrainian (Українська) (uk_UA) |  |
|
| Vietnamese (Tiếng Việt) (vi_VN) |  |
|
||||||
| Vietnamese (Tiếng Việt) (vi_VN) |  |
|
|
||||||
|
|
||||||
|
|
||||||
## Stirling PDF Enterprise
|
## Stirling PDF Enterprise
|
||||||
|
|||||||
30
build.gradle
30
build.gradle
@@ -52,15 +52,13 @@ sourceSets {
|
|||||||
java {
|
java {
|
||||||
if (System.getenv("DOCKER_ENABLE_SECURITY") == "false") {
|
if (System.getenv("DOCKER_ENABLE_SECURITY") == "false") {
|
||||||
exclude "stirling/software/SPDF/config/security/**"
|
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/UserController.java"
|
||||||
exclude "stirling/software/SPDF/controller/api/H2SQLCondition.java"
|
exclude "stirling/software/SPDF/controller/api/DatabaseController.java"
|
||||||
exclude "stirling/software/SPDF/controller/web/AccountWebController.java"
|
exclude "stirling/software/SPDF/controller/web/AccountWebController.java"
|
||||||
exclude "stirling/software/SPDF/controller/web/DatabaseWebController.java"
|
exclude "stirling/software/SPDF/controller/web/DatabaseWebController.java"
|
||||||
exclude "stirling/software/SPDF/model/ApiKeyAuthenticationToken.java"
|
exclude "stirling/software/SPDF/model/ApiKeyAuthenticationToken.java"
|
||||||
exclude "stirling/software/SPDF/model/AttemptCounter.java"
|
exclude "stirling/software/SPDF/model/AttemptCounter.java"
|
||||||
exclude "stirling/software/SPDF/model/Authority.java"
|
exclude "stirling/software/SPDF/model/Authority.java"
|
||||||
exclude "stirling/software/SPDF/model/BackupNotFoundException.java"
|
|
||||||
exclude "stirling/software/SPDF/model/PersistentLogin.java"
|
exclude "stirling/software/SPDF/model/PersistentLogin.java"
|
||||||
exclude "stirling/software/SPDF/model/SessionEntity.java"
|
exclude "stirling/software/SPDF/model/SessionEntity.java"
|
||||||
exclude "stirling/software/SPDF/model/User.java"
|
exclude "stirling/software/SPDF/model/User.java"
|
||||||
@@ -71,29 +69,7 @@ sourceSets {
|
|||||||
exclude "stirling/software/SPDF/UI/impl/**"
|
exclude "stirling/software/SPDF/UI/impl/**"
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
test {
|
|
||||||
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/repository/**"
|
|
||||||
}
|
|
||||||
|
|
||||||
if (System.getenv("STIRLING_PDF_DESKTOP_UI") == "false") {
|
|
||||||
exclude "stirling/software/SPDF/UI/impl/**"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -147,7 +123,7 @@ jpackage {
|
|||||||
windows {
|
windows {
|
||||||
launcherAsService = false
|
launcherAsService = false
|
||||||
appVersion = project.version
|
appVersion = project.version
|
||||||
|
|
||||||
winConsole = false
|
winConsole = false
|
||||||
winMenu = true // Creates start menu entry
|
winMenu = true // Creates start menu entry
|
||||||
winShortcut = true // Creates desktop shortcut
|
winShortcut = true // Creates desktop shortcut
|
||||||
@@ -323,12 +299,10 @@ dependencies {
|
|||||||
implementation "org.springframework.boot:spring-boot-starter-oauth2-client:$springBootVersion"
|
implementation "org.springframework.boot:spring-boot-starter-oauth2-client:$springBootVersion"
|
||||||
|
|
||||||
implementation "org.springframework.session:spring-session-core:$springBootVersion"
|
implementation "org.springframework.session:spring-session-core:$springBootVersion"
|
||||||
implementation "org.springframework:spring-jdbc:6.2.1"
|
|
||||||
|
|
||||||
implementation 'com.unboundid.product.scim2:scim2-sdk-client:2.3.5'
|
implementation 'com.unboundid.product.scim2:scim2-sdk-client:2.3.5'
|
||||||
// Don't upgrade h2database
|
// Don't upgrade h2database
|
||||||
runtimeOnly "com.h2database:h2:2.3.232"
|
runtimeOnly "com.h2database:h2:2.3.232"
|
||||||
runtimeOnly "org.postgresql:postgresql:42.7.4"
|
|
||||||
constraints {
|
constraints {
|
||||||
implementation "org.opensaml:opensaml-core:$openSamlVersion"
|
implementation "org.opensaml:opensaml-core:$openSamlVersion"
|
||||||
implementation "org.opensaml:opensaml-saml-api:$openSamlVersion"
|
implementation "org.opensaml:opensaml-saml-api:$openSamlVersion"
|
||||||
|
|||||||
@@ -1,5 +0,0 @@
|
|||||||
behave
|
|
||||||
requests
|
|
||||||
PyPDF2
|
|
||||||
reportlab
|
|
||||||
PyCryptodome
|
|
||||||
@@ -1,255 +1,5 @@
|
|||||||
#
|
behave
|
||||||
# This file is autogenerated by pip-compile with Python 3.10
|
requests
|
||||||
# by the following command:
|
PyPDF2
|
||||||
#
|
reportlab
|
||||||
# pip-compile --generate-hashes --output-file='cucumber\requirements.txt' 'cucumber\requirements.in'
|
PyCryptodome
|
||||||
#
|
|
||||||
behave==1.2.6 \
|
|
||||||
--hash=sha256:b9662327aa53294c1351b0a9c369093ccec1d21026f050c3bd9b3e5cccf81a86 \
|
|
||||||
--hash=sha256:ebda1a6c9e5bfe95c5f9f0a2794e01c7098b3dde86c10a95d8621c5907ff6f1c
|
|
||||||
# via -r cucumber\requirements.in
|
|
||||||
certifi==2024.12.14 \
|
|
||||||
--hash=sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56 \
|
|
||||||
--hash=sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db
|
|
||||||
# via requests
|
|
||||||
chardet==5.2.0 \
|
|
||||||
--hash=sha256:1b3b6ff479a8c414bc3fa2c0852995695c4a026dcd6d0633b2dd092ca39c1cf7 \
|
|
||||||
--hash=sha256:e1cf59446890a00105fe7b7912492ea04b6e6f06d4b742b2c788469e34c82970
|
|
||||||
# via reportlab
|
|
||||||
charset-normalizer==3.4.1 \
|
|
||||||
--hash=sha256:0167ddc8ab6508fe81860a57dd472b2ef4060e8d378f0cc555707126830f2537 \
|
|
||||||
--hash=sha256:01732659ba9b5b873fc117534143e4feefecf3b2078b0a6a2e925271bb6f4cfa \
|
|
||||||
--hash=sha256:01ad647cdd609225c5350561d084b42ddf732f4eeefe6e678765636791e78b9a \
|
|
||||||
--hash=sha256:04432ad9479fa40ec0f387795ddad4437a2b50417c69fa275e212933519ff294 \
|
|
||||||
--hash=sha256:0907f11d019260cdc3f94fbdb23ff9125f6b5d1039b76003b5b0ac9d6a6c9d5b \
|
|
||||||
--hash=sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd \
|
|
||||||
--hash=sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601 \
|
|
||||||
--hash=sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd \
|
|
||||||
--hash=sha256:0af291f4fe114be0280cdd29d533696a77b5b49cfde5467176ecab32353395c4 \
|
|
||||||
--hash=sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d \
|
|
||||||
--hash=sha256:1a2bc9f351a75ef49d664206d51f8e5ede9da246602dc2d2726837620ea034b2 \
|
|
||||||
--hash=sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313 \
|
|
||||||
--hash=sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd \
|
|
||||||
--hash=sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa \
|
|
||||||
--hash=sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8 \
|
|
||||||
--hash=sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1 \
|
|
||||||
--hash=sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2 \
|
|
||||||
--hash=sha256:2a75d49014d118e4198bcee5ee0a6f25856b29b12dbf7cd012791f8a6cc5c496 \
|
|
||||||
--hash=sha256:2bdfe3ac2e1bbe5b59a1a63721eb3b95fc9b6817ae4a46debbb4e11f6232428d \
|
|
||||||
--hash=sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b \
|
|
||||||
--hash=sha256:2fb9bd477fdea8684f78791a6de97a953c51831ee2981f8e4f583ff3b9d9687e \
|
|
||||||
--hash=sha256:311f30128d7d333eebd7896965bfcfbd0065f1716ec92bd5638d7748eb6f936a \
|
|
||||||
--hash=sha256:329ce159e82018d646c7ac45b01a430369d526569ec08516081727a20e9e4af4 \
|
|
||||||
--hash=sha256:345b0426edd4e18138d6528aed636de7a9ed169b4aaf9d61a8c19e39d26838ca \
|
|
||||||
--hash=sha256:363e2f92b0f0174b2f8238240a1a30142e3db7b957a5dd5689b0e75fb717cc78 \
|
|
||||||
--hash=sha256:3a3bd0dcd373514dcec91c411ddb9632c0d7d92aed7093b8c3bbb6d69ca74408 \
|
|
||||||
--hash=sha256:3bed14e9c89dcb10e8f3a29f9ccac4955aebe93c71ae803af79265c9ca5644c5 \
|
|
||||||
--hash=sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3 \
|
|
||||||
--hash=sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f \
|
|
||||||
--hash=sha256:4532bff1b8421fd0a320463030c7520f56a79c9024a4e88f01c537316019005a \
|
|
||||||
--hash=sha256:49402233c892a461407c512a19435d1ce275543138294f7ef013f0b63d5d3765 \
|
|
||||||
--hash=sha256:4c0907b1928a36d5a998d72d64d8eaa7244989f7aaaf947500d3a800c83a3fd6 \
|
|
||||||
--hash=sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146 \
|
|
||||||
--hash=sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6 \
|
|
||||||
--hash=sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9 \
|
|
||||||
--hash=sha256:619a609aa74ae43d90ed2e89bdd784765de0a25ca761b93e196d938b8fd1dbbd \
|
|
||||||
--hash=sha256:6e27f48bcd0957c6d4cb9d6fa6b61d192d0b13d5ef563e5f2ae35feafc0d179c \
|
|
||||||
--hash=sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f \
|
|
||||||
--hash=sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545 \
|
|
||||||
--hash=sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176 \
|
|
||||||
--hash=sha256:75832c08354f595c760a804588b9357d34ec00ba1c940c15e31e96d902093770 \
|
|
||||||
--hash=sha256:7709f51f5f7c853f0fb938bcd3bc59cdfdc5203635ffd18bf354f6967ea0f824 \
|
|
||||||
--hash=sha256:78baa6d91634dfb69ec52a463534bc0df05dbd546209b79a3880a34487f4b84f \
|
|
||||||
--hash=sha256:7974a0b5ecd505609e3b19742b60cee7aa2aa2fb3151bc917e6e2646d7667dcf \
|
|
||||||
--hash=sha256:7a4f97a081603d2050bfaffdefa5b02a9ec823f8348a572e39032caa8404a487 \
|
|
||||||
--hash=sha256:7b1bef6280950ee6c177b326508f86cad7ad4dff12454483b51d8b7d673a2c5d \
|
|
||||||
--hash=sha256:7d053096f67cd1241601111b698f5cad775f97ab25d81567d3f59219b5f1adbd \
|
|
||||||
--hash=sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b \
|
|
||||||
--hash=sha256:807f52c1f798eef6cf26beb819eeb8819b1622ddfeef9d0977a8502d4db6d534 \
|
|
||||||
--hash=sha256:80ed5e856eb7f30115aaf94e4a08114ccc8813e6ed1b5efa74f9f82e8509858f \
|
|
||||||
--hash=sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b \
|
|
||||||
--hash=sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9 \
|
|
||||||
--hash=sha256:89149166622f4db9b4b6a449256291dc87a99ee53151c74cbd82a53c8c2f6ccd \
|
|
||||||
--hash=sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125 \
|
|
||||||
--hash=sha256:8c60ca7339acd497a55b0ea5d506b2a2612afb2826560416f6894e8b5770d4a9 \
|
|
||||||
--hash=sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de \
|
|
||||||
--hash=sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11 \
|
|
||||||
--hash=sha256:97f68b8d6831127e4787ad15e6757232e14e12060bec17091b85eb1486b91d8d \
|
|
||||||
--hash=sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35 \
|
|
||||||
--hash=sha256:9f0b8b1c6d84c8034a44893aba5e767bf9c7a211e313a9605d9c617d7083829f \
|
|
||||||
--hash=sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda \
|
|
||||||
--hash=sha256:ab36c8eb7e454e34e60eb55ca5d241a5d18b2c6244f6827a30e451c42410b5f7 \
|
|
||||||
--hash=sha256:b010a7a4fd316c3c484d482922d13044979e78d1861f0e0650423144c616a46a \
|
|
||||||
--hash=sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971 \
|
|
||||||
--hash=sha256:b7b2d86dd06bfc2ade3312a83a5c364c7ec2e3498f8734282c6c3d4b07b346b8 \
|
|
||||||
--hash=sha256:b97e690a2118911e39b4042088092771b4ae3fc3aa86518f84b8cf6888dbdb41 \
|
|
||||||
--hash=sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d \
|
|
||||||
--hash=sha256:c0429126cf75e16c4f0ad00ee0eae4242dc652290f940152ca8c75c3a4b6ee8f \
|
|
||||||
--hash=sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757 \
|
|
||||||
--hash=sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a \
|
|
||||||
--hash=sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886 \
|
|
||||||
--hash=sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77 \
|
|
||||||
--hash=sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76 \
|
|
||||||
--hash=sha256:d973f03c0cb71c5ed99037b870f2be986c3c05e63622c017ea9816881d2dd247 \
|
|
||||||
--hash=sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85 \
|
|
||||||
--hash=sha256:d9c3cdf5390dcd29aa8056d13e8e99526cda0305acc038b96b30352aff5ff2bb \
|
|
||||||
--hash=sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7 \
|
|
||||||
--hash=sha256:dccbe65bd2f7f7ec22c4ff99ed56faa1e9f785482b9bbd7c717e26fd723a1d1e \
|
|
||||||
--hash=sha256:dd78cfcda14a1ef52584dbb008f7ac81c1328c0f58184bf9a84c49c605002da6 \
|
|
||||||
--hash=sha256:e218488cd232553829be0664c2292d3af2eeeb94b32bea483cf79ac6a694e037 \
|
|
||||||
--hash=sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1 \
|
|
||||||
--hash=sha256:ea0d8d539afa5eb2728aa1932a988a9a7af94f18582ffae4bc10b3fbdad0626e \
|
|
||||||
--hash=sha256:eab677309cdb30d047996b36d34caeda1dc91149e4fdca0b1a039b3f79d9a807 \
|
|
||||||
--hash=sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407 \
|
|
||||||
--hash=sha256:ecddf25bee22fe4fe3737a399d0d177d72bc22be6913acfab364b40bce1ba83c \
|
|
||||||
--hash=sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12 \
|
|
||||||
--hash=sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3 \
|
|
||||||
--hash=sha256:f30bf9fd9be89ecb2360c7d94a711f00c09b976258846efe40db3d05828e8089 \
|
|
||||||
--hash=sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd \
|
|
||||||
--hash=sha256:fc54db6c8593ef7d4b2a331b58653356cf04f67c960f584edb7c3d8c97e8f39e \
|
|
||||||
--hash=sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00 \
|
|
||||||
--hash=sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616
|
|
||||||
# via requests
|
|
||||||
idna==3.10 \
|
|
||||||
--hash=sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9 \
|
|
||||||
--hash=sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3
|
|
||||||
# via requests
|
|
||||||
parse==1.20.2 \
|
|
||||||
--hash=sha256:967095588cb802add9177d0c0b6133b5ba33b1ea9007ca800e526f42a85af558 \
|
|
||||||
--hash=sha256:b41d604d16503c79d81af5165155c0b20f6c8d6c559efa66b4b695c3e5a0a0ce
|
|
||||||
# via
|
|
||||||
# behave
|
|
||||||
# parse-type
|
|
||||||
parse-type==0.6.4 \
|
|
||||||
--hash=sha256:5e1ec10440b000c3f818006033372939e693a9ec0176f446d9303e4db88489a6 \
|
|
||||||
--hash=sha256:83d41144a82d6b8541127bf212dd76c7f01baff680b498ce8a4d052a7a5bce4c
|
|
||||||
# via behave
|
|
||||||
pillow==11.1.0 \
|
|
||||||
--hash=sha256:015c6e863faa4779251436db398ae75051469f7c903b043a48f078e437656f83 \
|
|
||||||
--hash=sha256:0a2f91f8a8b367e7a57c6e91cd25af510168091fb89ec5146003e424e1558a96 \
|
|
||||||
--hash=sha256:11633d58b6ee5733bde153a8dafd25e505ea3d32e261accd388827ee987baf65 \
|
|
||||||
--hash=sha256:2062ffb1d36544d42fcaa277b069c88b01bb7298f4efa06731a7fd6cc290b81a \
|
|
||||||
--hash=sha256:31eba6bbdd27dde97b0174ddf0297d7a9c3a507a8a1480e1e60ef914fe23d352 \
|
|
||||||
--hash=sha256:3362c6ca227e65c54bf71a5f88b3d4565ff1bcbc63ae72c34b07bbb1cc59a43f \
|
|
||||||
--hash=sha256:368da70808b36d73b4b390a8ffac11069f8a5c85f29eff1f1b01bcf3ef5b2a20 \
|
|
||||||
--hash=sha256:36ba10b9cb413e7c7dfa3e189aba252deee0602c86c309799da5a74009ac7a1c \
|
|
||||||
--hash=sha256:3764d53e09cdedd91bee65c2527815d315c6b90d7b8b79759cc48d7bf5d4f114 \
|
|
||||||
--hash=sha256:3a5fe20a7b66e8135d7fd617b13272626a28278d0e578c98720d9ba4b2439d49 \
|
|
||||||
--hash=sha256:3cdcdb0b896e981678eee140d882b70092dac83ac1cdf6b3a60e2216a73f2b91 \
|
|
||||||
--hash=sha256:4637b88343166249fe8aa94e7c4a62a180c4b3898283bb5d3d2fd5fe10d8e4e0 \
|
|
||||||
--hash=sha256:4db853948ce4e718f2fc775b75c37ba2efb6aaea41a1a5fc57f0af59eee774b2 \
|
|
||||||
--hash=sha256:4dd43a78897793f60766563969442020e90eb7847463eca901e41ba186a7d4a5 \
|
|
||||||
--hash=sha256:54251ef02a2309b5eec99d151ebf5c9904b77976c8abdcbce7891ed22df53884 \
|
|
||||||
--hash=sha256:54ce1c9a16a9561b6d6d8cb30089ab1e5eb66918cb47d457bd996ef34182922e \
|
|
||||||
--hash=sha256:593c5fd6be85da83656b93ffcccc2312d2d149d251e98588b14fbc288fd8909c \
|
|
||||||
--hash=sha256:5bb94705aea800051a743aa4874bb1397d4695fb0583ba5e425ee0328757f196 \
|
|
||||||
--hash=sha256:67cd427c68926108778a9005f2a04adbd5e67c442ed21d95389fe1d595458756 \
|
|
||||||
--hash=sha256:70ca5ef3b3b1c4a0812b5c63c57c23b63e53bc38e758b37a951e5bc466449861 \
|
|
||||||
--hash=sha256:73ddde795ee9b06257dac5ad42fcb07f3b9b813f8c1f7f870f402f4dc54b5269 \
|
|
||||||
--hash=sha256:758e9d4ef15d3560214cddbc97b8ef3ef86ce04d62ddac17ad39ba87e89bd3b1 \
|
|
||||||
--hash=sha256:7d33d2fae0e8b170b6a6c57400e077412240f6f5bb2a342cf1ee512a787942bb \
|
|
||||||
--hash=sha256:7fdadc077553621911f27ce206ffcbec7d3f8d7b50e0da39f10997e8e2bb7f6a \
|
|
||||||
--hash=sha256:8000376f139d4d38d6851eb149b321a52bb8893a88dae8ee7d95840431977081 \
|
|
||||||
--hash=sha256:837060a8599b8f5d402e97197d4924f05a2e0d68756998345c829c33186217b1 \
|
|
||||||
--hash=sha256:89dbdb3e6e9594d512780a5a1c42801879628b38e3efc7038094430844e271d8 \
|
|
||||||
--hash=sha256:8c730dc3a83e5ac137fbc92dfcfe1511ce3b2b5d7578315b63dbbb76f7f51d90 \
|
|
||||||
--hash=sha256:8e275ee4cb11c262bd108ab2081f750db2a1c0b8c12c1897f27b160c8bd57bbc \
|
|
||||||
--hash=sha256:9044b5e4f7083f209c4e35aa5dd54b1dd5b112b108648f5c902ad586d4f945c5 \
|
|
||||||
--hash=sha256:93a18841d09bcdd774dcdc308e4537e1f867b3dec059c131fde0327899734aa1 \
|
|
||||||
--hash=sha256:9409c080586d1f683df3f184f20e36fb647f2e0bc3988094d4fd8c9f4eb1b3b3 \
|
|
||||||
--hash=sha256:96f82000e12f23e4f29346e42702b6ed9a2f2fea34a740dd5ffffcc8c539eb35 \
|
|
||||||
--hash=sha256:9aa9aeddeed452b2f616ff5507459e7bab436916ccb10961c4a382cd3e03f47f \
|
|
||||||
--hash=sha256:9ee85f0696a17dd28fbcfceb59f9510aa71934b483d1f5601d1030c3c8304f3c \
|
|
||||||
--hash=sha256:a07dba04c5e22824816b2615ad7a7484432d7f540e6fa86af60d2de57b0fcee2 \
|
|
||||||
--hash=sha256:a3cd561ded2cf2bbae44d4605837221b987c216cff94f49dfeed63488bb228d2 \
|
|
||||||
--hash=sha256:a697cd8ba0383bba3d2d3ada02b34ed268cb548b369943cd349007730c92bddf \
|
|
||||||
--hash=sha256:a76da0a31da6fcae4210aa94fd779c65c75786bc9af06289cd1c184451ef7a65 \
|
|
||||||
--hash=sha256:a85b653980faad27e88b141348707ceeef8a1186f75ecc600c395dcac19f385b \
|
|
||||||
--hash=sha256:a8d65b38173085f24bc07f8b6c505cbb7418009fa1a1fcb111b1f4961814a442 \
|
|
||||||
--hash=sha256:aa8dd43daa836b9a8128dbe7d923423e5ad86f50a7a14dc688194b7be5c0dea2 \
|
|
||||||
--hash=sha256:ab8a209b8485d3db694fa97a896d96dd6533d63c22829043fd9de627060beade \
|
|
||||||
--hash=sha256:abc56501c3fd148d60659aae0af6ddc149660469082859fa7b066a298bde9482 \
|
|
||||||
--hash=sha256:ad5db5781c774ab9a9b2c4302bbf0c1014960a0a7be63278d13ae6fdf88126fe \
|
|
||||||
--hash=sha256:ae98e14432d458fc3de11a77ccb3ae65ddce70f730e7c76140653048c71bfcbc \
|
|
||||||
--hash=sha256:b20be51b37a75cc54c2c55def3fa2c65bb94ba859dde241cd0a4fd302de5ae0a \
|
|
||||||
--hash=sha256:b523466b1a31d0dcef7c5be1f20b942919b62fd6e9a9be199d035509cbefc0ec \
|
|
||||||
--hash=sha256:b5d658fbd9f0d6eea113aea286b21d3cd4d3fd978157cbf2447a6035916506d3 \
|
|
||||||
--hash=sha256:b6123aa4a59d75f06e9dd3dac5bf8bc9aa383121bb3dd9a7a612e05eabc9961a \
|
|
||||||
--hash=sha256:bd165131fd51697e22421d0e467997ad31621b74bfc0b75956608cb2906dda07 \
|
|
||||||
--hash=sha256:bf902d7413c82a1bfa08b06a070876132a5ae6b2388e2712aab3a7cbc02205c6 \
|
|
||||||
--hash=sha256:c12fc111ef090845de2bb15009372175d76ac99969bdf31e2ce9b42e4b8cd88f \
|
|
||||||
--hash=sha256:c1eec9d950b6fe688edee07138993e54ee4ae634c51443cfb7c1e7613322718e \
|
|
||||||
--hash=sha256:c640e5a06869c75994624551f45e5506e4256562ead981cce820d5ab39ae2192 \
|
|
||||||
--hash=sha256:cc1331b6d5a6e144aeb5e626f4375f5b7ae9934ba620c0ac6b3e43d5e683a0f0 \
|
|
||||||
--hash=sha256:cfd5cd998c2e36a862d0e27b2df63237e67273f2fc78f47445b14e73a810e7e6 \
|
|
||||||
--hash=sha256:d3d8da4a631471dfaf94c10c85f5277b1f8e42ac42bade1ac67da4b4a7359b73 \
|
|
||||||
--hash=sha256:d44ff19eea13ae4acdaaab0179fa68c0c6f2f45d66a4d8ec1eda7d6cecbcc15f \
|
|
||||||
--hash=sha256:dd0052e9db3474df30433f83a71b9b23bd9e4ef1de13d92df21a52c0303b8ab6 \
|
|
||||||
--hash=sha256:dd0e081319328928531df7a0e63621caf67652c8464303fd102141b785ef9547 \
|
|
||||||
--hash=sha256:dda60aa465b861324e65a78c9f5cf0f4bc713e4309f83bc387be158b077963d9 \
|
|
||||||
--hash=sha256:e06695e0326d05b06833b40b7ef477e475d0b1ba3a6d27da1bb48c23209bf457 \
|
|
||||||
--hash=sha256:e1abe69aca89514737465752b4bcaf8016de61b3be1397a8fc260ba33321b3a8 \
|
|
||||||
--hash=sha256:e267b0ed063341f3e60acd25c05200df4193e15a4a5807075cd71225a2386e26 \
|
|
||||||
--hash=sha256:e5449ca63da169a2e6068dd0e2fcc8d91f9558aba89ff6d02121ca8ab11e79e5 \
|
|
||||||
--hash=sha256:e63e4e5081de46517099dc30abe418122f54531a6ae2ebc8680bcd7096860eab \
|
|
||||||
--hash=sha256:f189805c8be5ca5add39e6f899e6ce2ed824e65fb45f3c28cb2841911da19070 \
|
|
||||||
--hash=sha256:f7955ecf5609dee9442cbface754f2c6e541d9e6eda87fad7f7a989b0bdb9d71 \
|
|
||||||
--hash=sha256:f86d3a7a9af5d826744fabf4afd15b9dfef44fe69a98541f666f66fbb8d3fef9 \
|
|
||||||
--hash=sha256:fbd43429d0d7ed6533b25fc993861b8fd512c42d04514a0dd6337fb3ccf22761
|
|
||||||
# via reportlab
|
|
||||||
pycryptodome==3.21.0 \
|
|
||||||
--hash=sha256:0714206d467fc911042d01ea3a1847c847bc10884cf674c82e12915cfe1649f8 \
|
|
||||||
--hash=sha256:0fa0a05a6a697ccbf2a12cec3d6d2650b50881899b845fac6e87416f8cb7e87d \
|
|
||||||
--hash=sha256:0fd54003ec3ce4e0f16c484a10bc5d8b9bd77fa662a12b85779a2d2d85d67ee0 \
|
|
||||||
--hash=sha256:18caa8cfbc676eaaf28613637a89980ad2fd96e00c564135bf90bc3f0b34dd93 \
|
|
||||||
--hash=sha256:2480ec2c72438430da9f601ebc12c518c093c13111a5c1644c82cdfc2e50b1e4 \
|
|
||||||
--hash=sha256:26412b21df30b2861424a6c6d5b1d8ca8107612a4cfa4d0183e71c5d200fb34a \
|
|
||||||
--hash=sha256:280b67d20e33bb63171d55b1067f61fbd932e0b1ad976b3a184303a3dad22764 \
|
|
||||||
--hash=sha256:2cb635b67011bc147c257e61ce864879ffe6d03342dc74b6045059dfbdedafca \
|
|
||||||
--hash=sha256:2de4b7263a33947ff440412339cb72b28a5a4c769b5c1ca19e33dd6cd1dcec6e \
|
|
||||||
--hash=sha256:3ba4cc304eac4d4d458f508d4955a88ba25026890e8abff9b60404f76a62c55e \
|
|
||||||
--hash=sha256:4c26a2f0dc15f81ea3afa3b0c87b87e501f235d332b7f27e2225ecb80c0b1cdd \
|
|
||||||
--hash=sha256:590ef0898a4b0a15485b05210b4a1c9de8806d3ad3d47f74ab1dc07c67a6827f \
|
|
||||||
--hash=sha256:5dfafca172933506773482b0e18f0cd766fd3920bd03ec85a283df90d8a17bc6 \
|
|
||||||
--hash=sha256:6cce52e196a5f1d6797ff7946cdff2038d3b5f0aba4a43cb6bf46b575fd1b5bb \
|
|
||||||
--hash=sha256:7cb087b8612c8a1a14cf37dd754685be9a8d9869bed2ffaaceb04850a8aeef7e \
|
|
||||||
--hash=sha256:7d85c1b613121ed3dbaa5a97369b3b757909531a959d229406a75b912dd51dd1 \
|
|
||||||
--hash=sha256:7ee86cbde706be13f2dec5a42b52b1c1d1cbb90c8e405c68d0755134735c8dc6 \
|
|
||||||
--hash=sha256:8898a66425a57bcf15e25fc19c12490b87bd939800f39a03ea2de2aea5e3611a \
|
|
||||||
--hash=sha256:8acd7d34af70ee63f9a849f957558e49a98f8f1634f86a59d2be62bb8e93f71c \
|
|
||||||
--hash=sha256:932c905b71a56474bff8a9c014030bc3c882cee696b448af920399f730a650c2 \
|
|
||||||
--hash=sha256:a1752eca64c60852f38bb29e2c86fca30d7672c024128ef5d70cc15868fa10f4 \
|
|
||||||
--hash=sha256:a3804675283f4764a02db05f5191eb8fec2bb6ca34d466167fc78a5f05bbe6b3 \
|
|
||||||
--hash=sha256:a4e74c522d630766b03a836c15bff77cb657c5fdf098abf8b1ada2aebc7d0819 \
|
|
||||||
--hash=sha256:a915597ffccabe902e7090e199a7bf7a381c5506a747d5e9d27ba55197a2c568 \
|
|
||||||
--hash=sha256:b7aa25fc0baa5b1d95b7633af4f5f1838467f1815442b22487426f94e0d66c53 \
|
|
||||||
--hash=sha256:cc2269ab4bce40b027b49663d61d816903a4bd90ad88cb99ed561aadb3888dd3 \
|
|
||||||
--hash=sha256:d5ebe0763c982f069d3877832254f64974139f4f9655058452603ff559c482e8 \
|
|
||||||
--hash=sha256:dad9bf36eda068e89059d1f07408e397856be9511d7113ea4b586642a429a4fd \
|
|
||||||
--hash=sha256:de18954104667f565e2fbb4783b56667f30fb49c4d79b346f52a29cb198d5b6b \
|
|
||||||
--hash=sha256:f35e442630bc4bc2e1878482d6f59ea22e280d7121d7adeaedba58c23ab6386b \
|
|
||||||
--hash=sha256:f7787e0d469bdae763b876174cf2e6c0f7be79808af26b1da96f1a64bcf47297 \
|
|
||||||
--hash=sha256:ff99f952db3db2fbe98a0b355175f93ec334ba3d01bbde25ad3a5a33abc02b58
|
|
||||||
# via -r cucumber\requirements.in
|
|
||||||
pypdf2==3.0.1 \
|
|
||||||
--hash=sha256:a74408f69ba6271f71b9352ef4ed03dc53a31aa404d29b5d31f53bfecfee1440 \
|
|
||||||
--hash=sha256:d16e4205cfee272fbdc0568b68d82be796540b1537508cef59388f839c191928
|
|
||||||
# via -r cucumber\requirements.in
|
|
||||||
reportlab==4.2.5 \
|
|
||||||
--hash=sha256:5cf35b8fd609b68080ac7bbb0ae1e376104f7d5f7b2d3914c7adc63f2593941f \
|
|
||||||
--hash=sha256:eb2745525a982d9880babb991619e97ac3f661fae30571b7d50387026ca765ee
|
|
||||||
# via -r cucumber\requirements.in
|
|
||||||
requests==2.32.3 \
|
|
||||||
--hash=sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760 \
|
|
||||||
--hash=sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6
|
|
||||||
# via -r cucumber\requirements.in
|
|
||||||
six==1.17.0 \
|
|
||||||
--hash=sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274 \
|
|
||||||
--hash=sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81
|
|
||||||
# via
|
|
||||||
# behave
|
|
||||||
# parse-type
|
|
||||||
urllib3==2.3.0 \
|
|
||||||
--hash=sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df \
|
|
||||||
--hash=sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d
|
|
||||||
# via requests
|
|
||||||
|
|||||||
@@ -1,63 +0,0 @@
|
|||||||
services:
|
|
||||||
stirling-pdf:
|
|
||||||
container_name: Stirling-PDF-Security-Fat-Postgres
|
|
||||||
image: stirlingtools/stirling-pdf:latest-fat-postgres
|
|
||||||
deploy:
|
|
||||||
resources:
|
|
||||||
limits:
|
|
||||||
memory: 4G
|
|
||||||
depends_on:
|
|
||||||
- db
|
|
||||||
healthcheck:
|
|
||||||
test: [ "CMD-SHELL", "curl -f http://localhost:8080/api/v1/info/status | grep -q 'UP'" ]
|
|
||||||
interval: 5s
|
|
||||||
timeout: 10s
|
|
||||||
retries: 16
|
|
||||||
ports:
|
|
||||||
- 8080:8080
|
|
||||||
volumes:
|
|
||||||
- ./stirling/latest/data:/usr/share/tessdata:rw
|
|
||||||
- ./stirling/latest/config:/configs:rw
|
|
||||||
- ./stirling/latest/logs:/logs:rw
|
|
||||||
environment:
|
|
||||||
DOCKER_ENABLE_SECURITY: "true"
|
|
||||||
SECURITY_ENABLELOGIN: "false"
|
|
||||||
PUID: 1002
|
|
||||||
PGID: 1002
|
|
||||||
UMASK: "022"
|
|
||||||
SYSTEM_DEFAULTLOCALE: en-US
|
|
||||||
UI_APPNAME: Stirling-PDF
|
|
||||||
UI_HOMEDESCRIPTION: Demo site for Stirling-PDF Latest-fat with Security and PostgreSQL
|
|
||||||
UI_APPNAMENAVBAR: Stirling-PDF Latest-fat-PostgreSQL
|
|
||||||
SYSTEM_MAXFILESIZE: "100"
|
|
||||||
METRICS_ENABLED: "true"
|
|
||||||
SYSTEM_GOOGLEVISIBILITY: "true"
|
|
||||||
SYSTEM_DATASOURCE_ENABLECUSTOMDATABASE: "true"
|
|
||||||
SYSTEM_DATASOURCE_CUSTOMDATABASEURL: "jdbc:postgresql://db:5432/stirling_pdf"
|
|
||||||
SYSTEM_DATASOURCE_USERNAME: "admin"
|
|
||||||
SYSTEM_DATASOURCE_PASSWORD: "stirling"
|
|
||||||
restart: on-failure:5
|
|
||||||
|
|
||||||
db:
|
|
||||||
image: 'postgres:17.2-alpine'
|
|
||||||
restart: on-failure:5
|
|
||||||
container_name: db
|
|
||||||
ports:
|
|
||||||
- "5432:5432"
|
|
||||||
environment:
|
|
||||||
POSTGRES_DB: "stirling_pdf"
|
|
||||||
POSTGRES_USER: "admin"
|
|
||||||
POSTGRES_PASSWORD: "stirling"
|
|
||||||
shm_size: "512mb"
|
|
||||||
deploy:
|
|
||||||
resources:
|
|
||||||
limits:
|
|
||||||
memory: 512m
|
|
||||||
cpus: "0.5"
|
|
||||||
healthcheck:
|
|
||||||
test: [ "CMD-SHELL", "pg_isready -U admin stirling_pdf" ]
|
|
||||||
interval: 1s
|
|
||||||
timeout: 5s
|
|
||||||
retries: 10
|
|
||||||
volumes:
|
|
||||||
- ./stirling/latest/data:/pgdata
|
|
||||||
@@ -14,9 +14,9 @@ services:
|
|||||||
ports:
|
ports:
|
||||||
- 8080:8080
|
- 8080:8080
|
||||||
volumes:
|
volumes:
|
||||||
- ./stirling/latest/data:/usr/share/tessdata:rw
|
- /stirling/latest/data:/usr/share/tessdata:rw
|
||||||
- ./stirling/latest/config:/configs:rw
|
- /stirling/latest/config:/configs:rw
|
||||||
- ./stirling/latest/logs:/logs:rw
|
- /stirling/latest/logs:/logs:rw
|
||||||
environment:
|
environment:
|
||||||
DOCKER_ENABLE_SECURITY: "true"
|
DOCKER_ENABLE_SECURITY: "true"
|
||||||
SECURITY_ENABLELOGIN: "false"
|
SECURITY_ENABLELOGIN: "false"
|
||||||
|
|||||||
@@ -14,9 +14,9 @@ services:
|
|||||||
ports:
|
ports:
|
||||||
- "8080:8080"
|
- "8080:8080"
|
||||||
volumes:
|
volumes:
|
||||||
- ./stirling/latest/data:/usr/share/tessdata:rw
|
- /stirling/latest/data:/usr/share/tessdata:rw
|
||||||
- ./stirling/latest/config:/configs:rw
|
- /stirling/latest/config:/configs:rw
|
||||||
- ./stirling/latest/logs:/logs:rw
|
- /stirling/latest/logs:/logs:rw
|
||||||
environment:
|
environment:
|
||||||
DOCKER_ENABLE_SECURITY: "true"
|
DOCKER_ENABLE_SECURITY: "true"
|
||||||
SECURITY_ENABLELOGIN: "true"
|
SECURITY_ENABLELOGIN: "true"
|
||||||
|
|||||||
@@ -247,11 +247,6 @@ ignore = [
|
|||||||
'showJS.tags',
|
'showJS.tags',
|
||||||
]
|
]
|
||||||
|
|
||||||
[zh_BO]
|
|
||||||
ignore = [
|
|
||||||
'language.direction',
|
|
||||||
]
|
|
||||||
|
|
||||||
[zh_CN]
|
[zh_CN]
|
||||||
ignore = [
|
ignore = [
|
||||||
'language.direction',
|
'language.direction',
|
||||||
|
|||||||
@@ -27,9 +27,4 @@ public class EEAppConfig {
|
|||||||
public boolean runningEnterpriseEdition() {
|
public boolean runningEnterpriseEdition() {
|
||||||
return licenseKeyChecker.getEnterpriseEnabledResult();
|
return licenseKeyChecker.getEnterpriseEnabledResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean(name = "SSOAutoLogin")
|
|
||||||
public boolean ssoAutoLogin() {
|
|
||||||
return applicationProperties.getEnterpriseEdition().isSsoAutoLogin();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ public class KeygenLicenseVerifier {
|
|||||||
.build();
|
.build();
|
||||||
|
|
||||||
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
|
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
|
||||||
log.debug(" validateLicenseResponse body: " + response.body());
|
log.info(" validateLicenseResponse body: " + response.body());
|
||||||
JsonNode jsonResponse = objectMapper.readTree(response.body());
|
JsonNode jsonResponse = objectMapper.readTree(response.body());
|
||||||
if (response.statusCode() == 200) {
|
if (response.statusCode() == 200) {
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ public class LicenseKeyChecker {
|
|||||||
|
|
||||||
private final ApplicationProperties applicationProperties;
|
private final ApplicationProperties applicationProperties;
|
||||||
|
|
||||||
private boolean enterpriseEnabledResult = false;
|
private boolean enterpriseEnbaledResult = false;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public LicenseKeyChecker(
|
public LicenseKeyChecker(
|
||||||
@@ -35,12 +35,12 @@ public class LicenseKeyChecker {
|
|||||||
|
|
||||||
private void checkLicense() {
|
private void checkLicense() {
|
||||||
if (!applicationProperties.getEnterpriseEdition().isEnabled()) {
|
if (!applicationProperties.getEnterpriseEdition().isEnabled()) {
|
||||||
enterpriseEnabledResult = false;
|
enterpriseEnbaledResult = false;
|
||||||
} else {
|
} else {
|
||||||
enterpriseEnabledResult =
|
enterpriseEnbaledResult =
|
||||||
licenseService.verifyLicense(
|
licenseService.verifyLicense(
|
||||||
applicationProperties.getEnterpriseEdition().getKey());
|
applicationProperties.getEnterpriseEdition().getKey());
|
||||||
if (enterpriseEnabledResult) {
|
if (enterpriseEnbaledResult) {
|
||||||
log.info("License key is valid.");
|
log.info("License key is valid.");
|
||||||
} else {
|
} else {
|
||||||
log.info("License key is invalid.");
|
log.info("License key is invalid.");
|
||||||
@@ -55,6 +55,6 @@ public class LicenseKeyChecker {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean getEnterpriseEnabledResult() {
|
public boolean getEnterpriseEnabledResult() {
|
||||||
return enterpriseEnabledResult;
|
return enterpriseEnbaledResult;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,14 +28,13 @@ import stirling.software.SPDF.config.ConfigInitializer;
|
|||||||
import stirling.software.SPDF.config.InstallationPathConfig;
|
import stirling.software.SPDF.config.InstallationPathConfig;
|
||||||
import stirling.software.SPDF.model.ApplicationProperties;
|
import stirling.software.SPDF.model.ApplicationProperties;
|
||||||
|
|
||||||
@Slf4j
|
|
||||||
@EnableScheduling
|
|
||||||
@SpringBootApplication
|
@SpringBootApplication
|
||||||
public class SPDFApplication {
|
@EnableScheduling
|
||||||
|
@Slf4j
|
||||||
|
public class SPdfApplication {
|
||||||
|
|
||||||
private static String serverPortStatic;
|
|
||||||
private static String baseUrlStatic;
|
private static String baseUrlStatic;
|
||||||
|
private static String serverPortStatic;
|
||||||
private final Environment env;
|
private final Environment env;
|
||||||
private final ApplicationProperties applicationProperties;
|
private final ApplicationProperties applicationProperties;
|
||||||
private final WebBrowser webBrowser;
|
private final WebBrowser webBrowser;
|
||||||
@@ -43,7 +42,7 @@ public class SPDFApplication {
|
|||||||
@Value("${baseUrl:http://localhost}")
|
@Value("${baseUrl:http://localhost}")
|
||||||
private String baseUrl;
|
private String baseUrl;
|
||||||
|
|
||||||
public SPDFApplication(
|
public SPdfApplication(
|
||||||
Environment env,
|
Environment env,
|
||||||
ApplicationProperties applicationProperties,
|
ApplicationProperties applicationProperties,
|
||||||
@Autowired(required = false) WebBrowser webBrowser) {
|
@Autowired(required = false) WebBrowser webBrowser) {
|
||||||
@@ -52,19 +51,33 @@ public class SPDFApplication {
|
|||||||
this.webBrowser = webBrowser;
|
this.webBrowser = webBrowser;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Optionally keep this method if you want to provide a manual port-incrementation fallback.
|
||||||
|
private static String findAvailablePort(int startPort) {
|
||||||
|
int port = startPort;
|
||||||
|
while (!isPortAvailable(port)) {
|
||||||
|
port++;
|
||||||
|
}
|
||||||
|
return String.valueOf(port);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isPortAvailable(int port) {
|
||||||
|
try (ServerSocket socket = new ServerSocket(port)) {
|
||||||
|
return true;
|
||||||
|
} catch (IOException e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static void main(String[] args) throws IOException, InterruptedException {
|
public static void main(String[] args) throws IOException, InterruptedException {
|
||||||
SpringApplication app = new SpringApplication(SPDFApplication.class);
|
SpringApplication app = new SpringApplication(SPdfApplication.class);
|
||||||
|
|
||||||
Properties props = new Properties();
|
Properties props = new Properties();
|
||||||
|
|
||||||
if (Boolean.parseBoolean(System.getProperty("STIRLING_PDF_DESKTOP_UI", "false"))) {
|
if (Boolean.parseBoolean(System.getProperty("STIRLING_PDF_DESKTOP_UI", "false"))) {
|
||||||
System.setProperty("java.awt.headless", "false");
|
System.setProperty("java.awt.headless", "false");
|
||||||
app.setHeadless(false);
|
app.setHeadless(false);
|
||||||
props.put("java.awt.headless", "false");
|
props.put("java.awt.headless", "false");
|
||||||
props.put("spring.main.web-application-type", "servlet");
|
props.put("spring.main.web-application-type", "servlet");
|
||||||
}
|
}
|
||||||
|
app.setAdditionalProfiles("default");
|
||||||
app.setAdditionalProfiles(getActiveProfile(args));
|
|
||||||
|
|
||||||
ConfigInitializer initializer = new ConfigInitializer();
|
ConfigInitializer initializer = new ConfigInitializer();
|
||||||
try {
|
try {
|
||||||
@@ -72,8 +85,8 @@ public class SPDFApplication {
|
|||||||
} catch (IOException | URISyntaxException e) {
|
} catch (IOException | URISyntaxException e) {
|
||||||
log.error("Error initialising configuration", e);
|
log.error("Error initialising configuration", e);
|
||||||
}
|
}
|
||||||
Map<String, String> propertyFiles = new HashMap<>();
|
|
||||||
|
|
||||||
|
Map<String, String> propertyFiles = new HashMap<>();
|
||||||
// External config files
|
// External config files
|
||||||
log.info("Settings file: {}", InstallationPathConfig.getSettingsPath());
|
log.info("Settings file: {}", InstallationPathConfig.getSettingsPath());
|
||||||
if (Files.exists(Paths.get(InstallationPathConfig.getSettingsPath()))) {
|
if (Files.exists(Paths.get(InstallationPathConfig.getSettingsPath()))) {
|
||||||
@@ -85,7 +98,6 @@ public class SPDFApplication {
|
|||||||
"External configuration file '{}' does not exist.",
|
"External configuration file '{}' does not exist.",
|
||||||
InstallationPathConfig.getSettingsPath());
|
InstallationPathConfig.getSettingsPath());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Files.exists(Paths.get(InstallationPathConfig.getCustomSettingsPath()))) {
|
if (Files.exists(Paths.get(InstallationPathConfig.getCustomSettingsPath()))) {
|
||||||
String existingLocation =
|
String existingLocation =
|
||||||
propertyFiles.getOrDefault("spring.config.additional-location", "");
|
propertyFiles.getOrDefault("spring.config.additional-location", "");
|
||||||
@@ -101,21 +113,17 @@ public class SPDFApplication {
|
|||||||
InstallationPathConfig.getCustomSettingsPath());
|
InstallationPathConfig.getCustomSettingsPath());
|
||||||
}
|
}
|
||||||
Properties finalProps = new Properties();
|
Properties finalProps = new Properties();
|
||||||
|
|
||||||
if (!propertyFiles.isEmpty()) {
|
if (!propertyFiles.isEmpty()) {
|
||||||
finalProps.putAll(
|
finalProps.putAll(
|
||||||
Collections.singletonMap(
|
Collections.singletonMap(
|
||||||
"spring.config.additional-location",
|
"spring.config.additional-location",
|
||||||
propertyFiles.get("spring.config.additional-location")));
|
propertyFiles.get("spring.config.additional-location")));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!props.isEmpty()) {
|
if (!props.isEmpty()) {
|
||||||
finalProps.putAll(props);
|
finalProps.putAll(props);
|
||||||
}
|
}
|
||||||
app.setDefaultProperties(finalProps);
|
app.setDefaultProperties(finalProps);
|
||||||
|
|
||||||
app.run(args);
|
app.run(args);
|
||||||
|
|
||||||
// Ensure directories are created
|
// Ensure directories are created
|
||||||
try {
|
try {
|
||||||
Files.createDirectories(Path.of(InstallationPathConfig.getTemplatesPath()));
|
Files.createDirectories(Path.of(InstallationPathConfig.getTemplatesPath()));
|
||||||
@@ -123,10 +131,34 @@ public class SPDFApplication {
|
|||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("Error creating directories: {}", e.getMessage());
|
log.error("Error creating directories: {}", e.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
printStartupLogs();
|
printStartupLogs();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void printStartupLogs() {
|
||||||
|
log.info("Stirling-PDF Started.");
|
||||||
|
String url = baseUrlStatic + ":" + getStaticPort();
|
||||||
|
log.info("Navigate to {}", url);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getStaticBaseUrl() {
|
||||||
|
return baseUrlStatic;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getStaticPort() {
|
||||||
|
return serverPortStatic;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Value("${server.port:8080}")
|
||||||
|
public void setServerPortStatic(String port) {
|
||||||
|
if ("auto".equalsIgnoreCase(port)) {
|
||||||
|
// Use Spring Boot's automatic port assignment (server.port=0)
|
||||||
|
SPdfApplication.serverPortStatic = // This will let Spring Boot assign an available port
|
||||||
|
"0";
|
||||||
|
} else {
|
||||||
|
SPdfApplication.serverPortStatic = port;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@PostConstruct
|
@PostConstruct
|
||||||
public void init() {
|
public void init() {
|
||||||
baseUrlStatic = this.baseUrl;
|
baseUrlStatic = this.baseUrl;
|
||||||
@@ -157,17 +189,6 @@ public class SPDFApplication {
|
|||||||
log.info("Running configs {}", applicationProperties.toString());
|
log.info("Running configs {}", applicationProperties.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Value("${server.port:8080}")
|
|
||||||
public void setServerPortStatic(String port) {
|
|
||||||
if ("auto".equalsIgnoreCase(port)) {
|
|
||||||
// Use Spring Boot's automatic port assignment (server.port=0)
|
|
||||||
SPDFApplication.serverPortStatic =
|
|
||||||
"0"; // This will let Spring Boot assign an available port
|
|
||||||
} else {
|
|
||||||
SPDFApplication.serverPortStatic = port;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@PreDestroy
|
@PreDestroy
|
||||||
public void cleanup() {
|
public void cleanup() {
|
||||||
if (webBrowser != null) {
|
if (webBrowser != null) {
|
||||||
@@ -175,55 +196,10 @@ public class SPDFApplication {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void printStartupLogs() {
|
|
||||||
log.info("Stirling-PDF Started.");
|
|
||||||
String url = baseUrlStatic + ":" + getStaticPort();
|
|
||||||
log.info("Navigate to {}", url);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String[] getActiveProfile(String[] args) {
|
|
||||||
if (args == null) {
|
|
||||||
return new String[] {"default"};
|
|
||||||
}
|
|
||||||
|
|
||||||
for (String arg : args) {
|
|
||||||
if (arg.contains("spring.profiles.active")) {
|
|
||||||
return arg.substring(args[0].indexOf('=') + 1).split(", ");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return new String[] {"default"};
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean isPortAvailable(int port) {
|
|
||||||
try (ServerSocket socket = new ServerSocket(port)) {
|
|
||||||
return true;
|
|
||||||
} catch (IOException e) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Optionally keep this method if you want to provide a manual port-incrementation fallback.
|
|
||||||
private static String findAvailablePort(int startPort) {
|
|
||||||
int port = startPort;
|
|
||||||
while (!isPortAvailable(port)) {
|
|
||||||
port++;
|
|
||||||
}
|
|
||||||
return String.valueOf(port);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getStaticBaseUrl() {
|
|
||||||
return baseUrlStatic;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getNonStaticBaseUrl() {
|
public String getNonStaticBaseUrl() {
|
||||||
return baseUrlStatic;
|
return baseUrlStatic;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getStaticPort() {
|
|
||||||
return serverPortStatic;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getNonStaticPort() {
|
public String getNonStaticPort() {
|
||||||
return serverPortStatic;
|
return serverPortStatic;
|
||||||
}
|
}
|
||||||
@@ -136,7 +136,6 @@ public class EndpointConfiguration {
|
|||||||
addEndpointToGroup("Security", "remove-cert-sign");
|
addEndpointToGroup("Security", "remove-cert-sign");
|
||||||
addEndpointToGroup("Security", "sanitize-pdf");
|
addEndpointToGroup("Security", "sanitize-pdf");
|
||||||
addEndpointToGroup("Security", "auto-redact");
|
addEndpointToGroup("Security", "auto-redact");
|
||||||
addEndpointToGroup("Security", "redact");
|
|
||||||
|
|
||||||
// Adding endpoints to "Other" group
|
// Adding endpoints to "Other" group
|
||||||
addEndpointToGroup("Other", "ocr-pdf");
|
addEndpointToGroup("Other", "ocr-pdf");
|
||||||
@@ -236,7 +235,6 @@ public class EndpointConfiguration {
|
|||||||
addEndpointToGroup("Java", "markdown-to-pdf");
|
addEndpointToGroup("Java", "markdown-to-pdf");
|
||||||
addEndpointToGroup("Java", "show-javascript");
|
addEndpointToGroup("Java", "show-javascript");
|
||||||
addEndpointToGroup("Java", "auto-redact");
|
addEndpointToGroup("Java", "auto-redact");
|
||||||
addEndpointToGroup("Java", "redact");
|
|
||||||
addEndpointToGroup("Java", "pdf-to-csv");
|
addEndpointToGroup("Java", "pdf-to-csv");
|
||||||
addEndpointToGroup("Java", "split-by-size-or-count");
|
addEndpointToGroup("Java", "split-by-size-or-count");
|
||||||
addEndpointToGroup("Java", "overlay-pdf");
|
addEndpointToGroup("Java", "overlay-pdf");
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
package stirling.software.SPDF.config.interfaces;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import stirling.software.SPDF.utils.FileInfo;
|
||||||
|
|
||||||
|
public interface DatabaseBackupInterface {
|
||||||
|
|
||||||
|
void exportDatabase() throws IOException;
|
||||||
|
|
||||||
|
boolean importDatabase();
|
||||||
|
|
||||||
|
boolean hasBackup();
|
||||||
|
|
||||||
|
List<FileInfo> getBackupList();
|
||||||
|
}
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
package stirling.software.SPDF.config.interfaces;
|
|
||||||
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import stirling.software.SPDF.model.provider.UnsupportedProviderException;
|
|
||||||
import stirling.software.SPDF.utils.FileInfo;
|
|
||||||
|
|
||||||
public interface DatabaseInterface {
|
|
||||||
void exportDatabase() throws SQLException, UnsupportedProviderException;
|
|
||||||
|
|
||||||
void importDatabase();
|
|
||||||
|
|
||||||
boolean hasBackup();
|
|
||||||
|
|
||||||
List<FileInfo> getBackupList();
|
|
||||||
}
|
|
||||||
@@ -20,7 +20,7 @@ import jakarta.servlet.http.HttpServletRequest;
|
|||||||
import jakarta.servlet.http.HttpServletResponse;
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import stirling.software.SPDF.SPDFApplication;
|
import stirling.software.SPDF.SPdfApplication;
|
||||||
import stirling.software.SPDF.config.security.saml2.CertificateUtils;
|
import stirling.software.SPDF.config.security.saml2.CertificateUtils;
|
||||||
import stirling.software.SPDF.config.security.saml2.CustomSaml2AuthenticatedPrincipal;
|
import stirling.software.SPDF.config.security.saml2.CustomSaml2AuthenticatedPrincipal;
|
||||||
import stirling.software.SPDF.model.ApplicationProperties;
|
import stirling.software.SPDF.model.ApplicationProperties;
|
||||||
@@ -110,7 +110,7 @@ public class CustomLogoutSuccessHandler extends SimpleUrlLogoutSuccessHandler {
|
|||||||
|
|
||||||
// Construct URLs required for SAML configuration
|
// Construct URLs required for SAML configuration
|
||||||
String serverUrl =
|
String serverUrl =
|
||||||
SPDFApplication.getStaticBaseUrl() + ":" + SPDFApplication.getStaticPort();
|
SPdfApplication.getStaticBaseUrl() + ":" + SPdfApplication.getStaticPort();
|
||||||
|
|
||||||
String relyingPartyIdentifier =
|
String relyingPartyIdentifier =
|
||||||
serverUrl + "/saml2/service-provider-metadata/" + registrationId;
|
serverUrl + "/saml2/service-provider-metadata/" + registrationId;
|
||||||
|
|||||||
@@ -1,56 +1,49 @@
|
|||||||
package stirling.software.SPDF.config.security;
|
package stirling.software.SPDF.config.security;
|
||||||
|
|
||||||
import java.sql.SQLException;
|
import java.io.IOException;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import jakarta.annotation.PostConstruct;
|
import jakarta.annotation.PostConstruct;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import stirling.software.SPDF.config.interfaces.DatabaseInterface;
|
import stirling.software.SPDF.config.interfaces.DatabaseBackupInterface;
|
||||||
import stirling.software.SPDF.model.ApplicationProperties;
|
import stirling.software.SPDF.model.ApplicationProperties;
|
||||||
import stirling.software.SPDF.model.Role;
|
import stirling.software.SPDF.model.Role;
|
||||||
import stirling.software.SPDF.model.provider.UnsupportedProviderException;
|
|
||||||
|
|
||||||
@Slf4j
|
|
||||||
@Component
|
@Component
|
||||||
|
@Slf4j
|
||||||
public class InitialSecuritySetup {
|
public class InitialSecuritySetup {
|
||||||
|
|
||||||
private final UserService userService;
|
private final UserService userService;
|
||||||
|
|
||||||
private final ApplicationProperties applicationProperties;
|
private final ApplicationProperties applicationProperties;
|
||||||
|
|
||||||
private final DatabaseInterface databaseService;
|
private final DatabaseBackupInterface databaseBackupHelper;
|
||||||
|
|
||||||
public InitialSecuritySetup(
|
public InitialSecuritySetup(
|
||||||
UserService userService,
|
UserService userService,
|
||||||
ApplicationProperties applicationProperties,
|
ApplicationProperties applicationProperties,
|
||||||
DatabaseInterface databaseService) {
|
DatabaseBackupInterface databaseBackupHelper) {
|
||||||
this.userService = userService;
|
this.userService = userService;
|
||||||
this.applicationProperties = applicationProperties;
|
this.applicationProperties = applicationProperties;
|
||||||
this.databaseService = databaseService;
|
this.databaseBackupHelper = databaseBackupHelper;
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostConstruct
|
@PostConstruct
|
||||||
public void init() {
|
public void init() throws IllegalArgumentException, IOException {
|
||||||
try {
|
if (databaseBackupHelper.hasBackup() && !userService.hasUsers()) {
|
||||||
if (databaseService.hasBackup()) {
|
databaseBackupHelper.importDatabase();
|
||||||
databaseService.importDatabase();
|
} else if (!userService.hasUsers()) {
|
||||||
}
|
initializeAdminUser();
|
||||||
|
} else {
|
||||||
if (!userService.hasUsers()) {
|
databaseBackupHelper.exportDatabase();
|
||||||
initializeAdminUser();
|
|
||||||
}
|
|
||||||
|
|
||||||
userService.migrateOauth2ToSSO();
|
userService.migrateOauth2ToSSO();
|
||||||
initializeInternalApiUser();
|
|
||||||
} catch (IllegalArgumentException | SQLException | UnsupportedProviderException e) {
|
|
||||||
log.error("Failed to initialize security setup.", e);
|
|
||||||
System.exit(1);
|
|
||||||
}
|
}
|
||||||
|
initializeInternalApiUser();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initializeAdminUser() throws SQLException, UnsupportedProviderException {
|
private void initializeAdminUser() throws IOException {
|
||||||
String initialUsername =
|
String initialUsername =
|
||||||
applicationProperties.getSecurity().getInitialLogin().getUsername();
|
applicationProperties.getSecurity().getInitialLogin().getUsername();
|
||||||
String initialPassword =
|
String initialPassword =
|
||||||
@@ -59,34 +52,36 @@ public class InitialSecuritySetup {
|
|||||||
&& !initialUsername.isEmpty()
|
&& !initialUsername.isEmpty()
|
||||||
&& initialPassword != null
|
&& initialPassword != null
|
||||||
&& !initialPassword.isEmpty()
|
&& !initialPassword.isEmpty()
|
||||||
&& userService.findByUsernameIgnoreCase(initialUsername).isEmpty()) {
|
&& !userService.findByUsernameIgnoreCase(initialUsername).isPresent()) {
|
||||||
|
try {
|
||||||
userService.saveUser(initialUsername, initialPassword, Role.ADMIN.getRoleId());
|
userService.saveUser(initialUsername, initialPassword, Role.ADMIN.getRoleId());
|
||||||
log.info("Admin user created: {}", initialUsername);
|
log.info("Admin user created: " + initialUsername);
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
log.error("Failed to initialize security setup", e);
|
||||||
|
System.exit(1);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
createDefaultAdminUser();
|
createDefaultAdminUser();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createDefaultAdminUser() throws SQLException, UnsupportedProviderException {
|
private void createDefaultAdminUser() throws IllegalArgumentException, IOException {
|
||||||
String defaultUsername = "admin";
|
String defaultUsername = "admin";
|
||||||
String defaultPassword = "stirling";
|
String defaultPassword = "stirling";
|
||||||
|
if (!userService.findByUsernameIgnoreCase(defaultUsername).isPresent()) {
|
||||||
if (userService.findByUsernameIgnoreCase(defaultUsername).isEmpty()) {
|
|
||||||
userService.saveUser(defaultUsername, defaultPassword, Role.ADMIN.getRoleId(), true);
|
userService.saveUser(defaultUsername, defaultPassword, Role.ADMIN.getRoleId(), true);
|
||||||
log.info("Default admin user created: {}", defaultUsername);
|
log.info("Default admin user created: " + defaultUsername);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initializeInternalApiUser()
|
private void initializeInternalApiUser() throws IllegalArgumentException, IOException {
|
||||||
throws IllegalArgumentException, SQLException, UnsupportedProviderException {
|
|
||||||
if (!userService.usernameExistsIgnoreCase(Role.INTERNAL_API_USER.getRoleId())) {
|
if (!userService.usernameExistsIgnoreCase(Role.INTERNAL_API_USER.getRoleId())) {
|
||||||
userService.saveUser(
|
userService.saveUser(
|
||||||
Role.INTERNAL_API_USER.getRoleId(),
|
Role.INTERNAL_API_USER.getRoleId(),
|
||||||
UUID.randomUUID().toString(),
|
UUID.randomUUID().toString(),
|
||||||
Role.INTERNAL_API_USER.getRoleId());
|
Role.INTERNAL_API_USER.getRoleId());
|
||||||
userService.addApiKeyToUser(Role.INTERNAL_API_USER.getRoleId());
|
userService.addApiKeyToUser(Role.INTERNAL_API_USER.getRoleId());
|
||||||
log.info("Internal API user created: {}", Role.INTERNAL_API_USER.getRoleId());
|
log.info("Internal API user created: " + Role.INTERNAL_API_USER.getRoleId());
|
||||||
}
|
}
|
||||||
userService.syncCustomApiUser(applicationProperties.getSecurity().getCustomGlobalAPIKey());
|
userService.syncCustomApiUser(applicationProperties.getSecurity().getCustomGlobalAPIKey());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,24 +1,39 @@
|
|||||||
package stirling.software.SPDF.config.security;
|
package stirling.software.SPDF.config.security;
|
||||||
|
|
||||||
|
import java.security.cert.X509Certificate;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.opensaml.saml.saml2.core.AuthnRequest;
|
||||||
import org.springframework.beans.factory.annotation.Qualifier;
|
import org.springframework.beans.factory.annotation.Qualifier;
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.context.annotation.DependsOn;
|
import org.springframework.context.annotation.DependsOn;
|
||||||
import org.springframework.context.annotation.Lazy;
|
import org.springframework.context.annotation.Lazy;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.security.authentication.ProviderManager;
|
import org.springframework.security.authentication.ProviderManager;
|
||||||
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
|
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
|
||||||
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
|
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
|
||||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||||
import org.springframework.security.config.http.SessionCreationPolicy;
|
import org.springframework.security.config.http.SessionCreationPolicy;
|
||||||
|
import org.springframework.security.core.GrantedAuthority;
|
||||||
|
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
||||||
import org.springframework.security.core.authority.mapping.GrantedAuthoritiesMapper;
|
import org.springframework.security.core.authority.mapping.GrantedAuthoritiesMapper;
|
||||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||||
|
import org.springframework.security.oauth2.client.registration.ClientRegistration;
|
||||||
|
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
|
||||||
|
import org.springframework.security.oauth2.client.registration.ClientRegistrations;
|
||||||
|
import org.springframework.security.oauth2.client.registration.InMemoryClientRegistrationRepository;
|
||||||
|
import org.springframework.security.oauth2.core.user.OAuth2UserAuthority;
|
||||||
|
import org.springframework.security.saml2.core.Saml2X509Credential;
|
||||||
|
import org.springframework.security.saml2.core.Saml2X509Credential.Saml2X509CredentialType;
|
||||||
import org.springframework.security.saml2.provider.service.authentication.OpenSaml4AuthenticationProvider;
|
import org.springframework.security.saml2.provider.service.authentication.OpenSaml4AuthenticationProvider;
|
||||||
|
import org.springframework.security.saml2.provider.service.registration.InMemoryRelyingPartyRegistrationRepository;
|
||||||
|
import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistration;
|
||||||
import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistrationRepository;
|
import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistrationRepository;
|
||||||
|
import org.springframework.security.saml2.provider.service.registration.Saml2MessageBinding;
|
||||||
import org.springframework.security.saml2.provider.service.web.authentication.OpenSaml4AuthenticationRequestResolver;
|
import org.springframework.security.saml2.provider.service.web.authentication.OpenSaml4AuthenticationRequestResolver;
|
||||||
import org.springframework.security.web.SecurityFilterChain;
|
import org.springframework.security.web.SecurityFilterChain;
|
||||||
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
|
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
|
||||||
@@ -28,16 +43,24 @@ import org.springframework.security.web.csrf.CsrfTokenRequestAttributeHandler;
|
|||||||
import org.springframework.security.web.savedrequest.NullRequestCache;
|
import org.springframework.security.web.savedrequest.NullRequestCache;
|
||||||
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
|
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
|
||||||
|
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import stirling.software.SPDF.config.security.oauth2.CustomOAuth2AuthenticationFailureHandler;
|
import stirling.software.SPDF.config.security.oauth2.CustomOAuth2AuthenticationFailureHandler;
|
||||||
import stirling.software.SPDF.config.security.oauth2.CustomOAuth2AuthenticationSuccessHandler;
|
import stirling.software.SPDF.config.security.oauth2.CustomOAuth2AuthenticationSuccessHandler;
|
||||||
import stirling.software.SPDF.config.security.oauth2.CustomOAuth2UserService;
|
import stirling.software.SPDF.config.security.oauth2.CustomOAuth2UserService;
|
||||||
|
import stirling.software.SPDF.config.security.saml2.CertificateUtils;
|
||||||
import stirling.software.SPDF.config.security.saml2.CustomSaml2AuthenticationFailureHandler;
|
import stirling.software.SPDF.config.security.saml2.CustomSaml2AuthenticationFailureHandler;
|
||||||
import stirling.software.SPDF.config.security.saml2.CustomSaml2AuthenticationSuccessHandler;
|
import stirling.software.SPDF.config.security.saml2.CustomSaml2AuthenticationSuccessHandler;
|
||||||
import stirling.software.SPDF.config.security.saml2.CustomSaml2ResponseAuthenticationConverter;
|
import stirling.software.SPDF.config.security.saml2.CustomSaml2ResponseAuthenticationConverter;
|
||||||
import stirling.software.SPDF.config.security.session.SessionPersistentRegistry;
|
import stirling.software.SPDF.config.security.session.SessionPersistentRegistry;
|
||||||
import stirling.software.SPDF.model.ApplicationProperties;
|
import stirling.software.SPDF.model.ApplicationProperties;
|
||||||
|
import stirling.software.SPDF.model.ApplicationProperties.Security.OAUTH2;
|
||||||
|
import stirling.software.SPDF.model.ApplicationProperties.Security.OAUTH2.Client;
|
||||||
|
import stirling.software.SPDF.model.ApplicationProperties.Security.SAML2;
|
||||||
import stirling.software.SPDF.model.User;
|
import stirling.software.SPDF.model.User;
|
||||||
|
import stirling.software.SPDF.model.provider.GithubProvider;
|
||||||
|
import stirling.software.SPDF.model.provider.GoogleProvider;
|
||||||
|
import stirling.software.SPDF.model.provider.KeycloakProvider;
|
||||||
import stirling.software.SPDF.repository.JPATokenRepositoryImpl;
|
import stirling.software.SPDF.repository.JPATokenRepositoryImpl;
|
||||||
import stirling.software.SPDF.repository.PersistentLoginRepository;
|
import stirling.software.SPDF.repository.PersistentLoginRepository;
|
||||||
|
|
||||||
@@ -49,7 +72,7 @@ import stirling.software.SPDF.repository.PersistentLoginRepository;
|
|||||||
public class SecurityConfiguration {
|
public class SecurityConfiguration {
|
||||||
|
|
||||||
private final CustomUserDetailsService userDetailsService;
|
private final CustomUserDetailsService userDetailsService;
|
||||||
private final UserService userService;
|
@Lazy private final UserService userService;
|
||||||
|
|
||||||
@Qualifier("loginEnabled")
|
@Qualifier("loginEnabled")
|
||||||
private final boolean loginEnabledValue;
|
private final boolean loginEnabledValue;
|
||||||
@@ -63,10 +86,16 @@ public class SecurityConfiguration {
|
|||||||
private final FirstLoginFilter firstLoginFilter;
|
private final FirstLoginFilter firstLoginFilter;
|
||||||
private final SessionPersistentRegistry sessionRegistry;
|
private final SessionPersistentRegistry sessionRegistry;
|
||||||
private final PersistentLoginRepository persistentLoginRepository;
|
private final PersistentLoginRepository persistentLoginRepository;
|
||||||
private final GrantedAuthoritiesMapper oAuth2userAuthoritiesMapper;
|
|
||||||
private final RelyingPartyRegistrationRepository saml2RelyingPartyRegistrations;
|
|
||||||
private final OpenSaml4AuthenticationRequestResolver saml2AuthenticationRequestResolver;
|
|
||||||
|
|
||||||
|
// // Only Dev test
|
||||||
|
// @Bean
|
||||||
|
// public WebSecurityCustomizer webSecurityCustomizer() {
|
||||||
|
// return (web) ->
|
||||||
|
// web.ignoring()
|
||||||
|
// .requestMatchers(
|
||||||
|
// "/css/**", "/images/**", "/js/**", "/**.svg",
|
||||||
|
// "/pdfjs-legacy/**");
|
||||||
|
// }
|
||||||
public SecurityConfiguration(
|
public SecurityConfiguration(
|
||||||
PersistentLoginRepository persistentLoginRepository,
|
PersistentLoginRepository persistentLoginRepository,
|
||||||
CustomUserDetailsService userDetailsService,
|
CustomUserDetailsService userDetailsService,
|
||||||
@@ -77,12 +106,7 @@ public class SecurityConfiguration {
|
|||||||
UserAuthenticationFilter userAuthenticationFilter,
|
UserAuthenticationFilter userAuthenticationFilter,
|
||||||
LoginAttemptService loginAttemptService,
|
LoginAttemptService loginAttemptService,
|
||||||
FirstLoginFilter firstLoginFilter,
|
FirstLoginFilter firstLoginFilter,
|
||||||
SessionPersistentRegistry sessionRegistry,
|
SessionPersistentRegistry sessionRegistry) {
|
||||||
@Autowired(required = false) GrantedAuthoritiesMapper oAuth2userAuthoritiesMapper,
|
|
||||||
@Autowired(required = false)
|
|
||||||
RelyingPartyRegistrationRepository saml2RelyingPartyRegistrations,
|
|
||||||
@Autowired(required = false)
|
|
||||||
OpenSaml4AuthenticationRequestResolver saml2AuthenticationRequestResolver) {
|
|
||||||
this.userDetailsService = userDetailsService;
|
this.userDetailsService = userDetailsService;
|
||||||
this.userService = userService;
|
this.userService = userService;
|
||||||
this.loginEnabledValue = loginEnabledValue;
|
this.loginEnabledValue = loginEnabledValue;
|
||||||
@@ -93,9 +117,6 @@ public class SecurityConfiguration {
|
|||||||
this.firstLoginFilter = firstLoginFilter;
|
this.firstLoginFilter = firstLoginFilter;
|
||||||
this.sessionRegistry = sessionRegistry;
|
this.sessionRegistry = sessionRegistry;
|
||||||
this.persistentLoginRepository = persistentLoginRepository;
|
this.persistentLoginRepository = persistentLoginRepository;
|
||||||
this.oAuth2userAuthoritiesMapper = oAuth2userAuthoritiesMapper;
|
|
||||||
this.saml2RelyingPartyRegistrations = saml2RelyingPartyRegistrations;
|
|
||||||
this.saml2AuthenticationRequestResolver = saml2AuthenticationRequestResolver;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@@ -253,7 +274,7 @@ public class SecurityConfiguration {
|
|||||||
userService,
|
userService,
|
||||||
loginAttemptService))
|
loginAttemptService))
|
||||||
.userAuthoritiesMapper(
|
.userAuthoritiesMapper(
|
||||||
oAuth2userAuthoritiesMapper))
|
userAuthoritiesMapper()))
|
||||||
.permitAll());
|
.permitAll());
|
||||||
}
|
}
|
||||||
// Handle SAML
|
// Handle SAML
|
||||||
@@ -270,7 +291,7 @@ public class SecurityConfiguration {
|
|||||||
try {
|
try {
|
||||||
saml2.loginPage("/saml2")
|
saml2.loginPage("/saml2")
|
||||||
.relyingPartyRegistrationRepository(
|
.relyingPartyRegistrationRepository(
|
||||||
saml2RelyingPartyRegistrations)
|
relyingPartyRegistrations())
|
||||||
.authenticationManager(
|
.authenticationManager(
|
||||||
new ProviderManager(authenticationProvider))
|
new ProviderManager(authenticationProvider))
|
||||||
.successHandler(
|
.successHandler(
|
||||||
@@ -281,7 +302,8 @@ public class SecurityConfiguration {
|
|||||||
.failureHandler(
|
.failureHandler(
|
||||||
new CustomSaml2AuthenticationFailureHandler())
|
new CustomSaml2AuthenticationFailureHandler())
|
||||||
.authenticationRequestResolver(
|
.authenticationRequestResolver(
|
||||||
saml2AuthenticationRequestResolver);
|
authenticationRequestResolver(
|
||||||
|
relyingPartyRegistrations()));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("Error configuring SAML2 login", e);
|
log.error("Error configuring SAML2 login", e);
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
@@ -289,11 +311,244 @@ public class SecurityConfiguration {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
// if (!applicationProperties.getSecurity().getCsrfDisabled()) {
|
||||||
|
// CookieCsrfTokenRepository cookieRepo =
|
||||||
|
// CookieCsrfTokenRepository.withHttpOnlyFalse();
|
||||||
|
// CsrfTokenRequestAttributeHandler requestHandler =
|
||||||
|
// new CsrfTokenRequestAttributeHandler();
|
||||||
|
// requestHandler.setCsrfRequestAttributeName(null);
|
||||||
|
// http.csrf(
|
||||||
|
// csrf ->
|
||||||
|
// csrf.csrfTokenRepository(cookieRepo)
|
||||||
|
// .csrfTokenRequestHandler(requestHandler));
|
||||||
|
// }
|
||||||
http.authorizeHttpRequests(authz -> authz.anyRequest().permitAll());
|
http.authorizeHttpRequests(authz -> authz.anyRequest().permitAll());
|
||||||
}
|
}
|
||||||
return http.build();
|
return http.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
@ConditionalOnProperty(
|
||||||
|
value = "security.oauth2.enabled",
|
||||||
|
havingValue = "true",
|
||||||
|
matchIfMissing = false)
|
||||||
|
public ClientRegistrationRepository clientRegistrationRepository() {
|
||||||
|
List<ClientRegistration> registrations = new ArrayList<>();
|
||||||
|
githubClientRegistration().ifPresent(registrations::add);
|
||||||
|
oidcClientRegistration().ifPresent(registrations::add);
|
||||||
|
googleClientRegistration().ifPresent(registrations::add);
|
||||||
|
keycloakClientRegistration().ifPresent(registrations::add);
|
||||||
|
if (registrations.isEmpty()) {
|
||||||
|
log.error("At least one OAuth2 provider must be configured");
|
||||||
|
System.exit(1);
|
||||||
|
}
|
||||||
|
return new InMemoryClientRegistrationRepository(registrations);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Optional<ClientRegistration> googleClientRegistration() {
|
||||||
|
OAUTH2 oauth = applicationProperties.getSecurity().getOauth2();
|
||||||
|
if (oauth == null || !oauth.getEnabled()) {
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
Client client = oauth.getClient();
|
||||||
|
if (client == null) {
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
GoogleProvider google = client.getGoogle();
|
||||||
|
return google != null && google.isSettingsValid()
|
||||||
|
? Optional.of(
|
||||||
|
ClientRegistration.withRegistrationId(google.getName())
|
||||||
|
.clientId(google.getClientId())
|
||||||
|
.clientSecret(google.getClientSecret())
|
||||||
|
.scope(google.getScopes())
|
||||||
|
.authorizationUri(google.getAuthorizationuri())
|
||||||
|
.tokenUri(google.getTokenuri())
|
||||||
|
.userInfoUri(google.getUserinfouri())
|
||||||
|
.userNameAttributeName(google.getUseAsUsername())
|
||||||
|
.clientName(google.getClientName())
|
||||||
|
.redirectUri("{baseUrl}/login/oauth2/code/" + google.getName())
|
||||||
|
.authorizationGrantType(
|
||||||
|
org.springframework.security.oauth2.core
|
||||||
|
.AuthorizationGrantType.AUTHORIZATION_CODE)
|
||||||
|
.build())
|
||||||
|
: Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Optional<ClientRegistration> keycloakClientRegistration() {
|
||||||
|
OAUTH2 oauth = applicationProperties.getSecurity().getOauth2();
|
||||||
|
if (oauth == null || !oauth.getEnabled()) {
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
Client client = oauth.getClient();
|
||||||
|
if (client == null) {
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
KeycloakProvider keycloak = client.getKeycloak();
|
||||||
|
return keycloak != null && keycloak.isSettingsValid()
|
||||||
|
? Optional.of(
|
||||||
|
ClientRegistrations.fromIssuerLocation(keycloak.getIssuer())
|
||||||
|
.registrationId(keycloak.getName())
|
||||||
|
.clientId(keycloak.getClientId())
|
||||||
|
.clientSecret(keycloak.getClientSecret())
|
||||||
|
.scope(keycloak.getScopes())
|
||||||
|
.userNameAttributeName(keycloak.getUseAsUsername())
|
||||||
|
.clientName(keycloak.getClientName())
|
||||||
|
.build())
|
||||||
|
: Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Optional<ClientRegistration> githubClientRegistration() {
|
||||||
|
OAUTH2 oauth = applicationProperties.getSecurity().getOauth2();
|
||||||
|
if (oauth == null || !oauth.getEnabled()) {
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
Client client = oauth.getClient();
|
||||||
|
if (client == null) {
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
GithubProvider github = client.getGithub();
|
||||||
|
return github != null && github.isSettingsValid()
|
||||||
|
? Optional.of(
|
||||||
|
ClientRegistration.withRegistrationId(github.getName())
|
||||||
|
.clientId(github.getClientId())
|
||||||
|
.clientSecret(github.getClientSecret())
|
||||||
|
.scope(github.getScopes())
|
||||||
|
.authorizationUri(github.getAuthorizationuri())
|
||||||
|
.tokenUri(github.getTokenuri())
|
||||||
|
.userInfoUri(github.getUserinfouri())
|
||||||
|
.userNameAttributeName(github.getUseAsUsername())
|
||||||
|
.clientName(github.getClientName())
|
||||||
|
.redirectUri("{baseUrl}/login/oauth2/code/" + github.getName())
|
||||||
|
.authorizationGrantType(
|
||||||
|
org.springframework.security.oauth2.core
|
||||||
|
.AuthorizationGrantType.AUTHORIZATION_CODE)
|
||||||
|
.build())
|
||||||
|
: Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Optional<ClientRegistration> oidcClientRegistration() {
|
||||||
|
OAUTH2 oauth = applicationProperties.getSecurity().getOauth2();
|
||||||
|
if (oauth == null
|
||||||
|
|| oauth.getIssuer() == null
|
||||||
|
|| oauth.getIssuer().isEmpty()
|
||||||
|
|| oauth.getClientId() == null
|
||||||
|
|| oauth.getClientId().isEmpty()
|
||||||
|
|| oauth.getClientSecret() == null
|
||||||
|
|| oauth.getClientSecret().isEmpty()
|
||||||
|
|| oauth.getScopes() == null
|
||||||
|
|| oauth.getScopes().isEmpty()
|
||||||
|
|| oauth.getUseAsUsername() == null
|
||||||
|
|| oauth.getUseAsUsername().isEmpty()) {
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
return Optional.of(
|
||||||
|
ClientRegistrations.fromIssuerLocation(oauth.getIssuer())
|
||||||
|
.registrationId("oidc")
|
||||||
|
.clientId(oauth.getClientId())
|
||||||
|
.clientSecret(oauth.getClientSecret())
|
||||||
|
.scope(oauth.getScopes())
|
||||||
|
.userNameAttributeName(oauth.getUseAsUsername())
|
||||||
|
.clientName("OIDC")
|
||||||
|
.build());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
@ConditionalOnProperty(
|
||||||
|
name = "security.saml2.enabled",
|
||||||
|
havingValue = "true",
|
||||||
|
matchIfMissing = false)
|
||||||
|
public RelyingPartyRegistrationRepository relyingPartyRegistrations() throws Exception {
|
||||||
|
SAML2 samlConf = applicationProperties.getSecurity().getSaml2();
|
||||||
|
X509Certificate idpCert = CertificateUtils.readCertificate(samlConf.getidpCert());
|
||||||
|
Saml2X509Credential verificationCredential = Saml2X509Credential.verification(idpCert);
|
||||||
|
Resource privateKeyResource = samlConf.getPrivateKey();
|
||||||
|
Resource certificateResource = samlConf.getSpCert();
|
||||||
|
Saml2X509Credential signingCredential =
|
||||||
|
new Saml2X509Credential(
|
||||||
|
CertificateUtils.readPrivateKey(privateKeyResource),
|
||||||
|
CertificateUtils.readCertificate(certificateResource),
|
||||||
|
Saml2X509CredentialType.SIGNING);
|
||||||
|
RelyingPartyRegistration rp =
|
||||||
|
RelyingPartyRegistration.withRegistrationId(samlConf.getRegistrationId())
|
||||||
|
.signingX509Credentials(c -> c.add(signingCredential))
|
||||||
|
.assertingPartyMetadata(
|
||||||
|
metadata ->
|
||||||
|
metadata.entityId(samlConf.getIdpIssuer())
|
||||||
|
.singleSignOnServiceLocation(
|
||||||
|
samlConf.getIdpSingleLoginUrl())
|
||||||
|
.verificationX509Credentials(
|
||||||
|
c -> c.add(verificationCredential))
|
||||||
|
.singleSignOnServiceBinding(
|
||||||
|
Saml2MessageBinding.POST)
|
||||||
|
.wantAuthnRequestsSigned(true))
|
||||||
|
.build();
|
||||||
|
return new InMemoryRelyingPartyRegistrationRepository(rp);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
@ConditionalOnProperty(
|
||||||
|
name = "security.saml2.enabled",
|
||||||
|
havingValue = "true",
|
||||||
|
matchIfMissing = false)
|
||||||
|
public OpenSaml4AuthenticationRequestResolver authenticationRequestResolver(
|
||||||
|
RelyingPartyRegistrationRepository relyingPartyRegistrationRepository) {
|
||||||
|
OpenSaml4AuthenticationRequestResolver resolver =
|
||||||
|
new OpenSaml4AuthenticationRequestResolver(relyingPartyRegistrationRepository);
|
||||||
|
resolver.setAuthnRequestCustomizer(
|
||||||
|
customizer -> {
|
||||||
|
log.debug("Customizing SAML Authentication request");
|
||||||
|
AuthnRequest authnRequest = customizer.getAuthnRequest();
|
||||||
|
log.debug("AuthnRequest ID: {}", authnRequest.getID());
|
||||||
|
if (authnRequest.getID() == null) {
|
||||||
|
authnRequest.setID("ARQ" + UUID.randomUUID().toString());
|
||||||
|
}
|
||||||
|
log.debug("AuthnRequest new ID after set: {}", authnRequest.getID());
|
||||||
|
log.debug("AuthnRequest IssueInstant: {}", authnRequest.getIssueInstant());
|
||||||
|
log.debug(
|
||||||
|
"AuthnRequest Issuer: {}",
|
||||||
|
authnRequest.getIssuer() != null
|
||||||
|
? authnRequest.getIssuer().getValue()
|
||||||
|
: "null");
|
||||||
|
HttpServletRequest request = customizer.getRequest();
|
||||||
|
// Log HTTP request details
|
||||||
|
log.debug("HTTP Request Method: {}", request.getMethod());
|
||||||
|
log.debug("Request URI: {}", request.getRequestURI());
|
||||||
|
log.debug("Request URL: {}", request.getRequestURL().toString());
|
||||||
|
log.debug("Query String: {}", request.getQueryString());
|
||||||
|
log.debug("Remote Address: {}", request.getRemoteAddr());
|
||||||
|
// Log headers
|
||||||
|
Collections.list(request.getHeaderNames())
|
||||||
|
.forEach(
|
||||||
|
headerName -> {
|
||||||
|
log.debug(
|
||||||
|
"Header - {}: {}",
|
||||||
|
headerName,
|
||||||
|
request.getHeader(headerName));
|
||||||
|
});
|
||||||
|
// Log SAML specific parameters
|
||||||
|
log.debug("SAML Request Parameters:");
|
||||||
|
log.debug("SAMLRequest: {}", request.getParameter("SAMLRequest"));
|
||||||
|
log.debug("RelayState: {}", request.getParameter("RelayState"));
|
||||||
|
// Log session debugrmation if exists
|
||||||
|
if (request.getSession(false) != null) {
|
||||||
|
log.debug("Session ID: {}", request.getSession().getId());
|
||||||
|
}
|
||||||
|
// Log any assertions consumer service details if present
|
||||||
|
if (authnRequest.getAssertionConsumerServiceURL() != null) {
|
||||||
|
log.debug(
|
||||||
|
"AssertionConsumerServiceURL: {}",
|
||||||
|
authnRequest.getAssertionConsumerServiceURL());
|
||||||
|
}
|
||||||
|
// Log NameID policy if present
|
||||||
|
if (authnRequest.getNameIDPolicy() != null) {
|
||||||
|
log.debug(
|
||||||
|
"NameIDPolicy Format: {}",
|
||||||
|
authnRequest.getNameIDPolicy().getFormat());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return resolver;
|
||||||
|
}
|
||||||
|
|
||||||
public DaoAuthenticationProvider daoAuthenticationProvider() {
|
public DaoAuthenticationProvider daoAuthenticationProvider() {
|
||||||
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
|
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
|
||||||
provider.setUserDetailsService(userDetailsService);
|
provider.setUserDetailsService(userDetailsService);
|
||||||
@@ -301,6 +556,46 @@ public class SecurityConfiguration {
|
|||||||
return provider;
|
return provider;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
This following function is to grant Authorities to the OAUTH2 user from the values stored in the database.
|
||||||
|
This is required for the internal; 'hasRole()' function to give out the correct role.
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
@ConditionalOnProperty(
|
||||||
|
value = "security.oauth2.enabled",
|
||||||
|
havingValue = "true",
|
||||||
|
matchIfMissing = false)
|
||||||
|
GrantedAuthoritiesMapper userAuthoritiesMapper() {
|
||||||
|
return (authorities) -> {
|
||||||
|
Set<GrantedAuthority> mappedAuthorities = new HashSet<>();
|
||||||
|
authorities.forEach(
|
||||||
|
authority -> {
|
||||||
|
// Add existing OAUTH2 Authorities
|
||||||
|
mappedAuthorities.add(new SimpleGrantedAuthority(authority.getAuthority()));
|
||||||
|
// Add Authorities from database for existing user, if user is present.
|
||||||
|
if (authority instanceof OAuth2UserAuthority oauth2Auth) {
|
||||||
|
String useAsUsername =
|
||||||
|
applicationProperties
|
||||||
|
.getSecurity()
|
||||||
|
.getOauth2()
|
||||||
|
.getUseAsUsername();
|
||||||
|
Optional<User> userOpt =
|
||||||
|
userService.findByUsernameIgnoreCase(
|
||||||
|
(String) oauth2Auth.getAttributes().get(useAsUsername));
|
||||||
|
if (userOpt.isPresent()) {
|
||||||
|
User user = userOpt.get();
|
||||||
|
if (user != null) {
|
||||||
|
mappedAuthorities.add(
|
||||||
|
new SimpleGrantedAuthority(
|
||||||
|
userService.findRole(user).getAuthority()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return mappedAuthorities;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public IPRateLimitingFilter rateLimitingFilter() {
|
public IPRateLimitingFilter rateLimitingFilter() {
|
||||||
// Example limit TODO add config level
|
// Example limit TODO add config level
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package stirling.software.SPDF.config.security;
|
package stirling.software.SPDF.config.security;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@@ -21,12 +20,11 @@ import org.springframework.stereotype.Service;
|
|||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import stirling.software.SPDF.config.interfaces.DatabaseInterface;
|
import stirling.software.SPDF.config.interfaces.DatabaseBackupInterface;
|
||||||
import stirling.software.SPDF.config.security.saml2.CustomSaml2AuthenticatedPrincipal;
|
import stirling.software.SPDF.config.security.saml2.CustomSaml2AuthenticatedPrincipal;
|
||||||
import stirling.software.SPDF.config.security.session.SessionPersistentRegistry;
|
import stirling.software.SPDF.config.security.session.SessionPersistentRegistry;
|
||||||
import stirling.software.SPDF.controller.api.pipeline.UserServiceInterface;
|
import stirling.software.SPDF.controller.api.pipeline.UserServiceInterface;
|
||||||
import stirling.software.SPDF.model.*;
|
import stirling.software.SPDF.model.*;
|
||||||
import stirling.software.SPDF.model.provider.UnsupportedProviderException;
|
|
||||||
import stirling.software.SPDF.repository.AuthorityRepository;
|
import stirling.software.SPDF.repository.AuthorityRepository;
|
||||||
import stirling.software.SPDF.repository.UserRepository;
|
import stirling.software.SPDF.repository.UserRepository;
|
||||||
|
|
||||||
@@ -44,7 +42,7 @@ public class UserService implements UserServiceInterface {
|
|||||||
|
|
||||||
private final SessionPersistentRegistry sessionRegistry;
|
private final SessionPersistentRegistry sessionRegistry;
|
||||||
|
|
||||||
private final DatabaseInterface databaseService;
|
private final DatabaseBackupInterface databaseBackupHelper;
|
||||||
|
|
||||||
private final ApplicationProperties applicationProperties;
|
private final ApplicationProperties applicationProperties;
|
||||||
|
|
||||||
@@ -54,14 +52,14 @@ public class UserService implements UserServiceInterface {
|
|||||||
PasswordEncoder passwordEncoder,
|
PasswordEncoder passwordEncoder,
|
||||||
MessageSource messageSource,
|
MessageSource messageSource,
|
||||||
SessionPersistentRegistry sessionRegistry,
|
SessionPersistentRegistry sessionRegistry,
|
||||||
DatabaseInterface databaseService,
|
DatabaseBackupInterface databaseBackupHelper,
|
||||||
ApplicationProperties applicationProperties) {
|
ApplicationProperties applicationProperties) {
|
||||||
this.userRepository = userRepository;
|
this.userRepository = userRepository;
|
||||||
this.authorityRepository = authorityRepository;
|
this.authorityRepository = authorityRepository;
|
||||||
this.passwordEncoder = passwordEncoder;
|
this.passwordEncoder = passwordEncoder;
|
||||||
this.messageSource = messageSource;
|
this.messageSource = messageSource;
|
||||||
this.sessionRegistry = sessionRegistry;
|
this.sessionRegistry = sessionRegistry;
|
||||||
this.databaseService = databaseService;
|
this.databaseBackupHelper = databaseBackupHelper;
|
||||||
this.applicationProperties = applicationProperties;
|
this.applicationProperties = applicationProperties;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -78,7 +76,7 @@ public class UserService implements UserServiceInterface {
|
|||||||
|
|
||||||
// Handle OAUTH2 login and user auto creation.
|
// Handle OAUTH2 login and user auto creation.
|
||||||
public boolean processSSOPostLogin(String username, boolean autoCreateUser)
|
public boolean processSSOPostLogin(String username, boolean autoCreateUser)
|
||||||
throws IllegalArgumentException, SQLException, UnsupportedProviderException {
|
throws IllegalArgumentException, IOException {
|
||||||
if (!isUsernameValid(username)) {
|
if (!isUsernameValid(username)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -165,12 +163,12 @@ public class UserService implements UserServiceInterface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void saveUser(String username, AuthenticationType authenticationType)
|
public void saveUser(String username, AuthenticationType authenticationType)
|
||||||
throws IllegalArgumentException, SQLException, UnsupportedProviderException {
|
throws IllegalArgumentException, IOException {
|
||||||
saveUser(username, authenticationType, Role.USER.getRoleId());
|
saveUser(username, authenticationType, Role.USER.getRoleId());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void saveUser(String username, AuthenticationType authenticationType, String role)
|
public void saveUser(String username, AuthenticationType authenticationType, String role)
|
||||||
throws IllegalArgumentException, SQLException, UnsupportedProviderException {
|
throws IllegalArgumentException, IOException {
|
||||||
if (!isUsernameValid(username)) {
|
if (!isUsernameValid(username)) {
|
||||||
throw new IllegalArgumentException(getInvalidUsernameMessage());
|
throw new IllegalArgumentException(getInvalidUsernameMessage());
|
||||||
}
|
}
|
||||||
@@ -181,11 +179,11 @@ public class UserService implements UserServiceInterface {
|
|||||||
user.addAuthority(new Authority(role, user));
|
user.addAuthority(new Authority(role, user));
|
||||||
user.setAuthenticationType(authenticationType);
|
user.setAuthenticationType(authenticationType);
|
||||||
userRepository.save(user);
|
userRepository.save(user);
|
||||||
databaseService.exportDatabase();
|
databaseBackupHelper.exportDatabase();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void saveUser(String username, String password)
|
public void saveUser(String username, String password)
|
||||||
throws IllegalArgumentException, SQLException, UnsupportedProviderException {
|
throws IllegalArgumentException, IOException {
|
||||||
if (!isUsernameValid(username)) {
|
if (!isUsernameValid(username)) {
|
||||||
throw new IllegalArgumentException(getInvalidUsernameMessage());
|
throw new IllegalArgumentException(getInvalidUsernameMessage());
|
||||||
}
|
}
|
||||||
@@ -195,11 +193,11 @@ public class UserService implements UserServiceInterface {
|
|||||||
user.setEnabled(true);
|
user.setEnabled(true);
|
||||||
user.setAuthenticationType(AuthenticationType.WEB);
|
user.setAuthenticationType(AuthenticationType.WEB);
|
||||||
userRepository.save(user);
|
userRepository.save(user);
|
||||||
databaseService.exportDatabase();
|
databaseBackupHelper.exportDatabase();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void saveUser(String username, String password, String role, boolean firstLogin)
|
public void saveUser(String username, String password, String role, boolean firstLogin)
|
||||||
throws IllegalArgumentException, SQLException, UnsupportedProviderException {
|
throws IllegalArgumentException, IOException {
|
||||||
if (!isUsernameValid(username)) {
|
if (!isUsernameValid(username)) {
|
||||||
throw new IllegalArgumentException(getInvalidUsernameMessage());
|
throw new IllegalArgumentException(getInvalidUsernameMessage());
|
||||||
}
|
}
|
||||||
@@ -211,11 +209,11 @@ public class UserService implements UserServiceInterface {
|
|||||||
user.setAuthenticationType(AuthenticationType.WEB);
|
user.setAuthenticationType(AuthenticationType.WEB);
|
||||||
user.setFirstLogin(firstLogin);
|
user.setFirstLogin(firstLogin);
|
||||||
userRepository.save(user);
|
userRepository.save(user);
|
||||||
databaseService.exportDatabase();
|
databaseBackupHelper.exportDatabase();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void saveUser(String username, String password, String role)
|
public void saveUser(String username, String password, String role)
|
||||||
throws IllegalArgumentException, SQLException, UnsupportedProviderException {
|
throws IllegalArgumentException, IOException {
|
||||||
saveUser(username, password, role, false);
|
saveUser(username, password, role, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -249,7 +247,7 @@ public class UserService implements UserServiceInterface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void updateUserSettings(String username, Map<String, String> updates)
|
public void updateUserSettings(String username, Map<String, String> updates)
|
||||||
throws SQLException, UnsupportedProviderException {
|
throws IOException {
|
||||||
Optional<User> userOpt = findByUsernameIgnoreCaseWithSettings(username);
|
Optional<User> userOpt = findByUsernameIgnoreCaseWithSettings(username);
|
||||||
if (userOpt.isPresent()) {
|
if (userOpt.isPresent()) {
|
||||||
User user = userOpt.get();
|
User user = userOpt.get();
|
||||||
@@ -261,7 +259,7 @@ public class UserService implements UserServiceInterface {
|
|||||||
settingsMap.putAll(updates);
|
settingsMap.putAll(updates);
|
||||||
user.setSettings(settingsMap);
|
user.setSettings(settingsMap);
|
||||||
userRepository.save(user);
|
userRepository.save(user);
|
||||||
databaseService.exportDatabase();
|
databaseBackupHelper.exportDatabase();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -282,45 +280,38 @@ public class UserService implements UserServiceInterface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void changeUsername(User user, String newUsername)
|
public void changeUsername(User user, String newUsername)
|
||||||
throws IllegalArgumentException,
|
throws IllegalArgumentException, IOException {
|
||||||
IOException,
|
|
||||||
SQLException,
|
|
||||||
UnsupportedProviderException {
|
|
||||||
if (!isUsernameValid(newUsername)) {
|
if (!isUsernameValid(newUsername)) {
|
||||||
throw new IllegalArgumentException(getInvalidUsernameMessage());
|
throw new IllegalArgumentException(getInvalidUsernameMessage());
|
||||||
}
|
}
|
||||||
user.setUsername(newUsername);
|
user.setUsername(newUsername);
|
||||||
userRepository.save(user);
|
userRepository.save(user);
|
||||||
databaseService.exportDatabase();
|
databaseBackupHelper.exportDatabase();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void changePassword(User user, String newPassword)
|
public void changePassword(User user, String newPassword) throws IOException {
|
||||||
throws SQLException, UnsupportedProviderException {
|
|
||||||
user.setPassword(passwordEncoder.encode(newPassword));
|
user.setPassword(passwordEncoder.encode(newPassword));
|
||||||
userRepository.save(user);
|
userRepository.save(user);
|
||||||
databaseService.exportDatabase();
|
databaseBackupHelper.exportDatabase();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void changeFirstUse(User user, boolean firstUse)
|
public void changeFirstUse(User user, boolean firstUse) throws IOException {
|
||||||
throws SQLException, UnsupportedProviderException {
|
|
||||||
user.setFirstLogin(firstUse);
|
user.setFirstLogin(firstUse);
|
||||||
userRepository.save(user);
|
userRepository.save(user);
|
||||||
databaseService.exportDatabase();
|
databaseBackupHelper.exportDatabase();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void changeRole(User user, String newRole)
|
public void changeRole(User user, String newRole) throws IOException {
|
||||||
throws SQLException, UnsupportedProviderException {
|
|
||||||
Authority userAuthority = this.findRole(user);
|
Authority userAuthority = this.findRole(user);
|
||||||
userAuthority.setAuthority(newRole);
|
userAuthority.setAuthority(newRole);
|
||||||
authorityRepository.save(userAuthority);
|
authorityRepository.save(userAuthority);
|
||||||
databaseService.exportDatabase();
|
databaseBackupHelper.exportDatabase();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void changeUserEnabled(User user, Boolean enbeled)
|
public void changeUserEnabled(User user, Boolean enbeled) throws IOException {
|
||||||
throws SQLException, UnsupportedProviderException {
|
|
||||||
user.setEnabled(enbeled);
|
user.setEnabled(enbeled);
|
||||||
userRepository.save(user);
|
userRepository.save(user);
|
||||||
databaseService.exportDatabase();
|
databaseBackupHelper.exportDatabase();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isPasswordCorrect(User user, String currentPassword) {
|
public boolean isPasswordCorrect(User user, String currentPassword) {
|
||||||
@@ -406,8 +397,7 @@ public class UserService implements UserServiceInterface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Transactional
|
@Transactional
|
||||||
public void syncCustomApiUser(String customApiKey)
|
public void syncCustomApiUser(String customApiKey) throws IOException {
|
||||||
throws SQLException, UnsupportedProviderException {
|
|
||||||
if (customApiKey == null || customApiKey.trim().length() == 0) {
|
if (customApiKey == null || customApiKey.trim().length() == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -424,14 +414,14 @@ public class UserService implements UserServiceInterface {
|
|||||||
user.setApiKey(customApiKey);
|
user.setApiKey(customApiKey);
|
||||||
user.addAuthority(new Authority(Role.INTERNAL_API_USER.getRoleId(), user));
|
user.addAuthority(new Authority(Role.INTERNAL_API_USER.getRoleId(), user));
|
||||||
userRepository.save(user);
|
userRepository.save(user);
|
||||||
databaseService.exportDatabase();
|
databaseBackupHelper.exportDatabase();
|
||||||
} else {
|
} else {
|
||||||
// Update API key if it has changed
|
// Update API key if it has changed
|
||||||
User user = existingUser.get();
|
User user = existingUser.get();
|
||||||
if (!customApiKey.equals(user.getApiKey())) {
|
if (!customApiKey.equals(user.getApiKey())) {
|
||||||
user.setApiKey(customApiKey);
|
user.setApiKey(customApiKey);
|
||||||
userRepository.save(user);
|
userRepository.save(user);
|
||||||
databaseService.exportDatabase();
|
databaseBackupHelper.exportDatabase();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,232 @@
|
|||||||
|
package stirling.software.SPDF.config.security.database;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.DirectoryStream;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.nio.file.attribute.BasicFileAttributes;
|
||||||
|
import java.sql.*;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.ZoneId;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import stirling.software.SPDF.config.interfaces.DatabaseBackupInterface;
|
||||||
|
import stirling.software.SPDF.utils.FileInfo;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@Configuration
|
||||||
|
public class DatabaseBackupHelper implements DatabaseBackupInterface {
|
||||||
|
|
||||||
|
@Value("${spring.datasource.url}")
|
||||||
|
private String url;
|
||||||
|
|
||||||
|
@Value("${spring.datasource.username}")
|
||||||
|
private String databaseUsername;
|
||||||
|
|
||||||
|
@Value("${spring.datasource.password}")
|
||||||
|
private String databasePassword;
|
||||||
|
|
||||||
|
private Path backupPath = Paths.get("configs/db/backup/");
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasBackup() {
|
||||||
|
// Check if there is at least one backup
|
||||||
|
return !getBackupList().isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<FileInfo> getBackupList() {
|
||||||
|
// Check if the backup directory exists, and create it if it does not
|
||||||
|
ensureBackupDirectoryExists();
|
||||||
|
|
||||||
|
List<FileInfo> backupFiles = new ArrayList<>();
|
||||||
|
|
||||||
|
// Read the backup directory and filter for files with the prefix "backup_" and suffix
|
||||||
|
// ".sql"
|
||||||
|
try (DirectoryStream<Path> stream =
|
||||||
|
Files.newDirectoryStream(
|
||||||
|
backupPath,
|
||||||
|
path ->
|
||||||
|
path.getFileName().toString().startsWith("backup_")
|
||||||
|
&& path.getFileName().toString().endsWith(".sql"))) {
|
||||||
|
for (Path entry : stream) {
|
||||||
|
BasicFileAttributes attrs = Files.readAttributes(entry, BasicFileAttributes.class);
|
||||||
|
LocalDateTime modificationDate =
|
||||||
|
LocalDateTime.ofInstant(
|
||||||
|
attrs.lastModifiedTime().toInstant(), ZoneId.systemDefault());
|
||||||
|
LocalDateTime creationDate =
|
||||||
|
LocalDateTime.ofInstant(
|
||||||
|
attrs.creationTime().toInstant(), ZoneId.systemDefault());
|
||||||
|
long fileSize = attrs.size();
|
||||||
|
backupFiles.add(
|
||||||
|
new FileInfo(
|
||||||
|
entry.getFileName().toString(),
|
||||||
|
entry.toString(),
|
||||||
|
modificationDate,
|
||||||
|
fileSize,
|
||||||
|
creationDate));
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.error("Error reading backup directory: {}", e.getMessage(), e);
|
||||||
|
}
|
||||||
|
return backupFiles;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Imports a database backup from the specified file.
|
||||||
|
public boolean importDatabaseFromUI(String fileName) throws IOException {
|
||||||
|
return this.importDatabaseFromUI(getBackupFilePath(fileName));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Imports a database backup from the specified path.
|
||||||
|
public boolean importDatabaseFromUI(Path tempTemplatePath) throws IOException {
|
||||||
|
boolean success = executeDatabaseScript(tempTemplatePath);
|
||||||
|
if (success) {
|
||||||
|
LocalDateTime dateNow = LocalDateTime.now();
|
||||||
|
DateTimeFormatter myFormatObj = DateTimeFormatter.ofPattern("yyyyMMddHHmm");
|
||||||
|
Path insertOutputFilePath =
|
||||||
|
this.getBackupFilePath("backup_user_" + dateNow.format(myFormatObj) + ".sql");
|
||||||
|
Files.copy(tempTemplatePath, insertOutputFilePath);
|
||||||
|
Files.deleteIfExists(tempTemplatePath);
|
||||||
|
}
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean importDatabase() {
|
||||||
|
if (!this.hasBackup()) return false;
|
||||||
|
|
||||||
|
List<FileInfo> backupList = this.getBackupList();
|
||||||
|
backupList.sort(Comparator.comparing(FileInfo::getModificationDate).reversed());
|
||||||
|
|
||||||
|
return executeDatabaseScript(Paths.get(backupList.get(0).getFilePath()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void exportDatabase() throws IOException {
|
||||||
|
// Check if the backup directory exists, and create it if it does not
|
||||||
|
ensureBackupDirectoryExists();
|
||||||
|
|
||||||
|
// Filter and delete old backups if there are more than 5
|
||||||
|
List<FileInfo> filteredBackupList =
|
||||||
|
this.getBackupList().stream()
|
||||||
|
.filter(backup -> !backup.getFileName().startsWith("backup_user_"))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
if (filteredBackupList.size() > 5) {
|
||||||
|
filteredBackupList.sort(
|
||||||
|
Comparator.comparing(
|
||||||
|
p -> p.getFileName().substring(7, p.getFileName().length() - 4)));
|
||||||
|
Files.deleteIfExists(Paths.get(filteredBackupList.get(0).getFilePath()));
|
||||||
|
log.info("Deleted oldest backup: {}", filteredBackupList.get(0).getFileName());
|
||||||
|
}
|
||||||
|
|
||||||
|
LocalDateTime dateNow = LocalDateTime.now();
|
||||||
|
DateTimeFormatter myFormatObj = DateTimeFormatter.ofPattern("yyyyMMddHHmm");
|
||||||
|
Path insertOutputFilePath =
|
||||||
|
this.getBackupFilePath("backup_" + dateNow.format(myFormatObj) + ".sql");
|
||||||
|
String query = "SCRIPT SIMPLE COLUMNS DROP to ?;";
|
||||||
|
|
||||||
|
try (Connection conn =
|
||||||
|
DriverManager.getConnection(url, databaseUsername, databasePassword);
|
||||||
|
PreparedStatement stmt = conn.prepareStatement(query)) {
|
||||||
|
stmt.setString(1, insertOutputFilePath.toString());
|
||||||
|
stmt.execute();
|
||||||
|
log.info("Database export completed: {}", insertOutputFilePath);
|
||||||
|
} catch (SQLException e) {
|
||||||
|
log.error("Error during database export: {}", e.getMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Retrieves the H2 database version.
|
||||||
|
public String getH2Version() {
|
||||||
|
String version = "Unknown";
|
||||||
|
try (Connection conn =
|
||||||
|
DriverManager.getConnection(url, databaseUsername, databasePassword)) {
|
||||||
|
try (Statement stmt = conn.createStatement();
|
||||||
|
ResultSet rs = stmt.executeQuery("SELECT H2VERSION() AS version")) {
|
||||||
|
if (rs.next()) {
|
||||||
|
version = rs.getString("version");
|
||||||
|
log.info("H2 Database Version: {}", version);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
log.error("Error retrieving H2 version: {}", e.getMessage(), e);
|
||||||
|
}
|
||||||
|
return version;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deletes a backup file.
|
||||||
|
public boolean deleteBackupFile(String fileName) throws IOException {
|
||||||
|
if (!isValidFileName(fileName)) {
|
||||||
|
log.error("Invalid file name: {}", fileName);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Path filePath = this.getBackupFilePath(fileName);
|
||||||
|
if (Files.deleteIfExists(filePath)) {
|
||||||
|
log.info("Deleted backup file: {}", fileName);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
log.error("File not found or could not be deleted: {}", fileName);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Gets the Path object for a given backup file name.
|
||||||
|
public Path getBackupFilePath(String fileName) {
|
||||||
|
Path filePath = Paths.get(backupPath.toString(), fileName).normalize();
|
||||||
|
if (!filePath.startsWith(backupPath)) {
|
||||||
|
throw new SecurityException("Path traversal detected");
|
||||||
|
}
|
||||||
|
return filePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean executeDatabaseScript(Path scriptPath) {
|
||||||
|
String query = "RUNSCRIPT from ?;";
|
||||||
|
|
||||||
|
try (Connection conn =
|
||||||
|
DriverManager.getConnection(url, databaseUsername, databasePassword);
|
||||||
|
PreparedStatement stmt = conn.prepareStatement(query)) {
|
||||||
|
stmt.setString(1, scriptPath.toString());
|
||||||
|
stmt.execute();
|
||||||
|
log.info("Database import completed: {}", scriptPath);
|
||||||
|
return true;
|
||||||
|
} catch (SQLException e) {
|
||||||
|
log.error("Error during database import: {}", e.getMessage(), e);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ensureBackupDirectoryExists() {
|
||||||
|
if (Files.notExists(backupPath)) {
|
||||||
|
try {
|
||||||
|
Files.createDirectories(backupPath);
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.error("Error creating directories: {}", e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isValidFileName(String fileName) {
|
||||||
|
// Check for invalid characters or sequences
|
||||||
|
return fileName != null
|
||||||
|
&& !fileName.contains("..")
|
||||||
|
&& !fileName.contains("/")
|
||||||
|
&& !fileName.contains("\\")
|
||||||
|
&& !fileName.contains(":")
|
||||||
|
&& !fileName.contains("*")
|
||||||
|
&& !fileName.contains("?")
|
||||||
|
&& !fileName.contains("\"")
|
||||||
|
&& !fileName.contains("<")
|
||||||
|
&& !fileName.contains(">")
|
||||||
|
&& !fileName.contains("|");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,139 +0,0 @@
|
|||||||
package stirling.software.SPDF.config.security.database;
|
|
||||||
|
|
||||||
import javax.sql.DataSource;
|
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Qualifier;
|
|
||||||
import org.springframework.boot.jdbc.DataSourceBuilder;
|
|
||||||
import org.springframework.context.annotation.Bean;
|
|
||||||
import org.springframework.context.annotation.Configuration;
|
|
||||||
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import stirling.software.SPDF.model.ApplicationProperties;
|
|
||||||
import stirling.software.SPDF.model.provider.UnsupportedProviderException;
|
|
||||||
|
|
||||||
@Slf4j
|
|
||||||
@Getter
|
|
||||||
@Configuration
|
|
||||||
public class DatabaseConfig {
|
|
||||||
|
|
||||||
public static final String DATASOURCE_DEFAULT_URL =
|
|
||||||
"jdbc:h2:file:./configs/stirling-pdf-DB-2.3.232;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE";
|
|
||||||
public static final String DATASOURCE_URL_TEMPLATE = "jdbc:%s://%s:%4d/%s";
|
|
||||||
public static final String DEFAULT_DRIVER = "org.h2.Driver";
|
|
||||||
public static final String DEFAULT_USERNAME = "sa";
|
|
||||||
public static final String POSTGRES_DRIVER = "org.postgresql.Driver";
|
|
||||||
|
|
||||||
private final ApplicationProperties applicationProperties;
|
|
||||||
private final boolean runningEE;
|
|
||||||
|
|
||||||
public DatabaseConfig(
|
|
||||||
ApplicationProperties applicationProperties,
|
|
||||||
@Qualifier("runningEE") boolean runningEE) {
|
|
||||||
this.applicationProperties = applicationProperties;
|
|
||||||
this.runningEE = runningEE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates the <code>DataSource</code> for the connection to the DB. If <code>useDefault</code>
|
|
||||||
* is set to <code>true</code>, it will use the default H2 DB. If it is set to <code>false
|
|
||||||
* </code>, it will use the user's custom configuration set in the settings.yml.
|
|
||||||
*
|
|
||||||
* @return a <code>DataSource</code> using the configuration settings in the settings.yml
|
|
||||||
* @throws UnsupportedProviderException if the type of database selected is not supported
|
|
||||||
*/
|
|
||||||
@Bean
|
|
||||||
@Qualifier("dataSource")
|
|
||||||
public DataSource dataSource() throws UnsupportedProviderException {
|
|
||||||
DataSourceBuilder<?> dataSourceBuilder = DataSourceBuilder.create();
|
|
||||||
|
|
||||||
if (!runningEE) {
|
|
||||||
return useDefaultDataSource(dataSourceBuilder);
|
|
||||||
}
|
|
||||||
|
|
||||||
ApplicationProperties.System system = applicationProperties.getSystem();
|
|
||||||
ApplicationProperties.Datasource datasource = system.getDatasource();
|
|
||||||
|
|
||||||
if (!datasource.isEnableCustomDatabase()) {
|
|
||||||
return useDefaultDataSource(dataSourceBuilder);
|
|
||||||
}
|
|
||||||
|
|
||||||
log.info("Using custom database configuration");
|
|
||||||
|
|
||||||
if (!datasource.getCustomDatabaseUrl().isBlank()) {
|
|
||||||
if (datasource.getCustomDatabaseUrl().contains("postgresql")) {
|
|
||||||
dataSourceBuilder.driverClassName(POSTGRES_DRIVER);
|
|
||||||
}
|
|
||||||
|
|
||||||
dataSourceBuilder.url(datasource.getCustomDatabaseUrl());
|
|
||||||
} else {
|
|
||||||
dataSourceBuilder.driverClassName(getDriverClassName(datasource.getType()));
|
|
||||||
dataSourceBuilder.url(
|
|
||||||
generateCustomDataSourceUrl(
|
|
||||||
datasource.getType(),
|
|
||||||
datasource.getHostName(),
|
|
||||||
datasource.getPort(),
|
|
||||||
datasource.getName()));
|
|
||||||
}
|
|
||||||
dataSourceBuilder.username(datasource.getUsername());
|
|
||||||
dataSourceBuilder.password(datasource.getPassword());
|
|
||||||
|
|
||||||
return dataSourceBuilder.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
private DataSource useDefaultDataSource(DataSourceBuilder<?> dataSourceBuilder) {
|
|
||||||
log.info("Using default H2 database");
|
|
||||||
|
|
||||||
dataSourceBuilder.url(DATASOURCE_DEFAULT_URL);
|
|
||||||
dataSourceBuilder.username(DEFAULT_USERNAME);
|
|
||||||
|
|
||||||
return dataSourceBuilder.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generate the URL the <code>DataSource</code> will use to connect to the database
|
|
||||||
*
|
|
||||||
* @param dataSourceType the type of the database
|
|
||||||
* @param hostname the host name
|
|
||||||
* @param port the port number to use for the database
|
|
||||||
* @param dataSourceName the name the database to connect to
|
|
||||||
* @return the <code>DataSource</code> URL
|
|
||||||
*/
|
|
||||||
private String generateCustomDataSourceUrl(
|
|
||||||
String dataSourceType, String hostname, Integer port, String dataSourceName) {
|
|
||||||
return DATASOURCE_URL_TEMPLATE.formatted(dataSourceType, hostname, port, dataSourceName);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Selects the database driver based on the type of database chosen.
|
|
||||||
*
|
|
||||||
* @param driverName the type of the driver (e.g. 'h2', 'postgresql')
|
|
||||||
* @return the fully qualified driver for the database chosen
|
|
||||||
* @throws UnsupportedProviderException when an unsupported database is selected
|
|
||||||
*/
|
|
||||||
private String getDriverClassName(String driverName) throws UnsupportedProviderException {
|
|
||||||
try {
|
|
||||||
ApplicationProperties.Driver driver =
|
|
||||||
ApplicationProperties.Driver.valueOf(driverName.toUpperCase());
|
|
||||||
|
|
||||||
switch (driver) {
|
|
||||||
case H2 -> {
|
|
||||||
log.debug("H2 driver selected");
|
|
||||||
return DEFAULT_DRIVER;
|
|
||||||
}
|
|
||||||
case POSTGRESQL -> {
|
|
||||||
log.debug("Postgres driver selected");
|
|
||||||
return POSTGRES_DRIVER;
|
|
||||||
}
|
|
||||||
default -> {
|
|
||||||
log.warn("{} driver selected", driverName);
|
|
||||||
throw new UnsupportedProviderException(
|
|
||||||
driverName + " is not currently supported");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (IllegalArgumentException e) {
|
|
||||||
log.warn("Unknown driver: {}", driverName);
|
|
||||||
throw new UnsupportedProviderException(driverName + " is not currently supported");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,301 +0,0 @@
|
|||||||
package stirling.software.SPDF.config.security.database;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.nio.file.DirectoryStream;
|
|
||||||
import java.nio.file.Files;
|
|
||||||
import java.nio.file.Path;
|
|
||||||
import java.nio.file.Paths;
|
|
||||||
import java.nio.file.attribute.BasicFileAttributes;
|
|
||||||
import java.sql.Connection;
|
|
||||||
import java.sql.PreparedStatement;
|
|
||||||
import java.sql.ResultSet;
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.sql.Statement;
|
|
||||||
import java.time.LocalDateTime;
|
|
||||||
import java.time.ZoneId;
|
|
||||||
import java.time.format.DateTimeFormatter;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Comparator;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
import javax.sql.DataSource;
|
|
||||||
|
|
||||||
import org.springframework.jdbc.datasource.init.CannotReadScriptException;
|
|
||||||
import org.springframework.jdbc.datasource.init.ScriptException;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import stirling.software.SPDF.config.interfaces.DatabaseInterface;
|
|
||||||
import stirling.software.SPDF.model.ApplicationProperties;
|
|
||||||
import stirling.software.SPDF.model.exception.BackupNotFoundException;
|
|
||||||
import stirling.software.SPDF.utils.FileInfo;
|
|
||||||
|
|
||||||
@Slf4j
|
|
||||||
@Service
|
|
||||||
public class DatabaseService implements DatabaseInterface {
|
|
||||||
|
|
||||||
public static final String BACKUP_PREFIX = "backup_";
|
|
||||||
public static final String SQL_SUFFIX = ".sql";
|
|
||||||
private static final String BACKUP_DIR = "configs/db/backup/";
|
|
||||||
|
|
||||||
private final ApplicationProperties applicationProperties;
|
|
||||||
private final DataSource dataSource;
|
|
||||||
|
|
||||||
public DatabaseService(ApplicationProperties applicationProperties, DataSource dataSource) {
|
|
||||||
this.applicationProperties = applicationProperties;
|
|
||||||
this.dataSource = dataSource;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if there is at least one backup. First checks if the directory exists, then checks if
|
|
||||||
* there are backup scripts within the directory
|
|
||||||
*
|
|
||||||
* @return true if there are backup scripts, false if there are not
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public boolean hasBackup() {
|
|
||||||
Path filePath = Paths.get(BACKUP_DIR);
|
|
||||||
|
|
||||||
if (Files.exists(filePath)) {
|
|
||||||
return !getBackupList().isEmpty();
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Read the backup directory and filter for files with the prefix "backup_" and suffix ".sql"
|
|
||||||
*
|
|
||||||
* @return a <code>List</code> of backup files
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public List<FileInfo> getBackupList() {
|
|
||||||
List<FileInfo> backupFiles = new ArrayList<>();
|
|
||||||
|
|
||||||
if (isH2Database()) {
|
|
||||||
Path backupPath = Paths.get(BACKUP_DIR);
|
|
||||||
|
|
||||||
try (DirectoryStream<Path> stream =
|
|
||||||
Files.newDirectoryStream(
|
|
||||||
backupPath,
|
|
||||||
path ->
|
|
||||||
path.getFileName().toString().startsWith(BACKUP_PREFIX)
|
|
||||||
&& path.getFileName()
|
|
||||||
.toString()
|
|
||||||
.endsWith(SQL_SUFFIX))) {
|
|
||||||
for (Path entry : stream) {
|
|
||||||
BasicFileAttributes attrs =
|
|
||||||
Files.readAttributes(entry, BasicFileAttributes.class);
|
|
||||||
LocalDateTime modificationDate =
|
|
||||||
LocalDateTime.ofInstant(
|
|
||||||
attrs.lastModifiedTime().toInstant(), ZoneId.systemDefault());
|
|
||||||
LocalDateTime creationDate =
|
|
||||||
LocalDateTime.ofInstant(
|
|
||||||
attrs.creationTime().toInstant(), ZoneId.systemDefault());
|
|
||||||
long fileSize = attrs.size();
|
|
||||||
backupFiles.add(
|
|
||||||
new FileInfo(
|
|
||||||
entry.getFileName().toString(),
|
|
||||||
entry.toString(),
|
|
||||||
modificationDate,
|
|
||||||
fileSize,
|
|
||||||
creationDate));
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
log.error("Error reading backup directory: {}", e.getMessage(), e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return backupFiles;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void importDatabase() {
|
|
||||||
if (!hasBackup()) throw new BackupNotFoundException("No backup scripts were found.");
|
|
||||||
|
|
||||||
List<FileInfo> backupList = this.getBackupList();
|
|
||||||
backupList.sort(Comparator.comparing(FileInfo::getModificationDate).reversed());
|
|
||||||
|
|
||||||
Path latestExport = Paths.get(backupList.get(0).getFilePath());
|
|
||||||
|
|
||||||
executeDatabaseScript(latestExport);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Imports a database backup from the specified file. */
|
|
||||||
public boolean importDatabaseFromUI(String fileName) {
|
|
||||||
try {
|
|
||||||
importDatabaseFromUI(getBackupFilePath(fileName));
|
|
||||||
return true;
|
|
||||||
} catch (IOException e) {
|
|
||||||
log.error(
|
|
||||||
"Error importing database from file: {}, message: {}",
|
|
||||||
fileName,
|
|
||||||
e.getMessage(),
|
|
||||||
e.getCause());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Imports a database backup from the specified path. */
|
|
||||||
public boolean importDatabaseFromUI(Path tempTemplatePath) throws IOException {
|
|
||||||
executeDatabaseScript(tempTemplatePath);
|
|
||||||
LocalDateTime dateNow = LocalDateTime.now();
|
|
||||||
DateTimeFormatter myFormatObj = DateTimeFormatter.ofPattern("yyyyMMddHHmm");
|
|
||||||
Path insertOutputFilePath =
|
|
||||||
this.getBackupFilePath(
|
|
||||||
BACKUP_PREFIX + "user_" + dateNow.format(myFormatObj) + SQL_SUFFIX);
|
|
||||||
Files.copy(tempTemplatePath, insertOutputFilePath);
|
|
||||||
Files.deleteIfExists(tempTemplatePath);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void exportDatabase() {
|
|
||||||
List<FileInfo> filteredBackupList =
|
|
||||||
this.getBackupList().stream()
|
|
||||||
.filter(backup -> !backup.getFileName().startsWith(BACKUP_PREFIX + "user_"))
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
|
|
||||||
if (filteredBackupList.size() > 5) {
|
|
||||||
deleteOldestBackup(filteredBackupList);
|
|
||||||
}
|
|
||||||
|
|
||||||
LocalDateTime dateNow = LocalDateTime.now();
|
|
||||||
DateTimeFormatter myFormatObj = DateTimeFormatter.ofPattern("yyyyMMddHHmm");
|
|
||||||
Path insertOutputFilePath =
|
|
||||||
this.getBackupFilePath(BACKUP_PREFIX + dateNow.format(myFormatObj) + SQL_SUFFIX);
|
|
||||||
|
|
||||||
if (isH2Database()) {
|
|
||||||
String query = "SCRIPT SIMPLE COLUMNS DROP to ?;";
|
|
||||||
|
|
||||||
try (Connection conn = dataSource.getConnection();
|
|
||||||
PreparedStatement stmt = conn.prepareStatement(query)) {
|
|
||||||
stmt.setString(1, insertOutputFilePath.toString());
|
|
||||||
stmt.execute();
|
|
||||||
} catch (SQLException e) {
|
|
||||||
log.error("Error during database export: {}", e.getMessage(), e);
|
|
||||||
} catch (CannotReadScriptException e) {
|
|
||||||
log.error("Error during database export: File {} not found", insertOutputFilePath);
|
|
||||||
}
|
|
||||||
|
|
||||||
log.info("Database export completed: {}", insertOutputFilePath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void deleteOldestBackup(List<FileInfo> filteredBackupList) {
|
|
||||||
try {
|
|
||||||
filteredBackupList.sort(
|
|
||||||
Comparator.comparing(
|
|
||||||
p -> p.getFileName().substring(7, p.getFileName().length() - 4)));
|
|
||||||
|
|
||||||
FileInfo oldestFile = filteredBackupList.get(0);
|
|
||||||
Files.deleteIfExists(Paths.get(oldestFile.getFilePath()));
|
|
||||||
log.info("Deleted oldest backup: {}", oldestFile.getFileName());
|
|
||||||
} catch (IOException e) {
|
|
||||||
log.error("Unable to delete oldest backup, message: {}", e.getMessage(), e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieves the H2 database version.
|
|
||||||
*
|
|
||||||
* @return <code>String</code> of the H2 version
|
|
||||||
*/
|
|
||||||
public String getH2Version() {
|
|
||||||
String version = "Unknown";
|
|
||||||
|
|
||||||
if (isH2Database()) {
|
|
||||||
try (Connection conn = dataSource.getConnection()) {
|
|
||||||
try (Statement stmt = conn.createStatement();
|
|
||||||
ResultSet rs = stmt.executeQuery("SELECT H2VERSION() AS version")) {
|
|
||||||
if (rs.next()) {
|
|
||||||
version = rs.getString("version");
|
|
||||||
log.info("H2 Database Version: {}", version);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (SQLException e) {
|
|
||||||
log.error("Error retrieving H2 version: {}", e.getMessage(), e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return version;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isH2Database() {
|
|
||||||
ApplicationProperties.Datasource datasource =
|
|
||||||
applicationProperties.getSystem().getDatasource();
|
|
||||||
return !datasource.isEnableCustomDatabase()
|
|
||||||
|| datasource.getType().equalsIgnoreCase(ApplicationProperties.Driver.H2.name());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Deletes a backup file.
|
|
||||||
*
|
|
||||||
* @return true if successful, false if not
|
|
||||||
*/
|
|
||||||
public boolean deleteBackupFile(String fileName) throws IOException {
|
|
||||||
if (!isValidFileName(fileName)) {
|
|
||||||
log.error("Invalid file name: {}", fileName);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
Path filePath = this.getBackupFilePath(fileName);
|
|
||||||
if (Files.deleteIfExists(filePath)) {
|
|
||||||
log.info("Deleted backup file: {}", fileName);
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
log.error("File not found or could not be deleted: {}", fileName);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the Path for a given backup file name.
|
|
||||||
*
|
|
||||||
* @return the <code>Path</code> object for the given file name
|
|
||||||
*/
|
|
||||||
public Path getBackupFilePath(String fileName) {
|
|
||||||
Path filePath = Paths.get(BACKUP_DIR, fileName).normalize();
|
|
||||||
if (!filePath.startsWith(BACKUP_DIR)) {
|
|
||||||
throw new SecurityException("Path traversal detected");
|
|
||||||
}
|
|
||||||
return filePath;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void executeDatabaseScript(Path scriptPath) {
|
|
||||||
if (isH2Database()) {
|
|
||||||
String query = "RUNSCRIPT from ?;";
|
|
||||||
|
|
||||||
try (Connection conn = dataSource.getConnection();
|
|
||||||
PreparedStatement stmt = conn.prepareStatement(query)) {
|
|
||||||
stmt.setString(1, scriptPath.toString());
|
|
||||||
stmt.execute();
|
|
||||||
} catch (SQLException e) {
|
|
||||||
log.error("Error during database import: {}", e.getMessage(), e);
|
|
||||||
} catch (ScriptException e) {
|
|
||||||
log.error("Error: File {} not found", scriptPath.toString(), e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
log.info("Database import completed: {}", scriptPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks for invalid characters or sequences
|
|
||||||
*
|
|
||||||
* @return true if it contains no invalid characters, false if it does
|
|
||||||
*/
|
|
||||||
private boolean isValidFileName(String fileName) {
|
|
||||||
return fileName != null
|
|
||||||
&& !fileName.contains("..")
|
|
||||||
&& !fileName.contains("/")
|
|
||||||
&& !fileName.contains("\\")
|
|
||||||
&& !fileName.contains(":")
|
|
||||||
&& !fileName.contains("*")
|
|
||||||
&& !fileName.contains("?")
|
|
||||||
&& !fileName.contains("\"")
|
|
||||||
&& !fileName.contains("<")
|
|
||||||
&& !fileName.contains(">")
|
|
||||||
&& !fileName.contains("|");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,27 +1,21 @@
|
|||||||
package stirling.software.SPDF.config.security.database;
|
package stirling.software.SPDF.config.security.database;
|
||||||
|
|
||||||
import java.sql.SQLException;
|
import java.io.IOException;
|
||||||
|
|
||||||
import org.springframework.context.annotation.Conditional;
|
|
||||||
import org.springframework.scheduling.annotation.Scheduled;
|
import org.springframework.scheduling.annotation.Scheduled;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import stirling.software.SPDF.config.interfaces.DatabaseInterface;
|
|
||||||
import stirling.software.SPDF.controller.api.H2SQLCondition;
|
|
||||||
import stirling.software.SPDF.model.provider.UnsupportedProviderException;
|
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
@Conditional(H2SQLCondition.class)
|
|
||||||
public class ScheduledTasks {
|
public class ScheduledTasks {
|
||||||
|
|
||||||
private final DatabaseInterface databaseService;
|
private final DatabaseBackupHelper databaseBackupService;
|
||||||
|
|
||||||
public ScheduledTasks(DatabaseInterface databaseService) {
|
public ScheduledTasks(DatabaseBackupHelper databaseBackupService) {
|
||||||
this.databaseService = databaseService;
|
this.databaseBackupService = databaseBackupService;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Scheduled(cron = "0 0 0 * * ?")
|
@Scheduled(cron = "0 0 0 * * ?")
|
||||||
public void performBackup() throws SQLException, UnsupportedProviderException {
|
public void performBackup() throws IOException {
|
||||||
databaseService.exportDatabase();
|
databaseBackupService.exportDatabase();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package stirling.software.SPDF.config.security.oauth2;
|
package stirling.software.SPDF.config.security.oauth2;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.sql.SQLException;
|
|
||||||
|
|
||||||
import org.springframework.security.authentication.LockedException;
|
import org.springframework.security.authentication.LockedException;
|
||||||
import org.springframework.security.core.Authentication;
|
import org.springframework.security.core.Authentication;
|
||||||
@@ -19,7 +18,6 @@ import stirling.software.SPDF.config.security.UserService;
|
|||||||
import stirling.software.SPDF.model.ApplicationProperties;
|
import stirling.software.SPDF.model.ApplicationProperties;
|
||||||
import stirling.software.SPDF.model.ApplicationProperties.Security.OAUTH2;
|
import stirling.software.SPDF.model.ApplicationProperties.Security.OAUTH2;
|
||||||
import stirling.software.SPDF.model.AuthenticationType;
|
import stirling.software.SPDF.model.AuthenticationType;
|
||||||
import stirling.software.SPDF.model.provider.UnsupportedProviderException;
|
|
||||||
import stirling.software.SPDF.utils.RequestUriUtils;
|
import stirling.software.SPDF.utils.RequestUriUtils;
|
||||||
|
|
||||||
public class CustomOAuth2AuthenticationSuccessHandler
|
public class CustomOAuth2AuthenticationSuccessHandler
|
||||||
@@ -99,8 +97,10 @@ public class CustomOAuth2AuthenticationSuccessHandler
|
|||||||
userService.processSSOPostLogin(username, oAuth.getAutoCreateUser());
|
userService.processSSOPostLogin(username, oAuth.getAutoCreateUser());
|
||||||
}
|
}
|
||||||
response.sendRedirect(contextPath + "/");
|
response.sendRedirect(contextPath + "/");
|
||||||
} catch (IllegalArgumentException | SQLException | UnsupportedProviderException e) {
|
return;
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
response.sendRedirect(contextPath + "/logout?invalidUsername=true");
|
response.sendRedirect(contextPath + "/logout?invalidUsername=true");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,213 +0,0 @@
|
|||||||
package stirling.software.SPDF.config.security.oauth2;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
|
||||||
import org.springframework.context.annotation.Bean;
|
|
||||||
import org.springframework.context.annotation.Configuration;
|
|
||||||
import org.springframework.context.annotation.Lazy;
|
|
||||||
import org.springframework.security.core.GrantedAuthority;
|
|
||||||
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
|
||||||
import org.springframework.security.core.authority.mapping.GrantedAuthoritiesMapper;
|
|
||||||
import org.springframework.security.oauth2.client.registration.ClientRegistration;
|
|
||||||
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
|
|
||||||
import org.springframework.security.oauth2.client.registration.ClientRegistrations;
|
|
||||||
import org.springframework.security.oauth2.client.registration.InMemoryClientRegistrationRepository;
|
|
||||||
import org.springframework.security.oauth2.core.user.OAuth2UserAuthority;
|
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import stirling.software.SPDF.config.security.UserService;
|
|
||||||
import stirling.software.SPDF.model.ApplicationProperties;
|
|
||||||
import stirling.software.SPDF.model.ApplicationProperties.Security.OAUTH2;
|
|
||||||
import stirling.software.SPDF.model.ApplicationProperties.Security.OAUTH2.Client;
|
|
||||||
import stirling.software.SPDF.model.User;
|
|
||||||
import stirling.software.SPDF.model.provider.GithubProvider;
|
|
||||||
import stirling.software.SPDF.model.provider.GoogleProvider;
|
|
||||||
import stirling.software.SPDF.model.provider.KeycloakProvider;
|
|
||||||
|
|
||||||
@Configuration
|
|
||||||
@Slf4j
|
|
||||||
@ConditionalOnProperty(
|
|
||||||
value = "security.oauth2.enabled",
|
|
||||||
havingValue = "true",
|
|
||||||
matchIfMissing = false)
|
|
||||||
public class OAuth2Configuration {
|
|
||||||
|
|
||||||
private final ApplicationProperties applicationProperties;
|
|
||||||
@Lazy private final UserService userService;
|
|
||||||
|
|
||||||
public OAuth2Configuration(
|
|
||||||
ApplicationProperties applicationProperties, @Lazy UserService userService) {
|
|
||||||
this.userService = userService;
|
|
||||||
this.applicationProperties = applicationProperties;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
@ConditionalOnProperty(
|
|
||||||
value = "security.oauth2.enabled",
|
|
||||||
havingValue = "true",
|
|
||||||
matchIfMissing = false)
|
|
||||||
public ClientRegistrationRepository clientRegistrationRepository() {
|
|
||||||
List<ClientRegistration> registrations = new ArrayList<>();
|
|
||||||
githubClientRegistration().ifPresent(registrations::add);
|
|
||||||
oidcClientRegistration().ifPresent(registrations::add);
|
|
||||||
googleClientRegistration().ifPresent(registrations::add);
|
|
||||||
keycloakClientRegistration().ifPresent(registrations::add);
|
|
||||||
if (registrations.isEmpty()) {
|
|
||||||
log.error("At least one OAuth2 provider must be configured");
|
|
||||||
System.exit(1);
|
|
||||||
}
|
|
||||||
return new InMemoryClientRegistrationRepository(registrations);
|
|
||||||
}
|
|
||||||
|
|
||||||
private Optional<ClientRegistration> googleClientRegistration() {
|
|
||||||
OAUTH2 oauth = applicationProperties.getSecurity().getOauth2();
|
|
||||||
if (oauth == null || !oauth.getEnabled()) {
|
|
||||||
return Optional.empty();
|
|
||||||
}
|
|
||||||
Client client = oauth.getClient();
|
|
||||||
if (client == null) {
|
|
||||||
return Optional.empty();
|
|
||||||
}
|
|
||||||
GoogleProvider google = client.getGoogle();
|
|
||||||
return google != null && google.isSettingsValid()
|
|
||||||
? Optional.of(
|
|
||||||
ClientRegistration.withRegistrationId(google.getName())
|
|
||||||
.clientId(google.getClientId())
|
|
||||||
.clientSecret(google.getClientSecret())
|
|
||||||
.scope(google.getScopes())
|
|
||||||
.authorizationUri(google.getAuthorizationuri())
|
|
||||||
.tokenUri(google.getTokenuri())
|
|
||||||
.userInfoUri(google.getUserinfouri())
|
|
||||||
.userNameAttributeName(google.getUseAsUsername())
|
|
||||||
.clientName(google.getClientName())
|
|
||||||
.redirectUri("{baseUrl}/login/oauth2/code/" + google.getName())
|
|
||||||
.authorizationGrantType(
|
|
||||||
org.springframework.security.oauth2.core
|
|
||||||
.AuthorizationGrantType.AUTHORIZATION_CODE)
|
|
||||||
.build())
|
|
||||||
: Optional.empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
private Optional<ClientRegistration> keycloakClientRegistration() {
|
|
||||||
OAUTH2 oauth = applicationProperties.getSecurity().getOauth2();
|
|
||||||
if (oauth == null || !oauth.getEnabled()) {
|
|
||||||
return Optional.empty();
|
|
||||||
}
|
|
||||||
Client client = oauth.getClient();
|
|
||||||
if (client == null) {
|
|
||||||
return Optional.empty();
|
|
||||||
}
|
|
||||||
KeycloakProvider keycloak = client.getKeycloak();
|
|
||||||
return keycloak != null && keycloak.isSettingsValid()
|
|
||||||
? Optional.of(
|
|
||||||
ClientRegistrations.fromIssuerLocation(keycloak.getIssuer())
|
|
||||||
.registrationId(keycloak.getName())
|
|
||||||
.clientId(keycloak.getClientId())
|
|
||||||
.clientSecret(keycloak.getClientSecret())
|
|
||||||
.scope(keycloak.getScopes())
|
|
||||||
.userNameAttributeName(keycloak.getUseAsUsername())
|
|
||||||
.clientName(keycloak.getClientName())
|
|
||||||
.build())
|
|
||||||
: Optional.empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
private Optional<ClientRegistration> githubClientRegistration() {
|
|
||||||
OAUTH2 oauth = applicationProperties.getSecurity().getOauth2();
|
|
||||||
if (oauth == null || !oauth.getEnabled()) {
|
|
||||||
return Optional.empty();
|
|
||||||
}
|
|
||||||
Client client = oauth.getClient();
|
|
||||||
if (client == null) {
|
|
||||||
return Optional.empty();
|
|
||||||
}
|
|
||||||
GithubProvider github = client.getGithub();
|
|
||||||
return github != null && github.isSettingsValid()
|
|
||||||
? Optional.of(
|
|
||||||
ClientRegistration.withRegistrationId(github.getName())
|
|
||||||
.clientId(github.getClientId())
|
|
||||||
.clientSecret(github.getClientSecret())
|
|
||||||
.scope(github.getScopes())
|
|
||||||
.authorizationUri(github.getAuthorizationuri())
|
|
||||||
.tokenUri(github.getTokenuri())
|
|
||||||
.userInfoUri(github.getUserinfouri())
|
|
||||||
.userNameAttributeName(github.getUseAsUsername())
|
|
||||||
.clientName(github.getClientName())
|
|
||||||
.redirectUri("{baseUrl}/login/oauth2/code/" + github.getName())
|
|
||||||
.authorizationGrantType(
|
|
||||||
org.springframework.security.oauth2.core
|
|
||||||
.AuthorizationGrantType.AUTHORIZATION_CODE)
|
|
||||||
.build())
|
|
||||||
: Optional.empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
private Optional<ClientRegistration> oidcClientRegistration() {
|
|
||||||
OAUTH2 oauth = applicationProperties.getSecurity().getOauth2();
|
|
||||||
if (oauth == null
|
|
||||||
|| oauth.getIssuer() == null
|
|
||||||
|| oauth.getIssuer().isEmpty()
|
|
||||||
|| oauth.getClientId() == null
|
|
||||||
|| oauth.getClientId().isEmpty()
|
|
||||||
|| oauth.getClientSecret() == null
|
|
||||||
|| oauth.getClientSecret().isEmpty()
|
|
||||||
|| oauth.getScopes() == null
|
|
||||||
|| oauth.getScopes().isEmpty()
|
|
||||||
|| oauth.getUseAsUsername() == null
|
|
||||||
|| oauth.getUseAsUsername().isEmpty()) {
|
|
||||||
return Optional.empty();
|
|
||||||
}
|
|
||||||
return Optional.of(
|
|
||||||
ClientRegistrations.fromIssuerLocation(oauth.getIssuer())
|
|
||||||
.registrationId("oidc")
|
|
||||||
.clientId(oauth.getClientId())
|
|
||||||
.clientSecret(oauth.getClientSecret())
|
|
||||||
.scope(oauth.getScopes())
|
|
||||||
.userNameAttributeName(oauth.getUseAsUsername())
|
|
||||||
.clientName("OIDC")
|
|
||||||
.build());
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
This following function is to grant Authorities to the OAUTH2 user from the values stored in the database.
|
|
||||||
This is required for the internal; 'hasRole()' function to give out the correct role.
|
|
||||||
*/
|
|
||||||
@Bean
|
|
||||||
@ConditionalOnProperty(
|
|
||||||
value = "security.oauth2.enabled",
|
|
||||||
havingValue = "true",
|
|
||||||
matchIfMissing = false)
|
|
||||||
GrantedAuthoritiesMapper userAuthoritiesMapper() {
|
|
||||||
return (authorities) -> {
|
|
||||||
Set<GrantedAuthority> mappedAuthorities = new HashSet<>();
|
|
||||||
authorities.forEach(
|
|
||||||
authority -> {
|
|
||||||
// Add existing OAUTH2 Authorities
|
|
||||||
mappedAuthorities.add(new SimpleGrantedAuthority(authority.getAuthority()));
|
|
||||||
// Add Authorities from database for existing user, if user is present.
|
|
||||||
if (authority instanceof OAuth2UserAuthority oauth2Auth) {
|
|
||||||
String useAsUsername =
|
|
||||||
applicationProperties
|
|
||||||
.getSecurity()
|
|
||||||
.getOauth2()
|
|
||||||
.getUseAsUsername();
|
|
||||||
Optional<User> userOpt =
|
|
||||||
userService.findByUsernameIgnoreCase(
|
|
||||||
(String) oauth2Auth.getAttributes().get(useAsUsername));
|
|
||||||
if (userOpt.isPresent()) {
|
|
||||||
User user = userOpt.get();
|
|
||||||
if (user != null) {
|
|
||||||
mappedAuthorities.add(
|
|
||||||
new SimpleGrantedAuthority(
|
|
||||||
userService.findRole(user).getAuthority()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return mappedAuthorities;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
package stirling.software.SPDF.config.security.saml2;
|
package stirling.software.SPDF.config.security.saml2;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.sql.SQLException;
|
|
||||||
|
|
||||||
import org.springframework.security.authentication.LockedException;
|
import org.springframework.security.authentication.LockedException;
|
||||||
import org.springframework.security.core.Authentication;
|
import org.springframework.security.core.Authentication;
|
||||||
@@ -19,7 +18,6 @@ import stirling.software.SPDF.config.security.UserService;
|
|||||||
import stirling.software.SPDF.model.ApplicationProperties;
|
import stirling.software.SPDF.model.ApplicationProperties;
|
||||||
import stirling.software.SPDF.model.ApplicationProperties.Security.SAML2;
|
import stirling.software.SPDF.model.ApplicationProperties.Security.SAML2;
|
||||||
import stirling.software.SPDF.model.AuthenticationType;
|
import stirling.software.SPDF.model.AuthenticationType;
|
||||||
import stirling.software.SPDF.model.provider.UnsupportedProviderException;
|
|
||||||
import stirling.software.SPDF.utils.RequestUriUtils;
|
import stirling.software.SPDF.utils.RequestUriUtils;
|
||||||
|
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@@ -111,7 +109,7 @@ public class CustomSaml2AuthenticationSuccessHandler
|
|||||||
log.debug("Successfully processed authentication for user: {}", username);
|
log.debug("Successfully processed authentication for user: {}", username);
|
||||||
response.sendRedirect(contextPath + "/");
|
response.sendRedirect(contextPath + "/");
|
||||||
return;
|
return;
|
||||||
} catch (IllegalArgumentException | SQLException | UnsupportedProviderException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
log.debug(
|
log.debug(
|
||||||
"Invalid username detected for user: {}, redirecting to logout",
|
"Invalid username detected for user: {}, redirecting to logout",
|
||||||
username);
|
username);
|
||||||
|
|||||||
@@ -1,136 +0,0 @@
|
|||||||
package stirling.software.SPDF.config.security.saml2;
|
|
||||||
|
|
||||||
import java.security.cert.X509Certificate;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
import org.opensaml.saml.saml2.core.AuthnRequest;
|
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
|
||||||
import org.springframework.context.annotation.Bean;
|
|
||||||
import org.springframework.context.annotation.Configuration;
|
|
||||||
import org.springframework.core.io.Resource;
|
|
||||||
import org.springframework.security.saml2.core.Saml2X509Credential;
|
|
||||||
import org.springframework.security.saml2.core.Saml2X509Credential.Saml2X509CredentialType;
|
|
||||||
import org.springframework.security.saml2.provider.service.registration.InMemoryRelyingPartyRegistrationRepository;
|
|
||||||
import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistration;
|
|
||||||
import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistrationRepository;
|
|
||||||
import org.springframework.security.saml2.provider.service.registration.Saml2MessageBinding;
|
|
||||||
import org.springframework.security.saml2.provider.service.web.authentication.OpenSaml4AuthenticationRequestResolver;
|
|
||||||
|
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import stirling.software.SPDF.model.ApplicationProperties;
|
|
||||||
import stirling.software.SPDF.model.ApplicationProperties.Security.SAML2;
|
|
||||||
|
|
||||||
@Configuration
|
|
||||||
@Slf4j
|
|
||||||
@ConditionalOnProperty(
|
|
||||||
value = "security.saml2.enabled",
|
|
||||||
havingValue = "true",
|
|
||||||
matchIfMissing = false)
|
|
||||||
public class SAML2Configuration {
|
|
||||||
|
|
||||||
private final ApplicationProperties applicationProperties;
|
|
||||||
|
|
||||||
public SAML2Configuration(ApplicationProperties applicationProperties) {
|
|
||||||
|
|
||||||
this.applicationProperties = applicationProperties;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
@ConditionalOnProperty(
|
|
||||||
name = "security.saml2.enabled",
|
|
||||||
havingValue = "true",
|
|
||||||
matchIfMissing = false)
|
|
||||||
public RelyingPartyRegistrationRepository relyingPartyRegistrations() throws Exception {
|
|
||||||
SAML2 samlConf = applicationProperties.getSecurity().getSaml2();
|
|
||||||
X509Certificate idpCert = CertificateUtils.readCertificate(samlConf.getidpCert());
|
|
||||||
Saml2X509Credential verificationCredential = Saml2X509Credential.verification(idpCert);
|
|
||||||
Resource privateKeyResource = samlConf.getPrivateKey();
|
|
||||||
Resource certificateResource = samlConf.getSpCert();
|
|
||||||
Saml2X509Credential signingCredential =
|
|
||||||
new Saml2X509Credential(
|
|
||||||
CertificateUtils.readPrivateKey(privateKeyResource),
|
|
||||||
CertificateUtils.readCertificate(certificateResource),
|
|
||||||
Saml2X509CredentialType.SIGNING);
|
|
||||||
RelyingPartyRegistration rp =
|
|
||||||
RelyingPartyRegistration.withRegistrationId(samlConf.getRegistrationId())
|
|
||||||
.signingX509Credentials(c -> c.add(signingCredential))
|
|
||||||
.assertingPartyMetadata(
|
|
||||||
metadata ->
|
|
||||||
metadata.entityId(samlConf.getIdpIssuer())
|
|
||||||
.singleSignOnServiceLocation(
|
|
||||||
samlConf.getIdpSingleLoginUrl())
|
|
||||||
.verificationX509Credentials(
|
|
||||||
c -> c.add(verificationCredential))
|
|
||||||
.singleSignOnServiceBinding(
|
|
||||||
Saml2MessageBinding.POST)
|
|
||||||
.wantAuthnRequestsSigned(true))
|
|
||||||
.build();
|
|
||||||
return new InMemoryRelyingPartyRegistrationRepository(rp);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
@ConditionalOnProperty(
|
|
||||||
name = "security.saml2.enabled",
|
|
||||||
havingValue = "true",
|
|
||||||
matchIfMissing = false)
|
|
||||||
public OpenSaml4AuthenticationRequestResolver authenticationRequestResolver(
|
|
||||||
RelyingPartyRegistrationRepository relyingPartyRegistrationRepository) {
|
|
||||||
OpenSaml4AuthenticationRequestResolver resolver =
|
|
||||||
new OpenSaml4AuthenticationRequestResolver(relyingPartyRegistrationRepository);
|
|
||||||
resolver.setAuthnRequestCustomizer(
|
|
||||||
customizer -> {
|
|
||||||
log.debug("Customizing SAML Authentication request");
|
|
||||||
AuthnRequest authnRequest = customizer.getAuthnRequest();
|
|
||||||
log.debug("AuthnRequest ID: {}", authnRequest.getID());
|
|
||||||
if (authnRequest.getID() == null) {
|
|
||||||
authnRequest.setID("ARQ" + UUID.randomUUID().toString());
|
|
||||||
}
|
|
||||||
log.debug("AuthnRequest new ID after set: {}", authnRequest.getID());
|
|
||||||
log.debug("AuthnRequest IssueInstant: {}", authnRequest.getIssueInstant());
|
|
||||||
log.debug(
|
|
||||||
"AuthnRequest Issuer: {}",
|
|
||||||
authnRequest.getIssuer() != null
|
|
||||||
? authnRequest.getIssuer().getValue()
|
|
||||||
: "null");
|
|
||||||
HttpServletRequest request = customizer.getRequest();
|
|
||||||
// Log HTTP request details
|
|
||||||
log.debug("HTTP Request Method: {}", request.getMethod());
|
|
||||||
log.debug("Request URI: {}", request.getRequestURI());
|
|
||||||
log.debug("Request URL: {}", request.getRequestURL().toString());
|
|
||||||
log.debug("Query String: {}", request.getQueryString());
|
|
||||||
log.debug("Remote Address: {}", request.getRemoteAddr());
|
|
||||||
// Log headers
|
|
||||||
Collections.list(request.getHeaderNames())
|
|
||||||
.forEach(
|
|
||||||
headerName -> {
|
|
||||||
log.debug(
|
|
||||||
"Header - {}: {}",
|
|
||||||
headerName,
|
|
||||||
request.getHeader(headerName));
|
|
||||||
});
|
|
||||||
// Log SAML specific parameters
|
|
||||||
log.debug("SAML Request Parameters:");
|
|
||||||
log.debug("SAMLRequest: {}", request.getParameter("SAMLRequest"));
|
|
||||||
log.debug("RelayState: {}", request.getParameter("RelayState"));
|
|
||||||
// Log session debugrmation if exists
|
|
||||||
if (request.getSession(false) != null) {
|
|
||||||
log.debug("Session ID: {}", request.getSession().getId());
|
|
||||||
}
|
|
||||||
// Log any assertions consumer service details if present
|
|
||||||
if (authnRequest.getAssertionConsumerServiceURL() != null) {
|
|
||||||
log.debug(
|
|
||||||
"AssertionConsumerServiceURL: {}",
|
|
||||||
authnRequest.getAssertionConsumerServiceURL());
|
|
||||||
}
|
|
||||||
// Log NameID policy if present
|
|
||||||
if (authnRequest.getNameIDPolicy() != null) {
|
|
||||||
log.debug(
|
|
||||||
"NameIDPolicy Format: {}",
|
|
||||||
authnRequest.getNameIDPolicy().getFormat());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return resolver;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -8,7 +8,6 @@ import java.nio.file.Path;
|
|||||||
import java.nio.file.StandardCopyOption;
|
import java.nio.file.StandardCopyOption;
|
||||||
|
|
||||||
import org.eclipse.jetty.http.HttpStatus;
|
import org.eclipse.jetty.http.HttpStatus;
|
||||||
import org.springframework.context.annotation.Conditional;
|
|
||||||
import org.springframework.core.io.InputStreamResource;
|
import org.springframework.core.io.InputStreamResource;
|
||||||
import org.springframework.http.HttpHeaders;
|
import org.springframework.http.HttpHeaders;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
@@ -25,20 +24,19 @@ import io.swagger.v3.oas.annotations.Parameter;
|
|||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import stirling.software.SPDF.config.security.database.DatabaseService;
|
import stirling.software.SPDF.config.security.database.DatabaseBackupHelper;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Controller
|
@Controller
|
||||||
@RequestMapping("/api/v1/database")
|
@RequestMapping("/api/v1/database")
|
||||||
@PreAuthorize("hasRole('ROLE_ADMIN')")
|
@PreAuthorize("hasRole('ROLE_ADMIN')")
|
||||||
@Conditional(H2SQLCondition.class)
|
|
||||||
@Tag(name = "Database", description = "Database APIs for backup, import, and management")
|
@Tag(name = "Database", description = "Database APIs for backup, import, and management")
|
||||||
public class DatabaseController {
|
public class DatabaseController {
|
||||||
|
|
||||||
private final DatabaseService databaseService;
|
private final DatabaseBackupHelper databaseBackupHelper;
|
||||||
|
|
||||||
public DatabaseController(DatabaseService databaseService) {
|
public DatabaseController(DatabaseBackupHelper databaseBackupHelper) {
|
||||||
this.databaseService = databaseService;
|
this.databaseBackupHelper = databaseBackupHelper;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Operation(
|
@Operation(
|
||||||
@@ -59,7 +57,7 @@ public class DatabaseController {
|
|||||||
Path tempTemplatePath = Files.createTempFile("backup_", ".sql");
|
Path tempTemplatePath = Files.createTempFile("backup_", ".sql");
|
||||||
try (InputStream in = file.getInputStream()) {
|
try (InputStream in = file.getInputStream()) {
|
||||||
Files.copy(in, tempTemplatePath, StandardCopyOption.REPLACE_EXISTING);
|
Files.copy(in, tempTemplatePath, StandardCopyOption.REPLACE_EXISTING);
|
||||||
boolean importSuccess = databaseService.importDatabaseFromUI(tempTemplatePath);
|
boolean importSuccess = databaseBackupHelper.importDatabaseFromUI(tempTemplatePath);
|
||||||
if (importSuccess) {
|
if (importSuccess) {
|
||||||
redirectAttributes.addAttribute("infoMessage", "importIntoDatabaseSuccessed");
|
redirectAttributes.addAttribute("infoMessage", "importIntoDatabaseSuccessed");
|
||||||
} else {
|
} else {
|
||||||
@@ -79,20 +77,21 @@ public class DatabaseController {
|
|||||||
@GetMapping("/import-database-file/{fileName}")
|
@GetMapping("/import-database-file/{fileName}")
|
||||||
public String importDatabaseFromBackupUI(
|
public String importDatabaseFromBackupUI(
|
||||||
@Parameter(description = "Name of the file to import", required = true) @PathVariable
|
@Parameter(description = "Name of the file to import", required = true) @PathVariable
|
||||||
String fileName) {
|
String fileName)
|
||||||
|
throws IOException {
|
||||||
if (fileName == null || fileName.isEmpty()) {
|
if (fileName == null || fileName.isEmpty()) {
|
||||||
return "redirect:/database?error=fileNullOrEmpty";
|
return "redirect:/database?error=fileNullOrEmpty";
|
||||||
}
|
}
|
||||||
// Check if the file exists in the backup list
|
// Check if the file exists in the backup list
|
||||||
boolean fileExists =
|
boolean fileExists =
|
||||||
databaseService.getBackupList().stream()
|
databaseBackupHelper.getBackupList().stream()
|
||||||
.anyMatch(backup -> backup.getFileName().equals(fileName));
|
.anyMatch(backup -> backup.getFileName().equals(fileName));
|
||||||
if (!fileExists) {
|
if (!fileExists) {
|
||||||
log.error("File {} not found in backup list", fileName);
|
log.error("File {} not found in backup list", fileName);
|
||||||
return "redirect:/database?error=fileNotFound";
|
return "redirect:/database?error=fileNotFound";
|
||||||
}
|
}
|
||||||
log.info("Received file: {}", fileName);
|
log.info("Received file: {}", fileName);
|
||||||
if (databaseService.importDatabaseFromUI(fileName)) {
|
if (databaseBackupHelper.importDatabaseFromUI(fileName)) {
|
||||||
log.info("File {} imported to database", fileName);
|
log.info("File {} imported to database", fileName);
|
||||||
return "redirect:/database?infoMessage=importIntoDatabaseSuccessed";
|
return "redirect:/database?infoMessage=importIntoDatabaseSuccessed";
|
||||||
}
|
}
|
||||||
@@ -111,7 +110,7 @@ public class DatabaseController {
|
|||||||
throw new IllegalArgumentException("File must not be null or empty");
|
throw new IllegalArgumentException("File must not be null or empty");
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
if (databaseService.deleteBackupFile(fileName)) {
|
if (databaseBackupHelper.deleteBackupFile(fileName)) {
|
||||||
log.info("Deleted file: {}", fileName);
|
log.info("Deleted file: {}", fileName);
|
||||||
} else {
|
} else {
|
||||||
log.error("Failed to delete file: {}", fileName);
|
log.error("Failed to delete file: {}", fileName);
|
||||||
@@ -136,7 +135,7 @@ public class DatabaseController {
|
|||||||
throw new IllegalArgumentException("File must not be null or empty");
|
throw new IllegalArgumentException("File must not be null or empty");
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
Path filePath = databaseService.getBackupFilePath(fileName);
|
Path filePath = databaseBackupHelper.getBackupFilePath(fileName);
|
||||||
InputStreamResource resource = new InputStreamResource(Files.newInputStream(filePath));
|
InputStreamResource resource = new InputStreamResource(Files.newInputStream(filePath));
|
||||||
return ResponseEntity.ok()
|
return ResponseEntity.ok()
|
||||||
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=" + fileName)
|
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=" + fileName)
|
||||||
@@ -158,9 +157,14 @@ public class DatabaseController {
|
|||||||
+ " database management page.")
|
+ " database management page.")
|
||||||
@GetMapping("/createDatabaseBackup")
|
@GetMapping("/createDatabaseBackup")
|
||||||
public String createDatabaseBackup() {
|
public String createDatabaseBackup() {
|
||||||
log.info("Starting database backup creation...");
|
try {
|
||||||
databaseService.exportDatabase();
|
log.info("Starting database backup creation...");
|
||||||
log.info("Database backup successfully created.");
|
databaseBackupHelper.exportDatabase();
|
||||||
|
log.info("Database backup successfully created.");
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.error("Error creating database backup: {}", e.getMessage(), e);
|
||||||
|
return "redirect:/database?error=" + e.getMessage();
|
||||||
|
}
|
||||||
return "redirect:/database?infoMessage=backupCreated";
|
return "redirect:/database?infoMessage=backupCreated";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,19 +0,0 @@
|
|||||||
package stirling.software.SPDF.controller.api;
|
|
||||||
|
|
||||||
import org.springframework.context.annotation.Condition;
|
|
||||||
import org.springframework.context.annotation.ConditionContext;
|
|
||||||
import org.springframework.core.type.AnnotatedTypeMetadata;
|
|
||||||
|
|
||||||
public class H2SQLCondition implements Condition {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
|
|
||||||
boolean enableCustomDatabase =
|
|
||||||
Boolean.parseBoolean(
|
|
||||||
context.getEnvironment()
|
|
||||||
.getProperty("system.datasource.enableCustomDatabase"));
|
|
||||||
String dataSourceType = context.getEnvironment().getProperty("system.datasource.type");
|
|
||||||
return !enableCustomDatabase
|
|
||||||
|| (enableCustomDatabase && "h2".equalsIgnoreCase(dataSourceType));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -2,7 +2,6 @@ package stirling.software.SPDF.controller.api;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.security.Principal;
|
import java.security.Principal;
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -34,7 +33,6 @@ import stirling.software.SPDF.model.AuthenticationType;
|
|||||||
import stirling.software.SPDF.model.Role;
|
import stirling.software.SPDF.model.Role;
|
||||||
import stirling.software.SPDF.model.User;
|
import stirling.software.SPDF.model.User;
|
||||||
import stirling.software.SPDF.model.api.user.UsernameAndPass;
|
import stirling.software.SPDF.model.api.user.UsernameAndPass;
|
||||||
import stirling.software.SPDF.model.provider.UnsupportedProviderException;
|
|
||||||
|
|
||||||
@Controller
|
@Controller
|
||||||
@Tag(name = "User", description = "User APIs")
|
@Tag(name = "User", description = "User APIs")
|
||||||
@@ -54,7 +52,7 @@ public class UserController {
|
|||||||
@PreAuthorize("!hasAuthority('ROLE_DEMO_USER')")
|
@PreAuthorize("!hasAuthority('ROLE_DEMO_USER')")
|
||||||
@PostMapping("/register")
|
@PostMapping("/register")
|
||||||
public String register(@ModelAttribute UsernameAndPass requestModel, Model model)
|
public String register(@ModelAttribute UsernameAndPass requestModel, Model model)
|
||||||
throws SQLException, UnsupportedProviderException {
|
throws IOException {
|
||||||
if (userService.usernameExistsIgnoreCase(requestModel.getUsername())) {
|
if (userService.usernameExistsIgnoreCase(requestModel.getUsername())) {
|
||||||
model.addAttribute("error", "Username already exists");
|
model.addAttribute("error", "Username already exists");
|
||||||
return "register";
|
return "register";
|
||||||
@@ -76,7 +74,7 @@ public class UserController {
|
|||||||
HttpServletRequest request,
|
HttpServletRequest request,
|
||||||
HttpServletResponse response,
|
HttpServletResponse response,
|
||||||
RedirectAttributes redirectAttributes)
|
RedirectAttributes redirectAttributes)
|
||||||
throws IOException, SQLException, UnsupportedProviderException {
|
throws IOException {
|
||||||
if (!userService.isUsernameValid(newUsername)) {
|
if (!userService.isUsernameValid(newUsername)) {
|
||||||
return new RedirectView("/account?messageType=invalidUsername", true);
|
return new RedirectView("/account?messageType=invalidUsername", true);
|
||||||
}
|
}
|
||||||
@@ -119,7 +117,7 @@ public class UserController {
|
|||||||
HttpServletRequest request,
|
HttpServletRequest request,
|
||||||
HttpServletResponse response,
|
HttpServletResponse response,
|
||||||
RedirectAttributes redirectAttributes)
|
RedirectAttributes redirectAttributes)
|
||||||
throws SQLException, UnsupportedProviderException {
|
throws IOException {
|
||||||
if (principal == null) {
|
if (principal == null) {
|
||||||
return new RedirectView("/change-creds?messageType=notAuthenticated", true);
|
return new RedirectView("/change-creds?messageType=notAuthenticated", true);
|
||||||
}
|
}
|
||||||
@@ -147,7 +145,7 @@ public class UserController {
|
|||||||
HttpServletRequest request,
|
HttpServletRequest request,
|
||||||
HttpServletResponse response,
|
HttpServletResponse response,
|
||||||
RedirectAttributes redirectAttributes)
|
RedirectAttributes redirectAttributes)
|
||||||
throws SQLException, UnsupportedProviderException {
|
throws IOException {
|
||||||
if (principal == null) {
|
if (principal == null) {
|
||||||
return new RedirectView("/account?messageType=notAuthenticated", true);
|
return new RedirectView("/account?messageType=notAuthenticated", true);
|
||||||
}
|
}
|
||||||
@@ -168,7 +166,7 @@ public class UserController {
|
|||||||
@PreAuthorize("!hasAuthority('ROLE_DEMO_USER')")
|
@PreAuthorize("!hasAuthority('ROLE_DEMO_USER')")
|
||||||
@PostMapping("/updateUserSettings")
|
@PostMapping("/updateUserSettings")
|
||||||
public String updateUserSettings(HttpServletRequest request, Principal principal)
|
public String updateUserSettings(HttpServletRequest request, Principal principal)
|
||||||
throws SQLException, UnsupportedProviderException {
|
throws IOException {
|
||||||
Map<String, String[]> paramMap = request.getParameterMap();
|
Map<String, String[]> paramMap = request.getParameterMap();
|
||||||
Map<String, String> updates = new HashMap<>();
|
Map<String, String> updates = new HashMap<>();
|
||||||
for (Map.Entry<String, String[]> entry : paramMap.entrySet()) {
|
for (Map.Entry<String, String[]> entry : paramMap.entrySet()) {
|
||||||
@@ -190,7 +188,7 @@ public class UserController {
|
|||||||
@RequestParam(name = "authType") String authType,
|
@RequestParam(name = "authType") String authType,
|
||||||
@RequestParam(name = "forceChange", required = false, defaultValue = "false")
|
@RequestParam(name = "forceChange", required = false, defaultValue = "false")
|
||||||
boolean forceChange)
|
boolean forceChange)
|
||||||
throws IllegalArgumentException, SQLException, UnsupportedProviderException {
|
throws IllegalArgumentException, IOException {
|
||||||
if (!userService.isUsernameValid(username)) {
|
if (!userService.isUsernameValid(username)) {
|
||||||
return new RedirectView("/addUsers?messageType=invalidUsername", true);
|
return new RedirectView("/addUsers?messageType=invalidUsername", true);
|
||||||
}
|
}
|
||||||
@@ -234,7 +232,7 @@ public class UserController {
|
|||||||
@RequestParam(name = "username") String username,
|
@RequestParam(name = "username") String username,
|
||||||
@RequestParam(name = "role") String role,
|
@RequestParam(name = "role") String role,
|
||||||
Authentication authentication)
|
Authentication authentication)
|
||||||
throws SQLException, UnsupportedProviderException {
|
throws IOException {
|
||||||
Optional<User> userOpt = userService.findByUsernameIgnoreCase(username);
|
Optional<User> userOpt = userService.findByUsernameIgnoreCase(username);
|
||||||
if (!userOpt.isPresent()) {
|
if (!userOpt.isPresent()) {
|
||||||
return new RedirectView("/addUsers?messageType=userNotFound", true);
|
return new RedirectView("/addUsers?messageType=userNotFound", true);
|
||||||
@@ -272,7 +270,7 @@ public class UserController {
|
|||||||
@PathVariable("username") String username,
|
@PathVariable("username") String username,
|
||||||
@RequestParam("enabled") boolean enabled,
|
@RequestParam("enabled") boolean enabled,
|
||||||
Authentication authentication)
|
Authentication authentication)
|
||||||
throws SQLException, UnsupportedProviderException {
|
throws IOException {
|
||||||
Optional<User> userOpt = userService.findByUsernameIgnoreCase(username);
|
Optional<User> userOpt = userService.findByUsernameIgnoreCase(username);
|
||||||
if (!userOpt.isPresent()) {
|
if (!userOpt.isPresent()) {
|
||||||
return new RedirectView("/addUsers?messageType=userNotFound", true);
|
return new RedirectView("/addUsers?messageType=userNotFound", true);
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
|
|||||||
|
|
||||||
import jakarta.servlet.ServletContext;
|
import jakarta.servlet.ServletContext;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import stirling.software.SPDF.SPDFApplication;
|
import stirling.software.SPDF.SPdfApplication;
|
||||||
import stirling.software.SPDF.model.ApiEndpoint;
|
import stirling.software.SPDF.model.ApiEndpoint;
|
||||||
import stirling.software.SPDF.model.Role;
|
import stirling.software.SPDF.model.Role;
|
||||||
|
|
||||||
@@ -44,7 +44,7 @@ public class ApiDocService {
|
|||||||
|
|
||||||
private String getApiDocsUrl() {
|
private String getApiDocsUrl() {
|
||||||
String contextPath = servletContext.getContextPath();
|
String contextPath = servletContext.getContextPath();
|
||||||
String port = SPDFApplication.getStaticPort();
|
String port = SPdfApplication.getStaticPort();
|
||||||
return "http://localhost:" + port + contextPath + "/v1/api-docs";
|
return "http://localhost:" + port + contextPath + "/v1/api-docs";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ import io.github.pixee.security.ZipSecurity;
|
|||||||
|
|
||||||
import jakarta.servlet.ServletContext;
|
import jakarta.servlet.ServletContext;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import stirling.software.SPDF.SPDFApplication;
|
import stirling.software.SPDF.SPdfApplication;
|
||||||
import stirling.software.SPDF.model.PipelineConfig;
|
import stirling.software.SPDF.model.PipelineConfig;
|
||||||
import stirling.software.SPDF.model.PipelineOperation;
|
import stirling.software.SPDF.model.PipelineOperation;
|
||||||
import stirling.software.SPDF.model.Role;
|
import stirling.software.SPDF.model.Role;
|
||||||
@@ -80,7 +80,7 @@ public class PipelineProcessor {
|
|||||||
|
|
||||||
private String getBaseUrl() {
|
private String getBaseUrl() {
|
||||||
String contextPath = servletContext.getContextPath();
|
String contextPath = servletContext.getContextPath();
|
||||||
String port = SPDFApplication.getStaticPort();
|
String port = SPdfApplication.getStaticPort();
|
||||||
return "http://localhost:" + port + contextPath + "/";
|
return "http://localhost:" + port + contextPath + "/";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,18 +3,13 @@ package stirling.software.SPDF.controller.api.security;
|
|||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||||
import org.apache.pdfbox.pdmodel.PDPage;
|
|
||||||
import org.apache.pdfbox.pdmodel.PDPageContentStream;
|
import org.apache.pdfbox.pdmodel.PDPageContentStream;
|
||||||
import org.apache.pdfbox.pdmodel.PDPageTree;
|
|
||||||
import org.apache.pdfbox.pdmodel.common.PDRectangle;
|
import org.apache.pdfbox.pdmodel.common.PDRectangle;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.WebDataBinder;
|
|
||||||
import org.springframework.web.bind.annotation.InitBinder;
|
|
||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
@@ -27,15 +22,11 @@ import io.swagger.v3.oas.annotations.tags.Tag;
|
|||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import stirling.software.SPDF.model.PDFText;
|
import stirling.software.SPDF.model.PDFText;
|
||||||
import stirling.software.SPDF.model.api.security.ManualRedactPdfRequest;
|
|
||||||
import stirling.software.SPDF.model.api.security.RedactPdfRequest;
|
import stirling.software.SPDF.model.api.security.RedactPdfRequest;
|
||||||
import stirling.software.SPDF.model.api.security.RedactionArea;
|
|
||||||
import stirling.software.SPDF.pdf.TextFinder;
|
import stirling.software.SPDF.pdf.TextFinder;
|
||||||
import stirling.software.SPDF.service.CustomPDDocumentFactory;
|
import stirling.software.SPDF.service.CustomPDDocumentFactory;
|
||||||
import stirling.software.SPDF.utils.GeneralUtils;
|
|
||||||
import stirling.software.SPDF.utils.PdfUtils;
|
import stirling.software.SPDF.utils.PdfUtils;
|
||||||
import stirling.software.SPDF.utils.WebResponseUtils;
|
import stirling.software.SPDF.utils.WebResponseUtils;
|
||||||
import stirling.software.SPDF.utils.propertyeditor.StringToArrayListPropertyEditor;
|
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/api/v1/security")
|
@RequestMapping("/api/v1/security")
|
||||||
@@ -50,120 +41,6 @@ public class RedactController {
|
|||||||
this.pdfDocumentFactory = pdfDocumentFactory;
|
this.pdfDocumentFactory = pdfDocumentFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
@InitBinder
|
|
||||||
public void initBinder(WebDataBinder binder) {
|
|
||||||
binder.registerCustomEditor(
|
|
||||||
List.class, "redactions", new StringToArrayListPropertyEditor());
|
|
||||||
}
|
|
||||||
|
|
||||||
@PostMapping(value = "/redact", consumes = "multipart/form-data")
|
|
||||||
@Operation(
|
|
||||||
summary = "Redacts areas and pages in a PDF document",
|
|
||||||
description =
|
|
||||||
"This operation takes an input PDF file with a list of areas, page number(s)/range(s)/function(s) to redact. Input:PDF, Output:PDF, Type:SISO")
|
|
||||||
public ResponseEntity<byte[]> redactPDF(@ModelAttribute ManualRedactPdfRequest request)
|
|
||||||
throws IOException {
|
|
||||||
MultipartFile file = request.getFileInput();
|
|
||||||
List<RedactionArea> redactionAreas = request.getRedactions();
|
|
||||||
|
|
||||||
PDDocument document = pdfDocumentFactory.load(file);
|
|
||||||
|
|
||||||
PDPageTree allPages = document.getDocumentCatalog().getPages();
|
|
||||||
|
|
||||||
redactPages(request, document, allPages);
|
|
||||||
redactAreas(redactionAreas, document, allPages);
|
|
||||||
|
|
||||||
if (request.isConvertPDFToImage()) {
|
|
||||||
PDDocument convertedPdf = PdfUtils.convertPdfToPdfImage(document);
|
|
||||||
document.close();
|
|
||||||
document = convertedPdf;
|
|
||||||
}
|
|
||||||
|
|
||||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
|
||||||
document.save(baos);
|
|
||||||
document.close();
|
|
||||||
|
|
||||||
byte[] pdfContent = baos.toByteArray();
|
|
||||||
return WebResponseUtils.bytesToWebResponse(
|
|
||||||
pdfContent,
|
|
||||||
Filenames.toSimpleFileName(file.getOriginalFilename()).replaceFirst("[.][^.]+$", "")
|
|
||||||
+ "_redacted.pdf");
|
|
||||||
}
|
|
||||||
|
|
||||||
private void redactAreas(
|
|
||||||
List<RedactionArea> redactionAreas, PDDocument document, PDPageTree allPages)
|
|
||||||
throws IOException {
|
|
||||||
Color redactColor = null;
|
|
||||||
for (RedactionArea redactionArea : redactionAreas) {
|
|
||||||
if (redactionArea.getPage() == null
|
|
||||||
|| redactionArea.getPage() <= 0
|
|
||||||
|| redactionArea.getHeight() == null
|
|
||||||
|| redactionArea.getHeight() <= 0.0D
|
|
||||||
|| redactionArea.getWidth() == null
|
|
||||||
|| redactionArea.getWidth() <= 0.0D) continue;
|
|
||||||
PDPage page = allPages.get(redactionArea.getPage() - 1);
|
|
||||||
|
|
||||||
PDPageContentStream contentStream =
|
|
||||||
new PDPageContentStream(
|
|
||||||
document, page, PDPageContentStream.AppendMode.APPEND, true, true);
|
|
||||||
redactColor = decodeOrDefault(redactionArea.getColor(), Color.BLACK);
|
|
||||||
contentStream.setNonStrokingColor(redactColor);
|
|
||||||
|
|
||||||
float x = redactionArea.getX().floatValue();
|
|
||||||
float y = redactionArea.getY().floatValue();
|
|
||||||
float width = redactionArea.getWidth().floatValue();
|
|
||||||
float height = redactionArea.getHeight().floatValue();
|
|
||||||
|
|
||||||
PDRectangle box = page.getBBox();
|
|
||||||
|
|
||||||
contentStream.addRect(x, box.getHeight() - y - height, width, height);
|
|
||||||
contentStream.fill();
|
|
||||||
contentStream.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void redactPages(
|
|
||||||
ManualRedactPdfRequest request, PDDocument document, PDPageTree allPages)
|
|
||||||
throws IOException {
|
|
||||||
Color redactColor = decodeOrDefault(request.getPageRedactionColor(), Color.BLACK);
|
|
||||||
List<Integer> pageNumbers = getPageNumbers(request, allPages.getCount());
|
|
||||||
for (Integer pageNumber : pageNumbers) {
|
|
||||||
PDPage page = allPages.get(pageNumber);
|
|
||||||
|
|
||||||
PDPageContentStream contentStream =
|
|
||||||
new PDPageContentStream(
|
|
||||||
document, page, PDPageContentStream.AppendMode.APPEND, true, true);
|
|
||||||
contentStream.setNonStrokingColor(redactColor);
|
|
||||||
|
|
||||||
PDRectangle box = page.getBBox();
|
|
||||||
|
|
||||||
contentStream.addRect(0, 0, box.getWidth(), box.getHeight());
|
|
||||||
contentStream.fill();
|
|
||||||
contentStream.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Color decodeOrDefault(String hex, Color defaultColor) {
|
|
||||||
Color color = null;
|
|
||||||
try {
|
|
||||||
color = Color.decode(hex);
|
|
||||||
} catch (Exception e) {
|
|
||||||
color = defaultColor;
|
|
||||||
}
|
|
||||||
|
|
||||||
return color;
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<Integer> getPageNumbers(ManualRedactPdfRequest request, int pagesCount) {
|
|
||||||
String pageNumbersInput = request.getPageNumbers();
|
|
||||||
String[] parsedPageNumbers =
|
|
||||||
pageNumbersInput != null ? pageNumbersInput.split(",") : new String[0];
|
|
||||||
List<Integer> pageNumbers =
|
|
||||||
GeneralUtils.parsePageList(parsedPageNumbers, pagesCount, false);
|
|
||||||
Collections.sort(pageNumbers);
|
|
||||||
return pageNumbers;
|
|
||||||
}
|
|
||||||
|
|
||||||
@PostMapping(value = "/auto-redact", consumes = "multipart/form-data")
|
@PostMapping(value = "/auto-redact", consumes = "multipart/form-data")
|
||||||
@Operation(
|
@Operation(
|
||||||
summary = "Redacts listOfText in a PDF document",
|
summary = "Redacts listOfText in a PDF document",
|
||||||
|
|||||||
@@ -14,11 +14,7 @@ import org.apache.pdfbox.pdmodel.PDDocument;
|
|||||||
import org.apache.pdfbox.pdmodel.interactive.digitalsignature.PDSignature;
|
import org.apache.pdfbox.pdmodel.interactive.digitalsignature.PDSignature;
|
||||||
import org.bouncycastle.cert.X509CertificateHolder;
|
import org.bouncycastle.cert.X509CertificateHolder;
|
||||||
import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
|
import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
|
||||||
import org.bouncycastle.cms.CMSProcessable;
|
import org.bouncycastle.cms.*;
|
||||||
import org.bouncycastle.cms.CMSProcessableByteArray;
|
|
||||||
import org.bouncycastle.cms.CMSSignedData;
|
|
||||||
import org.bouncycastle.cms.SignerInformation;
|
|
||||||
import org.bouncycastle.cms.SignerInformationStore;
|
|
||||||
import org.bouncycastle.cms.jcajce.JcaSimpleSignerInfoVerifierBuilder;
|
import org.bouncycastle.cms.jcajce.JcaSimpleSignerInfoVerifierBuilder;
|
||||||
import org.bouncycastle.util.Store;
|
import org.bouncycastle.util.Store;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
|||||||
@@ -11,17 +11,17 @@ import org.springframework.web.bind.annotation.GetMapping;
|
|||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import stirling.software.SPDF.config.security.database.DatabaseService;
|
import stirling.software.SPDF.config.security.database.DatabaseBackupHelper;
|
||||||
import stirling.software.SPDF.utils.FileInfo;
|
import stirling.software.SPDF.utils.FileInfo;
|
||||||
|
|
||||||
@Controller
|
@Controller
|
||||||
@Tag(name = "Database Management", description = "Database management and security APIs")
|
@Tag(name = "Database Management", description = "Database management and security APIs")
|
||||||
public class DatabaseWebController {
|
public class DatabaseWebController {
|
||||||
|
|
||||||
private final DatabaseService databaseService;
|
private final DatabaseBackupHelper databaseBackupHelper;
|
||||||
|
|
||||||
public DatabaseWebController(DatabaseService databaseService) {
|
public DatabaseWebController(DatabaseBackupHelper databaseBackupHelper) {
|
||||||
this.databaseService = databaseService;
|
this.databaseBackupHelper = databaseBackupHelper;
|
||||||
}
|
}
|
||||||
|
|
||||||
@PreAuthorize("hasRole('ROLE_ADMIN')")
|
@PreAuthorize("hasRole('ROLE_ADMIN')")
|
||||||
@@ -34,12 +34,9 @@ public class DatabaseWebController {
|
|||||||
} else if (confirmed != null) {
|
} else if (confirmed != null) {
|
||||||
model.addAttribute("infoMessage", confirmed);
|
model.addAttribute("infoMessage", confirmed);
|
||||||
}
|
}
|
||||||
List<FileInfo> backupList = databaseService.getBackupList();
|
List<FileInfo> backupList = databaseBackupHelper.getBackupList();
|
||||||
model.addAttribute("backupFiles", backupList);
|
model.addAttribute("backupFiles", backupList);
|
||||||
model.addAttribute("databaseVersion", databaseService.getH2Version());
|
model.addAttribute("databaseVersion", databaseBackupHelper.getH2Version());
|
||||||
if ("Unknown".equalsIgnoreCase(databaseService.getH2Version())) {
|
|
||||||
model.addAttribute("infoMessage", "notSupported");
|
|
||||||
}
|
|
||||||
return "database";
|
return "database";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,12 +18,6 @@ public class SecurityWebController {
|
|||||||
return "security/auto-redact";
|
return "security/auto-redact";
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/redact")
|
|
||||||
public String redactForm(Model model) {
|
|
||||||
model.addAttribute("currentPage", "redact");
|
|
||||||
return "security/redact";
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping("/add-password")
|
@GetMapping("/add-password")
|
||||||
@Hidden
|
@Hidden
|
||||||
public String addPasswordForm(Model model) {
|
public String addPasswordForm(Model model) {
|
||||||
|
|||||||
@@ -112,6 +112,23 @@ public class ApplicationProperties {
|
|||||||
return saml2.getEnabled() || oauth2.getEnabled();
|
return saml2.getEnabled() || oauth2.getEnabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isUserPass() {
|
||||||
|
return (loginMethod.equalsIgnoreCase(LoginMethods.NORMAL.toString())
|
||||||
|
|| loginMethod.equalsIgnoreCase(LoginMethods.ALL.toString()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isOauth2Activ() {
|
||||||
|
return (oauth2 != null
|
||||||
|
&& oauth2.getEnabled()
|
||||||
|
&& !loginMethod.equalsIgnoreCase(LoginMethods.NORMAL.toString()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isSaml2Activ() {
|
||||||
|
return (saml2 != null
|
||||||
|
&& saml2.getEnabled()
|
||||||
|
&& !loginMethod.equalsIgnoreCase(LoginMethods.NORMAL.toString()));
|
||||||
|
}
|
||||||
|
|
||||||
public enum LoginMethods {
|
public enum LoginMethods {
|
||||||
ALL("all"),
|
ALL("all"),
|
||||||
NORMAL("normal"),
|
NORMAL("normal"),
|
||||||
@@ -130,23 +147,6 @@ public class ApplicationProperties {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isUserPass() {
|
|
||||||
return (loginMethod.equalsIgnoreCase(LoginMethods.NORMAL.toString())
|
|
||||||
|| loginMethod.equalsIgnoreCase(LoginMethods.ALL.toString()));
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isOauth2Activ() {
|
|
||||||
return (oauth2 != null
|
|
||||||
&& oauth2.getEnabled()
|
|
||||||
&& !loginMethod.equalsIgnoreCase(LoginMethods.NORMAL.toString()));
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isSaml2Activ() {
|
|
||||||
return (saml2 != null
|
|
||||||
&& saml2.getEnabled()
|
|
||||||
&& !loginMethod.equalsIgnoreCase(LoginMethods.NORMAL.toString()));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
public static class InitialLogin {
|
public static class InitialLogin {
|
||||||
private String username;
|
private String username;
|
||||||
@@ -282,42 +282,6 @@ public class ApplicationProperties {
|
|||||||
private String tessdataDir;
|
private String tessdataDir;
|
||||||
private Boolean enableAlphaFunctionality;
|
private Boolean enableAlphaFunctionality;
|
||||||
private String enableAnalytics;
|
private String enableAnalytics;
|
||||||
private Datasource datasource;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Data
|
|
||||||
public static class Datasource {
|
|
||||||
private boolean enableCustomDatabase;
|
|
||||||
private String customDatabaseUrl;
|
|
||||||
private String type;
|
|
||||||
private String hostName;
|
|
||||||
private Integer port;
|
|
||||||
private String name;
|
|
||||||
private String username;
|
|
||||||
@ToString.Exclude private String password;
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum Driver {
|
|
||||||
H2("h2"),
|
|
||||||
POSTGRESQL("postgresql"),
|
|
||||||
ORACLE("oracle"),
|
|
||||||
MYSQL("mysql");
|
|
||||||
|
|
||||||
private final String driverName;
|
|
||||||
|
|
||||||
Driver(String driverName) {
|
|
||||||
this.driverName = driverName;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return """
|
|
||||||
Driver {
|
|
||||||
driverName='%s'
|
|
||||||
}
|
|
||||||
"""
|
|
||||||
.formatted(driverName);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
@@ -366,7 +330,6 @@ public class ApplicationProperties {
|
|||||||
private boolean enabled;
|
private boolean enabled;
|
||||||
@ToString.Exclude private String key;
|
@ToString.Exclude private String key;
|
||||||
private int maxUsers;
|
private int maxUsers;
|
||||||
private boolean ssoAutoLogin;
|
|
||||||
private CustomMetadata customMetadata = new CustomMetadata();
|
private CustomMetadata customMetadata = new CustomMetadata();
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import java.util.Date;
|
|||||||
|
|
||||||
import jakarta.persistence.Entity;
|
import jakarta.persistence.Entity;
|
||||||
import jakarta.persistence.Id;
|
import jakarta.persistence.Id;
|
||||||
|
import jakarta.persistence.Lob;
|
||||||
import jakarta.persistence.Table;
|
import jakarta.persistence.Table;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
@@ -14,7 +15,7 @@ import lombok.Data;
|
|||||||
public class SessionEntity implements Serializable {
|
public class SessionEntity implements Serializable {
|
||||||
@Id private String sessionId;
|
@Id private String sessionId;
|
||||||
|
|
||||||
private String principalName;
|
@Lob private String principalName;
|
||||||
|
|
||||||
private Date lastRequest;
|
private Date lastRequest;
|
||||||
|
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ public class User implements Serializable {
|
|||||||
@ElementCollection
|
@ElementCollection
|
||||||
@MapKeyColumn(name = "setting_key")
|
@MapKeyColumn(name = "setting_key")
|
||||||
@Lob
|
@Lob
|
||||||
@Column(name = "setting_value", columnDefinition = "text")
|
@Column(name = "setting_value", columnDefinition = "CLOB")
|
||||||
@CollectionTable(name = "user_settings", joinColumns = @JoinColumn(name = "user_id"))
|
@CollectionTable(name = "user_settings", joinColumns = @JoinColumn(name = "user_id"))
|
||||||
private Map<String, String> settings = new HashMap<>(); // Key-value pairs of settings.
|
private Map<String, String> settings = new HashMap<>(); // Key-value pairs of settings.
|
||||||
|
|
||||||
|
|||||||
@@ -1,22 +0,0 @@
|
|||||||
package stirling.software.SPDF.model.api.security;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
|
||||||
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.EqualsAndHashCode;
|
|
||||||
import stirling.software.SPDF.model.api.PDFWithPageNums;
|
|
||||||
|
|
||||||
@Data
|
|
||||||
@EqualsAndHashCode(callSuper = true)
|
|
||||||
public class ManualRedactPdfRequest extends PDFWithPageNums {
|
|
||||||
@Schema(description = "A list of areas that should be redacted")
|
|
||||||
private List<RedactionArea> redactions;
|
|
||||||
|
|
||||||
@Schema(description = "Convert the redacted PDF to an image", defaultValue = "false")
|
|
||||||
private boolean convertPDFToImage;
|
|
||||||
|
|
||||||
@Schema(description = "The color used to fully redact certain pages")
|
|
||||||
private String pageRedactionColor;
|
|
||||||
}
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
package stirling.software.SPDF.model.api.security;
|
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
|
||||||
|
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
@Data
|
|
||||||
public class RedactionArea {
|
|
||||||
@Schema(description = "The left edge point of the area to be redacted.")
|
|
||||||
private Double x;
|
|
||||||
|
|
||||||
@Schema(description = "The top edge point of the area to be redacted.")
|
|
||||||
private Double y;
|
|
||||||
|
|
||||||
@Schema(description = "The height of the area to be redacted.")
|
|
||||||
private Double height;
|
|
||||||
|
|
||||||
@Schema(description = "The width of the area to be redacted.")
|
|
||||||
private Double width;
|
|
||||||
|
|
||||||
@Schema(description = "The page on which the area should be redacted.")
|
|
||||||
private Integer page;
|
|
||||||
|
|
||||||
@Schema(description = "The color used to redact the specified area.")
|
|
||||||
private String color;
|
|
||||||
}
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
package stirling.software.SPDF.model.exception;
|
|
||||||
|
|
||||||
public class BackupNotFoundException extends RuntimeException {
|
|
||||||
public BackupNotFoundException(String message) {
|
|
||||||
super(message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
package stirling.software.SPDF.utils.propertyeditor;
|
|
||||||
|
|
||||||
import java.beans.PropertyEditorSupport;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.core.type.TypeReference;
|
|
||||||
import com.fasterxml.jackson.databind.DeserializationFeature;
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import stirling.software.SPDF.model.api.security.RedactionArea;
|
|
||||||
|
|
||||||
@Slf4j
|
|
||||||
public class StringToArrayListPropertyEditor extends PropertyEditorSupport {
|
|
||||||
|
|
||||||
private final ObjectMapper objectMapper = new ObjectMapper();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setAsText(String text) throws IllegalArgumentException {
|
|
||||||
if (text == null || text.trim().isEmpty()) {
|
|
||||||
setValue(new ArrayList<>());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
objectMapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);
|
|
||||||
TypeReference<ArrayList<RedactionArea>> typeRef =
|
|
||||||
new TypeReference<ArrayList<RedactionArea>>() {};
|
|
||||||
List<RedactionArea> list = objectMapper.readValue(text, typeRef);
|
|
||||||
setValue(list);
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("Exception while converting {}", e);
|
|
||||||
throw new IllegalArgumentException(
|
|
||||||
"Failed to convert java.lang.String to java.util.List");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -28,7 +28,7 @@ spring.thymeleaf.encoding=UTF-8
|
|||||||
spring.web.resources.mime-mappings.webmanifest=application/manifest+json
|
spring.web.resources.mime-mappings.webmanifest=application/manifest+json
|
||||||
spring.mvc.async.request-timeout=${SYSTEM_CONNECTIONTIMEOUTMILLISECONDS:1200000}
|
spring.mvc.async.request-timeout=${SYSTEM_CONNECTIONTIMEOUTMILLISECONDS:1200000}
|
||||||
|
|
||||||
spring.datasource.url=jdbc:h2:file:./configs/stirling-pdf-DB-2.3.232;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE;MODE=PostgreSQL
|
spring.datasource.url=jdbc:h2:file:./configs/stirling-pdf-DB-2.3.232;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE
|
||||||
spring.datasource.driver-class-name=org.h2.Driver
|
spring.datasource.driver-class-name=org.h2.Driver
|
||||||
spring.datasource.username=sa
|
spring.datasource.username=sa
|
||||||
spring.datasource.password=
|
spring.datasource.password=
|
||||||
|
|||||||
@@ -82,7 +82,6 @@ pages=صفحات
|
|||||||
loading=جارٍ التحميل...
|
loading=جارٍ التحميل...
|
||||||
addToDoc=إضافة إلى المستند
|
addToDoc=إضافة إلى المستند
|
||||||
reset=إعداة ضبط
|
reset=إعداة ضبط
|
||||||
apply=Apply
|
|
||||||
|
|
||||||
legal.privacy=سياسة الخصوصية
|
legal.privacy=سياسة الخصوصية
|
||||||
legal.terms=شروط الاستخدام
|
legal.terms=شروط الاستخدام
|
||||||
@@ -249,7 +248,6 @@ database.backupCreated=Database backup successful
|
|||||||
database.fileNotFound=لم يتم العثور على الملف
|
database.fileNotFound=لم يتم العثور على الملف
|
||||||
database.fileNullOrEmpty=يجب ألا يكون الملف فارغًا أو خاليًا
|
database.fileNullOrEmpty=يجب ألا يكون الملف فارغًا أو خاليًا
|
||||||
database.failedImportFile=فشل استيراد الملف
|
database.failedImportFile=فشل استيراد الملف
|
||||||
database.notSupported=This function is not available for your database connection.
|
|
||||||
|
|
||||||
session.expired=لقد انتهت جلستك. يرجى تحديث الصفحة والمحاولة مرة أخرى
|
session.expired=لقد انتهت جلستك. يرجى تحديث الصفحة والمحاولة مرة أخرى
|
||||||
session.refreshPage=تحديث الصفحة
|
session.refreshPage=تحديث الصفحة
|
||||||
@@ -476,10 +474,6 @@ home.autoRedact.title=حجب تلقائي
|
|||||||
home.autoRedact.desc=يحجب (يسود) النص في PDF تلقائيًا بناءً على النص المدخل
|
home.autoRedact.desc=يحجب (يسود) النص في PDF تلقائيًا بناءً على النص المدخل
|
||||||
autoRedact.tags=حجب,إخفاء,تسويد,أسود,علامة,مخفي
|
autoRedact.tags=حجب,إخفاء,تسويد,أسود,علامة,مخفي
|
||||||
|
|
||||||
home.redact.title=Manual Redaction
|
|
||||||
home.redact.desc=Redacts a PDF based on selected text, drawn shapes and/or selected page(s)
|
|
||||||
redact.tags=Redact,Hide,black out,black,marker,hidden,manual
|
|
||||||
|
|
||||||
home.tableExtraxt.title=PDF إلى CSV
|
home.tableExtraxt.title=PDF إلى CSV
|
||||||
home.tableExtraxt.desc=يستخرج الجداول من PDF ويحولها إلى CSV
|
home.tableExtraxt.desc=يستخرج الجداول من PDF ويحولها إلى CSV
|
||||||
tableExtraxt.tags=CSV,استخراج الجدول,استخراج,تحويل
|
tableExtraxt.tags=CSV,استخراج الجدول,استخراج,تحويل
|
||||||
@@ -585,31 +579,6 @@ autoRedact.customPaddingLabel=حشو إضافي مخصص
|
|||||||
autoRedact.convertPDFToImageLabel=تحويل PDF إلى صورة PDF (يستخدم لإزالة النص خلف المربع)
|
autoRedact.convertPDFToImageLabel=تحويل PDF إلى صورة PDF (يستخدم لإزالة النص خلف المربع)
|
||||||
autoRedact.submitButton=إرسال
|
autoRedact.submitButton=إرسال
|
||||||
|
|
||||||
#redact
|
|
||||||
redact.title=Manual Redaction
|
|
||||||
redact.header=Manual Redaction
|
|
||||||
redact.submit=Redact
|
|
||||||
redact.textBasedRedaction=Text based Redaction
|
|
||||||
redact.pageBasedRedaction=Page-based Redaction
|
|
||||||
redact.convertPDFToImageLabel=Convert PDF to PDF-Image (Used to remove text behind the box)
|
|
||||||
redact.pageRedactionNumbers.title=Pages
|
|
||||||
redact.pageRedactionNumbers.placeholder=(e.g. 1,2,8 or 4,7,12-16 or 2n-1)
|
|
||||||
redact.redactionColor.title=Redaction Color
|
|
||||||
redact.export=Export
|
|
||||||
redact.upload=Upload
|
|
||||||
redact.boxRedaction=Box draw redaction
|
|
||||||
redact.zoom=Zoom
|
|
||||||
redact.zoomIn=Zoom in
|
|
||||||
redact.zoomOut=Zoom out
|
|
||||||
redact.nextPage=Next Page
|
|
||||||
redact.previousPage=Previous Page
|
|
||||||
redact.toggleSidebar=Toggle Sidebar
|
|
||||||
redact.showThumbnails=Show Thumbnails
|
|
||||||
redact.showDocumentOutline=Show Document Outline (double-click to expand/collapse all items)
|
|
||||||
redact.showAttatchments=Show Attachments
|
|
||||||
redact.showLayers=Show Layers (double-click to reset all layers to the default state)
|
|
||||||
redact.colourPicker=Colour Picker
|
|
||||||
redact.findCurrentOutlineItem=Find current outline item
|
|
||||||
|
|
||||||
#showJS
|
#showJS
|
||||||
showJS.title=إظهار جافا سكريبت
|
showJS.title=إظهار جافا سكريبت
|
||||||
@@ -863,8 +832,6 @@ sign.last=Last page
|
|||||||
sign.next=Next page
|
sign.next=Next page
|
||||||
sign.previous=Previous page
|
sign.previous=Previous page
|
||||||
sign.maintainRatio=Toggle maintain aspect ratio
|
sign.maintainRatio=Toggle maintain aspect ratio
|
||||||
|
|
||||||
|
|
||||||
#repair
|
#repair
|
||||||
repair.title=إصلاح
|
repair.title=إصلاح
|
||||||
repair.header=إصلاح ملفات PDF
|
repair.header=إصلاح ملفات PDF
|
||||||
|
|||||||
@@ -82,7 +82,6 @@ pages=Səhifələr
|
|||||||
loading=Yüklənir...
|
loading=Yüklənir...
|
||||||
addToDoc=Sənədə Əlavə Et
|
addToDoc=Sənədə Əlavə Et
|
||||||
reset=Sıfırla
|
reset=Sıfırla
|
||||||
apply=Apply
|
|
||||||
|
|
||||||
legal.privacy=Məxfilik Siyasəti
|
legal.privacy=Məxfilik Siyasəti
|
||||||
legal.terms=Qaydalar və Şərtlər
|
legal.terms=Qaydalar və Şərtlər
|
||||||
@@ -249,7 +248,6 @@ database.backupCreated=Database backup successful
|
|||||||
database.fileNotFound=Fayl Tapılmadı
|
database.fileNotFound=Fayl Tapılmadı
|
||||||
database.fileNullOrEmpty=Fayl boş və ya "null" olmamalıdır
|
database.fileNullOrEmpty=Fayl boş və ya "null" olmamalıdır
|
||||||
database.failedImportFile=Faylı daxil etmək alınmadı
|
database.failedImportFile=Faylı daxil etmək alınmadı
|
||||||
database.notSupported=This function is not available for your database connection.
|
|
||||||
|
|
||||||
session.expired=Sessiyanızın vaxtı bitdi. Səhifəni yeniləyin və yenidən cəhd edin.
|
session.expired=Sessiyanızın vaxtı bitdi. Səhifəni yeniləyin və yenidən cəhd edin.
|
||||||
session.refreshPage=Səhifəni Yenilə
|
session.refreshPage=Səhifəni Yenilə
|
||||||
@@ -476,10 +474,6 @@ home.autoRedact.title=Avtomatik Gizlətmə
|
|||||||
home.autoRedact.desc=Daxil edilmiş data əsasında PDF-dəki müəyyən mətn hissəsini qara qutu ilə gizlədir
|
home.autoRedact.desc=Daxil edilmiş data əsasında PDF-dəki müəyyən mətn hissəsini qara qutu ilə gizlədir
|
||||||
autoRedact.tags=Qarala,gizlət,sil,qara,marker,gizli
|
autoRedact.tags=Qarala,gizlət,sil,qara,marker,gizli
|
||||||
|
|
||||||
home.redact.title=Manual Redaction
|
|
||||||
home.redact.desc=Redacts a PDF based on selected text, drawn shapes and/or selected page(s)
|
|
||||||
redact.tags=Redact,Hide,black out,black,marker,hidden,manual
|
|
||||||
|
|
||||||
home.tableExtraxt.title=PDF-dən CSV-ə
|
home.tableExtraxt.title=PDF-dən CSV-ə
|
||||||
home.tableExtraxt.desc=PDF-dən cədvəlləri CSV-ə çevirərək xaric edir
|
home.tableExtraxt.desc=PDF-dən cədvəlləri CSV-ə çevirərək xaric edir
|
||||||
tableExtraxt.tags=CSV,Cədvəl xaricetmə,xaric et,çevir
|
tableExtraxt.tags=CSV,Cədvəl xaricetmə,xaric et,çevir
|
||||||
@@ -585,31 +579,6 @@ autoRedact.customPaddingLabel=Fərdi Əlavə Başlıq
|
|||||||
autoRedact.convertPDFToImageLabel=PDF-i PDF-Şəkil-ə çevir (Qutunun arxasındakı yazını silmək üçün istifadə edilir)
|
autoRedact.convertPDFToImageLabel=PDF-i PDF-Şəkil-ə çevir (Qutunun arxasındakı yazını silmək üçün istifadə edilir)
|
||||||
autoRedact.submitButton=Təsdiqlə
|
autoRedact.submitButton=Təsdiqlə
|
||||||
|
|
||||||
#redact
|
|
||||||
redact.title=Manual Redaction
|
|
||||||
redact.header=Manual Redaction
|
|
||||||
redact.submit=Redact
|
|
||||||
redact.textBasedRedaction=Text based Redaction
|
|
||||||
redact.pageBasedRedaction=Page-based Redaction
|
|
||||||
redact.convertPDFToImageLabel=Convert PDF to PDF-Image (Used to remove text behind the box)
|
|
||||||
redact.pageRedactionNumbers.title=Pages
|
|
||||||
redact.pageRedactionNumbers.placeholder=(e.g. 1,2,8 or 4,7,12-16 or 2n-1)
|
|
||||||
redact.redactionColor.title=Redaction Color
|
|
||||||
redact.export=Export
|
|
||||||
redact.upload=Upload
|
|
||||||
redact.boxRedaction=Box draw redaction
|
|
||||||
redact.zoom=Zoom
|
|
||||||
redact.zoomIn=Zoom in
|
|
||||||
redact.zoomOut=Zoom out
|
|
||||||
redact.nextPage=Next Page
|
|
||||||
redact.previousPage=Previous Page
|
|
||||||
redact.toggleSidebar=Toggle Sidebar
|
|
||||||
redact.showThumbnails=Show Thumbnails
|
|
||||||
redact.showDocumentOutline=Show Document Outline (double-click to expand/collapse all items)
|
|
||||||
redact.showAttatchments=Show Attachments
|
|
||||||
redact.showLayers=Show Layers (double-click to reset all layers to the default state)
|
|
||||||
redact.colourPicker=Colour Picker
|
|
||||||
redact.findCurrentOutlineItem=Find current outline item
|
|
||||||
|
|
||||||
#showJS
|
#showJS
|
||||||
showJS.title=Javascripti Göstər
|
showJS.title=Javascripti Göstər
|
||||||
@@ -863,8 +832,6 @@ sign.last=Son səhifə
|
|||||||
sign.next=Növbəti səhifə
|
sign.next=Növbəti səhifə
|
||||||
sign.previous=Əvvəlki səhifə
|
sign.previous=Əvvəlki səhifə
|
||||||
sign.maintainRatio=Toggle maintain aspect ratio
|
sign.maintainRatio=Toggle maintain aspect ratio
|
||||||
|
|
||||||
|
|
||||||
#repair
|
#repair
|
||||||
repair.title=Bərpa Et
|
repair.title=Bərpa Et
|
||||||
repair.header=PDFləri Bərpa Et
|
repair.header=PDFləri Bərpa Et
|
||||||
|
|||||||
@@ -82,7 +82,6 @@ pages=Страници
|
|||||||
loading=Loading...
|
loading=Loading...
|
||||||
addToDoc=Add to Document
|
addToDoc=Add to Document
|
||||||
reset=Reset
|
reset=Reset
|
||||||
apply=Apply
|
|
||||||
|
|
||||||
legal.privacy=Политика за поверителност
|
legal.privacy=Политика за поверителност
|
||||||
legal.terms=Правила и условия
|
legal.terms=Правила и условия
|
||||||
@@ -249,7 +248,6 @@ database.backupCreated=Database backup successful
|
|||||||
database.fileNotFound=Файлът не е намерен
|
database.fileNotFound=Файлът не е намерен
|
||||||
database.fileNullOrEmpty=Файлът не трябва да е нулев или празен
|
database.fileNullOrEmpty=Файлът не трябва да е нулев или празен
|
||||||
database.failedImportFile=Неуспешно импортиране на файл
|
database.failedImportFile=Неуспешно импортиране на файл
|
||||||
database.notSupported=This function is not available for your database connection.
|
|
||||||
|
|
||||||
session.expired=Вашата сесия е изтекла. Моля, опреснете страницата и опитайте отново.
|
session.expired=Вашата сесия е изтекла. Моля, опреснете страницата и опитайте отново.
|
||||||
session.refreshPage=Refresh Page
|
session.refreshPage=Refresh Page
|
||||||
@@ -476,10 +474,6 @@ home.autoRedact.title=Автоматично редактиране
|
|||||||
home.autoRedact.desc=Автоматично редактира (зачернява) текст в PDF въз основа на въведен текст
|
home.autoRedact.desc=Автоматично редактира (зачернява) текст в PDF въз основа на въведен текст
|
||||||
autoRedact.tags=Редактиране,Скриване,затъмняване,черен,маркер,скрит
|
autoRedact.tags=Редактиране,Скриване,затъмняване,черен,маркер,скрит
|
||||||
|
|
||||||
home.redact.title=Manual Redaction
|
|
||||||
home.redact.desc=Redacts a PDF based on selected text, drawn shapes and/or selected page(s)
|
|
||||||
redact.tags=Redact,Hide,black out,black,marker,hidden,manual
|
|
||||||
|
|
||||||
home.tableExtraxt.title=PDF в CSV
|
home.tableExtraxt.title=PDF в CSV
|
||||||
home.tableExtraxt.desc=Извлича таблици от PDF, като ги конвертира в CSV
|
home.tableExtraxt.desc=Извлича таблици от PDF, като ги конвертира в CSV
|
||||||
tableExtraxt.tags=CSV,извличане на таблица,извличане,конвертиране
|
tableExtraxt.tags=CSV,извличане на таблица,извличане,конвертиране
|
||||||
@@ -585,31 +579,6 @@ autoRedact.customPaddingLabel=Персонализирана допълните
|
|||||||
autoRedact.convertPDFToImageLabel=Преобразуване на PDF към PDF-изображение (използва се за премахване на текст зад полето)
|
autoRedact.convertPDFToImageLabel=Преобразуване на PDF към PDF-изображение (използва се за премахване на текст зад полето)
|
||||||
autoRedact.submitButton=Изпращане
|
autoRedact.submitButton=Изпращане
|
||||||
|
|
||||||
#redact
|
|
||||||
redact.title=Manual Redaction
|
|
||||||
redact.header=Manual Redaction
|
|
||||||
redact.submit=Redact
|
|
||||||
redact.textBasedRedaction=Text based Redaction
|
|
||||||
redact.pageBasedRedaction=Page-based Redaction
|
|
||||||
redact.convertPDFToImageLabel=Convert PDF to PDF-Image (Used to remove text behind the box)
|
|
||||||
redact.pageRedactionNumbers.title=Pages
|
|
||||||
redact.pageRedactionNumbers.placeholder=(e.g. 1,2,8 or 4,7,12-16 or 2n-1)
|
|
||||||
redact.redactionColor.title=Redaction Color
|
|
||||||
redact.export=Export
|
|
||||||
redact.upload=Upload
|
|
||||||
redact.boxRedaction=Box draw redaction
|
|
||||||
redact.zoom=Zoom
|
|
||||||
redact.zoomIn=Zoom in
|
|
||||||
redact.zoomOut=Zoom out
|
|
||||||
redact.nextPage=Next Page
|
|
||||||
redact.previousPage=Previous Page
|
|
||||||
redact.toggleSidebar=Toggle Sidebar
|
|
||||||
redact.showThumbnails=Show Thumbnails
|
|
||||||
redact.showDocumentOutline=Show Document Outline (double-click to expand/collapse all items)
|
|
||||||
redact.showAttatchments=Show Attachments
|
|
||||||
redact.showLayers=Show Layers (double-click to reset all layers to the default state)
|
|
||||||
redact.colourPicker=Colour Picker
|
|
||||||
redact.findCurrentOutlineItem=Find current outline item
|
|
||||||
|
|
||||||
#showJS
|
#showJS
|
||||||
showJS.title=Покажи Javascript
|
showJS.title=Покажи Javascript
|
||||||
@@ -863,8 +832,6 @@ sign.last=Last page
|
|||||||
sign.next=Next page
|
sign.next=Next page
|
||||||
sign.previous=Previous page
|
sign.previous=Previous page
|
||||||
sign.maintainRatio=Toggle maintain aspect ratio
|
sign.maintainRatio=Toggle maintain aspect ratio
|
||||||
|
|
||||||
|
|
||||||
#repair
|
#repair
|
||||||
repair.title=Поправи
|
repair.title=Поправи
|
||||||
repair.header=Поправи PDF-и
|
repair.header=Поправи PDF-и
|
||||||
|
|||||||
@@ -82,7 +82,6 @@ pages=Pàgines
|
|||||||
loading=Carregant...
|
loading=Carregant...
|
||||||
addToDoc=Afegeix al document
|
addToDoc=Afegeix al document
|
||||||
reset=Reset
|
reset=Reset
|
||||||
apply=Apply
|
|
||||||
|
|
||||||
legal.privacy=Política de Privacitat
|
legal.privacy=Política de Privacitat
|
||||||
legal.terms=Termes i condicions
|
legal.terms=Termes i condicions
|
||||||
@@ -249,7 +248,6 @@ database.backupCreated=Database backup successful
|
|||||||
database.fileNotFound=Fitxer no trobat
|
database.fileNotFound=Fitxer no trobat
|
||||||
database.fileNullOrEmpty=El fitxer no ha de ser nul o buit
|
database.fileNullOrEmpty=El fitxer no ha de ser nul o buit
|
||||||
database.failedImportFile=Error en la importació del fitxer
|
database.failedImportFile=Error en la importació del fitxer
|
||||||
database.notSupported=This function is not available for your database connection.
|
|
||||||
|
|
||||||
session.expired=La teva sessió ha expirat. Si us plau, actualitza la pàgina i torna a intentar-ho.
|
session.expired=La teva sessió ha expirat. Si us plau, actualitza la pàgina i torna a intentar-ho.
|
||||||
session.refreshPage=Actualitza la pàgina
|
session.refreshPage=Actualitza la pàgina
|
||||||
@@ -476,10 +474,6 @@ home.autoRedact.title=Redacció Automàtica
|
|||||||
home.autoRedact.desc=Redacta automàticament (enfosqueix) text en un PDF basat en el text introduït
|
home.autoRedact.desc=Redacta automàticament (enfosqueix) text en un PDF basat en el text introduït
|
||||||
autoRedact.tags=Redact,Hide,black out,black,marker,hidden
|
autoRedact.tags=Redact,Hide,black out,black,marker,hidden
|
||||||
|
|
||||||
home.redact.title=Manual Redaction
|
|
||||||
home.redact.desc=Redacts a PDF based on selected text, drawn shapes and/or selected page(s)
|
|
||||||
redact.tags=Redact,Hide,black out,black,marker,hidden,manual
|
|
||||||
|
|
||||||
home.tableExtraxt.title=PDF a CSV
|
home.tableExtraxt.title=PDF a CSV
|
||||||
home.tableExtraxt.desc=Extreu taules d'un PDF convertint-les a CSV
|
home.tableExtraxt.desc=Extreu taules d'un PDF convertint-les a CSV
|
||||||
tableExtraxt.tags=CSV,Table Extraction,extract,convert
|
tableExtraxt.tags=CSV,Table Extraction,extract,convert
|
||||||
@@ -585,31 +579,6 @@ autoRedact.customPaddingLabel=Espai Extra Personalitzat
|
|||||||
autoRedact.convertPDFToImageLabel=Converteix PDF a Imatge PDF (S'utilitza per eliminar text darrere del quadre)
|
autoRedact.convertPDFToImageLabel=Converteix PDF a Imatge PDF (S'utilitza per eliminar text darrere del quadre)
|
||||||
autoRedact.submitButton=Envia
|
autoRedact.submitButton=Envia
|
||||||
|
|
||||||
#redact
|
|
||||||
redact.title=Manual Redaction
|
|
||||||
redact.header=Manual Redaction
|
|
||||||
redact.submit=Redact
|
|
||||||
redact.textBasedRedaction=Text based Redaction
|
|
||||||
redact.pageBasedRedaction=Page-based Redaction
|
|
||||||
redact.convertPDFToImageLabel=Convert PDF to PDF-Image (Used to remove text behind the box)
|
|
||||||
redact.pageRedactionNumbers.title=Pages
|
|
||||||
redact.pageRedactionNumbers.placeholder=(e.g. 1,2,8 or 4,7,12-16 or 2n-1)
|
|
||||||
redact.redactionColor.title=Redaction Color
|
|
||||||
redact.export=Export
|
|
||||||
redact.upload=Upload
|
|
||||||
redact.boxRedaction=Box draw redaction
|
|
||||||
redact.zoom=Zoom
|
|
||||||
redact.zoomIn=Zoom in
|
|
||||||
redact.zoomOut=Zoom out
|
|
||||||
redact.nextPage=Next Page
|
|
||||||
redact.previousPage=Previous Page
|
|
||||||
redact.toggleSidebar=Toggle Sidebar
|
|
||||||
redact.showThumbnails=Show Thumbnails
|
|
||||||
redact.showDocumentOutline=Show Document Outline (double-click to expand/collapse all items)
|
|
||||||
redact.showAttatchments=Show Attachments
|
|
||||||
redact.showLayers=Show Layers (double-click to reset all layers to the default state)
|
|
||||||
redact.colourPicker=Colour Picker
|
|
||||||
redact.findCurrentOutlineItem=Find current outline item
|
|
||||||
|
|
||||||
#showJS
|
#showJS
|
||||||
showJS.title=Mostra Javascript
|
showJS.title=Mostra Javascript
|
||||||
@@ -863,8 +832,6 @@ sign.last=Last page
|
|||||||
sign.next=Next page
|
sign.next=Next page
|
||||||
sign.previous=Previous page
|
sign.previous=Previous page
|
||||||
sign.maintainRatio=Toggle maintain aspect ratio
|
sign.maintainRatio=Toggle maintain aspect ratio
|
||||||
|
|
||||||
|
|
||||||
#repair
|
#repair
|
||||||
repair.title=Reparar
|
repair.title=Reparar
|
||||||
repair.header=Repara els PDF
|
repair.header=Repara els PDF
|
||||||
|
|||||||
@@ -82,7 +82,6 @@ pages=Strany
|
|||||||
loading=Načítání...
|
loading=Načítání...
|
||||||
addToDoc=Přidat do dokumentu
|
addToDoc=Přidat do dokumentu
|
||||||
reset=Reset
|
reset=Reset
|
||||||
apply=Apply
|
|
||||||
|
|
||||||
legal.privacy=Politika soukromí
|
legal.privacy=Politika soukromí
|
||||||
legal.terms=Podmínky použití
|
legal.terms=Podmínky použití
|
||||||
@@ -249,7 +248,6 @@ database.backupCreated=Database backup successful
|
|||||||
database.fileNotFound=File not Found
|
database.fileNotFound=File not Found
|
||||||
database.fileNullOrEmpty=Soubor nemůže být null nebo prázdný
|
database.fileNullOrEmpty=Soubor nemůže být null nebo prázdný
|
||||||
database.failedImportFile=Failed Import File
|
database.failedImportFile=Failed Import File
|
||||||
database.notSupported=This function is not available for your database connection.
|
|
||||||
|
|
||||||
session.expired=Vaše sesace vypršela. Prosím obnovte stránku a zkusit to znovu.
|
session.expired=Vaše sesace vypršela. Prosím obnovte stránku a zkusit to znovu.
|
||||||
session.refreshPage=Refresh Page
|
session.refreshPage=Refresh Page
|
||||||
@@ -476,10 +474,6 @@ home.autoRedact.title=Automatické odstranění
|
|||||||
home.autoRedact.desc=Automaticky zakrývá text v PDF na základě vstupního textu
|
home.autoRedact.desc=Automaticky zakrývá text v PDF na základě vstupního textu
|
||||||
autoRedact.tags=Odstranit,Skrytý,černý,zakrýt,značka,skrytý
|
autoRedact.tags=Odstranit,Skrytý,černý,zakrýt,značka,skrytý
|
||||||
|
|
||||||
home.redact.title=Manual Redaction
|
|
||||||
home.redact.desc=Redacts a PDF based on selected text, drawn shapes and/or selected page(s)
|
|
||||||
redact.tags=Redact,Hide,black out,black,marker,hidden,manual
|
|
||||||
|
|
||||||
home.tableExtraxt.title=PDF na CSV
|
home.tableExtraxt.title=PDF na CSV
|
||||||
home.tableExtraxt.desc=Extrahuje tabulky z PDF a konvertuje je do formátu CSV
|
home.tableExtraxt.desc=Extrahuje tabulky z PDF a konvertuje je do formátu CSV
|
||||||
tableExtraxt.tags=CSV,Extrakce tabulky,extrahovat,konvertovat
|
tableExtraxt.tags=CSV,Extrakce tabulky,extrahovat,konvertovat
|
||||||
@@ -585,31 +579,6 @@ autoRedact.customPaddingLabel=Vlastní doplňující vzdálenost
|
|||||||
autoRedact.convertPDFToImageLabel=Převést PDF do PDF-Obrázku (Pro odstranění textu za obdélníkem)
|
autoRedact.convertPDFToImageLabel=Převést PDF do PDF-Obrázku (Pro odstranění textu za obdélníkem)
|
||||||
autoRedact.submitButton=Odeslat
|
autoRedact.submitButton=Odeslat
|
||||||
|
|
||||||
#redact
|
|
||||||
redact.title=Manual Redaction
|
|
||||||
redact.header=Manual Redaction
|
|
||||||
redact.submit=Redact
|
|
||||||
redact.textBasedRedaction=Text based Redaction
|
|
||||||
redact.pageBasedRedaction=Page-based Redaction
|
|
||||||
redact.convertPDFToImageLabel=Convert PDF to PDF-Image (Used to remove text behind the box)
|
|
||||||
redact.pageRedactionNumbers.title=Pages
|
|
||||||
redact.pageRedactionNumbers.placeholder=(e.g. 1,2,8 or 4,7,12-16 or 2n-1)
|
|
||||||
redact.redactionColor.title=Redaction Color
|
|
||||||
redact.export=Export
|
|
||||||
redact.upload=Upload
|
|
||||||
redact.boxRedaction=Box draw redaction
|
|
||||||
redact.zoom=Zoom
|
|
||||||
redact.zoomIn=Zoom in
|
|
||||||
redact.zoomOut=Zoom out
|
|
||||||
redact.nextPage=Next Page
|
|
||||||
redact.previousPage=Previous Page
|
|
||||||
redact.toggleSidebar=Toggle Sidebar
|
|
||||||
redact.showThumbnails=Show Thumbnails
|
|
||||||
redact.showDocumentOutline=Show Document Outline (double-click to expand/collapse all items)
|
|
||||||
redact.showAttatchments=Show Attachments
|
|
||||||
redact.showLayers=Show Layers (double-click to reset all layers to the default state)
|
|
||||||
redact.colourPicker=Colour Picker
|
|
||||||
redact.findCurrentOutlineItem=Find current outline item
|
|
||||||
|
|
||||||
#showJS
|
#showJS
|
||||||
showJS.title=Zobrazit JavaScript
|
showJS.title=Zobrazit JavaScript
|
||||||
@@ -863,8 +832,6 @@ sign.last=Last page
|
|||||||
sign.next=Next page
|
sign.next=Next page
|
||||||
sign.previous=Previous page
|
sign.previous=Previous page
|
||||||
sign.maintainRatio=Toggle maintain aspect ratio
|
sign.maintainRatio=Toggle maintain aspect ratio
|
||||||
|
|
||||||
|
|
||||||
#repair
|
#repair
|
||||||
repair.title=Opravit
|
repair.title=Opravit
|
||||||
repair.header=Opravit PDF
|
repair.header=Opravit PDF
|
||||||
|
|||||||
@@ -82,7 +82,6 @@ pages=Sideantal
|
|||||||
loading=Laster...
|
loading=Laster...
|
||||||
addToDoc=Tilføj til Dokument
|
addToDoc=Tilføj til Dokument
|
||||||
reset=Reset
|
reset=Reset
|
||||||
apply=Apply
|
|
||||||
|
|
||||||
legal.privacy=Privacy Policy
|
legal.privacy=Privacy Policy
|
||||||
legal.terms=Vilkår og betingelser
|
legal.terms=Vilkår og betingelser
|
||||||
@@ -249,7 +248,6 @@ database.backupCreated=Database backup successful
|
|||||||
database.fileNotFound=Fil ikke fundet
|
database.fileNotFound=Fil ikke fundet
|
||||||
database.fileNullOrEmpty=Fil må ikke være null eller tom
|
database.fileNullOrEmpty=Fil må ikke være null eller tom
|
||||||
database.failedImportFile=Kunne ikke importere fil
|
database.failedImportFile=Kunne ikke importere fil
|
||||||
database.notSupported=This function is not available for your database connection.
|
|
||||||
|
|
||||||
session.expired=Din sesions tid har udløbet. Genlad siden og prøv igen.
|
session.expired=Din sesions tid har udløbet. Genlad siden og prøv igen.
|
||||||
session.refreshPage=Refresh Page
|
session.refreshPage=Refresh Page
|
||||||
@@ -476,10 +474,6 @@ home.autoRedact.title=Auto Rediger
|
|||||||
home.autoRedact.desc=Auto Redigerer (Sværter) tekst i en PDF baseret på input tekst
|
home.autoRedact.desc=Auto Redigerer (Sværter) tekst i en PDF baseret på input tekst
|
||||||
autoRedact.tags=Rediger,Skjul,sværte,sort,markør,skjult
|
autoRedact.tags=Rediger,Skjul,sværte,sort,markør,skjult
|
||||||
|
|
||||||
home.redact.title=Manual Redaction
|
|
||||||
home.redact.desc=Redacts a PDF based on selected text, drawn shapes and/or selected page(s)
|
|
||||||
redact.tags=Redact,Hide,black out,black,marker,hidden,manual
|
|
||||||
|
|
||||||
home.tableExtraxt.title=PDF til CSV
|
home.tableExtraxt.title=PDF til CSV
|
||||||
home.tableExtraxt.desc=Udtrækker Tabeller fra en PDF og konverterer dem til CSV
|
home.tableExtraxt.desc=Udtrækker Tabeller fra en PDF og konverterer dem til CSV
|
||||||
tableExtraxt.tags=CSV,Tabeludtrækning,udtræk,konvertér
|
tableExtraxt.tags=CSV,Tabeludtrækning,udtræk,konvertér
|
||||||
@@ -585,31 +579,6 @@ autoRedact.customPaddingLabel=Brugerdefineret Ekstra Polstring
|
|||||||
autoRedact.convertPDFToImageLabel=Konvertér PDF til PDF-Billede (Bruges til at fjerne tekst bag boksen)
|
autoRedact.convertPDFToImageLabel=Konvertér PDF til PDF-Billede (Bruges til at fjerne tekst bag boksen)
|
||||||
autoRedact.submitButton=Indsend
|
autoRedact.submitButton=Indsend
|
||||||
|
|
||||||
#redact
|
|
||||||
redact.title=Manual Redaction
|
|
||||||
redact.header=Manual Redaction
|
|
||||||
redact.submit=Redact
|
|
||||||
redact.textBasedRedaction=Text based Redaction
|
|
||||||
redact.pageBasedRedaction=Page-based Redaction
|
|
||||||
redact.convertPDFToImageLabel=Convert PDF to PDF-Image (Used to remove text behind the box)
|
|
||||||
redact.pageRedactionNumbers.title=Pages
|
|
||||||
redact.pageRedactionNumbers.placeholder=(e.g. 1,2,8 or 4,7,12-16 or 2n-1)
|
|
||||||
redact.redactionColor.title=Redaction Color
|
|
||||||
redact.export=Export
|
|
||||||
redact.upload=Upload
|
|
||||||
redact.boxRedaction=Box draw redaction
|
|
||||||
redact.zoom=Zoom
|
|
||||||
redact.zoomIn=Zoom in
|
|
||||||
redact.zoomOut=Zoom out
|
|
||||||
redact.nextPage=Next Page
|
|
||||||
redact.previousPage=Previous Page
|
|
||||||
redact.toggleSidebar=Toggle Sidebar
|
|
||||||
redact.showThumbnails=Show Thumbnails
|
|
||||||
redact.showDocumentOutline=Show Document Outline (double-click to expand/collapse all items)
|
|
||||||
redact.showAttatchments=Show Attachments
|
|
||||||
redact.showLayers=Show Layers (double-click to reset all layers to the default state)
|
|
||||||
redact.colourPicker=Colour Picker
|
|
||||||
redact.findCurrentOutlineItem=Find current outline item
|
|
||||||
|
|
||||||
#showJS
|
#showJS
|
||||||
showJS.title=Vis Javascript
|
showJS.title=Vis Javascript
|
||||||
@@ -863,8 +832,6 @@ sign.last=Last page
|
|||||||
sign.next=Next page
|
sign.next=Next page
|
||||||
sign.previous=Previous page
|
sign.previous=Previous page
|
||||||
sign.maintainRatio=Toggle maintain aspect ratio
|
sign.maintainRatio=Toggle maintain aspect ratio
|
||||||
|
|
||||||
|
|
||||||
#repair
|
#repair
|
||||||
repair.title=Reparér
|
repair.title=Reparér
|
||||||
repair.header=Reparér PDF'er
|
repair.header=Reparér PDF'er
|
||||||
|
|||||||
@@ -82,7 +82,6 @@ pages=Seiten
|
|||||||
loading=Laden...
|
loading=Laden...
|
||||||
addToDoc=In Dokument hinzufügen
|
addToDoc=In Dokument hinzufügen
|
||||||
reset=Zurücksetzen
|
reset=Zurücksetzen
|
||||||
apply=Apply
|
|
||||||
|
|
||||||
legal.privacy=Datenschutz
|
legal.privacy=Datenschutz
|
||||||
legal.terms=AGB
|
legal.terms=AGB
|
||||||
@@ -249,7 +248,6 @@ database.backupCreated=Datenbanksicherung erfolgreich
|
|||||||
database.fileNotFound=Datei nicht gefunden
|
database.fileNotFound=Datei nicht gefunden
|
||||||
database.fileNullOrEmpty=Datei darf nicht null oder leer sein
|
database.fileNullOrEmpty=Datei darf nicht null oder leer sein
|
||||||
database.failedImportFile=Dateiimport fehlgeschlagen
|
database.failedImportFile=Dateiimport fehlgeschlagen
|
||||||
database.notSupported=This function is not available for your database connection.
|
|
||||||
|
|
||||||
session.expired=Ihre Sitzung ist abgelaufen. Bitte laden Sie die Seite neu und versuchen Sie es erneut.
|
session.expired=Ihre Sitzung ist abgelaufen. Bitte laden Sie die Seite neu und versuchen Sie es erneut.
|
||||||
session.refreshPage=Seite aktualisieren
|
session.refreshPage=Seite aktualisieren
|
||||||
@@ -476,10 +474,6 @@ home.autoRedact.title=Automatisch zensieren/schwärzen
|
|||||||
home.autoRedact.desc=Automatisches Zensieren (Schwärzen) von Text in einer PDF-Datei basierend auf dem eingegebenen Text
|
home.autoRedact.desc=Automatisches Zensieren (Schwärzen) von Text in einer PDF-Datei basierend auf dem eingegebenen Text
|
||||||
autoRedact.tags=zensieren,schwärzen
|
autoRedact.tags=zensieren,schwärzen
|
||||||
|
|
||||||
home.redact.title=Manual Redaction
|
|
||||||
home.redact.desc=Redacts a PDF based on selected text, drawn shapes and/or selected page(s)
|
|
||||||
redact.tags=Redact,Hide,black out,black,marker,hidden,manual
|
|
||||||
|
|
||||||
home.tableExtraxt.title=Tabelle extrahieren
|
home.tableExtraxt.title=Tabelle extrahieren
|
||||||
home.tableExtraxt.desc=Tabelle aus PDF in CSV extrahieren
|
home.tableExtraxt.desc=Tabelle aus PDF in CSV extrahieren
|
||||||
tableExtraxt.tags=CSV,tabelle,extrahieren
|
tableExtraxt.tags=CSV,tabelle,extrahieren
|
||||||
@@ -585,31 +579,6 @@ autoRedact.customPaddingLabel=Zensierten Bereich vergrößern
|
|||||||
autoRedact.convertPDFToImageLabel=PDF in PDF-Bild konvertieren (zum Entfernen von Text hinter dem Kasten)
|
autoRedact.convertPDFToImageLabel=PDF in PDF-Bild konvertieren (zum Entfernen von Text hinter dem Kasten)
|
||||||
autoRedact.submitButton=Zensieren
|
autoRedact.submitButton=Zensieren
|
||||||
|
|
||||||
#redact
|
|
||||||
redact.title=Manual Redaction
|
|
||||||
redact.header=Manual Redaction
|
|
||||||
redact.submit=Redact
|
|
||||||
redact.textBasedRedaction=Text based Redaction
|
|
||||||
redact.pageBasedRedaction=Page-based Redaction
|
|
||||||
redact.convertPDFToImageLabel=Convert PDF to PDF-Image (Used to remove text behind the box)
|
|
||||||
redact.pageRedactionNumbers.title=Pages
|
|
||||||
redact.pageRedactionNumbers.placeholder=(e.g. 1,2,8 or 4,7,12-16 or 2n-1)
|
|
||||||
redact.redactionColor.title=Redaction Color
|
|
||||||
redact.export=Export
|
|
||||||
redact.upload=Upload
|
|
||||||
redact.boxRedaction=Box draw redaction
|
|
||||||
redact.zoom=Zoom
|
|
||||||
redact.zoomIn=Zoom in
|
|
||||||
redact.zoomOut=Zoom out
|
|
||||||
redact.nextPage=Next Page
|
|
||||||
redact.previousPage=Previous Page
|
|
||||||
redact.toggleSidebar=Toggle Sidebar
|
|
||||||
redact.showThumbnails=Show Thumbnails
|
|
||||||
redact.showDocumentOutline=Show Document Outline (double-click to expand/collapse all items)
|
|
||||||
redact.showAttatchments=Show Attachments
|
|
||||||
redact.showLayers=Show Layers (double-click to reset all layers to the default state)
|
|
||||||
redact.colourPicker=Colour Picker
|
|
||||||
redact.findCurrentOutlineItem=Find current outline item
|
|
||||||
|
|
||||||
#showJS
|
#showJS
|
||||||
showJS.title=Javascript anzeigen
|
showJS.title=Javascript anzeigen
|
||||||
@@ -863,8 +832,6 @@ sign.last=Letzte Seite
|
|||||||
sign.next=Nächste Seite
|
sign.next=Nächste Seite
|
||||||
sign.previous=Vorherige Seite
|
sign.previous=Vorherige Seite
|
||||||
sign.maintainRatio=Toggle maintain aspect ratio
|
sign.maintainRatio=Toggle maintain aspect ratio
|
||||||
|
|
||||||
|
|
||||||
#repair
|
#repair
|
||||||
repair.title=Reparieren
|
repair.title=Reparieren
|
||||||
repair.header=PDFs reparieren
|
repair.header=PDFs reparieren
|
||||||
|
|||||||
@@ -82,7 +82,6 @@ pages=Σελίδες
|
|||||||
loading=Φόρτωση...
|
loading=Φόρτωση...
|
||||||
addToDoc=Πρόσθεση στο Εκπομπώματο
|
addToDoc=Πρόσθεση στο Εκπομπώματο
|
||||||
reset=Reset
|
reset=Reset
|
||||||
apply=Apply
|
|
||||||
|
|
||||||
legal.privacy=Πολιτική Προνομίους
|
legal.privacy=Πολιτική Προνομίους
|
||||||
legal.terms=Φράσεις Υποχρεωτικότητας
|
legal.terms=Φράσεις Υποχρεωτικότητας
|
||||||
@@ -249,7 +248,6 @@ database.backupCreated=Database backup successful
|
|||||||
database.fileNotFound=File not Found
|
database.fileNotFound=File not Found
|
||||||
database.fileNullOrEmpty=Το αρχείο δεν μπορεί να είναι τυχόν ή κενό.
|
database.fileNullOrEmpty=Το αρχείο δεν μπορεί να είναι τυχόν ή κενό.
|
||||||
database.failedImportFile=Failed Import File
|
database.failedImportFile=Failed Import File
|
||||||
database.notSupported=This function is not available for your database connection.
|
|
||||||
|
|
||||||
session.expired=Η σεζώνη σας υπάρξει παραγωγή. Πατήστε για να ανανεώσετε το πλήρωμα και δοκιμάστε ξανά.
|
session.expired=Η σεζώνη σας υπάρξει παραγωγή. Πατήστε για να ανανεώσετε το πλήρωμα και δοκιμάστε ξανά.
|
||||||
session.refreshPage=Refresh Page
|
session.refreshPage=Refresh Page
|
||||||
@@ -476,10 +474,6 @@ home.autoRedact.title=Αυτόματο Μαύρισμα Κειμένου
|
|||||||
home.autoRedact.desc=Αυτόματη επεξεργασία (Μαύρισμα) κείμενου σε PDF με βάση το κείμενο εισαγωγής
|
home.autoRedact.desc=Αυτόματη επεξεργασία (Μαύρισμα) κείμενου σε PDF με βάση το κείμενο εισαγωγής
|
||||||
autoRedact.tags=ξεκράζω,φυλακίζω,εικόνο-κουπές,κρατήστε ασφαλείς,δημιουργήστε
|
autoRedact.tags=ξεκράζω,φυλακίζω,εικόνο-κουπές,κρατήστε ασφαλείς,δημιουργήστε
|
||||||
|
|
||||||
home.redact.title=Manual Redaction
|
|
||||||
home.redact.desc=Redacts a PDF based on selected text, drawn shapes and/or selected page(s)
|
|
||||||
redact.tags=Redact,Hide,black out,black,marker,hidden,manual
|
|
||||||
|
|
||||||
home.tableExtraxt.title=PDF σε CSV
|
home.tableExtraxt.title=PDF σε CSV
|
||||||
home.tableExtraxt.desc=Εξάγει πίνακες από PDF μετατρέποντάς το σε CSV
|
home.tableExtraxt.desc=Εξάγει πίνακες από PDF μετατρέποντάς το σε CSV
|
||||||
tableExtraxt.tags=CSV,καταθέσεις-τάβλες,αποδιατύπωση,μετατροπή
|
tableExtraxt.tags=CSV,καταθέσεις-τάβλες,αποδιατύπωση,μετατροπή
|
||||||
@@ -585,31 +579,6 @@ autoRedact.customPaddingLabel=Εμπνευσμένη Προσθήκη Ανάκρ
|
|||||||
autoRedact.convertPDFToImageLabel=Μετατροπή PDF σε PDF-Εικόνα (Χρησιμοποιείται για την αφαίρεση κειμένου πίσω από το πλαίσιο)
|
autoRedact.convertPDFToImageLabel=Μετατροπή PDF σε PDF-Εικόνα (Χρησιμοποιείται για την αφαίρεση κειμένου πίσω από το πλαίσιο)
|
||||||
autoRedact.submitButton=Υποβολή
|
autoRedact.submitButton=Υποβολή
|
||||||
|
|
||||||
#redact
|
|
||||||
redact.title=Manual Redaction
|
|
||||||
redact.header=Manual Redaction
|
|
||||||
redact.submit=Redact
|
|
||||||
redact.textBasedRedaction=Text based Redaction
|
|
||||||
redact.pageBasedRedaction=Page-based Redaction
|
|
||||||
redact.convertPDFToImageLabel=Convert PDF to PDF-Image (Used to remove text behind the box)
|
|
||||||
redact.pageRedactionNumbers.title=Pages
|
|
||||||
redact.pageRedactionNumbers.placeholder=(e.g. 1,2,8 or 4,7,12-16 or 2n-1)
|
|
||||||
redact.redactionColor.title=Redaction Color
|
|
||||||
redact.export=Export
|
|
||||||
redact.upload=Upload
|
|
||||||
redact.boxRedaction=Box draw redaction
|
|
||||||
redact.zoom=Zoom
|
|
||||||
redact.zoomIn=Zoom in
|
|
||||||
redact.zoomOut=Zoom out
|
|
||||||
redact.nextPage=Next Page
|
|
||||||
redact.previousPage=Previous Page
|
|
||||||
redact.toggleSidebar=Toggle Sidebar
|
|
||||||
redact.showThumbnails=Show Thumbnails
|
|
||||||
redact.showDocumentOutline=Show Document Outline (double-click to expand/collapse all items)
|
|
||||||
redact.showAttatchments=Show Attachments
|
|
||||||
redact.showLayers=Show Layers (double-click to reset all layers to the default state)
|
|
||||||
redact.colourPicker=Colour Picker
|
|
||||||
redact.findCurrentOutlineItem=Find current outline item
|
|
||||||
|
|
||||||
#showJS
|
#showJS
|
||||||
showJS.title=Εμφάνιση Javascript
|
showJS.title=Εμφάνιση Javascript
|
||||||
@@ -863,8 +832,6 @@ sign.last=Last page
|
|||||||
sign.next=Next page
|
sign.next=Next page
|
||||||
sign.previous=Previous page
|
sign.previous=Previous page
|
||||||
sign.maintainRatio=Toggle maintain aspect ratio
|
sign.maintainRatio=Toggle maintain aspect ratio
|
||||||
|
|
||||||
|
|
||||||
#repair
|
#repair
|
||||||
repair.title=Επιδιόρθωση
|
repair.title=Επιδιόρθωση
|
||||||
repair.header=Επιδιόρθωση PDFs
|
repair.header=Επιδιόρθωση PDFs
|
||||||
|
|||||||
@@ -82,7 +82,6 @@ pages=Pages
|
|||||||
loading=Loading...
|
loading=Loading...
|
||||||
addToDoc=Add to Document
|
addToDoc=Add to Document
|
||||||
reset=Reset
|
reset=Reset
|
||||||
apply=Apply
|
|
||||||
|
|
||||||
legal.privacy=Privacy Policy
|
legal.privacy=Privacy Policy
|
||||||
legal.terms=Terms and Conditions
|
legal.terms=Terms and Conditions
|
||||||
@@ -249,7 +248,6 @@ database.backupCreated=Database backup successful
|
|||||||
database.fileNotFound=File not found
|
database.fileNotFound=File not found
|
||||||
database.fileNullOrEmpty=File must not be null or empty
|
database.fileNullOrEmpty=File must not be null or empty
|
||||||
database.failedImportFile=Failed to import file
|
database.failedImportFile=Failed to import file
|
||||||
database.notSupported=This function is not available for your database connection.
|
|
||||||
|
|
||||||
session.expired=Your session has expired. Please refresh the page and try again.
|
session.expired=Your session has expired. Please refresh the page and try again.
|
||||||
session.refreshPage=Refresh Page
|
session.refreshPage=Refresh Page
|
||||||
@@ -476,10 +474,6 @@ home.autoRedact.title=Auto Redact
|
|||||||
home.autoRedact.desc=Auto Redacts(Blacks out) text in a PDF based on input text
|
home.autoRedact.desc=Auto Redacts(Blacks out) text in a PDF based on input text
|
||||||
autoRedact.tags=Redact,Hide,black out,black,marker,hidden
|
autoRedact.tags=Redact,Hide,black out,black,marker,hidden
|
||||||
|
|
||||||
home.redact.title=Manual Redaction
|
|
||||||
home.redact.desc=Redacts a PDF based on selected text, drawn shapes and/or selected page(s)
|
|
||||||
redact.tags=Redact,Hide,black out,black,marker,hidden,manual
|
|
||||||
|
|
||||||
home.tableExtraxt.title=PDF to CSV
|
home.tableExtraxt.title=PDF to CSV
|
||||||
home.tableExtraxt.desc=Extracts Tables from a PDF converting it to CSV
|
home.tableExtraxt.desc=Extracts Tables from a PDF converting it to CSV
|
||||||
tableExtraxt.tags=CSV,Table Extraction,extract,convert
|
tableExtraxt.tags=CSV,Table Extraction,extract,convert
|
||||||
@@ -585,31 +579,6 @@ autoRedact.customPaddingLabel=Custom Extra Padding
|
|||||||
autoRedact.convertPDFToImageLabel=Convert PDF to PDF-Image (Used to remove text behind the box)
|
autoRedact.convertPDFToImageLabel=Convert PDF to PDF-Image (Used to remove text behind the box)
|
||||||
autoRedact.submitButton=Submit
|
autoRedact.submitButton=Submit
|
||||||
|
|
||||||
#redact
|
|
||||||
redact.title=Manual Redaction
|
|
||||||
redact.header=Manual Redaction
|
|
||||||
redact.submit=Redact
|
|
||||||
redact.textBasedRedaction=Text based Redaction
|
|
||||||
redact.pageBasedRedaction=Page-based Redaction
|
|
||||||
redact.convertPDFToImageLabel=Convert PDF to PDF-Image (Used to remove text behind the box)
|
|
||||||
redact.pageRedactionNumbers.title=Pages
|
|
||||||
redact.pageRedactionNumbers.placeholder=(e.g. 1,2,8 or 4,7,12-16 or 2n-1)
|
|
||||||
redact.redactionColor.title=Redaction Color
|
|
||||||
redact.export=Export
|
|
||||||
redact.upload=Upload
|
|
||||||
redact.boxRedaction=Box draw redaction
|
|
||||||
redact.zoom=Zoom
|
|
||||||
redact.zoomIn=Zoom in
|
|
||||||
redact.zoomOut=Zoom out
|
|
||||||
redact.nextPage=Next Page
|
|
||||||
redact.previousPage=Previous Page
|
|
||||||
redact.toggleSidebar=Toggle Sidebar
|
|
||||||
redact.showThumbnails=Show Thumbnails
|
|
||||||
redact.showDocumentOutline=Show Document Outline (double-click to expand/collapse all items)
|
|
||||||
redact.showAttatchments=Show Attachments
|
|
||||||
redact.showLayers=Show Layers (double-click to reset all layers to the default state)
|
|
||||||
redact.colourPicker=Colour Picker
|
|
||||||
redact.findCurrentOutlineItem=Find current outline item
|
|
||||||
|
|
||||||
#showJS
|
#showJS
|
||||||
showJS.title=Show Javascript
|
showJS.title=Show Javascript
|
||||||
@@ -863,8 +832,6 @@ sign.last=Last page
|
|||||||
sign.next=Next page
|
sign.next=Next page
|
||||||
sign.previous=Previous page
|
sign.previous=Previous page
|
||||||
sign.maintainRatio=Toggle maintain aspect ratio
|
sign.maintainRatio=Toggle maintain aspect ratio
|
||||||
|
|
||||||
|
|
||||||
#repair
|
#repair
|
||||||
repair.title=Repair
|
repair.title=Repair
|
||||||
repair.header=Repair PDFs
|
repair.header=Repair PDFs
|
||||||
|
|||||||
@@ -82,7 +82,6 @@ pages=Pages
|
|||||||
loading=Loading...
|
loading=Loading...
|
||||||
addToDoc=Add to Document
|
addToDoc=Add to Document
|
||||||
reset=Reset
|
reset=Reset
|
||||||
apply=Apply
|
|
||||||
|
|
||||||
legal.privacy=Privacy Policy
|
legal.privacy=Privacy Policy
|
||||||
legal.terms=Terms and Conditions
|
legal.terms=Terms and Conditions
|
||||||
@@ -249,7 +248,6 @@ database.backupCreated=Database backup successful
|
|||||||
database.fileNotFound=File not Found
|
database.fileNotFound=File not Found
|
||||||
database.fileNullOrEmpty=File must not be null or empty
|
database.fileNullOrEmpty=File must not be null or empty
|
||||||
database.failedImportFile=Failed Import File
|
database.failedImportFile=Failed Import File
|
||||||
database.notSupported=This function is not available for your database connection.
|
|
||||||
|
|
||||||
session.expired=Your session has expired. Please refresh the page and try again.
|
session.expired=Your session has expired. Please refresh the page and try again.
|
||||||
session.refreshPage=Refresh Page
|
session.refreshPage=Refresh Page
|
||||||
@@ -476,10 +474,6 @@ home.autoRedact.title=Auto Redact
|
|||||||
home.autoRedact.desc=Auto Redacts(Blacks out) text in a PDF based on input text
|
home.autoRedact.desc=Auto Redacts(Blacks out) text in a PDF based on input text
|
||||||
autoRedact.tags=Redact,Hide,black out,black,marker,hidden
|
autoRedact.tags=Redact,Hide,black out,black,marker,hidden
|
||||||
|
|
||||||
home.redact.title=Manual Redaction
|
|
||||||
home.redact.desc=Redacts a PDF based on selected text, drawn shapes and/or selected page(s)
|
|
||||||
redact.tags=Redact,Hide,black out,black,marker,hidden,manual
|
|
||||||
|
|
||||||
home.tableExtraxt.title=PDF to CSV
|
home.tableExtraxt.title=PDF to CSV
|
||||||
home.tableExtraxt.desc=Extracts Tables from a PDF converting it to CSV
|
home.tableExtraxt.desc=Extracts Tables from a PDF converting it to CSV
|
||||||
tableExtraxt.tags=CSV,Table Extraction,extract,convert
|
tableExtraxt.tags=CSV,Table Extraction,extract,convert
|
||||||
@@ -585,31 +579,6 @@ autoRedact.customPaddingLabel=Custom Extra Padding
|
|||||||
autoRedact.convertPDFToImageLabel=Convert PDF to PDF-Image (Used to remove text behind the box)
|
autoRedact.convertPDFToImageLabel=Convert PDF to PDF-Image (Used to remove text behind the box)
|
||||||
autoRedact.submitButton=Submit
|
autoRedact.submitButton=Submit
|
||||||
|
|
||||||
#redact
|
|
||||||
redact.title=Manual Redaction
|
|
||||||
redact.header=Manual Redaction
|
|
||||||
redact.submit=Redact
|
|
||||||
redact.textBasedRedaction=Text based Redaction
|
|
||||||
redact.pageBasedRedaction=Page-based Redaction
|
|
||||||
redact.convertPDFToImageLabel=Convert PDF to PDF-Image (Used to remove text behind the box)
|
|
||||||
redact.pageRedactionNumbers.title=Pages
|
|
||||||
redact.pageRedactionNumbers.placeholder=(e.g. 1,2,8 or 4,7,12-16 or 2n-1)
|
|
||||||
redact.redactionColor.title=Redaction Color
|
|
||||||
redact.export=Export
|
|
||||||
redact.upload=Upload
|
|
||||||
redact.boxRedaction=Box draw redaction
|
|
||||||
redact.zoom=Zoom
|
|
||||||
redact.zoomIn=Zoom in
|
|
||||||
redact.zoomOut=Zoom out
|
|
||||||
redact.nextPage=Next Page
|
|
||||||
redact.previousPage=Previous Page
|
|
||||||
redact.toggleSidebar=Toggle Sidebar
|
|
||||||
redact.showThumbnails=Show Thumbnails
|
|
||||||
redact.showDocumentOutline=Show Document Outline (double-click to expand/collapse all items)
|
|
||||||
redact.showAttatchments=Show Attachments
|
|
||||||
redact.showLayers=Show Layers (double-click to reset all layers to the default state)
|
|
||||||
redact.colourPicker=Colour Picker
|
|
||||||
redact.findCurrentOutlineItem=Find current outline item
|
|
||||||
|
|
||||||
#showJS
|
#showJS
|
||||||
showJS.title=Show Javascript
|
showJS.title=Show Javascript
|
||||||
@@ -863,8 +832,6 @@ sign.last=Last page
|
|||||||
sign.next=Next page
|
sign.next=Next page
|
||||||
sign.previous=Previous page
|
sign.previous=Previous page
|
||||||
sign.maintainRatio=Toggle maintain aspect ratio
|
sign.maintainRatio=Toggle maintain aspect ratio
|
||||||
|
|
||||||
|
|
||||||
#repair
|
#repair
|
||||||
repair.title=Repair
|
repair.title=Repair
|
||||||
repair.header=Repair PDFs
|
repair.header=Repair PDFs
|
||||||
|
|||||||
@@ -82,7 +82,6 @@ pages=Páginas
|
|||||||
loading=Cargando...
|
loading=Cargando...
|
||||||
addToDoc=Agregar al Documento
|
addToDoc=Agregar al Documento
|
||||||
reset=Reset
|
reset=Reset
|
||||||
apply=Apply
|
|
||||||
|
|
||||||
legal.privacy=Política de Privacidad
|
legal.privacy=Política de Privacidad
|
||||||
legal.terms=Términos y Condiciones
|
legal.terms=Términos y Condiciones
|
||||||
@@ -249,7 +248,6 @@ database.backupCreated=Database backup successful
|
|||||||
database.fileNotFound=Archivo no encontrado
|
database.fileNotFound=Archivo no encontrado
|
||||||
database.fileNullOrEmpty=El archivo no debe ser nulo o vacío.
|
database.fileNullOrEmpty=El archivo no debe ser nulo o vacío.
|
||||||
database.failedImportFile=Archivo de importación fallido
|
database.failedImportFile=Archivo de importación fallido
|
||||||
database.notSupported=This function is not available for your database connection.
|
|
||||||
|
|
||||||
session.expired=Tu sesión ha caducado. Actualice la página e inténtelo de nuevo.
|
session.expired=Tu sesión ha caducado. Actualice la página e inténtelo de nuevo.
|
||||||
session.refreshPage=Refresh Page
|
session.refreshPage=Refresh Page
|
||||||
@@ -476,10 +474,6 @@ home.autoRedact.title=Auto Redactar
|
|||||||
home.autoRedact.desc=Redactar automáticamente (ocultar) texto en un PDF según el texto introducido
|
home.autoRedact.desc=Redactar automáticamente (ocultar) texto en un PDF según el texto introducido
|
||||||
autoRedact.tags=Redactar,Ocultar,ocultar,negro,subrayador,oculto
|
autoRedact.tags=Redactar,Ocultar,ocultar,negro,subrayador,oculto
|
||||||
|
|
||||||
home.redact.title=Manual Redaction
|
|
||||||
home.redact.desc=Redacts a PDF based on selected text, drawn shapes and/or selected page(s)
|
|
||||||
redact.tags=Redact,Hide,black out,black,marker,hidden,manual
|
|
||||||
|
|
||||||
home.tableExtraxt.title=PDF a CSV
|
home.tableExtraxt.title=PDF a CSV
|
||||||
home.tableExtraxt.desc=Extraer Tablas de un PDF convirtiéndolas a CSV
|
home.tableExtraxt.desc=Extraer Tablas de un PDF convirtiéndolas a CSV
|
||||||
tableExtraxt.tags=CSV,Extraer tabla,extraer,convertir
|
tableExtraxt.tags=CSV,Extraer tabla,extraer,convertir
|
||||||
@@ -585,31 +579,6 @@ autoRedact.customPaddingLabel=Extra Padding personalizado
|
|||||||
autoRedact.convertPDFToImageLabel=Convertir PDF a imagen PDF (Utilizado para quitar el texto detrás del cajetín)
|
autoRedact.convertPDFToImageLabel=Convertir PDF a imagen PDF (Utilizado para quitar el texto detrás del cajetín)
|
||||||
autoRedact.submitButton=Enviar
|
autoRedact.submitButton=Enviar
|
||||||
|
|
||||||
#redact
|
|
||||||
redact.title=Manual Redaction
|
|
||||||
redact.header=Manual Redaction
|
|
||||||
redact.submit=Redact
|
|
||||||
redact.textBasedRedaction=Text based Redaction
|
|
||||||
redact.pageBasedRedaction=Page-based Redaction
|
|
||||||
redact.convertPDFToImageLabel=Convert PDF to PDF-Image (Used to remove text behind the box)
|
|
||||||
redact.pageRedactionNumbers.title=Pages
|
|
||||||
redact.pageRedactionNumbers.placeholder=(e.g. 1,2,8 or 4,7,12-16 or 2n-1)
|
|
||||||
redact.redactionColor.title=Redaction Color
|
|
||||||
redact.export=Export
|
|
||||||
redact.upload=Upload
|
|
||||||
redact.boxRedaction=Box draw redaction
|
|
||||||
redact.zoom=Zoom
|
|
||||||
redact.zoomIn=Zoom in
|
|
||||||
redact.zoomOut=Zoom out
|
|
||||||
redact.nextPage=Next Page
|
|
||||||
redact.previousPage=Previous Page
|
|
||||||
redact.toggleSidebar=Toggle Sidebar
|
|
||||||
redact.showThumbnails=Show Thumbnails
|
|
||||||
redact.showDocumentOutline=Show Document Outline (double-click to expand/collapse all items)
|
|
||||||
redact.showAttatchments=Show Attachments
|
|
||||||
redact.showLayers=Show Layers (double-click to reset all layers to the default state)
|
|
||||||
redact.colourPicker=Colour Picker
|
|
||||||
redact.findCurrentOutlineItem=Find current outline item
|
|
||||||
|
|
||||||
#showJS
|
#showJS
|
||||||
showJS.title=Mostrar Javascript
|
showJS.title=Mostrar Javascript
|
||||||
@@ -863,8 +832,6 @@ sign.last=Last page
|
|||||||
sign.next=Next page
|
sign.next=Next page
|
||||||
sign.previous=Previous page
|
sign.previous=Previous page
|
||||||
sign.maintainRatio=Toggle maintain aspect ratio
|
sign.maintainRatio=Toggle maintain aspect ratio
|
||||||
|
|
||||||
|
|
||||||
#repair
|
#repair
|
||||||
repair.title=Reparar
|
repair.title=Reparar
|
||||||
repair.header=Reparar archivos PDF
|
repair.header=Reparar archivos PDF
|
||||||
|
|||||||
@@ -82,7 +82,6 @@ pages=Pages
|
|||||||
loading=Loading...
|
loading=Loading...
|
||||||
addToDoc=Add to Document
|
addToDoc=Add to Document
|
||||||
reset=Reset
|
reset=Reset
|
||||||
apply=Apply
|
|
||||||
|
|
||||||
legal.privacy=Privacy Policy
|
legal.privacy=Privacy Policy
|
||||||
legal.terms=Terms and Conditions
|
legal.terms=Terms and Conditions
|
||||||
@@ -249,7 +248,6 @@ database.backupCreated=Database backup successful
|
|||||||
database.fileNotFound=File not Found
|
database.fileNotFound=File not Found
|
||||||
database.fileNullOrEmpty=File must not be null or empty
|
database.fileNullOrEmpty=File must not be null or empty
|
||||||
database.failedImportFile=Failed Import File
|
database.failedImportFile=Failed Import File
|
||||||
database.notSupported=This function is not available for your database connection.
|
|
||||||
|
|
||||||
session.expired=Your session has expired. Please refresh the page and try again.
|
session.expired=Your session has expired. Please refresh the page and try again.
|
||||||
session.refreshPage=Refresh Page
|
session.refreshPage=Refresh Page
|
||||||
@@ -476,10 +474,6 @@ home.autoRedact.title=Auto Idatzi
|
|||||||
home.autoRedact.desc=Auto Idatzi testua pdf fitxategian sarrerako testuan oinarritua
|
home.autoRedact.desc=Auto Idatzi testua pdf fitxategian sarrerako testuan oinarritua
|
||||||
autoRedact.tags=Redact,Hide,black out,black,marker,hidden
|
autoRedact.tags=Redact,Hide,black out,black,marker,hidden
|
||||||
|
|
||||||
home.redact.title=Manual Redaction
|
|
||||||
home.redact.desc=Redacts a PDF based on selected text, drawn shapes and/or selected page(s)
|
|
||||||
redact.tags=Redact,Hide,black out,black,marker,hidden,manual
|
|
||||||
|
|
||||||
home.tableExtraxt.title=PDF to CSV
|
home.tableExtraxt.title=PDF to CSV
|
||||||
home.tableExtraxt.desc=Extracts Tables from a PDF converting it to CSV
|
home.tableExtraxt.desc=Extracts Tables from a PDF converting it to CSV
|
||||||
tableExtraxt.tags=CSV,Table Extraction,extract,convert
|
tableExtraxt.tags=CSV,Table Extraction,extract,convert
|
||||||
@@ -585,31 +579,6 @@ autoRedact.customPaddingLabel=Custom Extra Padding
|
|||||||
autoRedact.convertPDFToImageLabel=Bihurtu PDF fitxategi bat PDF-Irudi-ra (kaxaren atzean testua ezabatzeko erabilia)
|
autoRedact.convertPDFToImageLabel=Bihurtu PDF fitxategi bat PDF-Irudi-ra (kaxaren atzean testua ezabatzeko erabilia)
|
||||||
autoRedact.submitButton=Bidali
|
autoRedact.submitButton=Bidali
|
||||||
|
|
||||||
#redact
|
|
||||||
redact.title=Manual Redaction
|
|
||||||
redact.header=Manual Redaction
|
|
||||||
redact.submit=Redact
|
|
||||||
redact.textBasedRedaction=Text based Redaction
|
|
||||||
redact.pageBasedRedaction=Page-based Redaction
|
|
||||||
redact.convertPDFToImageLabel=Convert PDF to PDF-Image (Used to remove text behind the box)
|
|
||||||
redact.pageRedactionNumbers.title=Pages
|
|
||||||
redact.pageRedactionNumbers.placeholder=(e.g. 1,2,8 or 4,7,12-16 or 2n-1)
|
|
||||||
redact.redactionColor.title=Redaction Color
|
|
||||||
redact.export=Export
|
|
||||||
redact.upload=Upload
|
|
||||||
redact.boxRedaction=Box draw redaction
|
|
||||||
redact.zoom=Zoom
|
|
||||||
redact.zoomIn=Zoom in
|
|
||||||
redact.zoomOut=Zoom out
|
|
||||||
redact.nextPage=Next Page
|
|
||||||
redact.previousPage=Previous Page
|
|
||||||
redact.toggleSidebar=Toggle Sidebar
|
|
||||||
redact.showThumbnails=Show Thumbnails
|
|
||||||
redact.showDocumentOutline=Show Document Outline (double-click to expand/collapse all items)
|
|
||||||
redact.showAttatchments=Show Attachments
|
|
||||||
redact.showLayers=Show Layers (double-click to reset all layers to the default state)
|
|
||||||
redact.colourPicker=Colour Picker
|
|
||||||
redact.findCurrentOutlineItem=Find current outline item
|
|
||||||
|
|
||||||
#showJS
|
#showJS
|
||||||
showJS.title=Javascript erakutsi
|
showJS.title=Javascript erakutsi
|
||||||
@@ -863,8 +832,6 @@ sign.last=Last page
|
|||||||
sign.next=Next page
|
sign.next=Next page
|
||||||
sign.previous=Previous page
|
sign.previous=Previous page
|
||||||
sign.maintainRatio=Toggle maintain aspect ratio
|
sign.maintainRatio=Toggle maintain aspect ratio
|
||||||
|
|
||||||
|
|
||||||
#repair
|
#repair
|
||||||
repair.title=Konpondu
|
repair.title=Konpondu
|
||||||
repair.header=Konpondu PDF fitxategiak
|
repair.header=Konpondu PDF fitxategiak
|
||||||
|
|||||||
@@ -82,7 +82,6 @@ pages=صفحات
|
|||||||
loading=در حال بارگذاری...
|
loading=در حال بارگذاری...
|
||||||
addToDoc=اضافه کردن به سند
|
addToDoc=اضافه کردن به سند
|
||||||
reset=تنظیم مجدد
|
reset=تنظیم مجدد
|
||||||
apply=Apply
|
|
||||||
|
|
||||||
legal.privacy=سیاست حفظ حریم خصوصی
|
legal.privacy=سیاست حفظ حریم خصوصی
|
||||||
legal.terms=شرایط و ضوابط
|
legal.terms=شرایط و ضوابط
|
||||||
@@ -249,7 +248,6 @@ database.backupCreated=Database backup successful
|
|||||||
database.fileNotFound=فایل پیدا نشد
|
database.fileNotFound=فایل پیدا نشد
|
||||||
database.fileNullOrEmpty=فایل نباید خالی یا تهی باشد
|
database.fileNullOrEmpty=فایل نباید خالی یا تهی باشد
|
||||||
database.failedImportFile=وارد کردن فایل ناموفق بود
|
database.failedImportFile=وارد کردن فایل ناموفق بود
|
||||||
database.notSupported=This function is not available for your database connection.
|
|
||||||
|
|
||||||
session.expired=نشست شما به پایان رسیده است. لطفاً صفحه را تازهسازی کرده و دوباره تلاش کنید.
|
session.expired=نشست شما به پایان رسیده است. لطفاً صفحه را تازهسازی کرده و دوباره تلاش کنید.
|
||||||
session.refreshPage=تازهسازی صفحه
|
session.refreshPage=تازهسازی صفحه
|
||||||
@@ -476,10 +474,6 @@ home.autoRedact.title=سانسور خودکار
|
|||||||
home.autoRedact.desc=متنهای مشخص شده در PDF را بهطور خودکار سانسور (سیاه) میکند
|
home.autoRedact.desc=متنهای مشخص شده در PDF را بهطور خودکار سانسور (سیاه) میکند
|
||||||
autoRedact.tags=سانسور، مخفی کردن، سیاه کردن، پنهان
|
autoRedact.tags=سانسور، مخفی کردن، سیاه کردن، پنهان
|
||||||
|
|
||||||
home.redact.title=Manual Redaction
|
|
||||||
home.redact.desc=Redacts a PDF based on selected text, drawn shapes and/or selected page(s)
|
|
||||||
redact.tags=Redact,Hide,black out,black,marker,hidden,manual
|
|
||||||
|
|
||||||
home.tableExtraxt.title=PDF به CSV
|
home.tableExtraxt.title=PDF به CSV
|
||||||
home.tableExtraxt.desc=جداول را از PDF استخراج کرده و به CSV تبدیل میکند
|
home.tableExtraxt.desc=جداول را از PDF استخراج کرده و به CSV تبدیل میکند
|
||||||
tableExtraxt.tags=CSV، استخراج جدول، استخراج، تبدیل
|
tableExtraxt.tags=CSV، استخراج جدول، استخراج، تبدیل
|
||||||
@@ -585,31 +579,6 @@ autoRedact.customPaddingLabel=افزودن فاصله اضافی
|
|||||||
autoRedact.convertPDFToImageLabel=تبدیل PDF به PDF-تصویر (برای حذف متن پشت جعبه استفاده میشود)
|
autoRedact.convertPDFToImageLabel=تبدیل PDF به PDF-تصویر (برای حذف متن پشت جعبه استفاده میشود)
|
||||||
autoRedact.submitButton=ارسال
|
autoRedact.submitButton=ارسال
|
||||||
|
|
||||||
#redact
|
|
||||||
redact.title=Manual Redaction
|
|
||||||
redact.header=Manual Redaction
|
|
||||||
redact.submit=Redact
|
|
||||||
redact.textBasedRedaction=Text based Redaction
|
|
||||||
redact.pageBasedRedaction=Page-based Redaction
|
|
||||||
redact.convertPDFToImageLabel=Convert PDF to PDF-Image (Used to remove text behind the box)
|
|
||||||
redact.pageRedactionNumbers.title=Pages
|
|
||||||
redact.pageRedactionNumbers.placeholder=(e.g. 1,2,8 or 4,7,12-16 or 2n-1)
|
|
||||||
redact.redactionColor.title=Redaction Color
|
|
||||||
redact.export=Export
|
|
||||||
redact.upload=Upload
|
|
||||||
redact.boxRedaction=Box draw redaction
|
|
||||||
redact.zoom=Zoom
|
|
||||||
redact.zoomIn=Zoom in
|
|
||||||
redact.zoomOut=Zoom out
|
|
||||||
redact.nextPage=Next Page
|
|
||||||
redact.previousPage=Previous Page
|
|
||||||
redact.toggleSidebar=Toggle Sidebar
|
|
||||||
redact.showThumbnails=Show Thumbnails
|
|
||||||
redact.showDocumentOutline=Show Document Outline (double-click to expand/collapse all items)
|
|
||||||
redact.showAttatchments=Show Attachments
|
|
||||||
redact.showLayers=Show Layers (double-click to reset all layers to the default state)
|
|
||||||
redact.colourPicker=Colour Picker
|
|
||||||
redact.findCurrentOutlineItem=Find current outline item
|
|
||||||
|
|
||||||
#showJS
|
#showJS
|
||||||
showJS.title=نمایش جاوااسکریپت
|
showJS.title=نمایش جاوااسکریپت
|
||||||
@@ -863,8 +832,6 @@ sign.last=صفحه آخر
|
|||||||
sign.next=صفحه بعدی
|
sign.next=صفحه بعدی
|
||||||
sign.previous=صفحه قبلی
|
sign.previous=صفحه قبلی
|
||||||
sign.maintainRatio=Toggle maintain aspect ratio
|
sign.maintainRatio=Toggle maintain aspect ratio
|
||||||
|
|
||||||
|
|
||||||
#repair
|
#repair
|
||||||
repair.title=تعمیر
|
repair.title=تعمیر
|
||||||
repair.header=تعمیر PDFها
|
repair.header=تعمیر PDFها
|
||||||
|
|||||||
@@ -82,7 +82,6 @@ pages=Pages
|
|||||||
loading=Chargement...
|
loading=Chargement...
|
||||||
addToDoc=Ajouter au Document
|
addToDoc=Ajouter au Document
|
||||||
reset=Réinitialiser
|
reset=Réinitialiser
|
||||||
apply=Apply
|
|
||||||
|
|
||||||
legal.privacy=Politique de Confidentialité
|
legal.privacy=Politique de Confidentialité
|
||||||
legal.terms=Conditions Générales
|
legal.terms=Conditions Générales
|
||||||
@@ -249,7 +248,6 @@ database.backupCreated=Database backup successful
|
|||||||
database.fileNotFound=File not Found
|
database.fileNotFound=File not Found
|
||||||
database.fileNullOrEmpty=Fichier ne peut pas être null ou vide
|
database.fileNullOrEmpty=Fichier ne peut pas être null ou vide
|
||||||
database.failedImportFile=Failed Import File
|
database.failedImportFile=Failed Import File
|
||||||
database.notSupported=This function is not available for your database connection.
|
|
||||||
|
|
||||||
session.expired=Votre session a expiré. Veuillez recharger la page et réessayer.
|
session.expired=Votre session a expiré. Veuillez recharger la page et réessayer.
|
||||||
session.refreshPage=Refresh Page
|
session.refreshPage=Refresh Page
|
||||||
@@ -476,10 +474,6 @@ home.autoRedact.title=Caviarder automatiquement
|
|||||||
home.autoRedact.desc=Caviardez automatiquement les informations sensibles d'un PDF.
|
home.autoRedact.desc=Caviardez automatiquement les informations sensibles d'un PDF.
|
||||||
autoRedact.tags=caviarder,redact,auto
|
autoRedact.tags=caviarder,redact,auto
|
||||||
|
|
||||||
home.redact.title=Manual Redaction
|
|
||||||
home.redact.desc=Redacts a PDF based on selected text, drawn shapes and/or selected page(s)
|
|
||||||
redact.tags=Redact,Hide,black out,black,marker,hidden,manual
|
|
||||||
|
|
||||||
home.tableExtraxt.title=PDF en CSV
|
home.tableExtraxt.title=PDF en CSV
|
||||||
home.tableExtraxt.desc=Extrait les tableaux d'un PDF et les transforme en CSV.
|
home.tableExtraxt.desc=Extrait les tableaux d'un PDF et les transforme en CSV.
|
||||||
tableExtraxt.tags=CSV, Extraction de table, extraction, conversion
|
tableExtraxt.tags=CSV, Extraction de table, extraction, conversion
|
||||||
@@ -585,31 +579,6 @@ autoRedact.customPaddingLabel=Marge intérieure supplémentaire
|
|||||||
autoRedact.convertPDFToImageLabel=Convertir un PDF en PDF-Image (utilisé pour supprimer le texte en arrière-plan)
|
autoRedact.convertPDFToImageLabel=Convertir un PDF en PDF-Image (utilisé pour supprimer le texte en arrière-plan)
|
||||||
autoRedact.submitButton=Caviarder
|
autoRedact.submitButton=Caviarder
|
||||||
|
|
||||||
#redact
|
|
||||||
redact.title=Manual Redaction
|
|
||||||
redact.header=Manual Redaction
|
|
||||||
redact.submit=Redact
|
|
||||||
redact.textBasedRedaction=Text based Redaction
|
|
||||||
redact.pageBasedRedaction=Page-based Redaction
|
|
||||||
redact.convertPDFToImageLabel=Convert PDF to PDF-Image (Used to remove text behind the box)
|
|
||||||
redact.pageRedactionNumbers.title=Pages
|
|
||||||
redact.pageRedactionNumbers.placeholder=(e.g. 1,2,8 or 4,7,12-16 or 2n-1)
|
|
||||||
redact.redactionColor.title=Redaction Color
|
|
||||||
redact.export=Export
|
|
||||||
redact.upload=Upload
|
|
||||||
redact.boxRedaction=Box draw redaction
|
|
||||||
redact.zoom=Zoom
|
|
||||||
redact.zoomIn=Zoom in
|
|
||||||
redact.zoomOut=Zoom out
|
|
||||||
redact.nextPage=Next Page
|
|
||||||
redact.previousPage=Previous Page
|
|
||||||
redact.toggleSidebar=Toggle Sidebar
|
|
||||||
redact.showThumbnails=Show Thumbnails
|
|
||||||
redact.showDocumentOutline=Show Document Outline (double-click to expand/collapse all items)
|
|
||||||
redact.showAttatchments=Show Attachments
|
|
||||||
redact.showLayers=Show Layers (double-click to reset all layers to the default state)
|
|
||||||
redact.colourPicker=Colour Picker
|
|
||||||
redact.findCurrentOutlineItem=Find current outline item
|
|
||||||
|
|
||||||
#showJS
|
#showJS
|
||||||
showJS.title=Afficher le JavaScript
|
showJS.title=Afficher le JavaScript
|
||||||
@@ -863,8 +832,6 @@ sign.last=Last page
|
|||||||
sign.next=Next page
|
sign.next=Next page
|
||||||
sign.previous=Previous page
|
sign.previous=Previous page
|
||||||
sign.maintainRatio=Toggle maintain aspect ratio
|
sign.maintainRatio=Toggle maintain aspect ratio
|
||||||
|
|
||||||
|
|
||||||
#repair
|
#repair
|
||||||
repair.title=Réparer
|
repair.title=Réparer
|
||||||
repair.header=Réparer
|
repair.header=Réparer
|
||||||
|
|||||||
@@ -82,7 +82,6 @@ pages=Pages
|
|||||||
loading=Loading...
|
loading=Loading...
|
||||||
addToDoc=Add to Document
|
addToDoc=Add to Document
|
||||||
reset=Reset
|
reset=Reset
|
||||||
apply=Apply
|
|
||||||
|
|
||||||
legal.privacy=Privacy Policy
|
legal.privacy=Privacy Policy
|
||||||
legal.terms=Terms and Conditions
|
legal.terms=Terms and Conditions
|
||||||
@@ -249,7 +248,6 @@ database.backupCreated=Database backup successful
|
|||||||
database.fileNotFound=Comhad gan aimsiú
|
database.fileNotFound=Comhad gan aimsiú
|
||||||
database.fileNullOrEmpty=Níor cheart go mbeadh an comhad ar neamhní nó folamh
|
database.fileNullOrEmpty=Níor cheart go mbeadh an comhad ar neamhní nó folamh
|
||||||
database.failedImportFile=Theip ar iompórtáil an chomhaid
|
database.failedImportFile=Theip ar iompórtáil an chomhaid
|
||||||
database.notSupported=This function is not available for your database connection.
|
|
||||||
|
|
||||||
session.expired=Your session has expired. Please refresh the page and try again.
|
session.expired=Your session has expired. Please refresh the page and try again.
|
||||||
session.refreshPage=Refresh Page
|
session.refreshPage=Refresh Page
|
||||||
@@ -476,10 +474,6 @@ home.autoRedact.title=Auto Redact
|
|||||||
home.autoRedact.desc=Auto Redacts (Blacks out) téacs i PDF bunaithe ar an téacs ionchuir
|
home.autoRedact.desc=Auto Redacts (Blacks out) téacs i PDF bunaithe ar an téacs ionchuir
|
||||||
autoRedact.tags=Dearg, Folaigh, dubh amach, dubh, marcóir, i bhfolach
|
autoRedact.tags=Dearg, Folaigh, dubh amach, dubh, marcóir, i bhfolach
|
||||||
|
|
||||||
home.redact.title=Manual Redaction
|
|
||||||
home.redact.desc=Redacts a PDF based on selected text, drawn shapes and/or selected page(s)
|
|
||||||
redact.tags=Redact,Hide,black out,black,marker,hidden,manual
|
|
||||||
|
|
||||||
home.tableExtraxt.title=Ó CSV go PDF
|
home.tableExtraxt.title=Ó CSV go PDF
|
||||||
home.tableExtraxt.desc=Sleachta Táblaí ó PDF agus é a thiontú go CSV
|
home.tableExtraxt.desc=Sleachta Táblaí ó PDF agus é a thiontú go CSV
|
||||||
tableExtraxt.tags=CSV, Eastóscadh Tábla, sliocht, tiontú
|
tableExtraxt.tags=CSV, Eastóscadh Tábla, sliocht, tiontú
|
||||||
@@ -585,31 +579,6 @@ autoRedact.customPaddingLabel=Stuáil Breise Saincheaptha
|
|||||||
autoRedact.convertPDFToImageLabel=Tiontaigh PDF go PDF-Image (Úsáidte chun téacs a bhaint taobh thiar den bhosca)
|
autoRedact.convertPDFToImageLabel=Tiontaigh PDF go PDF-Image (Úsáidte chun téacs a bhaint taobh thiar den bhosca)
|
||||||
autoRedact.submitButton=Cuir isteach
|
autoRedact.submitButton=Cuir isteach
|
||||||
|
|
||||||
#redact
|
|
||||||
redact.title=Manual Redaction
|
|
||||||
redact.header=Manual Redaction
|
|
||||||
redact.submit=Redact
|
|
||||||
redact.textBasedRedaction=Text based Redaction
|
|
||||||
redact.pageBasedRedaction=Page-based Redaction
|
|
||||||
redact.convertPDFToImageLabel=Convert PDF to PDF-Image (Used to remove text behind the box)
|
|
||||||
redact.pageRedactionNumbers.title=Pages
|
|
||||||
redact.pageRedactionNumbers.placeholder=(e.g. 1,2,8 or 4,7,12-16 or 2n-1)
|
|
||||||
redact.redactionColor.title=Redaction Color
|
|
||||||
redact.export=Export
|
|
||||||
redact.upload=Upload
|
|
||||||
redact.boxRedaction=Box draw redaction
|
|
||||||
redact.zoom=Zoom
|
|
||||||
redact.zoomIn=Zoom in
|
|
||||||
redact.zoomOut=Zoom out
|
|
||||||
redact.nextPage=Next Page
|
|
||||||
redact.previousPage=Previous Page
|
|
||||||
redact.toggleSidebar=Toggle Sidebar
|
|
||||||
redact.showThumbnails=Show Thumbnails
|
|
||||||
redact.showDocumentOutline=Show Document Outline (double-click to expand/collapse all items)
|
|
||||||
redact.showAttatchments=Show Attachments
|
|
||||||
redact.showLayers=Show Layers (double-click to reset all layers to the default state)
|
|
||||||
redact.colourPicker=Colour Picker
|
|
||||||
redact.findCurrentOutlineItem=Find current outline item
|
|
||||||
|
|
||||||
#showJS
|
#showJS
|
||||||
showJS.title=Taispeáin Javascript
|
showJS.title=Taispeáin Javascript
|
||||||
@@ -863,8 +832,6 @@ sign.last=Last page
|
|||||||
sign.next=Next page
|
sign.next=Next page
|
||||||
sign.previous=Previous page
|
sign.previous=Previous page
|
||||||
sign.maintainRatio=Toggle maintain aspect ratio
|
sign.maintainRatio=Toggle maintain aspect ratio
|
||||||
|
|
||||||
|
|
||||||
#repair
|
#repair
|
||||||
repair.title=Deisiúchán
|
repair.title=Deisiúchán
|
||||||
repair.header=PDF a dheisiú
|
repair.header=PDF a dheisiú
|
||||||
|
|||||||
@@ -82,7 +82,6 @@ pages=पृष्ठों
|
|||||||
loading=डालिंग...
|
loading=डालिंग...
|
||||||
addToDoc=Add to Document
|
addToDoc=Add to Document
|
||||||
reset=Reset
|
reset=Reset
|
||||||
apply=Apply
|
|
||||||
|
|
||||||
legal.privacy=गुप्तता सूचना
|
legal.privacy=गुप्तता सूचना
|
||||||
legal.terms=शर्तें और प्रवाह
|
legal.terms=शर्तें और प्रवाह
|
||||||
@@ -249,7 +248,6 @@ database.backupCreated=Database backup successful
|
|||||||
database.fileNotFound=File not Found
|
database.fileNotFound=File not Found
|
||||||
database.fileNullOrEmpty=File must not be null or empty
|
database.fileNullOrEmpty=File must not be null or empty
|
||||||
database.failedImportFile=Failed Import File
|
database.failedImportFile=Failed Import File
|
||||||
database.notSupported=This function is not available for your database connection.
|
|
||||||
|
|
||||||
session.expired=Your session has expired. Please refresh the page and try again.
|
session.expired=Your session has expired. Please refresh the page and try again.
|
||||||
session.refreshPage=Refresh Page
|
session.refreshPage=Refresh Page
|
||||||
@@ -476,10 +474,6 @@ home.autoRedact.title=स्वतः गोपनीयकरण
|
|||||||
home.autoRedact.desc=प्रविष्ट पाठ के आधार पर पीडीएफ़ में पाठ को स्वतः गोपनीयकरित(काला करें)
|
home.autoRedact.desc=प्रविष्ट पाठ के आधार पर पीडीएफ़ में पाठ को स्वतः गोपनीयकरित(काला करें)
|
||||||
autoRedact.tags=गोपनीयकरण, छिपाना, काला करना, काला, मार्कर, छिपा हुआ
|
autoRedact.tags=गोपनीयकरण, छिपाना, काला करना, काला, मार्कर, छिपा हुआ
|
||||||
|
|
||||||
home.redact.title=Manual Redaction
|
|
||||||
home.redact.desc=Redacts a PDF based on selected text, drawn shapes and/or selected page(s)
|
|
||||||
redact.tags=Redact,Hide,black out,black,marker,hidden,manual
|
|
||||||
|
|
||||||
home.tableExtraxt.title=PDF से CSV में
|
home.tableExtraxt.title=PDF से CSV में
|
||||||
home.tableExtraxt.desc=CSV में बदलते हुए पीडीएफ़ से तालिकाएँ निकालता है
|
home.tableExtraxt.desc=CSV में बदलते हुए पीडीएफ़ से तालिकाएँ निकालता है
|
||||||
tableExtraxt.tags=CSV, तालिका निकालना, निकालना, परिवर्तित करना
|
tableExtraxt.tags=CSV, तालिका निकालना, निकालना, परिवर्तित करना
|
||||||
@@ -585,31 +579,6 @@ autoRedact.customPaddingLabel=कस्टम अतिरिक्त पैड
|
|||||||
autoRedact.convertPDFToImageLabel=PDF को छवि में बदलें (बॉक्स के पीछे पाठ को हटाने के लिए प्रयोग किया जाता है)
|
autoRedact.convertPDFToImageLabel=PDF को छवि में बदलें (बॉक्स के पीछे पाठ को हटाने के लिए प्रयोग किया जाता है)
|
||||||
autoRedact.submitButton=प्रस्तुत करें
|
autoRedact.submitButton=प्रस्तुत करें
|
||||||
|
|
||||||
#redact
|
|
||||||
redact.title=Manual Redaction
|
|
||||||
redact.header=Manual Redaction
|
|
||||||
redact.submit=Redact
|
|
||||||
redact.textBasedRedaction=Text based Redaction
|
|
||||||
redact.pageBasedRedaction=Page-based Redaction
|
|
||||||
redact.convertPDFToImageLabel=Convert PDF to PDF-Image (Used to remove text behind the box)
|
|
||||||
redact.pageRedactionNumbers.title=Pages
|
|
||||||
redact.pageRedactionNumbers.placeholder=(e.g. 1,2,8 or 4,7,12-16 or 2n-1)
|
|
||||||
redact.redactionColor.title=Redaction Color
|
|
||||||
redact.export=Export
|
|
||||||
redact.upload=Upload
|
|
||||||
redact.boxRedaction=Box draw redaction
|
|
||||||
redact.zoom=Zoom
|
|
||||||
redact.zoomIn=Zoom in
|
|
||||||
redact.zoomOut=Zoom out
|
|
||||||
redact.nextPage=Next Page
|
|
||||||
redact.previousPage=Previous Page
|
|
||||||
redact.toggleSidebar=Toggle Sidebar
|
|
||||||
redact.showThumbnails=Show Thumbnails
|
|
||||||
redact.showDocumentOutline=Show Document Outline (double-click to expand/collapse all items)
|
|
||||||
redact.showAttatchments=Show Attachments
|
|
||||||
redact.showLayers=Show Layers (double-click to reset all layers to the default state)
|
|
||||||
redact.colourPicker=Colour Picker
|
|
||||||
redact.findCurrentOutlineItem=Find current outline item
|
|
||||||
|
|
||||||
#showJS
|
#showJS
|
||||||
showJS.title=जावास्क्रिप्ट दिखाएं
|
showJS.title=जावास्क्रिप्ट दिखाएं
|
||||||
@@ -863,8 +832,6 @@ sign.last=Last page
|
|||||||
sign.next=Next page
|
sign.next=Next page
|
||||||
sign.previous=Previous page
|
sign.previous=Previous page
|
||||||
sign.maintainRatio=Toggle maintain aspect ratio
|
sign.maintainRatio=Toggle maintain aspect ratio
|
||||||
|
|
||||||
|
|
||||||
#repair
|
#repair
|
||||||
repair.title=मरम्मत
|
repair.title=मरम्मत
|
||||||
repair.header=पीडीएफ़ मरम्मत करें
|
repair.header=पीडीएफ़ मरम्मत करें
|
||||||
|
|||||||
@@ -82,7 +82,6 @@ pages=Stranice
|
|||||||
loading=Učitavanje...
|
loading=Učitavanje...
|
||||||
addToDoc=Dodaj u dokument
|
addToDoc=Dodaj u dokument
|
||||||
reset=Reset
|
reset=Reset
|
||||||
apply=Apply
|
|
||||||
|
|
||||||
legal.privacy=Politika privatnosti
|
legal.privacy=Politika privatnosti
|
||||||
legal.terms=Uspe sodržine
|
legal.terms=Uspe sodržine
|
||||||
@@ -249,7 +248,6 @@ database.backupCreated=Database backup successful
|
|||||||
database.fileNotFound=File not Found
|
database.fileNotFound=File not Found
|
||||||
database.fileNullOrEmpty=Datoteka ne smije biti null ili prazna
|
database.fileNullOrEmpty=Datoteka ne smije biti null ili prazna
|
||||||
database.failedImportFile=Failed Import File
|
database.failedImportFile=Failed Import File
|
||||||
database.notSupported=This function is not available for your database connection.
|
|
||||||
|
|
||||||
session.expired=Vaš sesija je istekla. Molim vas da osvježite stranicu i pokušate ponovno.
|
session.expired=Vaš sesija je istekla. Molim vas da osvježite stranicu i pokušate ponovno.
|
||||||
session.refreshPage=Refresh Page
|
session.refreshPage=Refresh Page
|
||||||
@@ -476,10 +474,6 @@ home.autoRedact.title=Automatsko uređivanje
|
|||||||
home.autoRedact.desc=Automatski redigira (zacrni) tekst u PDF-u na temelju unosa teksta
|
home.autoRedact.desc=Automatski redigira (zacrni) tekst u PDF-u na temelju unosa teksta
|
||||||
autoRedact.tags=Cenzura,Sakrij,prekrivanje,crna,marker,skriveno
|
autoRedact.tags=Cenzura,Sakrij,prekrivanje,crna,marker,skriveno
|
||||||
|
|
||||||
home.redact.title=Manual Redaction
|
|
||||||
home.redact.desc=Redacts a PDF based on selected text, drawn shapes and/or selected page(s)
|
|
||||||
redact.tags=Redact,Hide,black out,black,marker,hidden,manual
|
|
||||||
|
|
||||||
home.tableExtraxt.title=PDF u CSV
|
home.tableExtraxt.title=PDF u CSV
|
||||||
home.tableExtraxt.desc=Izdvaja tablice iz PDF-a pretvarajući ga u CSV
|
home.tableExtraxt.desc=Izdvaja tablice iz PDF-a pretvarajući ga u CSV
|
||||||
tableExtraxt.tags=CSV,Izdvajanje tabela,izdvajanje,pretvaranje
|
tableExtraxt.tags=CSV,Izdvajanje tabela,izdvajanje,pretvaranje
|
||||||
@@ -585,31 +579,6 @@ autoRedact.customPaddingLabel=Dodatni prazan prostor
|
|||||||
autoRedact.convertPDFToImageLabel=Pretvorite PDF u PDF-sliku (koristi se za uklanjanje teksta iza okvira)
|
autoRedact.convertPDFToImageLabel=Pretvorite PDF u PDF-sliku (koristi se za uklanjanje teksta iza okvira)
|
||||||
autoRedact.submitButton=Potvrdi
|
autoRedact.submitButton=Potvrdi
|
||||||
|
|
||||||
#redact
|
|
||||||
redact.title=Manual Redaction
|
|
||||||
redact.header=Manual Redaction
|
|
||||||
redact.submit=Redact
|
|
||||||
redact.textBasedRedaction=Text based Redaction
|
|
||||||
redact.pageBasedRedaction=Page-based Redaction
|
|
||||||
redact.convertPDFToImageLabel=Convert PDF to PDF-Image (Used to remove text behind the box)
|
|
||||||
redact.pageRedactionNumbers.title=Pages
|
|
||||||
redact.pageRedactionNumbers.placeholder=(e.g. 1,2,8 or 4,7,12-16 or 2n-1)
|
|
||||||
redact.redactionColor.title=Redaction Color
|
|
||||||
redact.export=Export
|
|
||||||
redact.upload=Upload
|
|
||||||
redact.boxRedaction=Box draw redaction
|
|
||||||
redact.zoom=Zoom
|
|
||||||
redact.zoomIn=Zoom in
|
|
||||||
redact.zoomOut=Zoom out
|
|
||||||
redact.nextPage=Next Page
|
|
||||||
redact.previousPage=Previous Page
|
|
||||||
redact.toggleSidebar=Toggle Sidebar
|
|
||||||
redact.showThumbnails=Show Thumbnails
|
|
||||||
redact.showDocumentOutline=Show Document Outline (double-click to expand/collapse all items)
|
|
||||||
redact.showAttatchments=Show Attachments
|
|
||||||
redact.showLayers=Show Layers (double-click to reset all layers to the default state)
|
|
||||||
redact.colourPicker=Colour Picker
|
|
||||||
redact.findCurrentOutlineItem=Find current outline item
|
|
||||||
|
|
||||||
#showJS
|
#showJS
|
||||||
showJS.title=Prikaži Javascript
|
showJS.title=Prikaži Javascript
|
||||||
@@ -863,8 +832,6 @@ sign.last=Last page
|
|||||||
sign.next=Next page
|
sign.next=Next page
|
||||||
sign.previous=Previous page
|
sign.previous=Previous page
|
||||||
sign.maintainRatio=Toggle maintain aspect ratio
|
sign.maintainRatio=Toggle maintain aspect ratio
|
||||||
|
|
||||||
|
|
||||||
#repair
|
#repair
|
||||||
repair.title=Popravi
|
repair.title=Popravi
|
||||||
repair.header=Popravi PDF datoteku
|
repair.header=Popravi PDF datoteku
|
||||||
|
|||||||
@@ -82,7 +82,6 @@ pages=Oldalak
|
|||||||
loading=Betöltés...
|
loading=Betöltés...
|
||||||
addToDoc=Hozzáadás dokumentumba
|
addToDoc=Hozzáadás dokumentumba
|
||||||
reset=Reset
|
reset=Reset
|
||||||
apply=Apply
|
|
||||||
|
|
||||||
legal.privacy=Adatvédelmi nyilatkozat
|
legal.privacy=Adatvédelmi nyilatkozat
|
||||||
legal.terms=Feltételek és feltételek
|
legal.terms=Feltételek és feltételek
|
||||||
@@ -249,7 +248,6 @@ database.backupCreated=Database backup successful
|
|||||||
database.fileNotFound=File not Found
|
database.fileNotFound=File not Found
|
||||||
database.fileNullOrEmpty=Fájlnull vagy üres nélkül nem lehet folytatni
|
database.fileNullOrEmpty=Fájlnull vagy üres nélkül nem lehet folytatni
|
||||||
database.failedImportFile=Failed Import File
|
database.failedImportFile=Failed Import File
|
||||||
database.notSupported=This function is not available for your database connection.
|
|
||||||
|
|
||||||
session.expired=A munkamenet letelezett. Frissítse a lapot és próbálkozzon újra.
|
session.expired=A munkamenet letelezett. Frissítse a lapot és próbálkozzon újra.
|
||||||
session.refreshPage=Refresh Page
|
session.refreshPage=Refresh Page
|
||||||
@@ -476,10 +474,6 @@ home.autoRedact.title=Automatikus Elrejtés
|
|||||||
home.autoRedact.desc=Automatikusan kitakar (elrejt) szöveget egy PDF-ben az input szöveg alapján
|
home.autoRedact.desc=Automatikusan kitakar (elrejt) szöveget egy PDF-ben az input szöveg alapján
|
||||||
autoRedact.tags=Elrejt,Elrejtés,kitakarás,fekete,fekete,marker,elrejtett
|
autoRedact.tags=Elrejt,Elrejtés,kitakarás,fekete,fekete,marker,elrejtett
|
||||||
|
|
||||||
home.redact.title=Manual Redaction
|
|
||||||
home.redact.desc=Redacts a PDF based on selected text, drawn shapes and/or selected page(s)
|
|
||||||
redact.tags=Redact,Hide,black out,black,marker,hidden,manual
|
|
||||||
|
|
||||||
home.tableExtraxt.title=PDF-től CSV-be való átalakítás
|
home.tableExtraxt.title=PDF-től CSV-be való átalakítás
|
||||||
home.tableExtraxt.desc=Táblázatok kinyerése a PDF-ből CSV formátumra konvertálva
|
home.tableExtraxt.desc=Táblázatok kinyerése a PDF-ből CSV formátumra konvertálva
|
||||||
tableExtraxt.tags=CSV,Táblázat kinyerése,kinyer,konvertál
|
tableExtraxt.tags=CSV,Táblázat kinyerése,kinyer,konvertál
|
||||||
@@ -585,31 +579,6 @@ autoRedact.customPaddingLabel=Egyedi extra kitöltés
|
|||||||
autoRedact.convertPDFToImageLabel=PDF átalakítása PDF-képé (a doboz mögötti szöveg eltávolításához)
|
autoRedact.convertPDFToImageLabel=PDF átalakítása PDF-képé (a doboz mögötti szöveg eltávolításához)
|
||||||
autoRedact.submitButton=Elküld
|
autoRedact.submitButton=Elküld
|
||||||
|
|
||||||
#redact
|
|
||||||
redact.title=Manual Redaction
|
|
||||||
redact.header=Manual Redaction
|
|
||||||
redact.submit=Redact
|
|
||||||
redact.textBasedRedaction=Text based Redaction
|
|
||||||
redact.pageBasedRedaction=Page-based Redaction
|
|
||||||
redact.convertPDFToImageLabel=Convert PDF to PDF-Image (Used to remove text behind the box)
|
|
||||||
redact.pageRedactionNumbers.title=Pages
|
|
||||||
redact.pageRedactionNumbers.placeholder=(e.g. 1,2,8 or 4,7,12-16 or 2n-1)
|
|
||||||
redact.redactionColor.title=Redaction Color
|
|
||||||
redact.export=Export
|
|
||||||
redact.upload=Upload
|
|
||||||
redact.boxRedaction=Box draw redaction
|
|
||||||
redact.zoom=Zoom
|
|
||||||
redact.zoomIn=Zoom in
|
|
||||||
redact.zoomOut=Zoom out
|
|
||||||
redact.nextPage=Next Page
|
|
||||||
redact.previousPage=Previous Page
|
|
||||||
redact.toggleSidebar=Toggle Sidebar
|
|
||||||
redact.showThumbnails=Show Thumbnails
|
|
||||||
redact.showDocumentOutline=Show Document Outline (double-click to expand/collapse all items)
|
|
||||||
redact.showAttatchments=Show Attachments
|
|
||||||
redact.showLayers=Show Layers (double-click to reset all layers to the default state)
|
|
||||||
redact.colourPicker=Colour Picker
|
|
||||||
redact.findCurrentOutlineItem=Find current outline item
|
|
||||||
|
|
||||||
#showJS
|
#showJS
|
||||||
showJS.title=JavaScript megjelenítése
|
showJS.title=JavaScript megjelenítése
|
||||||
@@ -863,8 +832,6 @@ sign.last=Last page
|
|||||||
sign.next=Next page
|
sign.next=Next page
|
||||||
sign.previous=Previous page
|
sign.previous=Previous page
|
||||||
sign.maintainRatio=Toggle maintain aspect ratio
|
sign.maintainRatio=Toggle maintain aspect ratio
|
||||||
|
|
||||||
|
|
||||||
#repair
|
#repair
|
||||||
repair.title=Javítás
|
repair.title=Javítás
|
||||||
repair.header=PDF-ek javítása
|
repair.header=PDF-ek javítása
|
||||||
|
|||||||
@@ -82,7 +82,6 @@ pages=Halaman-halaman
|
|||||||
loading=Mengambil data...
|
loading=Mengambil data...
|
||||||
addToDoc=Tambahkan ke Dokumen
|
addToDoc=Tambahkan ke Dokumen
|
||||||
reset=Reset
|
reset=Reset
|
||||||
apply=Apply
|
|
||||||
|
|
||||||
legal.privacy=Kebijakan Privasi
|
legal.privacy=Kebijakan Privasi
|
||||||
legal.terms=Syarat dan Ketentuan
|
legal.terms=Syarat dan Ketentuan
|
||||||
@@ -249,7 +248,6 @@ database.backupCreated=Database backup successful
|
|||||||
database.fileNotFound=Berkas tidak Ditemukan
|
database.fileNotFound=Berkas tidak Ditemukan
|
||||||
database.fileNullOrEmpty=Berkas tidak boleh null atau kosong
|
database.fileNullOrEmpty=Berkas tidak boleh null atau kosong
|
||||||
database.failedImportFile=Impor Berkas Gagal
|
database.failedImportFile=Impor Berkas Gagal
|
||||||
database.notSupported=This function is not available for your database connection.
|
|
||||||
|
|
||||||
session.expired=Sesi Anda telah kedaluwarsa. Silakan muat ulang halaman dan coba lagi.
|
session.expired=Sesi Anda telah kedaluwarsa. Silakan muat ulang halaman dan coba lagi.
|
||||||
session.refreshPage=Refresh Page
|
session.refreshPage=Refresh Page
|
||||||
@@ -476,10 +474,6 @@ home.autoRedact.title=Redaksional Otomatis
|
|||||||
home.autoRedact.desc=Menyunting Otomatis (Menghitamkan) teks dalam PDF berdasarkan teks masukan
|
home.autoRedact.desc=Menyunting Otomatis (Menghitamkan) teks dalam PDF berdasarkan teks masukan
|
||||||
autoRedact.tags=Hapus, Sembunyikan, padamkan, hitam, hitam, penanda, tersembunyi
|
autoRedact.tags=Hapus, Sembunyikan, padamkan, hitam, hitam, penanda, tersembunyi
|
||||||
|
|
||||||
home.redact.title=Manual Redaction
|
|
||||||
home.redact.desc=Redacts a PDF based on selected text, drawn shapes and/or selected page(s)
|
|
||||||
redact.tags=Redact,Hide,black out,black,marker,hidden,manual
|
|
||||||
|
|
||||||
home.tableExtraxt.title=PDF ke CSV
|
home.tableExtraxt.title=PDF ke CSV
|
||||||
home.tableExtraxt.desc=Mengekstrak Tabel dari PDF yang mengonversinya menjadi CSV
|
home.tableExtraxt.desc=Mengekstrak Tabel dari PDF yang mengonversinya menjadi CSV
|
||||||
tableExtraxt.tags=CSV, Ekstraksi Tabel, ekstrak, konversi
|
tableExtraxt.tags=CSV, Ekstraksi Tabel, ekstrak, konversi
|
||||||
@@ -585,31 +579,6 @@ autoRedact.customPaddingLabel=Padding Ekstra Kustom
|
|||||||
autoRedact.convertPDFToImageLabel=Konversi PDF ke PDF-Gambar (Digunakan untuk menghapus teks di belakang kotak)
|
autoRedact.convertPDFToImageLabel=Konversi PDF ke PDF-Gambar (Digunakan untuk menghapus teks di belakang kotak)
|
||||||
autoRedact.submitButton=Kirim
|
autoRedact.submitButton=Kirim
|
||||||
|
|
||||||
#redact
|
|
||||||
redact.title=Manual Redaction
|
|
||||||
redact.header=Manual Redaction
|
|
||||||
redact.submit=Redact
|
|
||||||
redact.textBasedRedaction=Text based Redaction
|
|
||||||
redact.pageBasedRedaction=Page-based Redaction
|
|
||||||
redact.convertPDFToImageLabel=Convert PDF to PDF-Image (Used to remove text behind the box)
|
|
||||||
redact.pageRedactionNumbers.title=Pages
|
|
||||||
redact.pageRedactionNumbers.placeholder=(e.g. 1,2,8 or 4,7,12-16 or 2n-1)
|
|
||||||
redact.redactionColor.title=Redaction Color
|
|
||||||
redact.export=Export
|
|
||||||
redact.upload=Upload
|
|
||||||
redact.boxRedaction=Box draw redaction
|
|
||||||
redact.zoom=Zoom
|
|
||||||
redact.zoomIn=Zoom in
|
|
||||||
redact.zoomOut=Zoom out
|
|
||||||
redact.nextPage=Next Page
|
|
||||||
redact.previousPage=Previous Page
|
|
||||||
redact.toggleSidebar=Toggle Sidebar
|
|
||||||
redact.showThumbnails=Show Thumbnails
|
|
||||||
redact.showDocumentOutline=Show Document Outline (double-click to expand/collapse all items)
|
|
||||||
redact.showAttatchments=Show Attachments
|
|
||||||
redact.showLayers=Show Layers (double-click to reset all layers to the default state)
|
|
||||||
redact.colourPicker=Colour Picker
|
|
||||||
redact.findCurrentOutlineItem=Find current outline item
|
|
||||||
|
|
||||||
#showJS
|
#showJS
|
||||||
showJS.title=Tampilkan Javascript
|
showJS.title=Tampilkan Javascript
|
||||||
@@ -863,8 +832,6 @@ sign.last=Last page
|
|||||||
sign.next=Next page
|
sign.next=Next page
|
||||||
sign.previous=Previous page
|
sign.previous=Previous page
|
||||||
sign.maintainRatio=Toggle maintain aspect ratio
|
sign.maintainRatio=Toggle maintain aspect ratio
|
||||||
|
|
||||||
|
|
||||||
#repair
|
#repair
|
||||||
repair.title=Perbaiki
|
repair.title=Perbaiki
|
||||||
repair.header=Perbaiki PDF
|
repair.header=Perbaiki PDF
|
||||||
|
|||||||
@@ -81,8 +81,7 @@ page=Pagina
|
|||||||
pages=Pagine
|
pages=Pagine
|
||||||
loading=Caricamento...
|
loading=Caricamento...
|
||||||
addToDoc=Aggiungi al documento
|
addToDoc=Aggiungi al documento
|
||||||
reset=Resetta
|
reset=Reset
|
||||||
apply=Applica
|
|
||||||
|
|
||||||
legal.privacy=Informativa sulla privacy
|
legal.privacy=Informativa sulla privacy
|
||||||
legal.terms=Termini e Condizioni
|
legal.terms=Termini e Condizioni
|
||||||
@@ -245,11 +244,10 @@ database.info_1=Quando si importano i dati, è fondamentale garantire la struttu
|
|||||||
database.info_2=Il nome del file non ha importanza durante il caricamento. Verrà rinominato in seguito per seguire il formato backup_user__yyyyMMddHHmm.sql,garantendo una convenzione di denominazione coerente.
|
database.info_2=Il nome del file non ha importanza durante il caricamento. Verrà rinominato in seguito per seguire il formato backup_user__yyyyMMddHHmm.sql,garantendo una convenzione di denominazione coerente.
|
||||||
database.submit=Importa Backup
|
database.submit=Importa Backup
|
||||||
database.importIntoDatabaseSuccessed=L'importazione nel database è avvenuta con successo
|
database.importIntoDatabaseSuccessed=L'importazione nel database è avvenuta con successo
|
||||||
database.backupCreated=Backup del database riuscito
|
database.backupCreated=Database backup successful
|
||||||
database.fileNotFound=File non trovato
|
database.fileNotFound=File non trovato
|
||||||
database.fileNullOrEmpty=Il file non deve essere nullo o vuoto
|
database.fileNullOrEmpty=Il file non deve essere nullo o vuoto
|
||||||
database.failedImportFile=Importazione file non riuscita
|
database.failedImportFile=Importazione file non riuscita
|
||||||
database.notSupported=Questa funzione non è disponibile per la connessione al database.
|
|
||||||
|
|
||||||
session.expired=La tua sessione è scaduta. Aggiorna la pagina e riprova.
|
session.expired=La tua sessione è scaduta. Aggiorna la pagina e riprova.
|
||||||
session.refreshPage=Aggiorna pagina
|
session.refreshPage=Aggiorna pagina
|
||||||
@@ -476,10 +474,6 @@ home.autoRedact.title=Redazione automatica
|
|||||||
home.autoRedact.desc=Redige automaticamente (oscura) il testo in un PDF in base al testo immesso
|
home.autoRedact.desc=Redige automaticamente (oscura) il testo in un PDF in base al testo immesso
|
||||||
autoRedact.tags=Redigere,nascondere,oscurare,nero,pennarello,nascosto
|
autoRedact.tags=Redigere,nascondere,oscurare,nero,pennarello,nascosto
|
||||||
|
|
||||||
home.redact.title=Redazione manuale
|
|
||||||
home.redact.desc=Redige un PDF in base al testo selezionato, alle forme disegnate e/o alle pagina selezionata(e)
|
|
||||||
redact.tags=Redigere,nascondere,oscurare,nero,pennarello,nascosto,manuale
|
|
||||||
|
|
||||||
home.tableExtraxt.title=Da PDF a CSV
|
home.tableExtraxt.title=Da PDF a CSV
|
||||||
home.tableExtraxt.desc=Estrae tabelle da un PDF convertendolo in CSV
|
home.tableExtraxt.desc=Estrae tabelle da un PDF convertendolo in CSV
|
||||||
tableExtraxt.tags=CSV,Estrazione tabella,estrai,converti
|
tableExtraxt.tags=CSV,Estrazione tabella,estrai,converti
|
||||||
@@ -518,7 +512,7 @@ removeImagePdf.tags=Rimuovi immagine,operazioni sulla pagina,back-end,lato serve
|
|||||||
|
|
||||||
home.splitPdfByChapters.title=Dividi PDF per capitoli
|
home.splitPdfByChapters.title=Dividi PDF per capitoli
|
||||||
home.splitPdfByChapters.desc=Dividi un PDF in più file in base alla struttura dei capitoli.
|
home.splitPdfByChapters.desc=Dividi un PDF in più file in base alla struttura dei capitoli.
|
||||||
splitPdfByChapters.tags=dividi,capitoli,segnalibri,organizza
|
splitPdfByChapters.tags=dividi, capitoli, segnalibri, organizza
|
||||||
|
|
||||||
home.validateSignature.title=Convalida la firma PDF
|
home.validateSignature.title=Convalida la firma PDF
|
||||||
home.validateSignature.desc=Verificare le firme digitali e i certificati nei documenti PDF
|
home.validateSignature.desc=Verificare le firme digitali e i certificati nei documenti PDF
|
||||||
@@ -585,31 +579,6 @@ autoRedact.customPaddingLabel=Padding extra personalizzato
|
|||||||
autoRedact.convertPDFToImageLabel=Converti PDF in immagine PDF (utilizzato per rimuovere il testo dietro la casella)
|
autoRedact.convertPDFToImageLabel=Converti PDF in immagine PDF (utilizzato per rimuovere il testo dietro la casella)
|
||||||
autoRedact.submitButton=Invia
|
autoRedact.submitButton=Invia
|
||||||
|
|
||||||
#redact
|
|
||||||
redact.title=Redazione manuale
|
|
||||||
redact.header=Redazione manuale
|
|
||||||
redact.submit=Redazione
|
|
||||||
redact.textBasedRedaction=TRedazione basata sul testo
|
|
||||||
redact.pageBasedRedaction=Redazione basata sulla pagina
|
|
||||||
redact.convertPDFToImageLabel=Converti PDF in immagine PDF (utilizzato per rimuovere il testo dietro la casella)
|
|
||||||
redact.pageRedactionNumbers.title=Pagine
|
|
||||||
redact.pageRedactionNumbers.placeholder=(es. 1,2,8 o 4,7,12-16 o 2n-1)
|
|
||||||
redact.redactionColor.title=Colore di redazione
|
|
||||||
redact.export=Esporta
|
|
||||||
redact.upload=Caricamento
|
|
||||||
redact.boxRedaction=Redazione del disegno della casella
|
|
||||||
redact.zoom=Zoom
|
|
||||||
redact.zoomIn=Ingrandisci
|
|
||||||
redact.zoomOut=Rimpicciolisci
|
|
||||||
redact.nextPage=Pagina successiva
|
|
||||||
redact.previousPage=Pagina precedente
|
|
||||||
redact.toggleSidebar=Attiva barra laterale
|
|
||||||
redact.showThumbnails=Mostra miniature
|
|
||||||
redact.showDocumentOutline=Mostra struttura documento (fare doppio clic per espandere/comprimere tutti gli elementi)
|
|
||||||
redact.showAttatchments=Mostra allegati
|
|
||||||
redact.showLayers=Mostra livelli (fare doppio clic per ripristinare tutti i livelli allo stato predefinito)
|
|
||||||
redact.colourPicker=Selettore colore
|
|
||||||
redact.findCurrentOutlineItem=Trova l'elemento di contorno corrente
|
|
||||||
|
|
||||||
#showJS
|
#showJS
|
||||||
showJS.title=Mostra Javascript
|
showJS.title=Mostra Javascript
|
||||||
@@ -863,8 +832,6 @@ sign.last=Ultima pagina
|
|||||||
sign.next=Prossima pagina
|
sign.next=Prossima pagina
|
||||||
sign.previous=Pagina precedente
|
sign.previous=Pagina precedente
|
||||||
sign.maintainRatio=Attiva il mantenimento delle proporzioni
|
sign.maintainRatio=Attiva il mantenimento delle proporzioni
|
||||||
|
|
||||||
|
|
||||||
#repair
|
#repair
|
||||||
repair.title=Ripara
|
repair.title=Ripara
|
||||||
repair.header=Ripara PDF
|
repair.header=Ripara PDF
|
||||||
|
|||||||
@@ -82,7 +82,6 @@ pages=ページ
|
|||||||
loading=読込中...
|
loading=読込中...
|
||||||
addToDoc=ドキュメントに追加
|
addToDoc=ドキュメントに追加
|
||||||
reset=リセット
|
reset=リセット
|
||||||
apply=Apply
|
|
||||||
|
|
||||||
legal.privacy=プライバシーポリシー
|
legal.privacy=プライバシーポリシー
|
||||||
legal.terms=利用規約
|
legal.terms=利用規約
|
||||||
@@ -249,7 +248,6 @@ database.backupCreated=Database backup successful
|
|||||||
database.fileNotFound=ファイルが見つかりません
|
database.fileNotFound=ファイルが見つかりません
|
||||||
database.fileNullOrEmpty=ファイルは null または空であってはなりません
|
database.fileNullOrEmpty=ファイルは null または空であってはなりません
|
||||||
database.failedImportFile=ファイルのインポートに失敗
|
database.failedImportFile=ファイルのインポートに失敗
|
||||||
database.notSupported=This function is not available for your database connection.
|
|
||||||
|
|
||||||
session.expired=セッションが期限切れです。ページを更新してもう一度お試しください。
|
session.expired=セッションが期限切れです。ページを更新してもう一度お試しください。
|
||||||
session.refreshPage=ページを更新
|
session.refreshPage=ページを更新
|
||||||
@@ -476,10 +474,6 @@ home.autoRedact.title=自動塗りつぶし
|
|||||||
home.autoRedact.desc=入力したテキストに基づいてPDF内のテキストを自動で塗りつぶし(黒塗り)します。
|
home.autoRedact.desc=入力したテキストに基づいてPDF内のテキストを自動で塗りつぶし(黒塗り)します。
|
||||||
autoRedact.tags=Redact,Hide,black out,black,marker,hidden
|
autoRedact.tags=Redact,Hide,black out,black,marker,hidden
|
||||||
|
|
||||||
home.redact.title=Manual Redaction
|
|
||||||
home.redact.desc=Redacts a PDF based on selected text, drawn shapes and/or selected page(s)
|
|
||||||
redact.tags=Redact,Hide,black out,black,marker,hidden,manual
|
|
||||||
|
|
||||||
home.tableExtraxt.title=PDFをCSVに変換
|
home.tableExtraxt.title=PDFをCSVに変換
|
||||||
home.tableExtraxt.desc=PDFから表を抽出しCSVに変換します。
|
home.tableExtraxt.desc=PDFから表を抽出しCSVに変換します。
|
||||||
tableExtraxt.tags=CSV,Table Extraction,extract,convert
|
tableExtraxt.tags=CSV,Table Extraction,extract,convert
|
||||||
@@ -585,31 +579,6 @@ autoRedact.customPaddingLabel=追加の余白
|
|||||||
autoRedact.convertPDFToImageLabel=PDFをPDF画像に変換 (塗りつぶしの後ろのテキストを削除するために使用)
|
autoRedact.convertPDFToImageLabel=PDFをPDF画像に変換 (塗りつぶしの後ろのテキストを削除するために使用)
|
||||||
autoRedact.submitButton=送信
|
autoRedact.submitButton=送信
|
||||||
|
|
||||||
#redact
|
|
||||||
redact.title=Manual Redaction
|
|
||||||
redact.header=Manual Redaction
|
|
||||||
redact.submit=Redact
|
|
||||||
redact.textBasedRedaction=Text based Redaction
|
|
||||||
redact.pageBasedRedaction=Page-based Redaction
|
|
||||||
redact.convertPDFToImageLabel=Convert PDF to PDF-Image (Used to remove text behind the box)
|
|
||||||
redact.pageRedactionNumbers.title=Pages
|
|
||||||
redact.pageRedactionNumbers.placeholder=(e.g. 1,2,8 or 4,7,12-16 or 2n-1)
|
|
||||||
redact.redactionColor.title=Redaction Color
|
|
||||||
redact.export=Export
|
|
||||||
redact.upload=Upload
|
|
||||||
redact.boxRedaction=Box draw redaction
|
|
||||||
redact.zoom=Zoom
|
|
||||||
redact.zoomIn=Zoom in
|
|
||||||
redact.zoomOut=Zoom out
|
|
||||||
redact.nextPage=Next Page
|
|
||||||
redact.previousPage=Previous Page
|
|
||||||
redact.toggleSidebar=Toggle Sidebar
|
|
||||||
redact.showThumbnails=Show Thumbnails
|
|
||||||
redact.showDocumentOutline=Show Document Outline (double-click to expand/collapse all items)
|
|
||||||
redact.showAttatchments=Show Attachments
|
|
||||||
redact.showLayers=Show Layers (double-click to reset all layers to the default state)
|
|
||||||
redact.colourPicker=Colour Picker
|
|
||||||
redact.findCurrentOutlineItem=Find current outline item
|
|
||||||
|
|
||||||
#showJS
|
#showJS
|
||||||
showJS.title=Javascriptを表示
|
showJS.title=Javascriptを表示
|
||||||
@@ -863,8 +832,6 @@ sign.last=最後のページ
|
|||||||
sign.next=次のページ
|
sign.next=次のページ
|
||||||
sign.previous=前のページ
|
sign.previous=前のページ
|
||||||
sign.maintainRatio=Toggle maintain aspect ratio
|
sign.maintainRatio=Toggle maintain aspect ratio
|
||||||
|
|
||||||
|
|
||||||
#repair
|
#repair
|
||||||
repair.title=修復
|
repair.title=修復
|
||||||
repair.header=PDFを修復
|
repair.header=PDFを修復
|
||||||
|
|||||||
@@ -82,7 +82,6 @@ pages=페이지
|
|||||||
loading=로딩 중...
|
loading=로딩 중...
|
||||||
addToDoc=문서에 추가
|
addToDoc=문서에 추가
|
||||||
reset=Reset
|
reset=Reset
|
||||||
apply=Apply
|
|
||||||
|
|
||||||
legal.privacy=개인 정보 정책
|
legal.privacy=개인 정보 정책
|
||||||
legal.terms=이용 약관
|
legal.terms=이용 약관
|
||||||
@@ -249,7 +248,6 @@ database.backupCreated=Database backup successful
|
|||||||
database.fileNotFound=File not Found
|
database.fileNotFound=File not Found
|
||||||
database.fileNullOrEmpty=파일은 null이나 빈 상태로 될 수 없습니다
|
database.fileNullOrEmpty=파일은 null이나 빈 상태로 될 수 없습니다
|
||||||
database.failedImportFile=Failed Import File
|
database.failedImportFile=Failed Import File
|
||||||
database.notSupported=This function is not available for your database connection.
|
|
||||||
|
|
||||||
session.expired=세션이 만료되었습니다. 페이지를 새로 고침하고 다시 시도해 주세요.
|
session.expired=세션이 만료되었습니다. 페이지를 새로 고침하고 다시 시도해 주세요.
|
||||||
session.refreshPage=Refresh Page
|
session.refreshPage=Refresh Page
|
||||||
@@ -476,10 +474,6 @@ home.autoRedact.title=자동 검열
|
|||||||
home.autoRedact.desc=PDF 문서에서 입력된 텍스트들을 자동으로 검열(모자이크)합니다.
|
home.autoRedact.desc=PDF 문서에서 입력된 텍스트들을 자동으로 검열(모자이크)합니다.
|
||||||
autoRedact.tags=노출 방지, 숨기기, 검은색 처리, 마커, 숨김
|
autoRedact.tags=노출 방지, 숨기기, 검은색 처리, 마커, 숨김
|
||||||
|
|
||||||
home.redact.title=Manual Redaction
|
|
||||||
home.redact.desc=Redacts a PDF based on selected text, drawn shapes and/or selected page(s)
|
|
||||||
redact.tags=Redact,Hide,black out,black,marker,hidden,manual
|
|
||||||
|
|
||||||
home.tableExtraxt.title=PDF에서 CSV로
|
home.tableExtraxt.title=PDF에서 CSV로
|
||||||
home.tableExtraxt.desc=PDF에서 표를 추출하여 CSV로 변환
|
home.tableExtraxt.desc=PDF에서 표를 추출하여 CSV로 변환
|
||||||
tableExtraxt.tags=CSV, 테이블 추출, 추출, 변환
|
tableExtraxt.tags=CSV, 테이블 추출, 추출, 변환
|
||||||
@@ -585,31 +579,6 @@ autoRedact.customPaddingLabel=추가 윤곽(패딩)
|
|||||||
autoRedact.convertPDFToImageLabel=PDF 문서의 내용을 이미지로 변환 (검열 박스 뒤의 텍스트를 제거하는 데 사용됩니다.)
|
autoRedact.convertPDFToImageLabel=PDF 문서의 내용을 이미지로 변환 (검열 박스 뒤의 텍스트를 제거하는 데 사용됩니다.)
|
||||||
autoRedact.submitButton=적용
|
autoRedact.submitButton=적용
|
||||||
|
|
||||||
#redact
|
|
||||||
redact.title=Manual Redaction
|
|
||||||
redact.header=Manual Redaction
|
|
||||||
redact.submit=Redact
|
|
||||||
redact.textBasedRedaction=Text based Redaction
|
|
||||||
redact.pageBasedRedaction=Page-based Redaction
|
|
||||||
redact.convertPDFToImageLabel=Convert PDF to PDF-Image (Used to remove text behind the box)
|
|
||||||
redact.pageRedactionNumbers.title=Pages
|
|
||||||
redact.pageRedactionNumbers.placeholder=(e.g. 1,2,8 or 4,7,12-16 or 2n-1)
|
|
||||||
redact.redactionColor.title=Redaction Color
|
|
||||||
redact.export=Export
|
|
||||||
redact.upload=Upload
|
|
||||||
redact.boxRedaction=Box draw redaction
|
|
||||||
redact.zoom=Zoom
|
|
||||||
redact.zoomIn=Zoom in
|
|
||||||
redact.zoomOut=Zoom out
|
|
||||||
redact.nextPage=Next Page
|
|
||||||
redact.previousPage=Previous Page
|
|
||||||
redact.toggleSidebar=Toggle Sidebar
|
|
||||||
redact.showThumbnails=Show Thumbnails
|
|
||||||
redact.showDocumentOutline=Show Document Outline (double-click to expand/collapse all items)
|
|
||||||
redact.showAttatchments=Show Attachments
|
|
||||||
redact.showLayers=Show Layers (double-click to reset all layers to the default state)
|
|
||||||
redact.colourPicker=Colour Picker
|
|
||||||
redact.findCurrentOutlineItem=Find current outline item
|
|
||||||
|
|
||||||
#showJS
|
#showJS
|
||||||
showJS.title=JavaScript 보기
|
showJS.title=JavaScript 보기
|
||||||
@@ -863,8 +832,6 @@ sign.last=Last page
|
|||||||
sign.next=Next page
|
sign.next=Next page
|
||||||
sign.previous=Previous page
|
sign.previous=Previous page
|
||||||
sign.maintainRatio=Toggle maintain aspect ratio
|
sign.maintainRatio=Toggle maintain aspect ratio
|
||||||
|
|
||||||
|
|
||||||
#repair
|
#repair
|
||||||
repair.title=복구
|
repair.title=복구
|
||||||
repair.header=PDF 복구
|
repair.header=PDF 복구
|
||||||
|
|||||||
@@ -82,7 +82,6 @@ pages=Pagen
|
|||||||
loading=Laden...
|
loading=Laden...
|
||||||
addToDoc=Toevoegen aan document
|
addToDoc=Toevoegen aan document
|
||||||
reset=Reset
|
reset=Reset
|
||||||
apply=Apply
|
|
||||||
|
|
||||||
legal.privacy=Privacybeleid
|
legal.privacy=Privacybeleid
|
||||||
legal.terms=Voorwaarden van gebruik
|
legal.terms=Voorwaarden van gebruik
|
||||||
@@ -249,7 +248,6 @@ database.backupCreated=Database backup successful
|
|||||||
database.fileNotFound=File not Found
|
database.fileNotFound=File not Found
|
||||||
database.fileNullOrEmpty=Bestand mag niet null of leeg zijn
|
database.fileNullOrEmpty=Bestand mag niet null of leeg zijn
|
||||||
database.failedImportFile=Failed Import File
|
database.failedImportFile=Failed Import File
|
||||||
database.notSupported=This function is not available for your database connection.
|
|
||||||
|
|
||||||
session.expired=Je sessie is verlopen. Voer de pagina opnieuw in en probeer het opnieuw.
|
session.expired=Je sessie is verlopen. Voer de pagina opnieuw in en probeer het opnieuw.
|
||||||
session.refreshPage=Refresh Page
|
session.refreshPage=Refresh Page
|
||||||
@@ -476,10 +474,6 @@ home.autoRedact.title=Automatisch censureren
|
|||||||
home.autoRedact.desc=Automatisch censureren (onherkenbaar maken) van tekst in een PDF op basis van ingevoerde tekst
|
home.autoRedact.desc=Automatisch censureren (onherkenbaar maken) van tekst in een PDF op basis van ingevoerde tekst
|
||||||
autoRedact.tags=Verzwakken, Verbergen, Uitroepen, Gekleurd, Verborgen
|
autoRedact.tags=Verzwakken, Verbergen, Uitroepen, Gekleurd, Verborgen
|
||||||
|
|
||||||
home.redact.title=Manual Redaction
|
|
||||||
home.redact.desc=Redacts a PDF based on selected text, drawn shapes and/or selected page(s)
|
|
||||||
redact.tags=Redact,Hide,black out,black,marker,hidden,manual
|
|
||||||
|
|
||||||
home.tableExtraxt.title=PDF naar CSV
|
home.tableExtraxt.title=PDF naar CSV
|
||||||
home.tableExtraxt.desc=Haalt tabellen uit een PDF en converteert ze naar CSV
|
home.tableExtraxt.desc=Haalt tabellen uit een PDF en converteert ze naar CSV
|
||||||
tableExtraxt.tags=CSV,tabel extractie,extractie,converteren
|
tableExtraxt.tags=CSV,tabel extractie,extractie,converteren
|
||||||
@@ -585,31 +579,6 @@ autoRedact.customPaddingLabel=Aangepaste extra ruimtevulling
|
|||||||
autoRedact.convertPDFToImageLabel=Converteer PDF naar PDF-afbeelding (wordt gebruikt om tekst achter het vak te verwijderen)
|
autoRedact.convertPDFToImageLabel=Converteer PDF naar PDF-afbeelding (wordt gebruikt om tekst achter het vak te verwijderen)
|
||||||
autoRedact.submitButton=Indienen
|
autoRedact.submitButton=Indienen
|
||||||
|
|
||||||
#redact
|
|
||||||
redact.title=Manual Redaction
|
|
||||||
redact.header=Manual Redaction
|
|
||||||
redact.submit=Redact
|
|
||||||
redact.textBasedRedaction=Text based Redaction
|
|
||||||
redact.pageBasedRedaction=Page-based Redaction
|
|
||||||
redact.convertPDFToImageLabel=Convert PDF to PDF-Image (Used to remove text behind the box)
|
|
||||||
redact.pageRedactionNumbers.title=Pages
|
|
||||||
redact.pageRedactionNumbers.placeholder=(e.g. 1,2,8 or 4,7,12-16 or 2n-1)
|
|
||||||
redact.redactionColor.title=Redaction Color
|
|
||||||
redact.export=Export
|
|
||||||
redact.upload=Upload
|
|
||||||
redact.boxRedaction=Box draw redaction
|
|
||||||
redact.zoom=Zoom
|
|
||||||
redact.zoomIn=Zoom in
|
|
||||||
redact.zoomOut=Zoom out
|
|
||||||
redact.nextPage=Next Page
|
|
||||||
redact.previousPage=Previous Page
|
|
||||||
redact.toggleSidebar=Toggle Sidebar
|
|
||||||
redact.showThumbnails=Show Thumbnails
|
|
||||||
redact.showDocumentOutline=Show Document Outline (double-click to expand/collapse all items)
|
|
||||||
redact.showAttatchments=Show Attachments
|
|
||||||
redact.showLayers=Show Layers (double-click to reset all layers to the default state)
|
|
||||||
redact.colourPicker=Colour Picker
|
|
||||||
redact.findCurrentOutlineItem=Find current outline item
|
|
||||||
|
|
||||||
#showJS
|
#showJS
|
||||||
showJS.title=Toon Javascript
|
showJS.title=Toon Javascript
|
||||||
@@ -863,8 +832,6 @@ sign.last=Last page
|
|||||||
sign.next=Next page
|
sign.next=Next page
|
||||||
sign.previous=Previous page
|
sign.previous=Previous page
|
||||||
sign.maintainRatio=Toggle maintain aspect ratio
|
sign.maintainRatio=Toggle maintain aspect ratio
|
||||||
|
|
||||||
|
|
||||||
#repair
|
#repair
|
||||||
repair.title=Repareren
|
repair.title=Repareren
|
||||||
repair.header=PDF's repareren
|
repair.header=PDF's repareren
|
||||||
|
|||||||
@@ -82,7 +82,6 @@ pages=Pages
|
|||||||
loading=Loading...
|
loading=Loading...
|
||||||
addToDoc=Add to Document
|
addToDoc=Add to Document
|
||||||
reset=Reset
|
reset=Reset
|
||||||
apply=Apply
|
|
||||||
|
|
||||||
legal.privacy=Privacy Policy
|
legal.privacy=Privacy Policy
|
||||||
legal.terms=Terms and Conditions
|
legal.terms=Terms and Conditions
|
||||||
@@ -249,7 +248,6 @@ database.backupCreated=Database backup successful
|
|||||||
database.fileNotFound=Fil ikke funnet
|
database.fileNotFound=Fil ikke funnet
|
||||||
database.fileNullOrEmpty=Fil må ikke være tom eller null
|
database.fileNullOrEmpty=Fil må ikke være tom eller null
|
||||||
database.failedImportFile=Import av fil mislyktes
|
database.failedImportFile=Import av fil mislyktes
|
||||||
database.notSupported=This function is not available for your database connection.
|
|
||||||
|
|
||||||
session.expired=Your session has expired. Please refresh the page and try again.
|
session.expired=Your session has expired. Please refresh the page and try again.
|
||||||
session.refreshPage=Refresh Page
|
session.refreshPage=Refresh Page
|
||||||
@@ -476,10 +474,6 @@ home.autoRedact.title=Automatisk Sensurering
|
|||||||
home.autoRedact.desc=Automatisk sensurering (sverter ut) tekst i en PDF basert på inntastet tekst
|
home.autoRedact.desc=Automatisk sensurering (sverter ut) tekst i en PDF basert på inntastet tekst
|
||||||
autoRedact.tags=Sensurere,Skjule,sverte ut,svart,markør,skjult
|
autoRedact.tags=Sensurere,Skjule,sverte ut,svart,markør,skjult
|
||||||
|
|
||||||
home.redact.title=Manual Redaction
|
|
||||||
home.redact.desc=Redacts a PDF based on selected text, drawn shapes and/or selected page(s)
|
|
||||||
redact.tags=Redact,Hide,black out,black,marker,hidden,manual
|
|
||||||
|
|
||||||
home.tableExtraxt.title=PDF til CSV
|
home.tableExtraxt.title=PDF til CSV
|
||||||
home.tableExtraxt.desc=Ekstraherer tabeller fra en PDF og konverterer dem til CSV
|
home.tableExtraxt.desc=Ekstraherer tabeller fra en PDF og konverterer dem til CSV
|
||||||
tableExtraxt.tags=CSV,tabelluttrekk,ekstrahere,konvertere
|
tableExtraxt.tags=CSV,tabelluttrekk,ekstrahere,konvertere
|
||||||
@@ -585,31 +579,6 @@ autoRedact.customPaddingLabel=Tilpasset ekstra polstring
|
|||||||
autoRedact.convertPDFToImageLabel=Konverter PDF til PDF-bilde (Brukes for å fjerne tekst bak boksen)
|
autoRedact.convertPDFToImageLabel=Konverter PDF til PDF-bilde (Brukes for å fjerne tekst bak boksen)
|
||||||
autoRedact.submitButton=Send inn
|
autoRedact.submitButton=Send inn
|
||||||
|
|
||||||
#redact
|
|
||||||
redact.title=Manual Redaction
|
|
||||||
redact.header=Manual Redaction
|
|
||||||
redact.submit=Redact
|
|
||||||
redact.textBasedRedaction=Text based Redaction
|
|
||||||
redact.pageBasedRedaction=Page-based Redaction
|
|
||||||
redact.convertPDFToImageLabel=Convert PDF to PDF-Image (Used to remove text behind the box)
|
|
||||||
redact.pageRedactionNumbers.title=Pages
|
|
||||||
redact.pageRedactionNumbers.placeholder=(e.g. 1,2,8 or 4,7,12-16 or 2n-1)
|
|
||||||
redact.redactionColor.title=Redaction Color
|
|
||||||
redact.export=Export
|
|
||||||
redact.upload=Upload
|
|
||||||
redact.boxRedaction=Box draw redaction
|
|
||||||
redact.zoom=Zoom
|
|
||||||
redact.zoomIn=Zoom in
|
|
||||||
redact.zoomOut=Zoom out
|
|
||||||
redact.nextPage=Next Page
|
|
||||||
redact.previousPage=Previous Page
|
|
||||||
redact.toggleSidebar=Toggle Sidebar
|
|
||||||
redact.showThumbnails=Show Thumbnails
|
|
||||||
redact.showDocumentOutline=Show Document Outline (double-click to expand/collapse all items)
|
|
||||||
redact.showAttatchments=Show Attachments
|
|
||||||
redact.showLayers=Show Layers (double-click to reset all layers to the default state)
|
|
||||||
redact.colourPicker=Colour Picker
|
|
||||||
redact.findCurrentOutlineItem=Find current outline item
|
|
||||||
|
|
||||||
#showJS
|
#showJS
|
||||||
showJS.title=Vis Javascript
|
showJS.title=Vis Javascript
|
||||||
@@ -863,8 +832,6 @@ sign.last=Last page
|
|||||||
sign.next=Next page
|
sign.next=Next page
|
||||||
sign.previous=Previous page
|
sign.previous=Previous page
|
||||||
sign.maintainRatio=Toggle maintain aspect ratio
|
sign.maintainRatio=Toggle maintain aspect ratio
|
||||||
|
|
||||||
|
|
||||||
#repair
|
#repair
|
||||||
repair.title=Reparer
|
repair.title=Reparer
|
||||||
repair.header=Reparer PDF-er
|
repair.header=Reparer PDF-er
|
||||||
|
|||||||
@@ -82,7 +82,6 @@ pages=Strony
|
|||||||
loading=Loading...
|
loading=Loading...
|
||||||
addToDoc=Add to Document
|
addToDoc=Add to Document
|
||||||
reset=Reset
|
reset=Reset
|
||||||
apply=Apply
|
|
||||||
|
|
||||||
legal.privacy=Polityka Prywatności
|
legal.privacy=Polityka Prywatności
|
||||||
legal.terms=Zasady i Postanowienia
|
legal.terms=Zasady i Postanowienia
|
||||||
@@ -249,7 +248,6 @@ database.backupCreated=Database backup successful
|
|||||||
database.fileNotFound=Plik nie znaleziony
|
database.fileNotFound=Plik nie znaleziony
|
||||||
database.fileNullOrEmpty=Plik nie może być pusty
|
database.fileNullOrEmpty=Plik nie może być pusty
|
||||||
database.failedImportFile=Nie udało się zaimportować pliku
|
database.failedImportFile=Nie udało się zaimportować pliku
|
||||||
database.notSupported=This function is not available for your database connection.
|
|
||||||
|
|
||||||
session.expired=Twoja sesja wygasła. Odśwież stronę i spróbuj ponownie.
|
session.expired=Twoja sesja wygasła. Odśwież stronę i spróbuj ponownie.
|
||||||
session.refreshPage=Refresh Page
|
session.refreshPage=Refresh Page
|
||||||
@@ -476,10 +474,6 @@ home.autoRedact.title=Zaciemnij
|
|||||||
home.autoRedact.desc=Zaciemnia dokument PDF bazując na podanej wartości
|
home.autoRedact.desc=Zaciemnia dokument PDF bazując na podanej wartości
|
||||||
autoRedact.tags=Redagowanie, ukrywanie, zaciemnianie, zaczernianie, zaznaczanie, ukrywanie
|
autoRedact.tags=Redagowanie, ukrywanie, zaciemnianie, zaczernianie, zaznaczanie, ukrywanie
|
||||||
|
|
||||||
home.redact.title=Manual Redaction
|
|
||||||
home.redact.desc=Redacts a PDF based on selected text, drawn shapes and/or selected page(s)
|
|
||||||
redact.tags=Redact,Hide,black out,black,marker,hidden,manual
|
|
||||||
|
|
||||||
home.tableExtraxt.title=PDF do CSV
|
home.tableExtraxt.title=PDF do CSV
|
||||||
home.tableExtraxt.desc=Konwertuje tabele z PDF do pliku CSV
|
home.tableExtraxt.desc=Konwertuje tabele z PDF do pliku CSV
|
||||||
tableExtraxt.tags=CSV, ekstrakcja tabeli, ekstrakcja, konwersja, wydobywanie
|
tableExtraxt.tags=CSV, ekstrakcja tabeli, ekstrakcja, konwersja, wydobywanie
|
||||||
@@ -585,31 +579,6 @@ autoRedact.customPaddingLabel=Dodatkowe wypełnienie
|
|||||||
autoRedact.convertPDFToImageLabel=Przerób PDF na PDF-obrazowy (usuwa tekst w tle)
|
autoRedact.convertPDFToImageLabel=Przerób PDF na PDF-obrazowy (usuwa tekst w tle)
|
||||||
autoRedact.submitButton=Wyślij
|
autoRedact.submitButton=Wyślij
|
||||||
|
|
||||||
#redact
|
|
||||||
redact.title=Manual Redaction
|
|
||||||
redact.header=Manual Redaction
|
|
||||||
redact.submit=Redact
|
|
||||||
redact.textBasedRedaction=Text based Redaction
|
|
||||||
redact.pageBasedRedaction=Page-based Redaction
|
|
||||||
redact.convertPDFToImageLabel=Convert PDF to PDF-Image (Used to remove text behind the box)
|
|
||||||
redact.pageRedactionNumbers.title=Pages
|
|
||||||
redact.pageRedactionNumbers.placeholder=(e.g. 1,2,8 or 4,7,12-16 or 2n-1)
|
|
||||||
redact.redactionColor.title=Redaction Color
|
|
||||||
redact.export=Export
|
|
||||||
redact.upload=Upload
|
|
||||||
redact.boxRedaction=Box draw redaction
|
|
||||||
redact.zoom=Zoom
|
|
||||||
redact.zoomIn=Zoom in
|
|
||||||
redact.zoomOut=Zoom out
|
|
||||||
redact.nextPage=Next Page
|
|
||||||
redact.previousPage=Previous Page
|
|
||||||
redact.toggleSidebar=Toggle Sidebar
|
|
||||||
redact.showThumbnails=Show Thumbnails
|
|
||||||
redact.showDocumentOutline=Show Document Outline (double-click to expand/collapse all items)
|
|
||||||
redact.showAttatchments=Show Attachments
|
|
||||||
redact.showLayers=Show Layers (double-click to reset all layers to the default state)
|
|
||||||
redact.colourPicker=Colour Picker
|
|
||||||
redact.findCurrentOutlineItem=Find current outline item
|
|
||||||
|
|
||||||
#showJS
|
#showJS
|
||||||
showJS.title=Pokaż Javascript
|
showJS.title=Pokaż Javascript
|
||||||
@@ -863,8 +832,6 @@ sign.last=Last page
|
|||||||
sign.next=Next page
|
sign.next=Next page
|
||||||
sign.previous=Previous page
|
sign.previous=Previous page
|
||||||
sign.maintainRatio=Toggle maintain aspect ratio
|
sign.maintainRatio=Toggle maintain aspect ratio
|
||||||
|
|
||||||
|
|
||||||
#repair
|
#repair
|
||||||
repair.title=Napraw
|
repair.title=Napraw
|
||||||
repair.header=Napraw dokument(y) PDF
|
repair.header=Napraw dokument(y) PDF
|
||||||
|
|||||||
@@ -82,7 +82,6 @@ pages=Páginas
|
|||||||
loading=Carregando...
|
loading=Carregando...
|
||||||
addToDoc=Adicionar ao Documento
|
addToDoc=Adicionar ao Documento
|
||||||
reset=Reiniciar
|
reset=Reiniciar
|
||||||
apply=Aplicar
|
|
||||||
|
|
||||||
legal.privacy=Política de Privacidade
|
legal.privacy=Política de Privacidade
|
||||||
legal.terms=Termos e Condições
|
legal.terms=Termos e Condições
|
||||||
@@ -94,7 +93,7 @@ legal.impressum=Informações legais
|
|||||||
# Pipeline #
|
# Pipeline #
|
||||||
###############
|
###############
|
||||||
pipeline.header=Menu do Pipeline (Beta)
|
pipeline.header=Menu do Pipeline (Beta)
|
||||||
pipeline.uploadButton=Carregar Arquivo Personalizado
|
pipeline.uploadButton=Upload de Arquivo Personalizado
|
||||||
pipeline.configureButton=Configurar
|
pipeline.configureButton=Configurar
|
||||||
pipeline.defaultOption=Arquivo Personalizado
|
pipeline.defaultOption=Arquivo Personalizado
|
||||||
pipeline.submitButton=Enviar
|
pipeline.submitButton=Enviar
|
||||||
@@ -249,7 +248,6 @@ database.backupCreated=Database backup successful
|
|||||||
database.fileNotFound=Arquivo não encontrado
|
database.fileNotFound=Arquivo não encontrado
|
||||||
database.fileNullOrEmpty=O arquivo não pode estar nulo ou vazio
|
database.fileNullOrEmpty=O arquivo não pode estar nulo ou vazio
|
||||||
database.failedImportFile=Falha ao importar arquivo
|
database.failedImportFile=Falha ao importar arquivo
|
||||||
database.notSupported=Esta função não está disponível para sua conexão de banco de dados.
|
|
||||||
|
|
||||||
session.expired=Sua sessão expirou. Por gentileza atualize a página e tente novamente.
|
session.expired=Sua sessão expirou. Por gentileza atualize a página e tente novamente.
|
||||||
session.refreshPage=Atualizar Página
|
session.refreshPage=Atualizar Página
|
||||||
@@ -472,14 +470,10 @@ home.showJS.title=Mostrar Javascript
|
|||||||
home.showJS.desc=Procura, exibe e extrai qualquer JavaScript injetado em um PDF.
|
home.showJS.desc=Procura, exibe e extrai qualquer JavaScript injetado em um PDF.
|
||||||
showJS.tags=JavaScript
|
showJS.tags=JavaScript
|
||||||
|
|
||||||
home.autoRedact.title=Ocultação de Texto Automática
|
home.autoRedact.title=Ocultação de Texto
|
||||||
home.autoRedact.desc=Ocultação automática (escurecimento) de texto em um PDF com base em texto de entrada.
|
home.autoRedact.desc=Ocultação automática (escurecimento) de texto em um PDF com base em texto de entrada.
|
||||||
autoRedact.tags=Redigir,ocultar,escurecer,preto,marcador,oculto
|
autoRedact.tags=Redigir,ocultar,escurecer,preto,marcador,oculto
|
||||||
|
|
||||||
home.redact.title=Ocultação de Texto Manual
|
|
||||||
home.redact.desc=Ocultação de texto manual baseada em um texto selecionado, desenho de formas ou/e páginas selecionadas.
|
|
||||||
redact.tags=Redigir,ocultar,escurecer,preto,marcador,oculto,manual
|
|
||||||
|
|
||||||
home.tableExtraxt.title=PDF para CSV
|
home.tableExtraxt.title=PDF para CSV
|
||||||
home.tableExtraxt.desc=Extração de tabelas de um PDF convertendo para CSV.
|
home.tableExtraxt.desc=Extração de tabelas de um PDF convertendo para CSV.
|
||||||
tableExtraxt.tags=CSV,extração de tabela,extrair,converter
|
tableExtraxt.tags=CSV,extração de tabela,extrair,converter
|
||||||
@@ -567,15 +561,15 @@ login.oauth2invalidRequest=Requisição Inválida
|
|||||||
login.oauth2AccessDenied=Acesso Negado
|
login.oauth2AccessDenied=Acesso Negado
|
||||||
login.oauth2InvalidTokenResponse=Resposta de Token Inválida
|
login.oauth2InvalidTokenResponse=Resposta de Token Inválida
|
||||||
login.oauth2InvalidIdToken=Id de Token Inválido
|
login.oauth2InvalidIdToken=Id de Token Inválido
|
||||||
login.relyingPartyRegistrationNotFound=Nenhum registro de parte confiável (RP) encontrado
|
login.relyingPartyRegistrationNotFound=No relying party registration found
|
||||||
login.userIsDisabled=O usuário está desativado, o login está atualmente bloqueado com este nome de usuário. Entre em contato com o administrador.
|
login.userIsDisabled=O usuário está desativado, o login está atualmente bloqueado com este nome de usuário. Entre em contato com o administrador.
|
||||||
login.alreadyLoggedIn=Você já está conectado em
|
login.alreadyLoggedIn=Você já está conectado em
|
||||||
login.alreadyLoggedIn2=aparelhos. Por favor saia dos aparelhos e tente novamente.
|
login.alreadyLoggedIn2=aparelhos. Por favor saia dos aparelhos e tente novamente.
|
||||||
login.toManySessions=Você tem muitas sessões ativas
|
login.toManySessions=Você tem muitas sessões ativas
|
||||||
|
|
||||||
#auto-redact
|
#auto-redact
|
||||||
autoRedact.title=Ocultação de Texto Automática
|
autoRedact.title=Ocultação de Texto
|
||||||
autoRedact.header=Ocultação de Texto Automática
|
autoRedact.header=Ocultação de Texto
|
||||||
autoRedact.colorLabel=Cor:
|
autoRedact.colorLabel=Cor:
|
||||||
autoRedact.textsToRedactLabel=Texto para ocultar (um por linha):
|
autoRedact.textsToRedactLabel=Texto para ocultar (um por linha):
|
||||||
autoRedact.textsToRedactPlaceholder=Por exemplo: \nConfidencial \nSecreto
|
autoRedact.textsToRedactPlaceholder=Por exemplo: \nConfidencial \nSecreto
|
||||||
@@ -583,33 +577,8 @@ autoRedact.useRegexLabel=Usar Regex (expressão regular).
|
|||||||
autoRedact.wholeWordSearchLabel=Pesquisa apenas palavras inteiras.
|
autoRedact.wholeWordSearchLabel=Pesquisa apenas palavras inteiras.
|
||||||
autoRedact.customPaddingLabel=Preenchimento extra personalizado:
|
autoRedact.customPaddingLabel=Preenchimento extra personalizado:
|
||||||
autoRedact.convertPDFToImageLabel=Converter PDF em imagem PDF (Usado para remover o texto atrás da caixa).
|
autoRedact.convertPDFToImageLabel=Converter PDF em imagem PDF (Usado para remover o texto atrás da caixa).
|
||||||
autoRedact.submitButton=Ocultar
|
autoRedact.submitButton=Enviar
|
||||||
|
|
||||||
#redact
|
|
||||||
redact.title=Ocultação de Texto Manual
|
|
||||||
redact.header=Ocultação de Texto Manual
|
|
||||||
redact.submit=Ocultar
|
|
||||||
redact.textBasedRedaction=Ocultação baseada em texto
|
|
||||||
redact.pageBasedRedaction=Ocultação baseada em páginas
|
|
||||||
redact.convertPDFToImageLabel=Converter PDF para PDF-Imagem (Utilizado para remover texto atrás da seleção)
|
|
||||||
redact.pageRedactionNumbers.title=Páginas
|
|
||||||
redact.pageRedactionNumbers.placeholder=(p.ex. 1,2,8 ou 4,7,12-16 ou 2n-1)
|
|
||||||
redact.redactionColor.title=Cor da Ocultação
|
|
||||||
redact.export=Exportar
|
|
||||||
redact.upload=Carregar
|
|
||||||
redact.boxRedaction=Ocultação baseada em formas
|
|
||||||
redact.zoom=Zoom
|
|
||||||
redact.zoomIn=Ampliar
|
|
||||||
redact.zoomOut=Reduzir
|
|
||||||
redact.nextPage=Proxima Página
|
|
||||||
redact.previousPage=Página Anterior
|
|
||||||
redact.toggleSidebar=Mostrar/Ocultar Barra Lateral
|
|
||||||
redact.showThumbnails=Mostrar Miniaturas
|
|
||||||
redact.showDocumentOutline=Mostrar Estrutura do Documento (duplo clique para expandir/recolher todos os itens)
|
|
||||||
redact.showAttatchments=Mostrar Anexos
|
|
||||||
redact.showLayers=Mostrar Camadas (duplo clique para restabelecer as camadas para o estado padrão)
|
|
||||||
redact.colourPicker=Seletor de Cores
|
|
||||||
redact.findCurrentOutlineItem=Encontrar item atual
|
|
||||||
|
|
||||||
#showJS
|
#showJS
|
||||||
showJS.title=Mostrar JavaScript
|
showJS.title=Mostrar JavaScript
|
||||||
@@ -846,7 +815,7 @@ PDFToBook.submit=Converter
|
|||||||
#sign
|
#sign
|
||||||
sign.title=Assinar
|
sign.title=Assinar
|
||||||
sign.header=Assinar
|
sign.header=Assinar
|
||||||
sign.upload=Carregar Imagem
|
sign.upload=Enviar Imagem
|
||||||
sign.draw=Desenhar Assinatura
|
sign.draw=Desenhar Assinatura
|
||||||
sign.text=Inserir Texto
|
sign.text=Inserir Texto
|
||||||
sign.clear=Limpar
|
sign.clear=Limpar
|
||||||
@@ -862,9 +831,7 @@ sign.first=Primeira página
|
|||||||
sign.last=Última página
|
sign.last=Última página
|
||||||
sign.next=Próxima página
|
sign.next=Próxima página
|
||||||
sign.previous=Página anterior
|
sign.previous=Página anterior
|
||||||
sign.maintainRatio=Habilitar manter proporção
|
sign.maintainRatio=Toggle maintain aspect ratio
|
||||||
|
|
||||||
|
|
||||||
#repair
|
#repair
|
||||||
repair.title=Reparar
|
repair.title=Reparar
|
||||||
repair.header=Reparar
|
repair.header=Reparar
|
||||||
@@ -945,7 +912,7 @@ compress.submit=Comprimir
|
|||||||
addImage.title=Adicionar Imagem
|
addImage.title=Adicionar Imagem
|
||||||
addImage.header=Adicionar Imagem
|
addImage.header=Adicionar Imagem
|
||||||
addImage.everyPage=Para cada página?
|
addImage.everyPage=Para cada página?
|
||||||
addImage.upload=Carregar imagem
|
addImage.upload=Enviar imagem
|
||||||
addImage.submit=Adicionar imagem
|
addImage.submit=Adicionar imagem
|
||||||
|
|
||||||
|
|
||||||
@@ -1075,7 +1042,7 @@ pdfToImage.grey=Escala de Cinza
|
|||||||
pdfToImage.blackwhite=Preto e Branco (pode perder informações!)
|
pdfToImage.blackwhite=Preto e Branco (pode perder informações!)
|
||||||
pdfToImage.submit=Converter
|
pdfToImage.submit=Converter
|
||||||
pdfToImage.info=Python não está instalado. Necessário para conversão WebP.
|
pdfToImage.info=Python não está instalado. Necessário para conversão WebP.
|
||||||
pdfToImage.placeholder=(por exemplo 1,2,8 ou 4,7,12-16 ou 2n-1)
|
pdfToImage.placeholder=(por exemplo 1,2,8 or 4,7,12-16 ou 2n-1)
|
||||||
|
|
||||||
|
|
||||||
#addPassword
|
#addPassword
|
||||||
@@ -1319,8 +1286,8 @@ splitByChapters.submit=Dividir
|
|||||||
fileChooser.click=Clique
|
fileChooser.click=Clique
|
||||||
fileChooser.or=ou
|
fileChooser.or=ou
|
||||||
fileChooser.dragAndDrop=Arraste & Solte
|
fileChooser.dragAndDrop=Arraste & Solte
|
||||||
fileChooser.dragAndDropPDF=Arraste & Solte PDF(s)
|
fileChooser.dragAndDropPDF=Drag & Drop PDF file
|
||||||
fileChooser.dragAndDropImage=Arraste & Solte Imagem(ns)
|
fileChooser.dragAndDropImage=Drag & Drop Image file
|
||||||
fileChooser.hoveredDragAndDrop=Arraste & Solte arquivo(s) aqui
|
fileChooser.hoveredDragAndDrop=Arraste & Solte arquivo(s) aqui
|
||||||
|
|
||||||
#release notes
|
#release notes
|
||||||
|
|||||||
@@ -82,7 +82,6 @@ pages=Páginas
|
|||||||
loading=A carregar...
|
loading=A carregar...
|
||||||
addToDoc=Adicionar ao Documento
|
addToDoc=Adicionar ao Documento
|
||||||
reset=Reset
|
reset=Reset
|
||||||
apply=Apply
|
|
||||||
|
|
||||||
legal.privacy=Política de Privacidade
|
legal.privacy=Política de Privacidade
|
||||||
legal.terms=Termos e Condições
|
legal.terms=Termos e Condições
|
||||||
@@ -249,7 +248,6 @@ database.backupCreated=Database backup successful
|
|||||||
database.fileNotFound=File not Found
|
database.fileNotFound=File not Found
|
||||||
database.fileNullOrEmpty=O ficheiro não pode ser nulo ou vazio
|
database.fileNullOrEmpty=O ficheiro não pode ser nulo ou vazio
|
||||||
database.failedImportFile=Failed Import File
|
database.failedImportFile=Failed Import File
|
||||||
database.notSupported=This function is not available for your database connection.
|
|
||||||
|
|
||||||
session.expired=A sessão expirou. Por favor, recarregue a página e tente novamente.
|
session.expired=A sessão expirou. Por favor, recarregue a página e tente novamente.
|
||||||
session.refreshPage=Refresh Page
|
session.refreshPage=Refresh Page
|
||||||
@@ -476,10 +474,6 @@ home.autoRedact.title=Edição automática
|
|||||||
home.autoRedact.desc=Edição automática (marca a preto) baseada numa expressão indicada de um PDF.
|
home.autoRedact.desc=Edição automática (marca a preto) baseada numa expressão indicada de um PDF.
|
||||||
autoRedact.tags=Esconder,censurar,marcador,tampado,máscara,oculto
|
autoRedact.tags=Esconder,censurar,marcador,tampado,máscara,oculto
|
||||||
|
|
||||||
home.redact.title=Manual Redaction
|
|
||||||
home.redact.desc=Redacts a PDF based on selected text, drawn shapes and/or selected page(s)
|
|
||||||
redact.tags=Redact,Hide,black out,black,marker,hidden,manual
|
|
||||||
|
|
||||||
home.tableExtraxt.title=PDF para CSV
|
home.tableExtraxt.title=PDF para CSV
|
||||||
home.tableExtraxt.desc=Extrai tabelas de um PDF convertendo em um CSV
|
home.tableExtraxt.desc=Extrai tabelas de um PDF convertendo em um CSV
|
||||||
tableExtraxt.tags=CSV,Tabelas Extracção,extracção,conversão
|
tableExtraxt.tags=CSV,Tabelas Extracção,extracção,conversão
|
||||||
@@ -585,31 +579,6 @@ autoRedact.customPaddingLabel=Preenchimento extra personalizado
|
|||||||
autoRedact.convertPDFToImageLabel=Converter PDF em imagem (usado para remover texto atrás de caixas)
|
autoRedact.convertPDFToImageLabel=Converter PDF em imagem (usado para remover texto atrás de caixas)
|
||||||
autoRedact.submitButton=Submeter
|
autoRedact.submitButton=Submeter
|
||||||
|
|
||||||
#redact
|
|
||||||
redact.title=Manual Redaction
|
|
||||||
redact.header=Manual Redaction
|
|
||||||
redact.submit=Redact
|
|
||||||
redact.textBasedRedaction=Text based Redaction
|
|
||||||
redact.pageBasedRedaction=Page-based Redaction
|
|
||||||
redact.convertPDFToImageLabel=Convert PDF to PDF-Image (Used to remove text behind the box)
|
|
||||||
redact.pageRedactionNumbers.title=Pages
|
|
||||||
redact.pageRedactionNumbers.placeholder=(e.g. 1,2,8 or 4,7,12-16 or 2n-1)
|
|
||||||
redact.redactionColor.title=Redaction Color
|
|
||||||
redact.export=Export
|
|
||||||
redact.upload=Upload
|
|
||||||
redact.boxRedaction=Box draw redaction
|
|
||||||
redact.zoom=Zoom
|
|
||||||
redact.zoomIn=Zoom in
|
|
||||||
redact.zoomOut=Zoom out
|
|
||||||
redact.nextPage=Next Page
|
|
||||||
redact.previousPage=Previous Page
|
|
||||||
redact.toggleSidebar=Toggle Sidebar
|
|
||||||
redact.showThumbnails=Show Thumbnails
|
|
||||||
redact.showDocumentOutline=Show Document Outline (double-click to expand/collapse all items)
|
|
||||||
redact.showAttatchments=Show Attachments
|
|
||||||
redact.showLayers=Show Layers (double-click to reset all layers to the default state)
|
|
||||||
redact.colourPicker=Colour Picker
|
|
||||||
redact.findCurrentOutlineItem=Find current outline item
|
|
||||||
|
|
||||||
#showJS
|
#showJS
|
||||||
showJS.title=Exibir JavaScript
|
showJS.title=Exibir JavaScript
|
||||||
@@ -863,8 +832,6 @@ sign.last=Last page
|
|||||||
sign.next=Next page
|
sign.next=Next page
|
||||||
sign.previous=Previous page
|
sign.previous=Previous page
|
||||||
sign.maintainRatio=Toggle maintain aspect ratio
|
sign.maintainRatio=Toggle maintain aspect ratio
|
||||||
|
|
||||||
|
|
||||||
#repair
|
#repair
|
||||||
repair.title=Reparar
|
repair.title=Reparar
|
||||||
repair.header=Reparar PDFs
|
repair.header=Reparar PDFs
|
||||||
|
|||||||
@@ -82,7 +82,6 @@ pages=Pages
|
|||||||
loading=Loading...
|
loading=Loading...
|
||||||
addToDoc=Add to Document
|
addToDoc=Add to Document
|
||||||
reset=Reset
|
reset=Reset
|
||||||
apply=Apply
|
|
||||||
|
|
||||||
legal.privacy=Privacy Policy
|
legal.privacy=Privacy Policy
|
||||||
legal.terms=Terms and Conditions
|
legal.terms=Terms and Conditions
|
||||||
@@ -249,7 +248,6 @@ database.backupCreated=Database backup successful
|
|||||||
database.fileNotFound=Fișierul nu a fost găsit
|
database.fileNotFound=Fișierul nu a fost găsit
|
||||||
database.fileNullOrEmpty=Fișierul nu trebuie să fie nul sau gol
|
database.fileNullOrEmpty=Fișierul nu trebuie să fie nul sau gol
|
||||||
database.failedImportFile=Importul Fișierului a Eșuat
|
database.failedImportFile=Importul Fișierului a Eșuat
|
||||||
database.notSupported=This function is not available for your database connection.
|
|
||||||
|
|
||||||
session.expired=Your session has expired. Please refresh the page and try again.
|
session.expired=Your session has expired. Please refresh the page and try again.
|
||||||
session.refreshPage=Refresh Page
|
session.refreshPage=Refresh Page
|
||||||
@@ -476,10 +474,6 @@ home.autoRedact.title=Redactare Automată
|
|||||||
home.autoRedact.desc=Redactează automat (înnegrește) text într-un PDF bazat pe textul de intrare
|
home.autoRedact.desc=Redactează automat (înnegrește) text într-un PDF bazat pe textul de intrare
|
||||||
autoRedact.tags=Redactează,Ascunde,înnegrește,negru,marker,ascuns
|
autoRedact.tags=Redactează,Ascunde,înnegrește,negru,marker,ascuns
|
||||||
|
|
||||||
home.redact.title=Manual Redaction
|
|
||||||
home.redact.desc=Redacts a PDF based on selected text, drawn shapes and/or selected page(s)
|
|
||||||
redact.tags=Redact,Hide,black out,black,marker,hidden,manual
|
|
||||||
|
|
||||||
home.tableExtraxt.title=PDF în CSV
|
home.tableExtraxt.title=PDF în CSV
|
||||||
home.tableExtraxt.desc=Extrage Tabelele dintr-un PDF convertindu-l în CSV
|
home.tableExtraxt.desc=Extrage Tabelele dintr-un PDF convertindu-l în CSV
|
||||||
tableExtraxt.tags=CSV,Extragere Tabel,extrage,convertește
|
tableExtraxt.tags=CSV,Extragere Tabel,extrage,convertește
|
||||||
@@ -585,31 +579,6 @@ autoRedact.customPaddingLabel=Spațiere Suplimentară Personalizată
|
|||||||
autoRedact.convertPDFToImageLabel=Convertește PDF în PDF-Imagine (Folosit pentru a elimina textul din spatele casetei)
|
autoRedact.convertPDFToImageLabel=Convertește PDF în PDF-Imagine (Folosit pentru a elimina textul din spatele casetei)
|
||||||
autoRedact.submitButton=Trimite
|
autoRedact.submitButton=Trimite
|
||||||
|
|
||||||
#redact
|
|
||||||
redact.title=Manual Redaction
|
|
||||||
redact.header=Manual Redaction
|
|
||||||
redact.submit=Redact
|
|
||||||
redact.textBasedRedaction=Text based Redaction
|
|
||||||
redact.pageBasedRedaction=Page-based Redaction
|
|
||||||
redact.convertPDFToImageLabel=Convert PDF to PDF-Image (Used to remove text behind the box)
|
|
||||||
redact.pageRedactionNumbers.title=Pages
|
|
||||||
redact.pageRedactionNumbers.placeholder=(e.g. 1,2,8 or 4,7,12-16 or 2n-1)
|
|
||||||
redact.redactionColor.title=Redaction Color
|
|
||||||
redact.export=Export
|
|
||||||
redact.upload=Upload
|
|
||||||
redact.boxRedaction=Box draw redaction
|
|
||||||
redact.zoom=Zoom
|
|
||||||
redact.zoomIn=Zoom in
|
|
||||||
redact.zoomOut=Zoom out
|
|
||||||
redact.nextPage=Next Page
|
|
||||||
redact.previousPage=Previous Page
|
|
||||||
redact.toggleSidebar=Toggle Sidebar
|
|
||||||
redact.showThumbnails=Show Thumbnails
|
|
||||||
redact.showDocumentOutline=Show Document Outline (double-click to expand/collapse all items)
|
|
||||||
redact.showAttatchments=Show Attachments
|
|
||||||
redact.showLayers=Show Layers (double-click to reset all layers to the default state)
|
|
||||||
redact.colourPicker=Colour Picker
|
|
||||||
redact.findCurrentOutlineItem=Find current outline item
|
|
||||||
|
|
||||||
#showJS
|
#showJS
|
||||||
showJS.title=Arată Javascript
|
showJS.title=Arată Javascript
|
||||||
@@ -863,8 +832,6 @@ sign.last=Last page
|
|||||||
sign.next=Next page
|
sign.next=Next page
|
||||||
sign.previous=Previous page
|
sign.previous=Previous page
|
||||||
sign.maintainRatio=Toggle maintain aspect ratio
|
sign.maintainRatio=Toggle maintain aspect ratio
|
||||||
|
|
||||||
|
|
||||||
#repair
|
#repair
|
||||||
repair.title=Repară
|
repair.title=Repară
|
||||||
repair.header=Repară documente PDF
|
repair.header=Repară documente PDF
|
||||||
|
|||||||
@@ -82,7 +82,6 @@ pages=Страницы
|
|||||||
loading=Загрузка...
|
loading=Загрузка...
|
||||||
addToDoc=Добавить в документ
|
addToDoc=Добавить в документ
|
||||||
reset=Reset
|
reset=Reset
|
||||||
apply=Apply
|
|
||||||
|
|
||||||
legal.privacy=Политика конфиденциальности
|
legal.privacy=Политика конфиденциальности
|
||||||
legal.terms=Условия использования
|
legal.terms=Условия использования
|
||||||
@@ -249,7 +248,6 @@ database.backupCreated=Database backup successful
|
|||||||
database.fileNotFound=File not Found
|
database.fileNotFound=File not Found
|
||||||
database.fileNullOrEmpty=Файл не должен быть пустым или NULL
|
database.fileNullOrEmpty=Файл не должен быть пустым или NULL
|
||||||
database.failedImportFile=Failed Import File
|
database.failedImportFile=Failed Import File
|
||||||
database.notSupported=This function is not available for your database connection.
|
|
||||||
|
|
||||||
session.expired=Ваша сессия истекла. Пожалуйста, обновите страницу и попробуйте снова.
|
session.expired=Ваша сессия истекла. Пожалуйста, обновите страницу и попробуйте снова.
|
||||||
session.refreshPage=Refresh Page
|
session.refreshPage=Refresh Page
|
||||||
@@ -476,10 +474,6 @@ home.autoRedact.title=Автоматическое редактирование
|
|||||||
home.autoRedact.desc=Автоматическое затемнение (чернение) текста в PDF на основе входного текста
|
home.autoRedact.desc=Автоматическое затемнение (чернение) текста в PDF на основе входного текста
|
||||||
autoRedact.tags=Скрыть, Закрыть, закрасить, блокировать, маркер, скрыто
|
autoRedact.tags=Скрыть, Закрыть, закрасить, блокировать, маркер, скрыто
|
||||||
|
|
||||||
home.redact.title=Manual Redaction
|
|
||||||
home.redact.desc=Redacts a PDF based on selected text, drawn shapes and/or selected page(s)
|
|
||||||
redact.tags=Redact,Hide,black out,black,marker,hidden,manual
|
|
||||||
|
|
||||||
home.tableExtraxt.title=PDF в CSV
|
home.tableExtraxt.title=PDF в CSV
|
||||||
home.tableExtraxt.desc=Извлекает таблицы из PDF и преобразует их в CSV
|
home.tableExtraxt.desc=Извлекает таблицы из PDF и преобразует их в CSV
|
||||||
tableExtraxt.tags=CSV, извлечение таблицы, вытащить, конвертировать
|
tableExtraxt.tags=CSV, извлечение таблицы, вытащить, конвертировать
|
||||||
@@ -585,31 +579,6 @@ autoRedact.customPaddingLabel=Дополнительное отступлени
|
|||||||
autoRedact.convertPDFToImageLabel=Преобразовать PDF в изображение PDF (используется для удаления текста за рамкой)
|
autoRedact.convertPDFToImageLabel=Преобразовать PDF в изображение PDF (используется для удаления текста за рамкой)
|
||||||
autoRedact.submitButton=Отправить
|
autoRedact.submitButton=Отправить
|
||||||
|
|
||||||
#redact
|
|
||||||
redact.title=Manual Redaction
|
|
||||||
redact.header=Manual Redaction
|
|
||||||
redact.submit=Redact
|
|
||||||
redact.textBasedRedaction=Text based Redaction
|
|
||||||
redact.pageBasedRedaction=Page-based Redaction
|
|
||||||
redact.convertPDFToImageLabel=Convert PDF to PDF-Image (Used to remove text behind the box)
|
|
||||||
redact.pageRedactionNumbers.title=Pages
|
|
||||||
redact.pageRedactionNumbers.placeholder=(e.g. 1,2,8 or 4,7,12-16 or 2n-1)
|
|
||||||
redact.redactionColor.title=Redaction Color
|
|
||||||
redact.export=Export
|
|
||||||
redact.upload=Upload
|
|
||||||
redact.boxRedaction=Box draw redaction
|
|
||||||
redact.zoom=Zoom
|
|
||||||
redact.zoomIn=Zoom in
|
|
||||||
redact.zoomOut=Zoom out
|
|
||||||
redact.nextPage=Next Page
|
|
||||||
redact.previousPage=Previous Page
|
|
||||||
redact.toggleSidebar=Toggle Sidebar
|
|
||||||
redact.showThumbnails=Show Thumbnails
|
|
||||||
redact.showDocumentOutline=Show Document Outline (double-click to expand/collapse all items)
|
|
||||||
redact.showAttatchments=Show Attachments
|
|
||||||
redact.showLayers=Show Layers (double-click to reset all layers to the default state)
|
|
||||||
redact.colourPicker=Colour Picker
|
|
||||||
redact.findCurrentOutlineItem=Find current outline item
|
|
||||||
|
|
||||||
#showJS
|
#showJS
|
||||||
showJS.title=Показать Javascript
|
showJS.title=Показать Javascript
|
||||||
@@ -863,8 +832,6 @@ sign.last=Last page
|
|||||||
sign.next=Next page
|
sign.next=Next page
|
||||||
sign.previous=Previous page
|
sign.previous=Previous page
|
||||||
sign.maintainRatio=Toggle maintain aspect ratio
|
sign.maintainRatio=Toggle maintain aspect ratio
|
||||||
|
|
||||||
|
|
||||||
#repair
|
#repair
|
||||||
repair.title=Ремонт
|
repair.title=Ремонт
|
||||||
repair.header=Ремонт PDF ов
|
repair.header=Ремонт PDF ов
|
||||||
|
|||||||
@@ -82,7 +82,6 @@ pages=Pages
|
|||||||
loading=Loading...
|
loading=Loading...
|
||||||
addToDoc=Add to Document
|
addToDoc=Add to Document
|
||||||
reset=Reset
|
reset=Reset
|
||||||
apply=Apply
|
|
||||||
|
|
||||||
legal.privacy=Privacy Policy
|
legal.privacy=Privacy Policy
|
||||||
legal.terms=Terms and Conditions
|
legal.terms=Terms and Conditions
|
||||||
@@ -249,7 +248,6 @@ database.backupCreated=Database backup successful
|
|||||||
database.fileNotFound=File not Found
|
database.fileNotFound=File not Found
|
||||||
database.fileNullOrEmpty=File must not be null or empty
|
database.fileNullOrEmpty=File must not be null or empty
|
||||||
database.failedImportFile=Failed Import File
|
database.failedImportFile=Failed Import File
|
||||||
database.notSupported=This function is not available for your database connection.
|
|
||||||
|
|
||||||
session.expired=Your session has expired. Please refresh the page and try again.
|
session.expired=Your session has expired. Please refresh the page and try again.
|
||||||
session.refreshPage=Refresh Page
|
session.refreshPage=Refresh Page
|
||||||
@@ -476,10 +474,6 @@ home.autoRedact.title=Automatické redigovanie
|
|||||||
home.autoRedact.desc=Automaticky rediguje (zatieni) text v PDF na základe zadaného textu
|
home.autoRedact.desc=Automaticky rediguje (zatieni) text v PDF na základe zadaného textu
|
||||||
autoRedact.tags=redigovať, skryť, zatieniť, čierne, marker, skryté
|
autoRedact.tags=redigovať, skryť, zatieniť, čierne, marker, skryté
|
||||||
|
|
||||||
home.redact.title=Manual Redaction
|
|
||||||
home.redact.desc=Redacts a PDF based on selected text, drawn shapes and/or selected page(s)
|
|
||||||
redact.tags=Redact,Hide,black out,black,marker,hidden,manual
|
|
||||||
|
|
||||||
home.tableExtraxt.title=PDF do CSV
|
home.tableExtraxt.title=PDF do CSV
|
||||||
home.tableExtraxt.desc=Extrahuje tabuľky z PDF a konvertuje ich do CSV
|
home.tableExtraxt.desc=Extrahuje tabuľky z PDF a konvertuje ich do CSV
|
||||||
tableExtraxt.tags=CSV, extrakcia tabuliek, extrahovať, konvertovať
|
tableExtraxt.tags=CSV, extrakcia tabuliek, extrahovať, konvertovať
|
||||||
@@ -585,31 +579,6 @@ autoRedact.customPaddingLabel=Vlastné odsadenie
|
|||||||
autoRedact.convertPDFToImageLabel=Konvertovať PDF na PDF-Obrázok (Používa sa na odstránenie textu za boxom)
|
autoRedact.convertPDFToImageLabel=Konvertovať PDF na PDF-Obrázok (Používa sa na odstránenie textu za boxom)
|
||||||
autoRedact.submitButton=Odoslať
|
autoRedact.submitButton=Odoslať
|
||||||
|
|
||||||
#redact
|
|
||||||
redact.title=Manual Redaction
|
|
||||||
redact.header=Manual Redaction
|
|
||||||
redact.submit=Redact
|
|
||||||
redact.textBasedRedaction=Text based Redaction
|
|
||||||
redact.pageBasedRedaction=Page-based Redaction
|
|
||||||
redact.convertPDFToImageLabel=Convert PDF to PDF-Image (Used to remove text behind the box)
|
|
||||||
redact.pageRedactionNumbers.title=Pages
|
|
||||||
redact.pageRedactionNumbers.placeholder=(e.g. 1,2,8 or 4,7,12-16 or 2n-1)
|
|
||||||
redact.redactionColor.title=Redaction Color
|
|
||||||
redact.export=Export
|
|
||||||
redact.upload=Upload
|
|
||||||
redact.boxRedaction=Box draw redaction
|
|
||||||
redact.zoom=Zoom
|
|
||||||
redact.zoomIn=Zoom in
|
|
||||||
redact.zoomOut=Zoom out
|
|
||||||
redact.nextPage=Next Page
|
|
||||||
redact.previousPage=Previous Page
|
|
||||||
redact.toggleSidebar=Toggle Sidebar
|
|
||||||
redact.showThumbnails=Show Thumbnails
|
|
||||||
redact.showDocumentOutline=Show Document Outline (double-click to expand/collapse all items)
|
|
||||||
redact.showAttatchments=Show Attachments
|
|
||||||
redact.showLayers=Show Layers (double-click to reset all layers to the default state)
|
|
||||||
redact.colourPicker=Colour Picker
|
|
||||||
redact.findCurrentOutlineItem=Find current outline item
|
|
||||||
|
|
||||||
#showJS
|
#showJS
|
||||||
showJS.title=Zobraziť JavaScript
|
showJS.title=Zobraziť JavaScript
|
||||||
@@ -863,8 +832,6 @@ sign.last=Last page
|
|||||||
sign.next=Next page
|
sign.next=Next page
|
||||||
sign.previous=Previous page
|
sign.previous=Previous page
|
||||||
sign.maintainRatio=Toggle maintain aspect ratio
|
sign.maintainRatio=Toggle maintain aspect ratio
|
||||||
|
|
||||||
|
|
||||||
#repair
|
#repair
|
||||||
repair.title=Opraviť
|
repair.title=Opraviť
|
||||||
repair.header=Opraviť PDF
|
repair.header=Opraviť PDF
|
||||||
|
|||||||
@@ -82,7 +82,6 @@ pages=Pages
|
|||||||
loading=Loading...
|
loading=Loading...
|
||||||
addToDoc=Add to Document
|
addToDoc=Add to Document
|
||||||
reset=Reset
|
reset=Reset
|
||||||
apply=Apply
|
|
||||||
|
|
||||||
legal.privacy=Privacy Policy
|
legal.privacy=Privacy Policy
|
||||||
legal.terms=Terms and Conditions
|
legal.terms=Terms and Conditions
|
||||||
@@ -249,7 +248,6 @@ database.backupCreated=Database backup successful
|
|||||||
database.fileNotFound=File not Found
|
database.fileNotFound=File not Found
|
||||||
database.fileNullOrEmpty=File must not be null or empty
|
database.fileNullOrEmpty=File must not be null or empty
|
||||||
database.failedImportFile=Failed Import File
|
database.failedImportFile=Failed Import File
|
||||||
database.notSupported=This function is not available for your database connection.
|
|
||||||
|
|
||||||
session.expired=Your session has expired. Please refresh the page and try again.
|
session.expired=Your session has expired. Please refresh the page and try again.
|
||||||
session.refreshPage=Refresh Page
|
session.refreshPage=Refresh Page
|
||||||
@@ -476,10 +474,6 @@ home.autoRedact.title=Automatsko Cenzurisanje
|
|||||||
home.autoRedact.desc=Automatsko cenzurisanje teksta u PDF-u na osnovu unetog teksta
|
home.autoRedact.desc=Automatsko cenzurisanje teksta u PDF-u na osnovu unetog teksta
|
||||||
autoRedact.tags=Cenzura,Sakrij,prekrivanje,crna,marker,skriveno
|
autoRedact.tags=Cenzura,Sakrij,prekrivanje,crna,marker,skriveno
|
||||||
|
|
||||||
home.redact.title=Manual Redaction
|
|
||||||
home.redact.desc=Redacts a PDF based on selected text, drawn shapes and/or selected page(s)
|
|
||||||
redact.tags=Redact,Hide,black out,black,marker,hidden,manual
|
|
||||||
|
|
||||||
home.tableExtraxt.title=PDF u CSV
|
home.tableExtraxt.title=PDF u CSV
|
||||||
home.tableExtraxt.desc=Izdvaja tabele iz PDF-a pretvarajući ih u CSV
|
home.tableExtraxt.desc=Izdvaja tabele iz PDF-a pretvarajući ih u CSV
|
||||||
tableExtraxt.tags=CSV,Izdvajanje tabela,izdvajanje,konvertovanje
|
tableExtraxt.tags=CSV,Izdvajanje tabela,izdvajanje,konvertovanje
|
||||||
@@ -585,31 +579,6 @@ autoRedact.customPaddingLabel=Dodatni prazan prostor
|
|||||||
autoRedact.convertPDFToImageLabel=Konvertuj PDF u PDF-Image (koristi se za uklanjanje teksta iza okvira)
|
autoRedact.convertPDFToImageLabel=Konvertuj PDF u PDF-Image (koristi se za uklanjanje teksta iza okvira)
|
||||||
autoRedact.submitButton=Potvrdi
|
autoRedact.submitButton=Potvrdi
|
||||||
|
|
||||||
#redact
|
|
||||||
redact.title=Manual Redaction
|
|
||||||
redact.header=Manual Redaction
|
|
||||||
redact.submit=Redact
|
|
||||||
redact.textBasedRedaction=Text based Redaction
|
|
||||||
redact.pageBasedRedaction=Page-based Redaction
|
|
||||||
redact.convertPDFToImageLabel=Convert PDF to PDF-Image (Used to remove text behind the box)
|
|
||||||
redact.pageRedactionNumbers.title=Pages
|
|
||||||
redact.pageRedactionNumbers.placeholder=(e.g. 1,2,8 or 4,7,12-16 or 2n-1)
|
|
||||||
redact.redactionColor.title=Redaction Color
|
|
||||||
redact.export=Export
|
|
||||||
redact.upload=Upload
|
|
||||||
redact.boxRedaction=Box draw redaction
|
|
||||||
redact.zoom=Zoom
|
|
||||||
redact.zoomIn=Zoom in
|
|
||||||
redact.zoomOut=Zoom out
|
|
||||||
redact.nextPage=Next Page
|
|
||||||
redact.previousPage=Previous Page
|
|
||||||
redact.toggleSidebar=Toggle Sidebar
|
|
||||||
redact.showThumbnails=Show Thumbnails
|
|
||||||
redact.showDocumentOutline=Show Document Outline (double-click to expand/collapse all items)
|
|
||||||
redact.showAttatchments=Show Attachments
|
|
||||||
redact.showLayers=Show Layers (double-click to reset all layers to the default state)
|
|
||||||
redact.colourPicker=Colour Picker
|
|
||||||
redact.findCurrentOutlineItem=Find current outline item
|
|
||||||
|
|
||||||
#showJS
|
#showJS
|
||||||
showJS.title=Prikaži Javascript
|
showJS.title=Prikaži Javascript
|
||||||
@@ -863,8 +832,6 @@ sign.last=Last page
|
|||||||
sign.next=Next page
|
sign.next=Next page
|
||||||
sign.previous=Previous page
|
sign.previous=Previous page
|
||||||
sign.maintainRatio=Toggle maintain aspect ratio
|
sign.maintainRatio=Toggle maintain aspect ratio
|
||||||
|
|
||||||
|
|
||||||
#repair
|
#repair
|
||||||
repair.title=Popravi
|
repair.title=Popravi
|
||||||
repair.header=Popravi PDF fajlove
|
repair.header=Popravi PDF fajlove
|
||||||
|
|||||||
@@ -82,7 +82,6 @@ pages=Sidor
|
|||||||
loading=Laddar...
|
loading=Laddar...
|
||||||
addToDoc=Lägg till i dokument
|
addToDoc=Lägg till i dokument
|
||||||
reset=Reset
|
reset=Reset
|
||||||
apply=Apply
|
|
||||||
|
|
||||||
legal.privacy=Dataprotektionspolicy
|
legal.privacy=Dataprotektionspolicy
|
||||||
legal.terms=Villkor och betingelser
|
legal.terms=Villkor och betingelser
|
||||||
@@ -249,7 +248,6 @@ database.backupCreated=Database backup successful
|
|||||||
database.fileNotFound=Filen hittades inte
|
database.fileNotFound=Filen hittades inte
|
||||||
database.fileNullOrEmpty=Filen får inte vara null eller tom
|
database.fileNullOrEmpty=Filen får inte vara null eller tom
|
||||||
database.failedImportFile=Misslyckades med att importera fil
|
database.failedImportFile=Misslyckades med att importera fil
|
||||||
database.notSupported=This function is not available for your database connection.
|
|
||||||
|
|
||||||
session.expired=Din session har löpt ut. Uppdatera sidan och försök igen.
|
session.expired=Din session har löpt ut. Uppdatera sidan och försök igen.
|
||||||
session.refreshPage=Uppdatera sida
|
session.refreshPage=Uppdatera sida
|
||||||
@@ -476,10 +474,6 @@ home.autoRedact.title=Auto-redigera
|
|||||||
home.autoRedact.desc=Auto-redigerar (svärtar) text i en PDF baserat på inmatad text
|
home.autoRedact.desc=Auto-redigerar (svärtar) text i en PDF baserat på inmatad text
|
||||||
autoRedact.tags=Redigera,Dölja,svärta,svart,markör,dold
|
autoRedact.tags=Redigera,Dölja,svärta,svart,markör,dold
|
||||||
|
|
||||||
home.redact.title=Manual Redaction
|
|
||||||
home.redact.desc=Redacts a PDF based on selected text, drawn shapes and/or selected page(s)
|
|
||||||
redact.tags=Redact,Hide,black out,black,marker,hidden,manual
|
|
||||||
|
|
||||||
home.tableExtraxt.title=PDF till CSV
|
home.tableExtraxt.title=PDF till CSV
|
||||||
home.tableExtraxt.desc=Extraherar tabeller från en PDF och konverterar dem till CSV
|
home.tableExtraxt.desc=Extraherar tabeller från en PDF och konverterar dem till CSV
|
||||||
tableExtraxt.tags=CSV,Tabellextraktion,extrahera,konvertera
|
tableExtraxt.tags=CSV,Tabellextraktion,extrahera,konvertera
|
||||||
@@ -585,31 +579,6 @@ autoRedact.customPaddingLabel=Anpassad extra utfyllnad
|
|||||||
autoRedact.convertPDFToImageLabel=Konvertera PDF till PDF-bild (Används för att ta bort text bakom rutan)
|
autoRedact.convertPDFToImageLabel=Konvertera PDF till PDF-bild (Används för att ta bort text bakom rutan)
|
||||||
autoRedact.submitButton=Skicka
|
autoRedact.submitButton=Skicka
|
||||||
|
|
||||||
#redact
|
|
||||||
redact.title=Manual Redaction
|
|
||||||
redact.header=Manual Redaction
|
|
||||||
redact.submit=Redact
|
|
||||||
redact.textBasedRedaction=Text based Redaction
|
|
||||||
redact.pageBasedRedaction=Page-based Redaction
|
|
||||||
redact.convertPDFToImageLabel=Convert PDF to PDF-Image (Used to remove text behind the box)
|
|
||||||
redact.pageRedactionNumbers.title=Pages
|
|
||||||
redact.pageRedactionNumbers.placeholder=(e.g. 1,2,8 or 4,7,12-16 or 2n-1)
|
|
||||||
redact.redactionColor.title=Redaction Color
|
|
||||||
redact.export=Export
|
|
||||||
redact.upload=Upload
|
|
||||||
redact.boxRedaction=Box draw redaction
|
|
||||||
redact.zoom=Zoom
|
|
||||||
redact.zoomIn=Zoom in
|
|
||||||
redact.zoomOut=Zoom out
|
|
||||||
redact.nextPage=Next Page
|
|
||||||
redact.previousPage=Previous Page
|
|
||||||
redact.toggleSidebar=Toggle Sidebar
|
|
||||||
redact.showThumbnails=Show Thumbnails
|
|
||||||
redact.showDocumentOutline=Show Document Outline (double-click to expand/collapse all items)
|
|
||||||
redact.showAttatchments=Show Attachments
|
|
||||||
redact.showLayers=Show Layers (double-click to reset all layers to the default state)
|
|
||||||
redact.colourPicker=Colour Picker
|
|
||||||
redact.findCurrentOutlineItem=Find current outline item
|
|
||||||
|
|
||||||
#showJS
|
#showJS
|
||||||
showJS.title=Visa Javascript
|
showJS.title=Visa Javascript
|
||||||
@@ -863,8 +832,6 @@ sign.last=Last page
|
|||||||
sign.next=Next page
|
sign.next=Next page
|
||||||
sign.previous=Previous page
|
sign.previous=Previous page
|
||||||
sign.maintainRatio=Toggle maintain aspect ratio
|
sign.maintainRatio=Toggle maintain aspect ratio
|
||||||
|
|
||||||
|
|
||||||
#repair
|
#repair
|
||||||
repair.title=Reparera
|
repair.title=Reparera
|
||||||
repair.header=Reparera PDF-filer
|
repair.header=Reparera PDF-filer
|
||||||
|
|||||||
@@ -82,7 +82,6 @@ pages=หน้า
|
|||||||
loading=กำลังโหลด...
|
loading=กำลังโหลด...
|
||||||
addToDoc=เพิ่มเข้าสู่เอกสาร
|
addToDoc=เพิ่มเข้าสู่เอกสาร
|
||||||
reset=Reset
|
reset=Reset
|
||||||
apply=Apply
|
|
||||||
|
|
||||||
legal.privacy=นโยบายความเป็นส่วนตัว
|
legal.privacy=นโยบายความเป็นส่วนตัว
|
||||||
legal.terms=ข้อกำหนดการใช้งาน
|
legal.terms=ข้อกำหนดการใช้งาน
|
||||||
@@ -249,7 +248,6 @@ database.backupCreated=Database backup successful
|
|||||||
database.fileNotFound=ไม่พบไฟล์
|
database.fileNotFound=ไม่พบไฟล์
|
||||||
database.fileNullOrEmpty=ไฟล์ต้องไม่ว่างเปล่าหรือไม่มีข้อมูล
|
database.fileNullOrEmpty=ไฟล์ต้องไม่ว่างเปล่าหรือไม่มีข้อมูล
|
||||||
database.failedImportFile=การนำเข้าไฟล์ล้มเหลว
|
database.failedImportFile=การนำเข้าไฟล์ล้มเหลว
|
||||||
database.notSupported=This function is not available for your database connection.
|
|
||||||
|
|
||||||
session.expired=สถานะของคุณในระบบหมดอายุ กรุณารีเฟรชหน้าและลองใหม่อีกครั้ง
|
session.expired=สถานะของคุณในระบบหมดอายุ กรุณารีเฟรชหน้าและลองใหม่อีกครั้ง
|
||||||
session.refreshPage=Refresh Page
|
session.refreshPage=Refresh Page
|
||||||
@@ -476,10 +474,6 @@ home.autoRedact.title=ซ่อนข้อมูลอัตโนมัติ
|
|||||||
home.autoRedact.desc=ซ่อนข้อความใน PDF โดยอัตโนมัติตามข้อความที่ป้อน
|
home.autoRedact.desc=ซ่อนข้อความใน PDF โดยอัตโนมัติตามข้อความที่ป้อน
|
||||||
autoRedact.tags=ซ่อน, ซ่อนข้อความ, ซ่อนด้วยสีดำ
|
autoRedact.tags=ซ่อน, ซ่อนข้อความ, ซ่อนด้วยสีดำ
|
||||||
|
|
||||||
home.redact.title=Manual Redaction
|
|
||||||
home.redact.desc=Redacts a PDF based on selected text, drawn shapes and/or selected page(s)
|
|
||||||
redact.tags=Redact,Hide,black out,black,marker,hidden,manual
|
|
||||||
|
|
||||||
home.tableExtraxt.title=PDF เป็น CSV
|
home.tableExtraxt.title=PDF เป็น CSV
|
||||||
home.tableExtraxt.desc=แยกตารางจาก PDF แปลงเป็น CSV
|
home.tableExtraxt.desc=แยกตารางจาก PDF แปลงเป็น CSV
|
||||||
tableExtraxt.tags=CSV, การแยกตาราง, แยก, การแปลง
|
tableExtraxt.tags=CSV, การแยกตาราง, แยก, การแปลง
|
||||||
@@ -585,31 +579,6 @@ autoRedact.customPaddingLabel=การเติมที่กำหนดเ
|
|||||||
autoRedact.convertPDFToImageLabel=แปลง PDF เป็นภาพ PDF (ใช้เพื่อลบข้อความที่อยู่ด้านหลังกล่อง)
|
autoRedact.convertPDFToImageLabel=แปลง PDF เป็นภาพ PDF (ใช้เพื่อลบข้อความที่อยู่ด้านหลังกล่อง)
|
||||||
autoRedact.submitButton=ส่ง
|
autoRedact.submitButton=ส่ง
|
||||||
|
|
||||||
#redact
|
|
||||||
redact.title=Manual Redaction
|
|
||||||
redact.header=Manual Redaction
|
|
||||||
redact.submit=Redact
|
|
||||||
redact.textBasedRedaction=Text based Redaction
|
|
||||||
redact.pageBasedRedaction=Page-based Redaction
|
|
||||||
redact.convertPDFToImageLabel=Convert PDF to PDF-Image (Used to remove text behind the box)
|
|
||||||
redact.pageRedactionNumbers.title=Pages
|
|
||||||
redact.pageRedactionNumbers.placeholder=(e.g. 1,2,8 or 4,7,12-16 or 2n-1)
|
|
||||||
redact.redactionColor.title=Redaction Color
|
|
||||||
redact.export=Export
|
|
||||||
redact.upload=Upload
|
|
||||||
redact.boxRedaction=Box draw redaction
|
|
||||||
redact.zoom=Zoom
|
|
||||||
redact.zoomIn=Zoom in
|
|
||||||
redact.zoomOut=Zoom out
|
|
||||||
redact.nextPage=Next Page
|
|
||||||
redact.previousPage=Previous Page
|
|
||||||
redact.toggleSidebar=Toggle Sidebar
|
|
||||||
redact.showThumbnails=Show Thumbnails
|
|
||||||
redact.showDocumentOutline=Show Document Outline (double-click to expand/collapse all items)
|
|
||||||
redact.showAttatchments=Show Attachments
|
|
||||||
redact.showLayers=Show Layers (double-click to reset all layers to the default state)
|
|
||||||
redact.colourPicker=Colour Picker
|
|
||||||
redact.findCurrentOutlineItem=Find current outline item
|
|
||||||
|
|
||||||
#showJS
|
#showJS
|
||||||
showJS.title=แสดง Javascript
|
showJS.title=แสดง Javascript
|
||||||
@@ -863,8 +832,6 @@ sign.last=Last page
|
|||||||
sign.next=Next page
|
sign.next=Next page
|
||||||
sign.previous=Previous page
|
sign.previous=Previous page
|
||||||
sign.maintainRatio=Toggle maintain aspect ratio
|
sign.maintainRatio=Toggle maintain aspect ratio
|
||||||
|
|
||||||
|
|
||||||
#repair
|
#repair
|
||||||
repair.title=ซ่อมแซม
|
repair.title=ซ่อมแซม
|
||||||
repair.header=ซ่อมแซม PDF
|
repair.header=ซ่อมแซม PDF
|
||||||
|
|||||||
@@ -82,7 +82,6 @@ pages=Pages
|
|||||||
loading=Loading...
|
loading=Loading...
|
||||||
addToDoc=Add to Document
|
addToDoc=Add to Document
|
||||||
reset=Reset
|
reset=Reset
|
||||||
apply=Apply
|
|
||||||
|
|
||||||
legal.privacy=Gizlilik Politikası
|
legal.privacy=Gizlilik Politikası
|
||||||
legal.terms=Şartlar ve koşullar
|
legal.terms=Şartlar ve koşullar
|
||||||
@@ -249,7 +248,6 @@ database.backupCreated=Database backup successful
|
|||||||
database.fileNotFound=Dosya bulunamadı
|
database.fileNotFound=Dosya bulunamadı
|
||||||
database.fileNullOrEmpty=Dosya yok veya boş olmamalıdır
|
database.fileNullOrEmpty=Dosya yok veya boş olmamalıdır
|
||||||
database.failedImportFile=Dosya İçe Aktarılamadı
|
database.failedImportFile=Dosya İçe Aktarılamadı
|
||||||
database.notSupported=This function is not available for your database connection.
|
|
||||||
|
|
||||||
session.expired=Your session has expired. Please refresh the page and try again.
|
session.expired=Your session has expired. Please refresh the page and try again.
|
||||||
session.refreshPage=Refresh Page
|
session.refreshPage=Refresh Page
|
||||||
@@ -476,10 +474,6 @@ home.autoRedact.title=Otomatik Karartma
|
|||||||
home.autoRedact.desc=Giriş metnine dayanarak bir PDF'teki metni Otomatik Karartır (Redakte)
|
home.autoRedact.desc=Giriş metnine dayanarak bir PDF'teki metni Otomatik Karartır (Redakte)
|
||||||
autoRedact.tags=Karart,Gizle,karartma,siyah,markör,gizli
|
autoRedact.tags=Karart,Gizle,karartma,siyah,markör,gizli
|
||||||
|
|
||||||
home.redact.title=Manual Redaction
|
|
||||||
home.redact.desc=Redacts a PDF based on selected text, drawn shapes and/or selected page(s)
|
|
||||||
redact.tags=Redact,Hide,black out,black,marker,hidden,manual
|
|
||||||
|
|
||||||
home.tableExtraxt.title=PDF'den CSV'ye
|
home.tableExtraxt.title=PDF'den CSV'ye
|
||||||
home.tableExtraxt.desc=PDF'den Tabloları çıkarır ve CSV'ye dönüştürür
|
home.tableExtraxt.desc=PDF'den Tabloları çıkarır ve CSV'ye dönüştürür
|
||||||
tableExtraxt.tags=CSV, Tablo Çıkarma, ayıklama, dönüştürme
|
tableExtraxt.tags=CSV, Tablo Çıkarma, ayıklama, dönüştürme
|
||||||
@@ -585,31 +579,6 @@ autoRedact.customPaddingLabel=Özel Ekstra Dolgu
|
|||||||
autoRedact.convertPDFToImageLabel=PDF'i PDF-Görüntü'ye dönüştür (Kutunun arkasındaki metni kaldırmak için kullanılır)
|
autoRedact.convertPDFToImageLabel=PDF'i PDF-Görüntü'ye dönüştür (Kutunun arkasındaki metni kaldırmak için kullanılır)
|
||||||
autoRedact.submitButton=Gönder
|
autoRedact.submitButton=Gönder
|
||||||
|
|
||||||
#redact
|
|
||||||
redact.title=Manual Redaction
|
|
||||||
redact.header=Manual Redaction
|
|
||||||
redact.submit=Redact
|
|
||||||
redact.textBasedRedaction=Text based Redaction
|
|
||||||
redact.pageBasedRedaction=Page-based Redaction
|
|
||||||
redact.convertPDFToImageLabel=Convert PDF to PDF-Image (Used to remove text behind the box)
|
|
||||||
redact.pageRedactionNumbers.title=Pages
|
|
||||||
redact.pageRedactionNumbers.placeholder=(e.g. 1,2,8 or 4,7,12-16 or 2n-1)
|
|
||||||
redact.redactionColor.title=Redaction Color
|
|
||||||
redact.export=Export
|
|
||||||
redact.upload=Upload
|
|
||||||
redact.boxRedaction=Box draw redaction
|
|
||||||
redact.zoom=Zoom
|
|
||||||
redact.zoomIn=Zoom in
|
|
||||||
redact.zoomOut=Zoom out
|
|
||||||
redact.nextPage=Next Page
|
|
||||||
redact.previousPage=Previous Page
|
|
||||||
redact.toggleSidebar=Toggle Sidebar
|
|
||||||
redact.showThumbnails=Show Thumbnails
|
|
||||||
redact.showDocumentOutline=Show Document Outline (double-click to expand/collapse all items)
|
|
||||||
redact.showAttatchments=Show Attachments
|
|
||||||
redact.showLayers=Show Layers (double-click to reset all layers to the default state)
|
|
||||||
redact.colourPicker=Colour Picker
|
|
||||||
redact.findCurrentOutlineItem=Find current outline item
|
|
||||||
|
|
||||||
#showJS
|
#showJS
|
||||||
showJS.title=Javascript'i Göster
|
showJS.title=Javascript'i Göster
|
||||||
@@ -863,8 +832,6 @@ sign.last=Last page
|
|||||||
sign.next=Next page
|
sign.next=Next page
|
||||||
sign.previous=Previous page
|
sign.previous=Previous page
|
||||||
sign.maintainRatio=Toggle maintain aspect ratio
|
sign.maintainRatio=Toggle maintain aspect ratio
|
||||||
|
|
||||||
|
|
||||||
#repair
|
#repair
|
||||||
repair.title=Onar
|
repair.title=Onar
|
||||||
repair.header=PDF'leri Onar
|
repair.header=PDF'leri Onar
|
||||||
|
|||||||
@@ -82,7 +82,6 @@ pages=Pages
|
|||||||
loading=Loading...
|
loading=Loading...
|
||||||
addToDoc=Add to Document
|
addToDoc=Add to Document
|
||||||
reset=Reset
|
reset=Reset
|
||||||
apply=Apply
|
|
||||||
|
|
||||||
legal.privacy=Privacy Policy
|
legal.privacy=Privacy Policy
|
||||||
legal.terms=Terms and Conditions
|
legal.terms=Terms and Conditions
|
||||||
@@ -249,7 +248,6 @@ database.backupCreated=Database backup successful
|
|||||||
database.fileNotFound=File not Found
|
database.fileNotFound=File not Found
|
||||||
database.fileNullOrEmpty=File must not be null or empty
|
database.fileNullOrEmpty=File must not be null or empty
|
||||||
database.failedImportFile=Failed Import File
|
database.failedImportFile=Failed Import File
|
||||||
database.notSupported=This function is not available for your database connection.
|
|
||||||
|
|
||||||
session.expired=Your session has expired. Please refresh the page and try again.
|
session.expired=Your session has expired. Please refresh the page and try again.
|
||||||
session.refreshPage=Refresh Page
|
session.refreshPage=Refresh Page
|
||||||
@@ -476,10 +474,6 @@ home.autoRedact.title=Автоматичне редагування
|
|||||||
home.autoRedact.desc=Автоматичне затемнення (чорніння) тексту в PDF на основі вхідного тексту
|
home.autoRedact.desc=Автоматичне затемнення (чорніння) тексту в PDF на основі вхідного тексту
|
||||||
autoRedact.tags=Redact,Hide,black out,black,marker,hidden
|
autoRedact.tags=Redact,Hide,black out,black,marker,hidden
|
||||||
|
|
||||||
home.redact.title=Manual Redaction
|
|
||||||
home.redact.desc=Redacts a PDF based on selected text, drawn shapes and/or selected page(s)
|
|
||||||
redact.tags=Redact,Hide,black out,black,marker,hidden,manual
|
|
||||||
|
|
||||||
home.tableExtraxt.title=PDF у CSV
|
home.tableExtraxt.title=PDF у CSV
|
||||||
home.tableExtraxt.desc=Видобуває таблиці з PDF та перетворює їх у CSV
|
home.tableExtraxt.desc=Видобуває таблиці з PDF та перетворює їх у CSV
|
||||||
tableExtraxt.tags=CSV,Table Extraction,extract,convert
|
tableExtraxt.tags=CSV,Table Extraction,extract,convert
|
||||||
@@ -585,31 +579,6 @@ autoRedact.customPaddingLabel=Додаткове заповнення за ко
|
|||||||
autoRedact.convertPDFToImageLabel=Перетворити PDF в зображення PDF (використовується для видалення тексту поза межами)
|
autoRedact.convertPDFToImageLabel=Перетворити PDF в зображення PDF (використовується для видалення тексту поза межами)
|
||||||
autoRedact.submitButton=Надіслати
|
autoRedact.submitButton=Надіслати
|
||||||
|
|
||||||
#redact
|
|
||||||
redact.title=Manual Redaction
|
|
||||||
redact.header=Manual Redaction
|
|
||||||
redact.submit=Redact
|
|
||||||
redact.textBasedRedaction=Text based Redaction
|
|
||||||
redact.pageBasedRedaction=Page-based Redaction
|
|
||||||
redact.convertPDFToImageLabel=Convert PDF to PDF-Image (Used to remove text behind the box)
|
|
||||||
redact.pageRedactionNumbers.title=Pages
|
|
||||||
redact.pageRedactionNumbers.placeholder=(e.g. 1,2,8 or 4,7,12-16 or 2n-1)
|
|
||||||
redact.redactionColor.title=Redaction Color
|
|
||||||
redact.export=Export
|
|
||||||
redact.upload=Upload
|
|
||||||
redact.boxRedaction=Box draw redaction
|
|
||||||
redact.zoom=Zoom
|
|
||||||
redact.zoomIn=Zoom in
|
|
||||||
redact.zoomOut=Zoom out
|
|
||||||
redact.nextPage=Next Page
|
|
||||||
redact.previousPage=Previous Page
|
|
||||||
redact.toggleSidebar=Toggle Sidebar
|
|
||||||
redact.showThumbnails=Show Thumbnails
|
|
||||||
redact.showDocumentOutline=Show Document Outline (double-click to expand/collapse all items)
|
|
||||||
redact.showAttatchments=Show Attachments
|
|
||||||
redact.showLayers=Show Layers (double-click to reset all layers to the default state)
|
|
||||||
redact.colourPicker=Colour Picker
|
|
||||||
redact.findCurrentOutlineItem=Find current outline item
|
|
||||||
|
|
||||||
#showJS
|
#showJS
|
||||||
showJS.title=Показати JavaScript
|
showJS.title=Показати JavaScript
|
||||||
@@ -863,8 +832,6 @@ sign.last=Last page
|
|||||||
sign.next=Next page
|
sign.next=Next page
|
||||||
sign.previous=Previous page
|
sign.previous=Previous page
|
||||||
sign.maintainRatio=Toggle maintain aspect ratio
|
sign.maintainRatio=Toggle maintain aspect ratio
|
||||||
|
|
||||||
|
|
||||||
#repair
|
#repair
|
||||||
repair.title=Ремонт
|
repair.title=Ремонт
|
||||||
repair.header=Ремонт PDF
|
repair.header=Ремонт PDF
|
||||||
|
|||||||
@@ -82,7 +82,6 @@ pages=Pages
|
|||||||
loading=Loading...
|
loading=Loading...
|
||||||
addToDoc=Add to Document
|
addToDoc=Add to Document
|
||||||
reset=Reset
|
reset=Reset
|
||||||
apply=Apply
|
|
||||||
|
|
||||||
legal.privacy=Privacy Policy
|
legal.privacy=Privacy Policy
|
||||||
legal.terms=Terms and Conditions
|
legal.terms=Terms and Conditions
|
||||||
@@ -249,7 +248,6 @@ database.backupCreated=Database backup successful
|
|||||||
database.fileNotFound=Không tìm thấy tệp
|
database.fileNotFound=Không tìm thấy tệp
|
||||||
database.fileNullOrEmpty=Tệp không được để trống hoặc rỗng
|
database.fileNullOrEmpty=Tệp không được để trống hoặc rỗng
|
||||||
database.failedImportFile=Không thể nhập tệp
|
database.failedImportFile=Không thể nhập tệp
|
||||||
database.notSupported=This function is not available for your database connection.
|
|
||||||
|
|
||||||
session.expired=Your session has expired. Please refresh the page and try again.
|
session.expired=Your session has expired. Please refresh the page and try again.
|
||||||
session.refreshPage=Refresh Page
|
session.refreshPage=Refresh Page
|
||||||
@@ -476,10 +474,6 @@ home.autoRedact.title=Tự động biên tập
|
|||||||
home.autoRedact.desc=Tự động biên tập (Che đen) văn bản trong PDF dựa trên văn bản đầu vào
|
home.autoRedact.desc=Tự động biên tập (Che đen) văn bản trong PDF dựa trên văn bản đầu vào
|
||||||
autoRedact.tags=Biên tập,Ẩn,che đen,đen,bút đánh dấu,ẩn
|
autoRedact.tags=Biên tập,Ẩn,che đen,đen,bút đánh dấu,ẩn
|
||||||
|
|
||||||
home.redact.title=Manual Redaction
|
|
||||||
home.redact.desc=Redacts a PDF based on selected text, drawn shapes and/or selected page(s)
|
|
||||||
redact.tags=Redact,Hide,black out,black,marker,hidden,manual
|
|
||||||
|
|
||||||
home.tableExtraxt.title=PDF sang CSV
|
home.tableExtraxt.title=PDF sang CSV
|
||||||
home.tableExtraxt.desc=Trích xuất bảng từ PDF chuyển đổi thành CSV
|
home.tableExtraxt.desc=Trích xuất bảng từ PDF chuyển đổi thành CSV
|
||||||
tableExtraxt.tags=CSV,Trích xuất bảng,trích xuất,chuyển đổi
|
tableExtraxt.tags=CSV,Trích xuất bảng,trích xuất,chuyển đổi
|
||||||
@@ -585,31 +579,6 @@ autoRedact.customPaddingLabel=Đệm thêm tùy chỉnh
|
|||||||
autoRedact.convertPDFToImageLabel=Chuyển đổi PDF thành PDF-Hình ảnh (Dùng để xóa văn bản phía sau ô)
|
autoRedact.convertPDFToImageLabel=Chuyển đổi PDF thành PDF-Hình ảnh (Dùng để xóa văn bản phía sau ô)
|
||||||
autoRedact.submitButton=Gửi
|
autoRedact.submitButton=Gửi
|
||||||
|
|
||||||
#redact
|
|
||||||
redact.title=Manual Redaction
|
|
||||||
redact.header=Manual Redaction
|
|
||||||
redact.submit=Redact
|
|
||||||
redact.textBasedRedaction=Text based Redaction
|
|
||||||
redact.pageBasedRedaction=Page-based Redaction
|
|
||||||
redact.convertPDFToImageLabel=Convert PDF to PDF-Image (Used to remove text behind the box)
|
|
||||||
redact.pageRedactionNumbers.title=Pages
|
|
||||||
redact.pageRedactionNumbers.placeholder=(e.g. 1,2,8 or 4,7,12-16 or 2n-1)
|
|
||||||
redact.redactionColor.title=Redaction Color
|
|
||||||
redact.export=Export
|
|
||||||
redact.upload=Upload
|
|
||||||
redact.boxRedaction=Box draw redaction
|
|
||||||
redact.zoom=Zoom
|
|
||||||
redact.zoomIn=Zoom in
|
|
||||||
redact.zoomOut=Zoom out
|
|
||||||
redact.nextPage=Next Page
|
|
||||||
redact.previousPage=Previous Page
|
|
||||||
redact.toggleSidebar=Toggle Sidebar
|
|
||||||
redact.showThumbnails=Show Thumbnails
|
|
||||||
redact.showDocumentOutline=Show Document Outline (double-click to expand/collapse all items)
|
|
||||||
redact.showAttatchments=Show Attachments
|
|
||||||
redact.showLayers=Show Layers (double-click to reset all layers to the default state)
|
|
||||||
redact.colourPicker=Colour Picker
|
|
||||||
redact.findCurrentOutlineItem=Find current outline item
|
|
||||||
|
|
||||||
#showJS
|
#showJS
|
||||||
showJS.title=Hiển thị Javascript
|
showJS.title=Hiển thị Javascript
|
||||||
@@ -863,8 +832,6 @@ sign.last=Last page
|
|||||||
sign.next=Next page
|
sign.next=Next page
|
||||||
sign.previous=Previous page
|
sign.previous=Previous page
|
||||||
sign.maintainRatio=Toggle maintain aspect ratio
|
sign.maintainRatio=Toggle maintain aspect ratio
|
||||||
|
|
||||||
|
|
||||||
#repair
|
#repair
|
||||||
repair.title=Sửa chữa
|
repair.title=Sửa chữa
|
||||||
repair.header=Sửa chữa PDF
|
repair.header=Sửa chữa PDF
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -82,7 +82,6 @@ pages=Pages
|
|||||||
loading=加载中...
|
loading=加载中...
|
||||||
addToDoc=Add to Document
|
addToDoc=Add to Document
|
||||||
reset=重置
|
reset=重置
|
||||||
apply=Apply
|
|
||||||
|
|
||||||
legal.privacy=隐私政策
|
legal.privacy=隐私政策
|
||||||
legal.terms=服务条款
|
legal.terms=服务条款
|
||||||
@@ -249,7 +248,6 @@ database.backupCreated=Database backup successful
|
|||||||
database.fileNotFound=未找到文件
|
database.fileNotFound=未找到文件
|
||||||
database.fileNullOrEmpty=文件不能为空
|
database.fileNullOrEmpty=文件不能为空
|
||||||
database.failedImportFile=导入文件失败
|
database.failedImportFile=导入文件失败
|
||||||
database.notSupported=This function is not available for your database connection.
|
|
||||||
|
|
||||||
session.expired=您的会话已过期。请刷新页面并重试。
|
session.expired=您的会话已过期。请刷新页面并重试。
|
||||||
session.refreshPage=刷新页面
|
session.refreshPage=刷新页面
|
||||||
@@ -476,10 +474,6 @@ home.autoRedact.title=自动删除
|
|||||||
home.autoRedact.desc=根据输入文本自动删除(覆盖)PDF 中的文本
|
home.autoRedact.desc=根据输入文本自动删除(覆盖)PDF 中的文本
|
||||||
autoRedact.tags=脱敏、隐藏、涂黑、标记、不可见
|
autoRedact.tags=脱敏、隐藏、涂黑、标记、不可见
|
||||||
|
|
||||||
home.redact.title=Manual Redaction
|
|
||||||
home.redact.desc=Redacts a PDF based on selected text, drawn shapes and/or selected page(s)
|
|
||||||
redact.tags=Redact,Hide,black out,black,marker,hidden,manual
|
|
||||||
|
|
||||||
home.tableExtraxt.title=PDF 转 CSV
|
home.tableExtraxt.title=PDF 转 CSV
|
||||||
home.tableExtraxt.desc=从 PDF 中提取表格并将其转换为 CSV
|
home.tableExtraxt.desc=从 PDF 中提取表格并将其转换为 CSV
|
||||||
tableExtraxt.tags=CSV、表格提取、提取、转换
|
tableExtraxt.tags=CSV、表格提取、提取、转换
|
||||||
@@ -585,31 +579,6 @@ autoRedact.customPaddingLabel=自定义额外间距
|
|||||||
autoRedact.convertPDFToImageLabel=将PDF转换为PDF-Image(用于删除方框后面的文本)
|
autoRedact.convertPDFToImageLabel=将PDF转换为PDF-Image(用于删除方框后面的文本)
|
||||||
autoRedact.submitButton=提交
|
autoRedact.submitButton=提交
|
||||||
|
|
||||||
#redact
|
|
||||||
redact.title=Manual Redaction
|
|
||||||
redact.header=Manual Redaction
|
|
||||||
redact.submit=Redact
|
|
||||||
redact.textBasedRedaction=Text based Redaction
|
|
||||||
redact.pageBasedRedaction=Page-based Redaction
|
|
||||||
redact.convertPDFToImageLabel=Convert PDF to PDF-Image (Used to remove text behind the box)
|
|
||||||
redact.pageRedactionNumbers.title=Pages
|
|
||||||
redact.pageRedactionNumbers.placeholder=(e.g. 1,2,8 or 4,7,12-16 or 2n-1)
|
|
||||||
redact.redactionColor.title=Redaction Color
|
|
||||||
redact.export=Export
|
|
||||||
redact.upload=Upload
|
|
||||||
redact.boxRedaction=Box draw redaction
|
|
||||||
redact.zoom=Zoom
|
|
||||||
redact.zoomIn=Zoom in
|
|
||||||
redact.zoomOut=Zoom out
|
|
||||||
redact.nextPage=Next Page
|
|
||||||
redact.previousPage=Previous Page
|
|
||||||
redact.toggleSidebar=Toggle Sidebar
|
|
||||||
redact.showThumbnails=Show Thumbnails
|
|
||||||
redact.showDocumentOutline=Show Document Outline (double-click to expand/collapse all items)
|
|
||||||
redact.showAttatchments=Show Attachments
|
|
||||||
redact.showLayers=Show Layers (double-click to reset all layers to the default state)
|
|
||||||
redact.colourPicker=Colour Picker
|
|
||||||
redact.findCurrentOutlineItem=Find current outline item
|
|
||||||
|
|
||||||
#showJS
|
#showJS
|
||||||
showJS.title=显示 JavaScript
|
showJS.title=显示 JavaScript
|
||||||
@@ -863,8 +832,6 @@ sign.last=末页
|
|||||||
sign.next=下一页
|
sign.next=下一页
|
||||||
sign.previous=上一页
|
sign.previous=上一页
|
||||||
sign.maintainRatio=Toggle maintain aspect ratio
|
sign.maintainRatio=Toggle maintain aspect ratio
|
||||||
|
|
||||||
|
|
||||||
#repair
|
#repair
|
||||||
repair.title=修复
|
repair.title=修复
|
||||||
repair.header=修复 PDF
|
repair.header=修复 PDF
|
||||||
|
|||||||
@@ -82,7 +82,6 @@ pages=頁面
|
|||||||
loading=載入中...
|
loading=載入中...
|
||||||
addToDoc=新增至文件
|
addToDoc=新增至文件
|
||||||
reset=重設
|
reset=重設
|
||||||
apply=Apply
|
|
||||||
|
|
||||||
legal.privacy=隱私權政策
|
legal.privacy=隱私權政策
|
||||||
legal.terms=使用條款
|
legal.terms=使用條款
|
||||||
@@ -249,7 +248,6 @@ database.backupCreated=資料庫備份成功
|
|||||||
database.fileNotFound=找不到檔案
|
database.fileNotFound=找不到檔案
|
||||||
database.fileNullOrEmpty=檔案不得為空或空白
|
database.fileNullOrEmpty=檔案不得為空或空白
|
||||||
database.failedImportFile=匯入檔案失敗
|
database.failedImportFile=匯入檔案失敗
|
||||||
database.notSupported=This function is not available for your database connection.
|
|
||||||
|
|
||||||
session.expired=您的工作階段已過期。請重新整理頁面並再試一次。
|
session.expired=您的工作階段已過期。請重新整理頁面並再試一次。
|
||||||
session.refreshPage=重新整理頁面
|
session.refreshPage=重新整理頁面
|
||||||
@@ -476,10 +474,6 @@ home.autoRedact.title=自動塗黑
|
|||||||
home.autoRedact.desc=根據輸入的文字自動塗黑 PDF 中的文字
|
home.autoRedact.desc=根據輸入的文字自動塗黑 PDF 中的文字
|
||||||
autoRedact.tags=塗黑,隱藏,塗黑,黑色,標記,隱藏
|
autoRedact.tags=塗黑,隱藏,塗黑,黑色,標記,隱藏
|
||||||
|
|
||||||
home.redact.title=Manual Redaction
|
|
||||||
home.redact.desc=Redacts a PDF based on selected text, drawn shapes and/or selected page(s)
|
|
||||||
redact.tags=Redact,Hide,black out,black,marker,hidden,manual
|
|
||||||
|
|
||||||
home.tableExtraxt.title=PDF 轉 CSV
|
home.tableExtraxt.title=PDF 轉 CSV
|
||||||
home.tableExtraxt.desc=從 PDF 中提取表格並將其轉換為 CSV
|
home.tableExtraxt.desc=從 PDF 中提取表格並將其轉換為 CSV
|
||||||
tableExtraxt.tags=CSV,表格提取,提取,轉換
|
tableExtraxt.tags=CSV,表格提取,提取,轉換
|
||||||
@@ -585,31 +579,6 @@ autoRedact.customPaddingLabel=自訂額外填充
|
|||||||
autoRedact.convertPDFToImageLabel=將 PDF 轉換為 PDF-影像(用於移除方框後面的文字)
|
autoRedact.convertPDFToImageLabel=將 PDF 轉換為 PDF-影像(用於移除方框後面的文字)
|
||||||
autoRedact.submitButton=送出
|
autoRedact.submitButton=送出
|
||||||
|
|
||||||
#redact
|
|
||||||
redact.title=Manual Redaction
|
|
||||||
redact.header=Manual Redaction
|
|
||||||
redact.submit=Redact
|
|
||||||
redact.textBasedRedaction=Text based Redaction
|
|
||||||
redact.pageBasedRedaction=Page-based Redaction
|
|
||||||
redact.convertPDFToImageLabel=Convert PDF to PDF-Image (Used to remove text behind the box)
|
|
||||||
redact.pageRedactionNumbers.title=Pages
|
|
||||||
redact.pageRedactionNumbers.placeholder=(e.g. 1,2,8 or 4,7,12-16 or 2n-1)
|
|
||||||
redact.redactionColor.title=Redaction Color
|
|
||||||
redact.export=Export
|
|
||||||
redact.upload=Upload
|
|
||||||
redact.boxRedaction=Box draw redaction
|
|
||||||
redact.zoom=Zoom
|
|
||||||
redact.zoomIn=Zoom in
|
|
||||||
redact.zoomOut=Zoom out
|
|
||||||
redact.nextPage=Next Page
|
|
||||||
redact.previousPage=Previous Page
|
|
||||||
redact.toggleSidebar=Toggle Sidebar
|
|
||||||
redact.showThumbnails=Show Thumbnails
|
|
||||||
redact.showDocumentOutline=Show Document Outline (double-click to expand/collapse all items)
|
|
||||||
redact.showAttatchments=Show Attachments
|
|
||||||
redact.showLayers=Show Layers (double-click to reset all layers to the default state)
|
|
||||||
redact.colourPicker=Colour Picker
|
|
||||||
redact.findCurrentOutlineItem=Find current outline item
|
|
||||||
|
|
||||||
#showJS
|
#showJS
|
||||||
showJS.title=顯示 JavaScript
|
showJS.title=顯示 JavaScript
|
||||||
@@ -863,8 +832,6 @@ sign.last=最後一頁
|
|||||||
sign.next=下一頁
|
sign.next=下一頁
|
||||||
sign.previous=上一頁
|
sign.previous=上一頁
|
||||||
sign.maintainRatio=Toggle maintain aspect ratio
|
sign.maintainRatio=Toggle maintain aspect ratio
|
||||||
|
|
||||||
|
|
||||||
#repair
|
#repair
|
||||||
repair.title=修復
|
repair.title=修復
|
||||||
repair.header=修復 PDF
|
repair.header=修復 PDF
|
||||||
|
|||||||
@@ -63,7 +63,6 @@ security:
|
|||||||
enterpriseEdition:
|
enterpriseEdition:
|
||||||
enabled: false # set to 'true' to enable enterprise edition
|
enabled: false # set to 'true' to enable enterprise edition
|
||||||
key: 00000000-0000-0000-0000-000000000000
|
key: 00000000-0000-0000-0000-000000000000
|
||||||
SSOAutoLogin: false # Enable to auto login to first provided SSO
|
|
||||||
CustomMetadata:
|
CustomMetadata:
|
||||||
autoUpdateMetadata: false # set to 'true' to automatically update metadata with below values
|
autoUpdateMetadata: false # set to 'true' to automatically update metadata with below values
|
||||||
author: username # supports text such as 'John Doe' or types such as username to autopopulate with user's username
|
author: username # supports text such as 'John Doe' or types such as username to autopopulate with user's username
|
||||||
@@ -85,16 +84,7 @@ system:
|
|||||||
showUpdateOnlyAdmin: false # only admins can see when a new update is available, depending on showUpdate it must be set to 'true'
|
showUpdateOnlyAdmin: false # only admins can see when a new update is available, depending on showUpdate it must be set to 'true'
|
||||||
customHTMLFiles: false # enable to have files placed in /customFiles/templates override the existing template HTML files
|
customHTMLFiles: false # enable to have files placed in /customFiles/templates override the existing template HTML files
|
||||||
tessdataDir: /usr/share/tessdata # path to the directory containing the Tessdata files. This setting is relevant for Windows systems. For Windows users, this path should be adjusted to point to the appropriate directory where the Tessdata files are stored.
|
tessdataDir: /usr/share/tessdata # path to the directory containing the Tessdata files. This setting is relevant for Windows systems. For Windows users, this path should be adjusted to point to the appropriate directory where the Tessdata files are stored.
|
||||||
enableAnalytics: 'true' # set to 'true' to enable analytics, set to 'false' to disable analytics; for enterprise users, this is set to true
|
enableAnalytics: undefined # set to 'true' to enable analytics, set to 'false' to disable analytics; for enterprise users, this is set to true
|
||||||
datasource:
|
|
||||||
enableCustomDatabase: false # Enterprise users ONLY, set this property to 'true' if you would like to use your own custom database configuration
|
|
||||||
customDatabaseUrl: '' # eg jdbc:postgresql://localhost:5432/postgres, set the url for your own custom database connection. If provided, the type, hostName, port and name are not necessary and will not be used
|
|
||||||
username: postgres # set the database username
|
|
||||||
password: postgres # set the database password
|
|
||||||
type: postgresql # the type of the database to set (e.g. 'h2', 'postgresql')
|
|
||||||
hostName: localhost # the host name to use for the database url. Set to 'localhost' when running the app locally. Set to match the name of the container name of your database container when running the app on a server (Docker configuration)
|
|
||||||
port: 5432 # set the port number of the database. Ensure this matches the port the database is listening to
|
|
||||||
name: postgres # set the name of your database. Should match the name of the database you create
|
|
||||||
|
|
||||||
ui:
|
ui:
|
||||||
appName: '' # application's visible name
|
appName: '' # application's visible name
|
||||||
|
|||||||
@@ -84,27 +84,6 @@
|
|||||||
"moduleLicense": "The Apache Software License, Version 2.0",
|
"moduleLicense": "The Apache Software License, Version 2.0",
|
||||||
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
|
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"moduleName": "com.fasterxml.jackson.jaxrs:jackson-jaxrs-base",
|
|
||||||
"moduleUrl": "https://github.com/FasterXML/jackson-jaxrs-providers/jackson-jaxrs-base",
|
|
||||||
"moduleVersion": "2.18.2",
|
|
||||||
"moduleLicense": "The Apache Software License, Version 2.0",
|
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0.txt"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"moduleName": "com.fasterxml.jackson.jaxrs:jackson-jaxrs-json-provider",
|
|
||||||
"moduleUrl": "https://github.com/FasterXML/jackson-jaxrs-providers/jackson-jaxrs-json-provider",
|
|
||||||
"moduleVersion": "2.18.2",
|
|
||||||
"moduleLicense": "The Apache Software License, Version 2.0",
|
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0.txt"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"moduleName": "com.fasterxml.jackson.module:jackson-module-jaxb-annotations",
|
|
||||||
"moduleUrl": "https://github.com/FasterXML/jackson-modules-base",
|
|
||||||
"moduleVersion": "2.18.2",
|
|
||||||
"moduleLicense": "The Apache Software License, Version 2.0",
|
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0.txt"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"moduleName": "com.fasterxml.jackson.module:jackson-module-parameter-names",
|
"moduleName": "com.fasterxml.jackson.module:jackson-module-parameter-names",
|
||||||
"moduleUrl": "https://github.com/FasterXML/jackson-modules-java8/jackson-module-parameter-names",
|
"moduleUrl": "https://github.com/FasterXML/jackson-modules-java8/jackson-module-parameter-names",
|
||||||
@@ -362,20 +341,6 @@
|
|||||||
"moduleLicense": "The BSD License",
|
"moduleLicense": "The BSD License",
|
||||||
"moduleLicenseUrl": "https://github.com/haraldk/TwelveMonkeys#license"
|
"moduleLicenseUrl": "https://github.com/haraldk/TwelveMonkeys#license"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"moduleName": "com.unboundid.product.scim2:scim2-sdk-client",
|
|
||||||
"moduleUrl": "https://github.com/pingidentity/scim2",
|
|
||||||
"moduleVersion": "2.3.5",
|
|
||||||
"moduleLicense": "UnboundID SCIM2 SDK Free Use License",
|
|
||||||
"moduleLicenseUrl": "https://github.com/pingidentity/scim2"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"moduleName": "com.unboundid.product.scim2:scim2-sdk-common",
|
|
||||||
"moduleUrl": "https://github.com/pingidentity/scim2",
|
|
||||||
"moduleVersion": "2.3.5",
|
|
||||||
"moduleLicense": "UnboundID SCIM2 SDK Free Use License",
|
|
||||||
"moduleLicenseUrl": "https://github.com/pingidentity/scim2"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"moduleName": "com.zaxxer:HikariCP",
|
"moduleName": "com.zaxxer:HikariCP",
|
||||||
"moduleUrl": "https://github.com/brettwooldridge/HikariCP",
|
"moduleUrl": "https://github.com/brettwooldridge/HikariCP",
|
||||||
@@ -584,20 +549,6 @@
|
|||||||
"moduleLicense": "GNU General Public License, version 2 with the GNU Classpath Exception",
|
"moduleLicense": "GNU General Public License, version 2 with the GNU Classpath Exception",
|
||||||
"moduleLicenseUrl": "https://www.gnu.org/software/classpath/license.html"
|
"moduleLicenseUrl": "https://www.gnu.org/software/classpath/license.html"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"moduleName": "javax.activation:javax.activation-api",
|
|
||||||
"moduleUrl": "http://www.oracle.com",
|
|
||||||
"moduleVersion": "1.2.0",
|
|
||||||
"moduleLicense": "COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0",
|
|
||||||
"moduleLicenseUrl": "https://opensource.org/licenses/CDDL-1.0"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"moduleName": "javax.xml.bind:jaxb-api",
|
|
||||||
"moduleUrl": "http://www.oracle.com/",
|
|
||||||
"moduleVersion": "2.3.1",
|
|
||||||
"moduleLicense": "GPL2 w/ CPE",
|
|
||||||
"moduleLicenseUrl": "https://oss.oracle.com/licenses/CDDL+GPL-1.1"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"moduleName": "me.friwi:gluegen-rt",
|
"moduleName": "me.friwi:gluegen-rt",
|
||||||
"moduleUrl": "http://jogamp.org/gluegen/www/",
|
"moduleUrl": "http://jogamp.org/gluegen/www/",
|
||||||
@@ -1238,13 +1189,6 @@
|
|||||||
"moduleLicense": "The Apache Software License, Version 2.0",
|
"moduleLicense": "The Apache Software License, Version 2.0",
|
||||||
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
|
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"moduleName": "org.postgresql:postgresql",
|
|
||||||
"moduleUrl": "https://jdbc.postgresql.org/",
|
|
||||||
"moduleVersion": "42.7.4",
|
|
||||||
"moduleLicense": "BSD-2-Clause",
|
|
||||||
"moduleLicenseUrl": "https://jdbc.postgresql.org/about/license.html"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"moduleName": "org.slf4j:jul-to-slf4j",
|
"moduleName": "org.slf4j:jul-to-slf4j",
|
||||||
"moduleUrl": "http://www.slf4j.org",
|
"moduleUrl": "http://www.slf4j.org",
|
||||||
|
|||||||
@@ -126,19 +126,4 @@ input[data-autocompleted] {
|
|||||||
}
|
}
|
||||||
.btn:hover .btn-tooltip {
|
.btn:hover .btn-tooltip {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
.btn-primary:hover .btn-tooltip {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
.btn-success:hover .btn-tooltip {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
.btn-secondary:hover .btn-tooltip {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
.btn-toolbarButton:hover .btn-tooltip {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
.toolbarButton:hover .btn-tooltip {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,322 +0,0 @@
|
|||||||
:root {
|
|
||||||
--page-redaction-color: #000000;
|
|
||||||
}
|
|
||||||
|
|
||||||
.textLayer span::selection,
|
|
||||||
.textLayer span::-moz-selection {
|
|
||||||
background-color: rgba(0, 100, 0, 0.26);
|
|
||||||
}
|
|
||||||
|
|
||||||
.selected-wrapper {
|
|
||||||
position: absolute;
|
|
||||||
outline: 2px solid darkgreen;
|
|
||||||
outline-offset: -2px;
|
|
||||||
z-index: 10;
|
|
||||||
}
|
|
||||||
|
|
||||||
.selected-wrapper:hover:not(:has(.redaction-overlay:hover)) {
|
|
||||||
outline-color: var(--palette-color, #000000);
|
|
||||||
background-color: var(--palette-color, #000000);
|
|
||||||
z-index: 10;
|
|
||||||
transition: background-color 0.065s linear;
|
|
||||||
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.redaction-overlay {
|
|
||||||
display: flex;
|
|
||||||
position: absolute;
|
|
||||||
|
|
||||||
left: 50%;
|
|
||||||
top: 100%;
|
|
||||||
|
|
||||||
min-width: 25px;
|
|
||||||
max-width: 90px;
|
|
||||||
|
|
||||||
min-height: 25px;
|
|
||||||
|
|
||||||
flex-wrap: nowrap;
|
|
||||||
|
|
||||||
column-gap: 5px;
|
|
||||||
row-gap: 2px;
|
|
||||||
|
|
||||||
border-radius: 2px;
|
|
||||||
padding: 2px;
|
|
||||||
|
|
||||||
box-sizing: border-box;
|
|
||||||
|
|
||||||
background-color: rgb(0 96 170);
|
|
||||||
outline: 1px solid gray;
|
|
||||||
translate: -50% -100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.redaction-overlay svg {
|
|
||||||
height: 25px;
|
|
||||||
width: 25px;
|
|
||||||
|
|
||||||
max-width: 35px;
|
|
||||||
max-height: 35px;
|
|
||||||
|
|
||||||
fill: rgba(255, 255, 255, 0.904);
|
|
||||||
user-select: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.redaction-overlay svg:hover {
|
|
||||||
cursor: pointer;
|
|
||||||
background-color: rgb(3, 63, 109);
|
|
||||||
fill: rgba(226, 226, 226, 0.904);
|
|
||||||
}
|
|
||||||
|
|
||||||
.textLayer div,
|
|
||||||
.textLayer div > * {
|
|
||||||
user-select: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rectangle {
|
|
||||||
border: 2px solid #ff0000;
|
|
||||||
position: absolute;
|
|
||||||
}
|
|
||||||
|
|
||||||
html {
|
|
||||||
--textLayer-pointer-events: auto;
|
|
||||||
--textLayer-user-select: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.textLayer * {
|
|
||||||
pointer-events: var(--textLayer-pointer-events);
|
|
||||||
user-select: var(--textLayer-user-select);
|
|
||||||
}
|
|
||||||
|
|
||||||
#showMoreBtnIcon::before {
|
|
||||||
left: 5px;
|
|
||||||
top: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#showMoreBtn {
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
#man-text-select-redact, #man-shape-redact, #downloadBtn, #uploadBtn, #pageBasedRedactionBtn, #pdfToImageBtn, #showMoreBtn {
|
|
||||||
height: var(--toolButton-height);
|
|
||||||
width: var(--toolButton-width);
|
|
||||||
|
|
||||||
border-radius: var(--toolButton-border-radius);
|
|
||||||
transition: color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;
|
|
||||||
user-select: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
#text-selection, #shape-selection, #downloadBtnIcon, #uploadBtnIcon, #pageBasedRedactionBtnIcon, #pdfToImageBtnIcon, #showMoreBtnIcon {
|
|
||||||
position: relative;
|
|
||||||
font-size: var(--toolButton-icon-font-size);
|
|
||||||
}
|
|
||||||
|
|
||||||
:is(#man-shape-redact, #man-text-select-redact, #sidebarToggle, #viewThumbnail, #viewOutline, #showMoreBtn).toggled {
|
|
||||||
background-color: rgb(50, 159, 243);
|
|
||||||
color: rgb(255 255 255);
|
|
||||||
outline:rgb(50, 159, 243) !important;
|
|
||||||
border-color: rgb(50, 159, 243) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
:is(#man-shape-redact, #man-text-select-redact, #redactionsPaletteContainer, #downloadBtn, #uploadBtn, #pageBasedRedactionBtn, #pdfToImageBtn, #showMoreBtn):hover {
|
|
||||||
background-color: rgba(6, 114, 197, 0.82);
|
|
||||||
color: rgb(255 255 255);
|
|
||||||
outline:rgba(6, 114, 197, 0.82) !important;
|
|
||||||
border-color: rgba(6, 114, 197, 0.82) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
#redactionsPaletteContainer {
|
|
||||||
height: var(--toolButton-height);
|
|
||||||
width: var(--toolButton-width);
|
|
||||||
|
|
||||||
border-radius: var(--toolButton-border-radius);
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
#redactionsPaletteContainer *, #showMoreBtn * {
|
|
||||||
user-select: none;
|
|
||||||
pointer-events: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
#redactions-palette {
|
|
||||||
display: inline;
|
|
||||||
position: relative;
|
|
||||||
|
|
||||||
border-bottom: 8px solid var(--palette-color);
|
|
||||||
border-radius: inherit;
|
|
||||||
border-bottom-left-radius: 0;
|
|
||||||
border-bottom-right-radius: 0;
|
|
||||||
font-size: var(--toolButton-icon-font-size);
|
|
||||||
}
|
|
||||||
|
|
||||||
#redactions-palette::before {
|
|
||||||
position: absolute;
|
|
||||||
content: '';
|
|
||||||
height: 6px;
|
|
||||||
width: 100%;
|
|
||||||
left: 0;
|
|
||||||
bottom: 0px;
|
|
||||||
background-color: var(--palette-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
#redactions-palette > input[type=color] {
|
|
||||||
visibility: hidden;
|
|
||||||
position: absolute;
|
|
||||||
left: 0;
|
|
||||||
top: var(--toolButton-height);
|
|
||||||
height: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#apply-redaction {
|
|
||||||
height: var(--toolButton-height);
|
|
||||||
width: var(--toolButton-width);
|
|
||||||
|
|
||||||
border-radius: var(--toolButton-border-radius);
|
|
||||||
}
|
|
||||||
|
|
||||||
#apply-redaction[disabled=true], #apply-redaction:disabled:not([disabled=false]) {
|
|
||||||
color: rgb(147, 149, 153);
|
|
||||||
box-shadow: none !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
#apply-redaction:is(:hover):not([disabled=true], :disabled:not([disabled=false])) {
|
|
||||||
cursor: pointer;
|
|
||||||
background-color: rgba(6, 114, 197, 0.82);
|
|
||||||
color: rgb(255 255 255);
|
|
||||||
outline:rgba(6, 114, 197, 0.82) !important;
|
|
||||||
border-color: rgba(6, 114, 197, 0.82) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.toolbar-btn-hover:hover {
|
|
||||||
cursor: pointer;
|
|
||||||
background-color: rgba(6, 114, 197, 0.82) !important;
|
|
||||||
color: rgb(255 255 255) !important;
|
|
||||||
outline:rgba(6, 114, 197, 0.82) !important;
|
|
||||||
border-color: rgba(6, 114, 197, 0.82) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
#apply-redaction-icon {
|
|
||||||
font-size: var(--toolButton-icon-font-size);
|
|
||||||
}
|
|
||||||
|
|
||||||
#apply-redaction > span {
|
|
||||||
user-select: none;
|
|
||||||
pointer-events: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
#pageRedactColor, input[data-for=pageRedactColor] {
|
|
||||||
flex: 1;
|
|
||||||
padding: 1px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#pageRedactColor:is(:hover, :focus-within), input[data-for=pageRedactColor]:is(:hover, :focus-within) {
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.palette-color {
|
|
||||||
border-bottom: 3px solid var(--palette-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
.palette-color:is(:hover, :focus-within) {
|
|
||||||
cursor: pointer;
|
|
||||||
background-color: var(--button-hover-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
.splitToolbarButton > .btn-primary, .splitToolbarButton > .btn-secondary, .splitToolbarButton > .toolbarButton {
|
|
||||||
margin-left: 3px;
|
|
||||||
margin-right: 3px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.spin-animation {
|
|
||||||
-webkit-animation: spin 2s linear infinite; /* Safari */
|
|
||||||
-moz-animation: spin 2s linear infinite;
|
|
||||||
-o-animation: spin 2s linear infinite;
|
|
||||||
animation: spin 2s linear infinite;
|
|
||||||
}
|
|
||||||
|
|
||||||
@-webkit-keyframes spin {
|
|
||||||
0% { -webkit-transform: rotate(0deg); }
|
|
||||||
100% { -webkit-transform: rotate(360deg); }
|
|
||||||
}
|
|
||||||
|
|
||||||
@-moz-keyframes spin {
|
|
||||||
0% { -webkit-transform: rotate(0deg); }
|
|
||||||
100% { -webkit-transform: rotate(360deg); }
|
|
||||||
}
|
|
||||||
|
|
||||||
@-o-keyframes spin {
|
|
||||||
0% { -webkit-transform: rotate(0deg); }
|
|
||||||
100% { -webkit-transform: rotate(360deg); }
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes spin {
|
|
||||||
0% { transform: rotate(0deg); }
|
|
||||||
100% { transform: rotate(360deg); }
|
|
||||||
}
|
|
||||||
|
|
||||||
.active-redaction {
|
|
||||||
z-index: 30 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
#pageBasedRedactionOverlay {
|
|
||||||
position: absolute;
|
|
||||||
left: 50%;
|
|
||||||
top: 50%;
|
|
||||||
background-color: var(--md-sys-color-surface);
|
|
||||||
color: var(--md-sys-color-on-surface);
|
|
||||||
border-radius: 3rem;
|
|
||||||
z-index: 100;
|
|
||||||
transform: translate(-50%, -50%);
|
|
||||||
}
|
|
||||||
|
|
||||||
.list-styling {
|
|
||||||
display: list-item !important;
|
|
||||||
margin-left: 15px;
|
|
||||||
list-style-type: disc;
|
|
||||||
}
|
|
||||||
|
|
||||||
.redacted-page {
|
|
||||||
--page-redaction-color: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.redacted-page-preview {
|
|
||||||
border: 2px solid blue;
|
|
||||||
}
|
|
||||||
|
|
||||||
.redacted-page-preview:hover {
|
|
||||||
background-color: var(--page-redaction-color) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.redacted-page-preview * {
|
|
||||||
user-select: none;
|
|
||||||
pointer-events: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.overlay-colorpicker-window {
|
|
||||||
position: absolute;
|
|
||||||
left: 0;
|
|
||||||
top: 24px;
|
|
||||||
height: 0;
|
|
||||||
visibility: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.redacted-thumbnail-image-preview {
|
|
||||||
border: 2px solid blue;
|
|
||||||
}
|
|
||||||
|
|
||||||
.redacted-thumbnail-preview {
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
.redacted-thumbnail-preview:hover::after {
|
|
||||||
content: '';
|
|
||||||
background-color: var(--page-redaction-color);
|
|
||||||
|
|
||||||
position: absolute;
|
|
||||||
left: 0;
|
|
||||||
top: 0;
|
|
||||||
|
|
||||||
height: var(--thumbnail-height);
|
|
||||||
width: var(--thumbnail-width);
|
|
||||||
}
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
document.addEventListener('DOMContentLoaded', function() {
|
|
||||||
// Get CSRF token from cookie
|
|
||||||
const getCsrfToken = () => {
|
|
||||||
return document.cookie
|
|
||||||
.split('; ')
|
|
||||||
.find(row => row.startsWith('XSRF-TOKEN='))
|
|
||||||
?.split('=')[1];
|
|
||||||
};
|
|
||||||
|
|
||||||
// Function to decode the URI-encoded cookie value
|
|
||||||
const decodeCsrfToken = (token) => {
|
|
||||||
if (token) {
|
|
||||||
return decodeURIComponent(token);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Find all forms and add CSRF token
|
|
||||||
const forms = document.querySelectorAll('form');
|
|
||||||
const csrfToken = decodeCsrfToken(getCsrfToken());
|
|
||||||
|
|
||||||
// Only proceed if we have a cookie-based token
|
|
||||||
if (csrfToken) {
|
|
||||||
forms.forEach(form => {
|
|
||||||
// Only now remove existing CSRF input fields since we have a new token
|
|
||||||
const existingCsrfInputs = form.querySelectorAll('input[name="_csrf"]');
|
|
||||||
existingCsrfInputs.forEach(input => input.remove());
|
|
||||||
|
|
||||||
// Create and add new CSRF input field
|
|
||||||
const csrfInput = document.createElement('input');
|
|
||||||
csrfInput.type = 'hidden';
|
|
||||||
csrfInput.name = '_csrf';
|
|
||||||
csrfInput.value = csrfToken;
|
|
||||||
form.appendChild(csrfInput);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
18
src/main/resources/static/pdfjs-legacy/pdf.mjs
vendored
18
src/main/resources/static/pdfjs-legacy/pdf.mjs
vendored
@@ -4630,7 +4630,7 @@ if (DESCRIPTORS && !('size' in URLSearchParamsPrototype)) {
|
|||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
/******/ // The module cache
|
/******/ // The module cache
|
||||||
/******/ var __webpack_module_cache__ = {};
|
/******/ var __webpack_module_cache__ = {};
|
||||||
/******/
|
/******/
|
||||||
/******/ // The require function
|
/******/ // The require function
|
||||||
/******/ function __webpack_require__(moduleId) {
|
/******/ function __webpack_require__(moduleId) {
|
||||||
/******/ // Check if module is in cache
|
/******/ // Check if module is in cache
|
||||||
@@ -4644,14 +4644,14 @@ if (DESCRIPTORS && !('size' in URLSearchParamsPrototype)) {
|
|||||||
/******/ // no module.loaded needed
|
/******/ // no module.loaded needed
|
||||||
/******/ exports: {}
|
/******/ exports: {}
|
||||||
/******/ };
|
/******/ };
|
||||||
/******/
|
/******/
|
||||||
/******/ // Execute the module function
|
/******/ // Execute the module function
|
||||||
/******/ __webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);
|
/******/ __webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);
|
||||||
/******/
|
/******/
|
||||||
/******/ // Return the exports of the module
|
/******/ // Return the exports of the module
|
||||||
/******/ return module.exports;
|
/******/ return module.exports;
|
||||||
/******/ }
|
/******/ }
|
||||||
/******/
|
/******/
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
/******/ /* webpack/runtime/define property getters */
|
/******/ /* webpack/runtime/define property getters */
|
||||||
/******/ (() => {
|
/******/ (() => {
|
||||||
@@ -4664,12 +4664,12 @@ if (DESCRIPTORS && !('size' in URLSearchParamsPrototype)) {
|
|||||||
/******/ }
|
/******/ }
|
||||||
/******/ };
|
/******/ };
|
||||||
/******/ })();
|
/******/ })();
|
||||||
/******/
|
/******/
|
||||||
/******/ /* webpack/runtime/hasOwnProperty shorthand */
|
/******/ /* webpack/runtime/hasOwnProperty shorthand */
|
||||||
/******/ (() => {
|
/******/ (() => {
|
||||||
/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
|
/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
|
||||||
/******/ })();
|
/******/ })();
|
||||||
/******/
|
/******/
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
var __webpack_exports__ = globalThis.pdfjsLib = {};
|
var __webpack_exports__ = globalThis.pdfjsLib = {};
|
||||||
// This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk.
|
// This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk.
|
||||||
@@ -6385,8 +6385,8 @@ function setLayerDimensions(div, viewport, mustFlip = false, mustRotate = true)
|
|||||||
const useRound = util_FeatureTest.isCSSRoundSupported;
|
const useRound = util_FeatureTest.isCSSRoundSupported;
|
||||||
const w = `var(--scale-factor) * ${pageWidth}px`,
|
const w = `var(--scale-factor) * ${pageWidth}px`,
|
||||||
h = `var(--scale-factor) * ${pageHeight}px`;
|
h = `var(--scale-factor) * ${pageHeight}px`;
|
||||||
const widthStr = useRound ? `round(up, ${w}, 1px)` : `calc(${w})`,
|
const widthStr = useRound ? `round(${w}, 1px)` : `calc(${w})`,
|
||||||
heightStr = useRound ? `round(up, ${h}, 1px)` : `calc(${h})`;
|
heightStr = useRound ? `round(${h}, 1px)` : `calc(${h})`;
|
||||||
if (!mustFlip || viewport.rotation % 180 === 0) {
|
if (!mustFlip || viewport.rotation % 180 === 0) {
|
||||||
style.width = widthStr;
|
style.width = widthStr;
|
||||||
style.height = heightStr;
|
style.height = heightStr;
|
||||||
@@ -24317,4 +24317,4 @@ var __webpack_exports__updateTextLayer = __webpack_exports__.updateTextLayer;
|
|||||||
var __webpack_exports__version = __webpack_exports__.version;
|
var __webpack_exports__version = __webpack_exports__.version;
|
||||||
export { __webpack_exports__AbortException as AbortException, __webpack_exports__AnnotationEditorLayer as AnnotationEditorLayer, __webpack_exports__AnnotationEditorParamsType as AnnotationEditorParamsType, __webpack_exports__AnnotationEditorType as AnnotationEditorType, __webpack_exports__AnnotationEditorUIManager as AnnotationEditorUIManager, __webpack_exports__AnnotationLayer as AnnotationLayer, __webpack_exports__AnnotationMode as AnnotationMode, __webpack_exports__CMapCompressionType as CMapCompressionType, __webpack_exports__ColorPicker as ColorPicker, __webpack_exports__DOMSVGFactory as DOMSVGFactory, __webpack_exports__DrawLayer as DrawLayer, __webpack_exports__FeatureTest as FeatureTest, __webpack_exports__GlobalWorkerOptions as GlobalWorkerOptions, __webpack_exports__ImageKind as ImageKind, __webpack_exports__InvalidPDFException as InvalidPDFException, __webpack_exports__MissingPDFException as MissingPDFException, __webpack_exports__OPS as OPS, __webpack_exports__Outliner as Outliner, __webpack_exports__PDFDataRangeTransport as PDFDataRangeTransport, __webpack_exports__PDFDateString as PDFDateString, __webpack_exports__PDFWorker as PDFWorker, __webpack_exports__PasswordResponses as PasswordResponses, __webpack_exports__PermissionFlag as PermissionFlag, __webpack_exports__PixelsPerInch as PixelsPerInch, __webpack_exports__RenderingCancelledException as RenderingCancelledException, __webpack_exports__TextLayer as TextLayer, __webpack_exports__UnexpectedResponseException as UnexpectedResponseException, __webpack_exports__Util as Util, __webpack_exports__VerbosityLevel as VerbosityLevel, __webpack_exports__XfaLayer as XfaLayer, __webpack_exports__build as build, __webpack_exports__createValidAbsoluteUrl as createValidAbsoluteUrl, __webpack_exports__fetchData as fetchData, __webpack_exports__getDocument as getDocument, __webpack_exports__getFilenameFromUrl as getFilenameFromUrl, __webpack_exports__getPdfFilenameFromUrl as getPdfFilenameFromUrl, __webpack_exports__getXfaPageViewport as getXfaPageViewport, __webpack_exports__isDataScheme as isDataScheme, __webpack_exports__isPdfFile as isPdfFile, __webpack_exports__noContextMenu as noContextMenu, __webpack_exports__normalizeUnicode as normalizeUnicode, __webpack_exports__renderTextLayer as renderTextLayer, __webpack_exports__setLayerDimensions as setLayerDimensions, __webpack_exports__shadow as shadow, __webpack_exports__updateTextLayer as updateTextLayer, __webpack_exports__version as version };
|
export { __webpack_exports__AbortException as AbortException, __webpack_exports__AnnotationEditorLayer as AnnotationEditorLayer, __webpack_exports__AnnotationEditorParamsType as AnnotationEditorParamsType, __webpack_exports__AnnotationEditorType as AnnotationEditorType, __webpack_exports__AnnotationEditorUIManager as AnnotationEditorUIManager, __webpack_exports__AnnotationLayer as AnnotationLayer, __webpack_exports__AnnotationMode as AnnotationMode, __webpack_exports__CMapCompressionType as CMapCompressionType, __webpack_exports__ColorPicker as ColorPicker, __webpack_exports__DOMSVGFactory as DOMSVGFactory, __webpack_exports__DrawLayer as DrawLayer, __webpack_exports__FeatureTest as FeatureTest, __webpack_exports__GlobalWorkerOptions as GlobalWorkerOptions, __webpack_exports__ImageKind as ImageKind, __webpack_exports__InvalidPDFException as InvalidPDFException, __webpack_exports__MissingPDFException as MissingPDFException, __webpack_exports__OPS as OPS, __webpack_exports__Outliner as Outliner, __webpack_exports__PDFDataRangeTransport as PDFDataRangeTransport, __webpack_exports__PDFDateString as PDFDateString, __webpack_exports__PDFWorker as PDFWorker, __webpack_exports__PasswordResponses as PasswordResponses, __webpack_exports__PermissionFlag as PermissionFlag, __webpack_exports__PixelsPerInch as PixelsPerInch, __webpack_exports__RenderingCancelledException as RenderingCancelledException, __webpack_exports__TextLayer as TextLayer, __webpack_exports__UnexpectedResponseException as UnexpectedResponseException, __webpack_exports__Util as Util, __webpack_exports__VerbosityLevel as VerbosityLevel, __webpack_exports__XfaLayer as XfaLayer, __webpack_exports__build as build, __webpack_exports__createValidAbsoluteUrl as createValidAbsoluteUrl, __webpack_exports__fetchData as fetchData, __webpack_exports__getDocument as getDocument, __webpack_exports__getFilenameFromUrl as getFilenameFromUrl, __webpack_exports__getPdfFilenameFromUrl as getPdfFilenameFromUrl, __webpack_exports__getXfaPageViewport as getXfaPageViewport, __webpack_exports__isDataScheme as isDataScheme, __webpack_exports__isPdfFile as isPdfFile, __webpack_exports__noContextMenu as noContextMenu, __webpack_exports__normalizeUnicode as normalizeUnicode, __webpack_exports__renderTextLayer as renderTextLayer, __webpack_exports__setLayerDimensions as setLayerDimensions, __webpack_exports__shadow as shadow, __webpack_exports__updateTextLayer as updateTextLayer, __webpack_exports__version as version };
|
||||||
|
|
||||||
//# sourceMappingURL=pdf.mjs.map
|
//# sourceMappingURL=pdf.mjs.map
|
||||||
@@ -267,7 +267,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script th:inline="javascript">
|
<script th:inline="javascript">
|
||||||
document.addEventListener("DOMContentLoaded", async function() {
|
document.addEventListener("DOMContentLoaded", function() {
|
||||||
const settingsTableBody = document.querySelector("#settingsTable tbody");
|
const settingsTableBody = document.querySelector("#settingsTable tbody");
|
||||||
|
|
||||||
/*<![CDATA[*/
|
/*<![CDATA[*/
|
||||||
@@ -306,38 +306,28 @@
|
|||||||
location.reload(); // Refresh the page after sync
|
location.reload(); // Refresh the page after sync
|
||||||
});
|
});
|
||||||
|
|
||||||
document.getElementById('syncToAccount').addEventListener('click', async function() {
|
document.getElementById('syncToAccount').addEventListener('click', function() {
|
||||||
/*<![CDATA[*/
|
/*<![CDATA[*/
|
||||||
const urlUpdateUserSettings = /*[[@{/api/v1/user/updateUserSettings}]]*/ "/api/v1/user/updateUserSettings";
|
const urlUpdateUserSettings = /*[[@{/api/v1/user/updateUserSettings}]]*/ "/api/v1/user/updateUserSettings";
|
||||||
/*]]>*/
|
/*]]>*/
|
||||||
|
let form = document.createElement("form");
|
||||||
let settings = {};
|
form.method = "POST";
|
||||||
for (let i = 0; i < localStorage.length; i++) {
|
form.action = urlUpdateUserSettings; // Your endpoint URL
|
||||||
const key = localStorage.key(i);
|
|
||||||
if(key !== 'debug' && key !== '0' && key !== '1' && !key.includes('pdfjs') && !key.includes('posthog') && !key.includes('pageViews')) {
|
for (let i = 0; i < localStorage.length; i++) {
|
||||||
settings[key] = localStorage.getItem(key);
|
const key = localStorage.key(i);
|
||||||
}
|
if(key !== 'debug' && key !== '0' && key !== '1' && !key.includes('pdfjs') && !key.includes('posthog') && !key.includes('pageViews')) { // Only send non-ignored keys
|
||||||
}
|
let hiddenField = document.createElement("input");
|
||||||
|
hiddenField.type = "hidden";
|
||||||
try {
|
hiddenField.name = key;
|
||||||
const response = await window.fetchWithCsrf(urlUpdateUserSettings, {
|
hiddenField.value = localStorage.getItem(key);
|
||||||
method: 'POST',
|
form.appendChild(hiddenField);
|
||||||
headers: {
|
}
|
||||||
'Content-Type': 'application/json',
|
}
|
||||||
},
|
|
||||||
body: JSON.stringify(settings)
|
document.body.appendChild(form);
|
||||||
});
|
form.submit();
|
||||||
|
});
|
||||||
if (response.ok) {
|
|
||||||
location.reload();
|
|
||||||
} else {
|
|
||||||
alert('Error syncing settings to account');
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Error:', error);
|
|
||||||
alert('Error syncing settings to account');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -60,7 +60,7 @@
|
|||||||
<div th:if="${deleteMessage}" class="alert alert-danger">
|
<div th:if="${deleteMessage}" class="alert alert-danger">
|
||||||
<span th:text="#{${deleteMessage}}">Default message if not found</span>
|
<span th:text="#{${deleteMessage}}">Default message if not found</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="bg-card mt-3 mb-3 table-responsive">
|
<div class="bg-card mt-3 mb-3">
|
||||||
<table class="table table-striped table-hover">
|
<table class="table table-striped table-hover">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<p th:if="${error}" th:text="#{'database.' + ${error}}" class="alert alert-danger text-center"></p>
|
<p th:if="${error}" th:text="#{'database.' + ${error}}" class="alert alert-danger text-center"></p>
|
||||||
<p th:if="${infoMessage}" th:text="#{'database.' + ${infoMessage}}" class="alert alert-success text-center"></p>
|
<p th:if="${infoMessage}" th:text="#{'database.' + ${infoMessage}}" class="alert alert-success text-center"></p>
|
||||||
<div th:if="${databaseVersion!='Unknown'}" class="bg-card mt-3 mb-3">
|
<div class="bg-card mt-3 mb-3">
|
||||||
<table class="table table-striped table-hover mb-0">
|
<table class="table table-striped table-hover mb-0">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
@@ -45,7 +45,7 @@
|
|||||||
<a th:title="#{database.createBackupFile}" th:text="#{database.createBackupFile}" th:href="@{'/api/v1/database/createDatabaseBackup'}" class="btn btn-outline-primary">Create Backup File</a>
|
<a th:title="#{database.createBackupFile}" th:text="#{database.createBackupFile}" th:href="@{'/api/v1/database/createDatabaseBackup'}" class="btn btn-outline-primary">Create Backup File</a>
|
||||||
</div>
|
</div>
|
||||||
<hr>
|
<hr>
|
||||||
<form th:if="${databaseVersion!='Unknown'}" th:action="@{'/api/v1/database/import-database'}" method="post" enctype="multipart/form-data" class="bg-card mt-3 mb-3">
|
<form th:action="@{'/api/v1/database/import-database'}" method="post" enctype="multipart/form-data" class="bg-card mt-3 mb-3">
|
||||||
<div style="background: var(--md-sys-color-error-container);border-radius: 2rem;" class="mb-3 p-3">
|
<div style="background: var(--md-sys-color-error-container);border-radius: 2rem;" class="mb-3 p-3">
|
||||||
<p th:text="#{database.info_1}"></p>
|
<p th:text="#{database.info_1}"></p>
|
||||||
<p th:text="#{database.info_2}"></p>
|
<p th:text="#{database.info_2}"></p>
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user