mirror of
https://github.com/Frooodle/Stirling-PDF.git
synced 2025-09-12 17:52:13 +02:00
Merge branch 'main' into session_2025_03_22
This commit is contained in:
commit
d923e65b94
2
.github/workflows/dependency-review.yml
vendored
2
.github/workflows/dependency-review.yml
vendored
@ -24,4 +24,4 @@ jobs:
|
|||||||
- name: "Checkout Repository"
|
- name: "Checkout Repository"
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||||
- name: "Dependency Review"
|
- name: "Dependency Review"
|
||||||
uses: actions/dependency-review-action@ce3cf9537a52e8119d91fd484ab5b8a807627bf8 # v4.6.0
|
uses: actions/dependency-review-action@38ecb5b593bf0eb19e335c03f97670f792489a8b # v4.7.0
|
||||||
|
@ -541,7 +541,7 @@ This would generate n entries of tr for each person in exampleData
|
|||||||
|
|
||||||
```html
|
```html
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link" th:href="@{/new-feature}">New Feature</a>
|
<a class="nav-link" th:href="@{'/new-feature'}">New Feature</a>
|
||||||
</li>
|
</li>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -112,7 +112,7 @@ Visit our comprehensive documentation at [docs.stirlingpdf.com](https://docs.sti
|
|||||||
|
|
||||||
## Supported Languages
|
## Supported Languages
|
||||||
|
|
||||||
Stirling-PDF currently supports 39 languages!
|
Stirling-PDF currently supports 40 languages!
|
||||||
|
|
||||||
| Language | Progress |
|
| Language | Progress |
|
||||||
| -------------------------------------------- | -------------------------------------- |
|
| -------------------------------------------- | -------------------------------------- |
|
||||||
@ -127,7 +127,7 @@ Stirling-PDF currently supports 39 languages!
|
|||||||
| 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) |  |
|
||||||
@ -156,12 +156,12 @@ Stirling-PDF currently supports 39 languages!
|
|||||||
| 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) |  |
|
||||||
|
| Malayalam (മലയാളം) (ml_ML) |  |
|
||||||
|
|
||||||
## Stirling PDF Enterprise
|
## Stirling PDF Enterprise
|
||||||
|
|
||||||
Stirling PDF offers an Enterprise edition of its software. This is the same great software but with added features, support and comforts.
|
Stirling PDF offers an Enterprise edition of its software. This is the same great software but with added features, support and comforts.
|
||||||
Check out our [Enterprise docs](https://docs.stirlingpdf.com/Enterprise%20Edition)
|
Check out our [Enterprise docs](https://docs.stirlingpdf.com/Pro)
|
||||||
|
|
||||||
|
|
||||||
## 🤝 Looking to contribute?
|
## 🤝 Looking to contribute?
|
||||||
|
@ -29,7 +29,7 @@ ext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
group = "stirling.software"
|
group = "stirling.software"
|
||||||
version = "0.46.0"
|
version = "0.46.1"
|
||||||
|
|
||||||
java {
|
java {
|
||||||
// 17 is lowest but we support and recommend 21
|
// 17 is lowest but we support and recommend 21
|
||||||
@ -481,7 +481,7 @@ dependencies {
|
|||||||
testImplementation "org.springframework.boot:spring-boot-starter-test:$springBootVersion"
|
testImplementation "org.springframework.boot:spring-boot-starter-test:$springBootVersion"
|
||||||
|
|
||||||
// Batik
|
// Batik
|
||||||
implementation "org.apache.xmlgraphics:batik-all:1.18"
|
implementation "org.apache.xmlgraphics:batik-all:1.19"
|
||||||
|
|
||||||
// TwelveMonkeys
|
// TwelveMonkeys
|
||||||
runtimeOnly "com.twelvemonkeys.imageio:imageio-batik:$imageioVersion"
|
runtimeOnly "com.twelvemonkeys.imageio:imageio-batik:$imageioVersion"
|
||||||
@ -529,7 +529,7 @@ dependencies {
|
|||||||
implementation "org.bouncycastle:bcprov-jdk18on:$bouncycastleVersion"
|
implementation "org.bouncycastle:bcprov-jdk18on:$bouncycastleVersion"
|
||||||
implementation "org.bouncycastle:bcpkix-jdk18on:$bouncycastleVersion"
|
implementation "org.bouncycastle:bcpkix-jdk18on:$bouncycastleVersion"
|
||||||
implementation "org.springframework.boot:spring-boot-starter-actuator:$springBootVersion"
|
implementation "org.springframework.boot:spring-boot-starter-actuator:$springBootVersion"
|
||||||
implementation "io.micrometer:micrometer-core:1.14.6"
|
implementation "io.micrometer:micrometer-core:1.14.7"
|
||||||
implementation group: "com.google.zxing", name: "core", version: "3.5.3"
|
implementation group: "com.google.zxing", name: "core", version: "3.5.3"
|
||||||
// https://mvnrepository.com/artifact/org.commonmark/commonmark
|
// https://mvnrepository.com/artifact/org.commonmark/commonmark
|
||||||
implementation "org.commonmark:commonmark:0.24.0"
|
implementation "org.commonmark:commonmark:0.24.0"
|
||||||
|
@ -34,6 +34,11 @@ public class EEAppConfig {
|
|||||||
return licenseKeyChecker.getPremiumLicenseEnabledResult() != License.NORMAL;
|
return licenseKeyChecker.getPremiumLicenseEnabledResult() != License.NORMAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Bean(name = "license")
|
||||||
|
public String licenseType() {
|
||||||
|
return licenseKeyChecker.getPremiumLicenseEnabledResult().name();
|
||||||
|
}
|
||||||
|
|
||||||
@Bean(name = "runningEE")
|
@Bean(name = "runningEE")
|
||||||
public boolean runningEnterprise() {
|
public boolean runningEnterprise() {
|
||||||
return licenseKeyChecker.getPremiumLicenseEnabledResult() == License.ENTERPRISE;
|
return licenseKeyChecker.getPremiumLicenseEnabledResult() == License.ENTERPRISE;
|
||||||
|
@ -5,6 +5,7 @@ import java.nio.file.Files;
|
|||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
@ -15,6 +16,7 @@ import org.springframework.context.annotation.Bean;
|
|||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.context.annotation.Lazy;
|
import org.springframework.context.annotation.Lazy;
|
||||||
import org.springframework.context.annotation.Scope;
|
import org.springframework.context.annotation.Scope;
|
||||||
|
import org.springframework.core.env.Environment;
|
||||||
import org.springframework.core.io.ClassPathResource;
|
import org.springframework.core.io.ClassPathResource;
|
||||||
import org.springframework.core.io.Resource;
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.core.io.ResourceLoader;
|
import org.springframework.core.io.ResourceLoader;
|
||||||
@ -33,6 +35,8 @@ public class AppConfig {
|
|||||||
|
|
||||||
private final ApplicationProperties applicationProperties;
|
private final ApplicationProperties applicationProperties;
|
||||||
|
|
||||||
|
private final Environment env;
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@ConditionalOnProperty(name = "system.customHTMLFiles", havingValue = "true")
|
@ConditionalOnProperty(name = "system.customHTMLFiles", havingValue = "true")
|
||||||
public SpringTemplateEngine templateEngine(ResourceLoader resourceLoader) {
|
public SpringTemplateEngine templateEngine(ResourceLoader resourceLoader) {
|
||||||
@ -193,4 +197,37 @@ public class AppConfig {
|
|||||||
public String uuid() {
|
public String uuid() {
|
||||||
return applicationProperties.getAutomaticallyGenerated().getUUID();
|
return applicationProperties.getAutomaticallyGenerated().getUUID();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Bean(name = "disablePixel")
|
||||||
|
public boolean disablePixel() {
|
||||||
|
return Boolean.getBoolean(env.getProperty("DISABLE_PIXEL"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean(name = "machineType")
|
||||||
|
public String determineMachineType() {
|
||||||
|
try {
|
||||||
|
boolean isDocker = runningInDocker();
|
||||||
|
boolean isKubernetes = System.getenv("KUBERNETES_SERVICE_HOST") != null;
|
||||||
|
boolean isBrowserOpen = "true".equalsIgnoreCase(env.getProperty("BROWSER_OPEN"));
|
||||||
|
|
||||||
|
if (isKubernetes) {
|
||||||
|
return "Kubernetes";
|
||||||
|
} else if (isDocker) {
|
||||||
|
return "Docker";
|
||||||
|
} else if (isBrowserOpen) {
|
||||||
|
String os = System.getProperty("os.name").toLowerCase(Locale.ROOT);
|
||||||
|
if (os.contains("win")) {
|
||||||
|
return "Client-windows";
|
||||||
|
} else if (os.contains("mac")) {
|
||||||
|
return "Client-mac";
|
||||||
|
} else {
|
||||||
|
return "Client-unix";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return "Server-jar";
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
return "Unknown";
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -73,7 +73,7 @@ public class InitialSetup {
|
|||||||
// Initialize Terms and Conditions
|
// Initialize Terms and Conditions
|
||||||
String termsUrl = applicationProperties.getLegal().getTermsAndConditions();
|
String termsUrl = applicationProperties.getLegal().getTermsAndConditions();
|
||||||
if (StringUtils.isEmpty(termsUrl)) {
|
if (StringUtils.isEmpty(termsUrl)) {
|
||||||
String defaultTermsUrl = "https://www.stirlingpdf.com/terms-and-conditions";
|
String defaultTermsUrl = "https://www.stirlingpdf.com/terms";
|
||||||
GeneralUtils.saveKeyToSettings("legal.termsAndConditions", defaultTermsUrl);
|
GeneralUtils.saveKeyToSettings("legal.termsAndConditions", defaultTermsUrl);
|
||||||
applicationProperties.getLegal().setTermsAndConditions(defaultTermsUrl);
|
applicationProperties.getLegal().setTermsAndConditions(defaultTermsUrl);
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@ public class MetricsConfig {
|
|||||||
return new MeterFilter() {
|
return new MeterFilter() {
|
||||||
@Override
|
@Override
|
||||||
public MeterFilterReply accept(Meter.Id id) {
|
public MeterFilterReply accept(Meter.Id id) {
|
||||||
if (id.getName().equals("http.requests")) {
|
if ("http.requests".equals(id.getName())) {
|
||||||
return MeterFilterReply.NEUTRAL;
|
return MeterFilterReply.NEUTRAL;
|
||||||
}
|
}
|
||||||
return MeterFilterReply.DENY;
|
return MeterFilterReply.DENY;
|
||||||
|
@ -5,7 +5,9 @@ import org.springframework.context.annotation.Configuration;
|
|||||||
|
|
||||||
import io.swagger.v3.oas.models.Components;
|
import io.swagger.v3.oas.models.Components;
|
||||||
import io.swagger.v3.oas.models.OpenAPI;
|
import io.swagger.v3.oas.models.OpenAPI;
|
||||||
|
import io.swagger.v3.oas.models.info.Contact;
|
||||||
import io.swagger.v3.oas.models.info.Info;
|
import io.swagger.v3.oas.models.info.Info;
|
||||||
|
import io.swagger.v3.oas.models.info.License;
|
||||||
import io.swagger.v3.oas.models.security.SecurityRequirement;
|
import io.swagger.v3.oas.models.security.SecurityRequirement;
|
||||||
import io.swagger.v3.oas.models.security.SecurityScheme;
|
import io.swagger.v3.oas.models.security.SecurityScheme;
|
||||||
|
|
||||||
@ -31,14 +33,25 @@ public class OpenApiConfig {
|
|||||||
// default version if all else fails
|
// default version if all else fails
|
||||||
version = "1.0.0";
|
version = "1.0.0";
|
||||||
}
|
}
|
||||||
|
Info info =
|
||||||
|
new Info()
|
||||||
|
.title(DEFAULT_TITLE)
|
||||||
|
.version(version)
|
||||||
|
.license(
|
||||||
|
new License()
|
||||||
|
.name("MIT")
|
||||||
|
.url(
|
||||||
|
"https://raw.githubusercontent.com/Stirling-Tools/Stirling-PDF/refs/heads/main/LICENSE")
|
||||||
|
.identifier("MIT"))
|
||||||
|
.termsOfService("https://www.stirlingpdf.com/terms")
|
||||||
|
.contact(
|
||||||
|
new Contact()
|
||||||
|
.name("Stirling Software")
|
||||||
|
.url("https://www.stirlingpdf.com")
|
||||||
|
.email("contact@stirlingpdf.com"))
|
||||||
|
.description(DEFAULT_DESCRIPTION);
|
||||||
if (!applicationProperties.getSecurity().getEnableLogin()) {
|
if (!applicationProperties.getSecurity().getEnableLogin()) {
|
||||||
return new OpenAPI()
|
return new OpenAPI().components(new Components()).info(info);
|
||||||
.components(new Components())
|
|
||||||
.info(
|
|
||||||
new Info()
|
|
||||||
.title(DEFAULT_TITLE)
|
|
||||||
.version(version)
|
|
||||||
.description(DEFAULT_DESCRIPTION));
|
|
||||||
} else {
|
} else {
|
||||||
SecurityScheme apiKeyScheme =
|
SecurityScheme apiKeyScheme =
|
||||||
new SecurityScheme()
|
new SecurityScheme()
|
||||||
@ -47,11 +60,7 @@ public class OpenApiConfig {
|
|||||||
.name("X-API-KEY");
|
.name("X-API-KEY");
|
||||||
return new OpenAPI()
|
return new OpenAPI()
|
||||||
.components(new Components().addSecuritySchemes("apiKey", apiKeyScheme))
|
.components(new Components().addSecuritySchemes("apiKey", apiKeyScheme))
|
||||||
.info(
|
.info(info)
|
||||||
new Info()
|
|
||||||
.title(DEFAULT_TITLE)
|
|
||||||
.version(version)
|
|
||||||
.description(DEFAULT_DESCRIPTION))
|
|
||||||
.addSecurityItem(new SecurityRequirement().addList("apiKey"));
|
.addSecurityItem(new SecurityRequirement().addList("apiKey"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -180,14 +180,15 @@ public class AnalysisController {
|
|||||||
|
|
||||||
// Get permissions
|
// Get permissions
|
||||||
Map<String, Boolean> permissions = new HashMap<>();
|
Map<String, Boolean> permissions = new HashMap<>();
|
||||||
permissions.put("canPrint", document.getCurrentAccessPermission().canPrint());
|
permissions.put("preventPrinting", !document.getCurrentAccessPermission().canPrint());
|
||||||
permissions.put("canModify", document.getCurrentAccessPermission().canModify());
|
|
||||||
permissions.put(
|
permissions.put(
|
||||||
"canExtractContent",
|
"preventModify", !document.getCurrentAccessPermission().canModify());
|
||||||
document.getCurrentAccessPermission().canExtractContent());
|
|
||||||
permissions.put(
|
permissions.put(
|
||||||
"canModifyAnnotations",
|
"preventExtractContent",
|
||||||
document.getCurrentAccessPermission().canModifyAnnotations());
|
!document.getCurrentAccessPermission().canExtractContent());
|
||||||
|
permissions.put(
|
||||||
|
"preventModifyAnnotations",
|
||||||
|
!document.getCurrentAccessPermission().canModifyAnnotations());
|
||||||
|
|
||||||
securityInfo.put("permissions", permissions);
|
securityInfo.put("permissions", permissions);
|
||||||
} else {
|
} else {
|
||||||
|
@ -626,25 +626,32 @@ public class CompressController {
|
|||||||
|
|
||||||
// Scale factors for different optimization levels
|
// Scale factors for different optimization levels
|
||||||
private double getScaleFactorForLevel(int optimizeLevel) {
|
private double getScaleFactorForLevel(int optimizeLevel) {
|
||||||
return switch (optimizeLevel) {
|
return switch (optimizeLevel) {
|
||||||
case 4 -> 0.9; // 90% - lite compression
|
case 3 -> 0.85;
|
||||||
case 5 -> 0.8; // 80% - lite compression
|
case 4 -> 0.75;
|
||||||
case 6 -> 0.7; // 70% - lite compression
|
case 5 -> 0.65;
|
||||||
case 7 -> 0.6; // 60% - intense compression
|
case 6 -> 0.55;
|
||||||
case 8 -> 0.5; // 50% - intense compression
|
case 7 -> 0.45;
|
||||||
case 9, 10 -> 0.4; // 40% - intense compression
|
case 8 -> 0.35;
|
||||||
default -> 1.0; // No scaling for levels 1-3
|
case 9 -> 0.25;
|
||||||
};
|
case 10 -> 0.15;
|
||||||
|
default -> 1.0;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// JPEG quality for different optimization levels
|
// JPEG quality for different optimization levels
|
||||||
private float getJpegQualityForLevel(int optimizeLevel) {
|
private float getJpegQualityForLevel(int optimizeLevel) {
|
||||||
return switch (optimizeLevel) {
|
return switch (optimizeLevel) {
|
||||||
case 7 -> 0.8f; // 80% quality
|
case 3 -> 0.85f;
|
||||||
case 8 -> 0.6f; // 60% quality
|
case 4 -> 0.80f;
|
||||||
case 9, 10 -> 0.4f; // 40% quality
|
case 5 -> 0.75f;
|
||||||
default -> 0.7f; // 70% quality for levels 1-6
|
case 6 -> 0.70f;
|
||||||
};
|
case 7 -> 0.60f;
|
||||||
|
case 8 -> 0.50f;
|
||||||
|
case 9 -> 0.35f;
|
||||||
|
case 10 -> 0.2f;
|
||||||
|
default -> 0.7f;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping(consumes = "multipart/form-data", value = "/compress-pdf")
|
@PostMapping(consumes = "multipart/form-data", value = "/compress-pdf")
|
||||||
@ -698,7 +705,7 @@ public class CompressController {
|
|||||||
|
|
||||||
while (!sizeMet && optimizeLevel <= 9) {
|
while (!sizeMet && optimizeLevel <= 9) {
|
||||||
// Apply image compression for levels 4-9
|
// Apply image compression for levels 4-9
|
||||||
if ((optimizeLevel >= 4 || Boolean.TRUE.equals(convertToGrayscale))
|
if ((optimizeLevel >= 3 || Boolean.TRUE.equals(convertToGrayscale))
|
||||||
&& !imageCompressionApplied) {
|
&& !imageCompressionApplied) {
|
||||||
double scaleFactor = getScaleFactorForLevel(optimizeLevel);
|
double scaleFactor = getScaleFactorForLevel(optimizeLevel);
|
||||||
float jpegQuality = getJpegQualityForLevel(optimizeLevel);
|
float jpegQuality = getJpegQualityForLevel(optimizeLevel);
|
||||||
@ -790,10 +797,14 @@ public class CompressController {
|
|||||||
log.info("Pre-QPDF file size: {}", GeneralUtils.formatBytes(preQpdfSize));
|
log.info("Pre-QPDF file size: {}", GeneralUtils.formatBytes(preQpdfSize));
|
||||||
|
|
||||||
// Map optimization levels to QPDF compression levels
|
// Map optimization levels to QPDF compression levels
|
||||||
int qpdfCompressionLevel =
|
int qpdfCompressionLevel;
|
||||||
optimizeLevel <= 3
|
if (optimizeLevel == 1) {
|
||||||
? optimizeLevel * 3 // Level 1->3, 2->6, 3->9
|
qpdfCompressionLevel = 5;
|
||||||
: 9; // Max compression for levels 4-9
|
} else if (optimizeLevel == 2) {
|
||||||
|
qpdfCompressionLevel = 9;
|
||||||
|
} else {
|
||||||
|
qpdfCompressionLevel = 9;
|
||||||
|
}
|
||||||
|
|
||||||
// Create output file for QPDF
|
// Create output file for QPDF
|
||||||
Path qpdfOutputFile = Files.createTempFile("qpdf_output_", ".pdf");
|
Path qpdfOutputFile = Files.createTempFile("qpdf_output_", ".pdf");
|
||||||
|
@ -622,8 +622,8 @@ public class GetInfoOnPDF {
|
|||||||
permissionsNode.put("Document Assembly", getPermissionState(ap.canAssembleDocument()));
|
permissionsNode.put("Document Assembly", getPermissionState(ap.canAssembleDocument()));
|
||||||
permissionsNode.put("Extracting Content", getPermissionState(ap.canExtractContent()));
|
permissionsNode.put("Extracting Content", getPermissionState(ap.canExtractContent()));
|
||||||
permissionsNode.put(
|
permissionsNode.put(
|
||||||
"Extracting for accessibility",
|
"Extracting for accessibility",
|
||||||
getPermissionState(ap.canExtractForAccessibility()));
|
getPermissionState(ap.canExtractForAccessibility()));
|
||||||
permissionsNode.put("Form Filling", getPermissionState(ap.canFillInForm()));
|
permissionsNode.put("Form Filling", getPermissionState(ap.canFillInForm()));
|
||||||
permissionsNode.put("Modifying", getPermissionState(ap.canModify()));
|
permissionsNode.put("Modifying", getPermissionState(ap.canModify()));
|
||||||
permissionsNode.put("Modifying annotations", getPermissionState(ap.canModifyAnnotations()));
|
permissionsNode.put("Modifying annotations", getPermissionState(ap.canModifyAnnotations()));
|
||||||
|
@ -63,25 +63,25 @@ public class PasswordController {
|
|||||||
String ownerPassword = request.getOwnerPassword();
|
String ownerPassword = request.getOwnerPassword();
|
||||||
String password = request.getPassword();
|
String password = request.getPassword();
|
||||||
int keyLength = request.getKeyLength();
|
int keyLength = request.getKeyLength();
|
||||||
boolean canAssembleDocument = request.isCanAssembleDocument();
|
boolean preventAssembly = request.isPreventAssembly();
|
||||||
boolean canExtractContent = request.isCanExtractContent();
|
boolean preventExtractContent = request.isPreventExtractContent();
|
||||||
boolean canExtractForAccessibility = request.isCanExtractForAccessibility();
|
boolean preventExtractForAccessibility = request.isPreventExtractForAccessibility();
|
||||||
boolean canFillInForm = request.isCanFillInForm();
|
boolean preventFillInForm = request.isPreventFillInForm();
|
||||||
boolean canModify = request.isCanModify();
|
boolean preventModify = request.isPreventModify();
|
||||||
boolean canModifyAnnotations = request.isCanModifyAnnotations();
|
boolean preventModifyAnnotations = request.isPreventModifyAnnotations();
|
||||||
boolean canPrint = request.isCanPrint();
|
boolean preventPrinting = request.isPreventPrinting();
|
||||||
boolean canPrintFaithful = request.isCanPrintFaithful();
|
boolean preventPrintingFaithful = request.isPreventPrintingFaithful();
|
||||||
|
|
||||||
PDDocument document = pdfDocumentFactory.load(fileInput);
|
PDDocument document = pdfDocumentFactory.load(fileInput);
|
||||||
AccessPermission ap = new AccessPermission();
|
AccessPermission ap = new AccessPermission();
|
||||||
ap.setCanAssembleDocument(!canAssembleDocument);
|
ap.setCanAssembleDocument(!preventAssembly);
|
||||||
ap.setCanExtractContent(!canExtractContent);
|
ap.setCanExtractContent(!preventExtractContent);
|
||||||
ap.setCanExtractForAccessibility(!canExtractForAccessibility);
|
ap.setCanExtractForAccessibility(!preventExtractForAccessibility);
|
||||||
ap.setCanFillInForm(!canFillInForm);
|
ap.setCanFillInForm(!preventFillInForm);
|
||||||
ap.setCanModify(!canModify);
|
ap.setCanModify(!preventModify);
|
||||||
ap.setCanModifyAnnotations(!canModifyAnnotations);
|
ap.setCanModifyAnnotations(!preventModifyAnnotations);
|
||||||
ap.setCanPrint(!canPrint);
|
ap.setCanPrint(!preventPrinting);
|
||||||
ap.setCanPrintFaithful(!canPrintFaithful);
|
ap.setCanPrintFaithful(!preventPrintingFaithful);
|
||||||
StandardProtectionPolicy spp = new StandardProtectionPolicy(ownerPassword, password, ap);
|
StandardProtectionPolicy spp = new StandardProtectionPolicy(ownerPassword, password, ap);
|
||||||
|
|
||||||
if (!"".equals(ownerPassword) || !"".equals(password)) {
|
if (!"".equals(ownerPassword) || !"".equals(password)) {
|
||||||
|
@ -170,16 +170,17 @@ public class RedactController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Color decodeOrDefault(String hex, Color defaultColor) {
|
private Color decodeOrDefault(String hex, Color defaultColor) {
|
||||||
Color color = null;
|
|
||||||
try {
|
try {
|
||||||
color = Color.decode(hex);
|
if (hex != null && !hex.startsWith("#")) {
|
||||||
|
hex = "#" + hex;
|
||||||
|
}
|
||||||
|
return Color.decode(hex);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
color = defaultColor;
|
return defaultColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
return color;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private List<Integer> getPageNumbers(ManualRedactPdfRequest request, int pagesCount) {
|
private List<Integer> getPageNumbers(ManualRedactPdfRequest request, int pagesCount) {
|
||||||
String pageNumbersInput = request.getPageNumbers();
|
String pageNumbersInput = request.getPageNumbers();
|
||||||
String[] parsedPageNumbers =
|
String[] parsedPageNumbers =
|
||||||
|
@ -29,31 +29,29 @@ public class AddPasswordRequest extends PDFFile {
|
|||||||
defaultValue = "256")
|
defaultValue = "256")
|
||||||
private int keyLength = 256;
|
private int keyLength = 256;
|
||||||
|
|
||||||
@Schema(description = "Whether the document assembly is allowed", example = "false")
|
@Schema(description = "Whether document assembly is prevented", example = "false")
|
||||||
private boolean canAssembleDocument;
|
private boolean preventAssembly;
|
||||||
|
|
||||||
|
@Schema(description = "Whether content extraction is prevented", example = "false")
|
||||||
|
private boolean preventExtractContent;
|
||||||
|
|
||||||
@Schema(
|
@Schema(
|
||||||
description = "Whether content extraction for accessibility is allowed",
|
description = "Whether content extraction for accessibility is prevented",
|
||||||
example = "false")
|
example = "false")
|
||||||
private boolean canExtractContent;
|
private boolean preventExtractForAccessibility;
|
||||||
|
|
||||||
@Schema(
|
@Schema(description = "Whether form filling is prevented", example = "false")
|
||||||
description = "Whether content extraction for accessibility is allowed",
|
private boolean preventFillInForm;
|
||||||
example = "false")
|
|
||||||
private boolean canExtractForAccessibility;
|
|
||||||
|
|
||||||
@Schema(description = "Whether form filling is allowed", example = "false")
|
@Schema(description = "Whether document modification is prevented", example = "false")
|
||||||
private boolean canFillInForm;
|
private boolean preventModify;
|
||||||
|
|
||||||
@Schema(description = "Whether the document modification is allowed", example = "false")
|
@Schema(description = "Whether modification of annotations is prevented", example = "false")
|
||||||
private boolean canModify;
|
private boolean preventModifyAnnotations;
|
||||||
|
|
||||||
@Schema(description = "Whether modification of annotations is allowed", example = "false")
|
@Schema(description = "Whether printing of the document is prevented", example = "false")
|
||||||
private boolean canModifyAnnotations;
|
private boolean preventPrinting;
|
||||||
|
|
||||||
@Schema(description = "Whether printing of the document is allowed", example = "false")
|
@Schema(description = "Whether faithful printing is prevented", example = "false")
|
||||||
private boolean canPrint;
|
private boolean preventPrintingFaithful;
|
||||||
|
|
||||||
@Schema(description = "Whether faithful printing is allowed", example = "false")
|
|
||||||
private boolean canPrintFaithful;
|
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,7 @@ public class RedactPdfRequest extends PDFFile {
|
|||||||
@Schema(description = "Whether to use whole word search", defaultValue = "false")
|
@Schema(description = "Whether to use whole word search", defaultValue = "false")
|
||||||
private boolean wholeWordSearch;
|
private boolean wholeWordSearch;
|
||||||
|
|
||||||
@Schema(description = "The color for redaction", defaultValue = "#000000")
|
@Schema(description = "Hexadecimal color code for redaction, e.g. #FF0000 or 000000", defaultValue = "#000000")
|
||||||
private String redactColor = "#000000";
|
private String redactColor = "#000000";
|
||||||
|
|
||||||
@Schema(description = "Custom padding for redaction", type = "number")
|
@Schema(description = "Custom padding for redaction", type = "number")
|
||||||
|
@ -517,13 +517,13 @@ home.showJS.title=Afficher le JavaScript
|
|||||||
home.showJS.desc=Recherche et affiche tout JavaScript injecté dans un PDF.
|
home.showJS.desc=Recherche et affiche tout JavaScript injecté dans un PDF.
|
||||||
showJS.tags=JS
|
showJS.tags=JS
|
||||||
|
|
||||||
home.autoRedact.title=Censure automatique
|
home.autoRedact.title=Caviardage automatique
|
||||||
home.autoRedact.desc=Censurer automatiquement les informations sensibles d'un PDF.
|
home.autoRedact.desc=Caviardez automatiquement les informations sensibles d'un PDF.
|
||||||
autoRedact.tags=caviarder,rédiger,censurer,redact,auto
|
autoRedact.tags=caviarder,redact,auto,Masquer,noircir,noir,marqueur,caché,rédiger,censurer
|
||||||
|
|
||||||
home.redact.title=Censure manuelle
|
home.redact.title=Caviardage manuel
|
||||||
home.redact.desc=Censurer un PDF en fonction de texte sélectionné, formes dessinées et/ou des pages sélectionnées.
|
home.redact.desc=Caviarder un PDF en fonction de texte sélectionné, formes dessinées et/ou des pages sélectionnées.
|
||||||
redact.tags=Redact,Hide,black out,black,marker,hidden,manual,caviarder,rédiger,censurer
|
redact.tags=Caviarder,Redact,Masquer,noircir,noir,marqueur,caché,rédiger,censurer
|
||||||
|
|
||||||
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.
|
||||||
@ -624,31 +624,31 @@ autoRedact.convertPDFToImageLabel=Convertir un PDF en PDF-Image (utilisé pour s
|
|||||||
autoRedact.submitButton=Caviarder
|
autoRedact.submitButton=Caviarder
|
||||||
|
|
||||||
#redact
|
#redact
|
||||||
redact.title=Rédaction manuelle
|
redact.title=Caviardage manuel
|
||||||
redact.header=Rédaction manuelle
|
redact.header=Caviardage manuel
|
||||||
redact.submit=Rédiger
|
redact.submit=Caviarder
|
||||||
redact.textBasedRedaction=Rédaction en fonction de texte
|
redact.textBasedRedaction=Caviarder du texte
|
||||||
redact.pageBasedRedaction=Rédaction en fonction de pages
|
redact.pageBasedRedaction=Caviarder des pages
|
||||||
redact.convertPDFToImageLabel=Convertir en PDF-Image (pour supprimer le texte derrière le rectangle)
|
redact.convertPDFToImageLabel=Convertir en PDF-Image (pour supprimer le texte derrière le rectangle)
|
||||||
redact.pageRedactionNumbers.title=Pages
|
redact.pageRedactionNumbers.title=Pages
|
||||||
redact.pageRedactionNumbers.placeholder=(ex: 1,2,8 ou 4,7,12-16 ou 2n-1)
|
redact.pageRedactionNumbers.placeholder=(ex: 1,2,8 ou 4,7,12-16 ou 2n-1)
|
||||||
redact.redactionColor.title=Couleur
|
redact.redactionColor.title=Couleur
|
||||||
redact.export=Exporter
|
redact.export=Exporter
|
||||||
redact.upload=Téléverser
|
redact.upload=Téléverser
|
||||||
redact.boxRedaction=Dessiner le rectangle à rédiger
|
redact.boxRedaction=Tracer le rectangle à caviarder
|
||||||
redact.zoom=Zoom
|
redact.zoom=Zoom
|
||||||
redact.zoomIn=Zoom avant
|
redact.zoomIn=Zoom avant
|
||||||
redact.zoomOut=Zoom arrière
|
redact.zoomOut=Zoom arrière
|
||||||
redact.nextPage=Page suivante
|
redact.nextPage=Page suivante
|
||||||
redact.previousPage=Page précédente
|
redact.previousPage=Page précédente
|
||||||
redact.toggleSidebar=Toggle Sidebar
|
redact.toggleSidebar=Montrer la barre latérale
|
||||||
redact.showThumbnails=Afficher les miniatures
|
redact.showThumbnails=Afficher les miniatures
|
||||||
redact.showDocumentOutline=Montrer les contours du document (double-click pour agrandir/réduire tous les éléments)
|
redact.showDocumentOutline=Montrer les contours du document (double-click pour agrandir/réduire tous les éléments)
|
||||||
redact.showAttatchments=Montrer les éléments attachés
|
redact.showAttatchments=Montrer les éléments attachés
|
||||||
redact.showLayers=Montrer les calques (double-click pour réinitialiser tous les calques à l'état par défaut)
|
redact.showLayers=Montrer les calques (double-click pour réinitialiser tous les calques à l'état par défaut)
|
||||||
redact.colourPicker=Sélection de couleur
|
redact.colourPicker=Sélection de couleur
|
||||||
redact.findCurrentOutlineItem=Trouver l'élément de contour courrant
|
redact.findCurrentOutlineItem=Trouver l'élément de contour courrant
|
||||||
redact.applyChanges=Apply Changes
|
redact.applyChanges=Appliquer les changements
|
||||||
|
|
||||||
#showJS
|
#showJS
|
||||||
showJS.title=Afficher le JavaScript
|
showJS.title=Afficher le JavaScript
|
||||||
|
1439
src/main/resources/messages_ml_ML.properties
Normal file
1439
src/main/resources/messages_ml_ML.properties
Normal file
File diff suppressed because it is too large
Load Diff
@ -77,7 +77,7 @@ premium:
|
|||||||
appId: ''
|
appId: ''
|
||||||
|
|
||||||
mail:
|
mail:
|
||||||
enabled: true # set to 'true' to enable sending emails
|
enabled: false # set to 'true' to enable sending emails
|
||||||
host: smtp.example.com # SMTP server hostname
|
host: smtp.example.com # SMTP server hostname
|
||||||
port: 587 # SMTP server port
|
port: 587 # SMTP server port
|
||||||
username: '' # SMTP server username
|
username: '' # SMTP server username
|
||||||
@ -85,7 +85,7 @@ mail:
|
|||||||
from: '' # sender email address
|
from: '' # sender email address
|
||||||
|
|
||||||
legal:
|
legal:
|
||||||
termsAndConditions: https://www.stirlingpdf.com/terms-and-conditions # URL to the terms and conditions of your application (e.g. https://example.com/terms). Empty string to disable or filename to load from local file in static folder
|
termsAndConditions: https://www.stirlingpdf.com/terms # URL to the terms and conditions of your application (e.g. https://example.com/terms). Empty string to disable or filename to load from local file in static folder
|
||||||
privacyPolicy: https://www.stirlingpdf.com/privacy-policy # URL to the privacy policy of your application (e.g. https://example.com/privacy). Empty string to disable or filename to load from local file in static folder
|
privacyPolicy: https://www.stirlingpdf.com/privacy-policy # URL to the privacy policy of your application (e.g. https://example.com/privacy). Empty string to disable or filename to load from local file in static folder
|
||||||
accessibilityStatement: '' # URL to the accessibility statement of your application (e.g. https://example.com/accessibility). Empty string to disable or filename to load from local file in static folder
|
accessibilityStatement: '' # URL to the accessibility statement of your application (e.g. https://example.com/accessibility). Empty string to disable or filename to load from local file in static folder
|
||||||
cookiePolicy: '' # URL to the cookie policy of your application (e.g. https://example.com/cookie). Empty string to disable or filename to load from local file in static folder
|
cookiePolicy: '' # URL to the cookie policy of your application (e.g. https://example.com/cookie). Empty string to disable or filename to load from local file in static folder
|
||||||
@ -113,11 +113,11 @@ system:
|
|||||||
name: postgres # set the name of your database. Should match the name of the database you create
|
name: postgres # set the name of your database. Should match the name of the database you create
|
||||||
customPaths:
|
customPaths:
|
||||||
pipeline:
|
pipeline:
|
||||||
watchedFoldersDir: '' #Defaults to /pipeline/watchedFolders
|
watchedFoldersDir: '' # Defaults to /pipeline/watchedFolders
|
||||||
finishedFoldersDir: '' #Defaults to /pipeline/finishedFolders
|
finishedFoldersDir: '' # Defaults to /pipeline/finishedFolders
|
||||||
operations:
|
operations:
|
||||||
weasyprint: '' #Defaults to /opt/venv/bin/weasyprint
|
weasyprint: '' # Defaults to /opt/venv/bin/weasyprint
|
||||||
unoconvert: '' #Defaults to /opt/venv/bin/unoconvert
|
unoconvert: '' # Defaults to /opt/venv/bin/unoconvert
|
||||||
fileUploadLimit: '' # Defaults to "". No limit when string is empty. Set a number, between 0 and 999, followed by one of the following strings to set a limit. "KB", "MB", "GB".
|
fileUploadLimit: '' # Defaults to "". No limit when string is empty. Set a number, between 0 and 999, followed by one of the following strings to set a limit. "KB", "MB", "GB".
|
||||||
|
|
||||||
ui:
|
ui:
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
#page-container {
|
#page-container {
|
||||||
min-height: 100vh;
|
height: 100vh;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
overflow-x: clip;
|
||||||
}
|
}
|
||||||
|
|
||||||
#content-wrap {
|
#content-wrap {
|
||||||
|
@ -162,6 +162,7 @@ html[dir="rtl"] .lang-dropdown-item-wrapper {
|
|||||||
text-wrap: wrap;
|
text-wrap: wrap;
|
||||||
word-break: break-word;
|
word-break: break-word;
|
||||||
width: 80%;
|
width: 80%;
|
||||||
|
font-size: large;
|
||||||
}
|
}
|
||||||
|
|
||||||
.close-icon {
|
.close-icon {
|
||||||
@ -476,6 +477,9 @@ html[dir="rtl"] .dropdown-menu[data-bs-popper] {
|
|||||||
display: flex;
|
display: flex;
|
||||||
gap: 30px;
|
gap: 30px;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
width: 140%;
|
||||||
|
position: relative;
|
||||||
|
left: -20%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.feature-group {
|
.feature-group {
|
||||||
|
@ -4,10 +4,21 @@ document.addEventListener('DOMContentLoaded', function () {
|
|||||||
if (window.analyticsPromptBoolean) {
|
if (window.analyticsPromptBoolean) {
|
||||||
const analyticsModal = new bootstrap.Modal(document.getElementById('analyticsModal'));
|
const analyticsModal = new bootstrap.Modal(document.getElementById('analyticsModal'));
|
||||||
analyticsModal.show();
|
analyticsModal.show();
|
||||||
|
|
||||||
|
let retryCount = 0;
|
||||||
|
function hideCookieBanner() {
|
||||||
|
const cookieBanner = document.querySelector('#cc-main');
|
||||||
|
if (cookieBanner && cookieBanner.offsetHeight > 0) {
|
||||||
|
cookieBanner.style.display = "none";
|
||||||
|
} else if (retryCount < 20) {
|
||||||
|
retryCount++;
|
||||||
|
setTimeout(hideCookieBanner, 100);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
hideCookieBanner();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
/*]]>*/
|
/*]]>*/function setAnalytics(enabled) {
|
||||||
function setAnalytics(enabled) {
|
|
||||||
fetchWithCsrf('api/v1/settings/update-enable-analytics', {
|
fetchWithCsrf('api/v1/settings/update-enable-analytics', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
@ -19,6 +30,15 @@ function setAnalytics(enabled) {
|
|||||||
if (response.status === 200) {
|
if (response.status === 200) {
|
||||||
console.log('Analytics setting updated successfully');
|
console.log('Analytics setting updated successfully');
|
||||||
bootstrap.Modal.getInstance(document.getElementById('analyticsModal')).hide();
|
bootstrap.Modal.getInstance(document.getElementById('analyticsModal')).hide();
|
||||||
|
|
||||||
|
if (typeof CookieConsent !== "undefined") {
|
||||||
|
if (enabled) {
|
||||||
|
CookieConsent.acceptCategory(['analytics']);
|
||||||
|
} else {
|
||||||
|
CookieConsent.acceptCategory([]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} else if (response.status === 208) {
|
} else if (response.status === 208) {
|
||||||
console.log('Analytics setting has already been set. Please edit /config/settings.yml to change it.', response);
|
console.log('Analytics setting has already been set. Please edit /config/settings.yml to change it.', response);
|
||||||
alert('Analytics setting has already been set. Please edit /config/settings.yml to change it.');
|
alert('Analytics setting has already been set. Please edit /config/settings.yml to change it.');
|
||||||
|
@ -299,21 +299,42 @@ document.getElementById("addOperationBtn").addEventListener("click", function ()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
listItem.innerHTML = `
|
let containerDiv = document.createElement("div");
|
||||||
<div class="d-flex justify-content-between align-items-center w-100">
|
containerDiv.className = "d-flex justify-content-between align-items-center w-100";
|
||||||
<div class="operationName">${selectedOperation}</div>
|
|
||||||
<div class="arrows d-flex">
|
let operationNameDiv = document.createElement("div");
|
||||||
<button class="btn btn-secondary move-up ms-1"><span class="material-symbols-rounded">arrow_upward</span></button>
|
operationNameDiv.className = "operationName";
|
||||||
<button class="btn btn-secondary move-down ms-1"><span class="material-symbols-rounded">arrow_downward</span></button>
|
operationNameDiv.textContent = selectedOperation;
|
||||||
<button class="btn ${hasSettings ? "btn-warning" : "btn-secondary"} pipelineSettings ms-1" ${
|
containerDiv.appendChild(operationNameDiv);
|
||||||
hasSettings ? "" : "disabled"
|
|
||||||
}>
|
let arrowsDiv = document.createElement("div");
|
||||||
<span class="material-symbols-rounded">settings</span>
|
arrowsDiv.className = "arrows d-flex";
|
||||||
</button>
|
|
||||||
<button class="btn btn-danger remove ms-1"><span class="material-symbols-rounded">close</span></button>
|
let moveUpButton = document.createElement("button");
|
||||||
</div>
|
moveUpButton.className = "btn btn-secondary move-up ms-1";
|
||||||
</div>
|
moveUpButton.innerHTML = '<span class="material-symbols-rounded">arrow_upward</span>';
|
||||||
`;
|
arrowsDiv.appendChild(moveUpButton);
|
||||||
|
|
||||||
|
let moveDownButton = document.createElement("button");
|
||||||
|
moveDownButton.className = "btn btn-secondary move-down ms-1";
|
||||||
|
moveDownButton.innerHTML = '<span class="material-symbols-rounded">arrow_downward</span>';
|
||||||
|
arrowsDiv.appendChild(moveDownButton);
|
||||||
|
|
||||||
|
let settingsButton = document.createElement("button");
|
||||||
|
settingsButton.className = `btn ${hasSettings ? "btn-warning" : "btn-secondary"} pipelineSettings ms-1`;
|
||||||
|
if (!hasSettings) {
|
||||||
|
settingsButton.disabled = true;
|
||||||
|
}
|
||||||
|
settingsButton.innerHTML = '<span class="material-symbols-rounded">settings</span>';
|
||||||
|
arrowsDiv.appendChild(settingsButton);
|
||||||
|
|
||||||
|
let removeButton = document.createElement("button");
|
||||||
|
removeButton.className = "btn btn-danger remove ms-1";
|
||||||
|
removeButton.innerHTML = '<span class="material-symbols-rounded">close</span>';
|
||||||
|
arrowsDiv.appendChild(removeButton);
|
||||||
|
|
||||||
|
containerDiv.appendChild(arrowsDiv);
|
||||||
|
listItem.appendChild(containerDiv);
|
||||||
|
|
||||||
pipelineList.appendChild(listItem);
|
pipelineList.appendChild(listItem);
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ TabContainer = {
|
|||||||
tabList.classList.add('tab-buttons');
|
tabList.classList.add('tab-buttons');
|
||||||
tabTitles.forEach((title) => {
|
tabTitles.forEach((title) => {
|
||||||
const tabButton = document.createElement('button');
|
const tabButton = document.createElement('button');
|
||||||
tabButton.innerHTML = title;
|
tabButton.textContent = title;
|
||||||
tabButton.onclick = (e) => {
|
tabButton.onclick = (e) => {
|
||||||
this.setActiveTab(e.target);
|
this.setActiveTab(e.target);
|
||||||
};
|
};
|
||||||
|
@ -34,16 +34,32 @@
|
|||||||
<span class="tool-header-text" th:text="#{adminUserSettings.header}">Admin User Control Settings</span>
|
<span class="tool-header-text" th:text="#{adminUserSettings.header}">Admin User Control Settings</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- User Settings Title -->
|
<!-- User Settings Title -->
|
||||||
<div
|
<div style="background: var(--md-sys-color-outline-variant);padding: .8rem; margin: 10px 0; border-radius: 2rem; text-align: center;">
|
||||||
style="background: var(--md-sys-color-outline-variant);padding: .8rem; margin: 10px 0; border-radius: 2rem; text-align: center;">
|
<a href="#"
|
||||||
<a href="#" th:data-bs-toggle="${totalUsers >= maxPaidUsers} ? null : 'modal'"
|
th:data-bs-toggle="${@runningProOrHigher && totalUsers >= maxPaidUsers} ? null : 'modal'"
|
||||||
th:data-bs-target="${@runningProOrHigher && totalUsers >= maxPaidUsers} ? null : '#addUserModal'"
|
th:data-bs-target="${@runningProOrHigher && totalUsers >= maxPaidUsers} ? null : '#addUserModal'"
|
||||||
th:class="${totalUsers >= maxPaidUsers} ? 'btn btn-danger' : 'btn btn-outline-success'"
|
th:class="${@runningProOrHigher && totalUsers >= maxPaidUsers} ? 'btn btn-danger' : 'btn btn-outline-success'"
|
||||||
th:title="${totalUsers >= maxPaidUsers} ? #{adminUserSettings.maxUsersReached} : #{adminUserSettings.addUser}">
|
th:title="${@runningProOrHigher && totalUsers >= maxPaidUsers} ? #{adminUserSettings.maxUsersReached} : #{adminUserSettings.addUser}">
|
||||||
<span class="material-symbols-rounded">person_add</span>
|
<span class="material-symbols-rounded">person_add</span>
|
||||||
<span th:text="#{adminUserSettings.addUser}">Add New User</span>
|
<span th:text="#{adminUserSettings.addUser}">Add New User</span>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
|
<a href="#"
|
||||||
|
data-bs-toggle="modal"
|
||||||
|
data-bs-target="#changeUserRoleModal"
|
||||||
|
class="btn btn-outline-success"
|
||||||
|
th:title="#{adminUserSettings.changeUserRole}">
|
||||||
|
<span class="material-symbols-rounded">edit</span>
|
||||||
|
<span th:text="#{adminUserSettings.changeUserRole}">Change User's Role</span>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<a th:href="@{'/usage'}" th:if="${@runningEE}"
|
||||||
|
class="btn btn-outline-success"
|
||||||
|
th:title="#{adminUserSettings.usage}">
|
||||||
|
<span class="material-symbols-rounded">analytics</span>
|
||||||
|
<span th:text="#{adminUserSettings.usage}">Usage Statistics</span>
|
||||||
|
</a>
|
||||||
|
|
||||||
<a href="#" data-bs-toggle="modal" data-bs-target="#changeUserRoleModal" class="btn btn-outline-success"
|
<a href="#" data-bs-toggle="modal" data-bs-target="#changeUserRoleModal" class="btn btn-outline-success"
|
||||||
th:title="#{adminUserSettings.changeUserRole}">
|
th:title="#{adminUserSettings.changeUserRole}">
|
||||||
@ -400,10 +416,8 @@
|
|||||||
checkboxContainer.slideDown('fast');
|
checkboxContainer.slideDown('fast');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
</script>
|
||||||
</script>
|
<th:block th:insert="~{fragments/footer.html :: footer}"></th:block>
|
||||||
<th:block th:insert="~{fragments/footer.html :: footer}"></th:block>
|
</div>
|
||||||
</div>
|
</body>
|
||||||
</body>
|
</html>
|
||||||
|
|
||||||
</html>
|
|
||||||
|
@ -41,8 +41,14 @@
|
|||||||
<link rel="stylesheet" th:href="@{'/css/bootstrap-icons.min.css'}">
|
<link rel="stylesheet" th:href="@{'/css/bootstrap-icons.min.css'}">
|
||||||
|
|
||||||
<!-- Pixel, doesn't collect any PII-->
|
<!-- Pixel, doesn't collect any PII-->
|
||||||
<img referrerpolicy="no-referrer-when-downgrade" src="https://pixel.stirlingpdf.com/a.png?x-pxid=4f5fa02f-a065-4efb-bb2c-24509a4b6b92" style="position: absolute; visibility: hidden;"/>
|
<img th:if="${!@disablePixel}" referrerpolicy="no-referrer-when-downgrade"
|
||||||
|
th:src="'https://pixel.stirlingpdf.com/a.png?x-pxid=4f5fa02f-a065-4efb-bb2c-24509a4b6b92'
|
||||||
|
+ '&machineType=' + ${@machineType}
|
||||||
|
+ '&appVersion=' + ${@appVersion}
|
||||||
|
+ '&licenseType=' + ${@license}
|
||||||
|
+ '&loginEnabled=' + ${@loginEnabled}"
|
||||||
|
style="position: absolute; visibility: hidden;" />
|
||||||
|
|
||||||
<!-- Custom -->
|
<!-- Custom -->
|
||||||
<link rel="stylesheet" th:href="@{'/css/general.css'}">
|
<link rel="stylesheet" th:href="@{'/css/general.css'}">
|
||||||
<link rel="stylesheet" th:href="@{'/css/theme/theme.css'}">
|
<link rel="stylesheet" th:href="@{'/css/theme/theme.css'}">
|
||||||
|
@ -1,43 +1,44 @@
|
|||||||
<th:block th:fragment="langs">
|
<th:block th:fragment="langs">
|
||||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('bg_BG', 'Български')}" ></div>
|
<div th:replace="~{fragments/languageEntry :: languageEntry ('bg_BG', 'Български')}"></div>
|
||||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('ar_AR', 'العربية')}" ></div>
|
<div th:replace="~{fragments/languageEntry :: languageEntry ('ar_AR', 'العربية')}"></div>
|
||||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('ca_CA', 'Català')}" ></div>
|
<div th:replace="~{fragments/languageEntry :: languageEntry ('ca_CA', 'Català')}"></div>
|
||||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('zh_CN', '简体中文')}" ></div>
|
<div th:replace="~{fragments/languageEntry :: languageEntry ('zh_CN', '简体中文')}"></div>
|
||||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('zh_TW', '繁體中文')}" ></div>
|
<div th:replace="~{fragments/languageEntry :: languageEntry ('zh_TW', '繁體中文')}"></div>
|
||||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('zh_BO', 'བོད་ཡིག')}" ></div>
|
<div th:replace="~{fragments/languageEntry :: languageEntry ('zh_BO', 'བོད་ཡིག')}"></div>
|
||||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('az_AZ', 'Azərbaycan Dili')}" ></div>
|
<div th:replace="~{fragments/languageEntry :: languageEntry ('az_AZ', 'Azərbaycan Dili')}"></div>
|
||||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('da_DK', 'Dansk')}" ></div>
|
<div th:replace="~{fragments/languageEntry :: languageEntry ('da_DK', 'Dansk')}"></div>
|
||||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('de_DE', 'Deutsch')}" ></div>
|
<div th:replace="~{fragments/languageEntry :: languageEntry ('de_DE', 'Deutsch')}"></div>
|
||||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('en_GB', 'English (GB)')}" ></div>
|
<div th:replace="~{fragments/languageEntry :: languageEntry ('en_GB', 'English (GB)')}"></div>
|
||||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('en_US', 'English (US)')}" ></div>
|
<div th:replace="~{fragments/languageEntry :: languageEntry ('en_US', 'English (US)')}"></div>
|
||||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('eu_ES', 'Euskara')}" ></div>
|
<div th:replace="~{fragments/languageEntry :: languageEntry ('eu_ES', 'Euskara')}"></div>
|
||||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('es_ES', 'Español')}" ></div>
|
<div th:replace="~{fragments/languageEntry :: languageEntry ('es_ES', 'Español')}"></div>
|
||||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('fr_FR', 'Français')}" ></div>
|
<div th:replace="~{fragments/languageEntry :: languageEntry ('fr_FR', 'Français')}"></div>
|
||||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('id_ID', 'Bahasa Indonesia')}" ></div>
|
<div th:replace="~{fragments/languageEntry :: languageEntry ('id_ID', 'Bahasa Indonesia')}"></div>
|
||||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('ga_IE', 'Gaeilge')}" ></div>
|
<div th:replace="~{fragments/languageEntry :: languageEntry ('ga_IE', 'Gaeilge')}"></div>
|
||||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('it_IT', 'Italiano')}" ></div>
|
<div th:replace="~{fragments/languageEntry :: languageEntry ('it_IT', 'Italiano')}"></div>
|
||||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('nl_NL', 'Nederlands')}" ></div>
|
<div th:replace="~{fragments/languageEntry :: languageEntry ('nl_NL', 'Nederlands')}"></div>
|
||||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('fa_IR', 'پارسی')}" ></div>
|
<div th:replace="~{fragments/languageEntry :: languageEntry ('fa_IR', 'پارسی')}"></div>
|
||||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('pl_PL', 'Polski')}" ></div>
|
<div th:replace="~{fragments/languageEntry :: languageEntry ('pl_PL', 'Polski')}"></div>
|
||||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('pt_BR', 'Português (BR)')}" ></div>
|
<div th:replace="~{fragments/languageEntry :: languageEntry ('pt_BR', 'Português (BR)')}"></div>
|
||||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('pt_PT', 'Português (PT)')}" ></div>
|
<div th:replace="~{fragments/languageEntry :: languageEntry ('pt_PT', 'Português (PT)')}"></div>
|
||||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('ro_RO', 'Română')}" ></div>
|
<div th:replace="~{fragments/languageEntry :: languageEntry ('ro_RO', 'Română')}"></div>
|
||||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('sk_SK', 'Slovenčina')}" ></div>
|
<div th:replace="~{fragments/languageEntry :: languageEntry ('sk_SK', 'Slovenčina')}"></div>
|
||||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('sl_SI', 'Slovenščina')}" ></div>
|
<div th:replace="~{fragments/languageEntry :: languageEntry ('sl_SI', 'Slovenščina')}"></div>
|
||||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('sv_SE', 'Svenska')}" ></div>
|
<div th:replace="~{fragments/languageEntry :: languageEntry ('sv_SE', 'Svenska')}"></div>
|
||||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('tr_TR', 'Türkçe')}" ></div>
|
<div th:replace="~{fragments/languageEntry :: languageEntry ('tr_TR', 'Türkçe')}"></div>
|
||||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('ru_RU', 'Русский')}" ></div>
|
<div th:replace="~{fragments/languageEntry :: languageEntry ('ru_RU', 'Русский')}"></div>
|
||||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('ko_KR', '한국어')}" ></div>
|
<div th:replace="~{fragments/languageEntry :: languageEntry ('ko_KR', '한국어')}"></div>
|
||||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('ja_JP', '日本語')}" ></div>
|
<div th:replace="~{fragments/languageEntry :: languageEntry ('ja_JP', '日本語')}"></div>
|
||||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('el_GR', 'Ελληνικά')}" ></div>
|
<div th:replace="~{fragments/languageEntry :: languageEntry ('el_GR', 'Ελληνικά')}"></div>
|
||||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('hu_HU', 'Magyar')}" ></div>
|
<div th:replace="~{fragments/languageEntry :: languageEntry ('hu_HU', 'Magyar')}"></div>
|
||||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('hi_IN', 'हिन्दी')}" ></div>
|
<div th:replace="~{fragments/languageEntry :: languageEntry ('hi_IN', 'हिन्दी')}"></div>
|
||||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('sr_LATN_RS', 'Srpski')}" ></div>
|
<div th:replace="~{fragments/languageEntry :: languageEntry ('sr_LATN_RS', 'Srpski')}"></div>
|
||||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('uk_UA', 'Українська')}" ></div>
|
<div th:replace="~{fragments/languageEntry :: languageEntry ('uk_UA', 'Українська')}"></div>
|
||||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('cs_CZ', 'Česky')}" ></div>
|
<div th:replace="~{fragments/languageEntry :: languageEntry ('cs_CZ', 'Česky')}"></div>
|
||||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('hr_HR', 'Hrvatski')}" ></div>
|
<div th:replace="~{fragments/languageEntry :: languageEntry ('hr_HR', 'Hrvatski')}"></div>
|
||||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('no_NB', 'Norsk')}" ></div>
|
<div th:replace="~{fragments/languageEntry :: languageEntry ('no_NB', 'Norsk')}"></div>
|
||||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('th_TH', 'ไทย')}" ></div>
|
<div th:replace="~{fragments/languageEntry :: languageEntry ('th_TH', 'ไทย')}"></div>
|
||||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('vi_VN', 'Tiếng Việt')}"></div>
|
<div th:replace="~{fragments/languageEntry :: languageEntry ('vi_VN', 'Tiếng Việt')}"></div>
|
||||||
|
<div th:replace="~{fragments/languageEntry :: languageEntry ('ml_IN', 'മലയാളം')}"></div>
|
||||||
|
|
||||||
</th:block>
|
</th:block>
|
@ -1,4 +1,4 @@
|
|||||||
<div th:fragment="navbar" class="mx-auto" style="position: sticky; top:0; z-index:10000">
|
<div th:fragment="navbar" class="mx-auto" style="position: sticky; top:0; z-index:10000; width:100%">
|
||||||
<script th:src="@{'/js/languageSelection.js'}"></script>
|
<script th:src="@{'/js/languageSelection.js'}"></script>
|
||||||
<script th:src="@{'/js/navbar.js'}"></script>
|
<script th:src="@{'/js/navbar.js'}"></script>
|
||||||
<script th:src="@{'/js/additionalLanguageCode.js'}"></script>
|
<script th:src="@{'/js/additionalLanguageCode.js'}"></script>
|
||||||
|
@ -7,20 +7,18 @@
|
|||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<div id="page-container">
|
<div id="page-container">
|
||||||
<div id="content-wrap">
|
<th:block th:insert="~{fragments/navbar.html :: navbar}"></th:block>
|
||||||
<th:block th:insert="~{fragments/navbar.html :: navbar}"></th:block>
|
<div style="transform-origin: top;"
|
||||||
|
id="scale-wrap">
|
||||||
|
|
||||||
|
|
||||||
<br class="d-md-none">
|
<br class="d-md-none">
|
||||||
<!-- Features -->
|
<!-- Features -->
|
||||||
<script th:src="@{'/js/homecard.js'}"></script>
|
<script th:src="@{'/js/homecard.js'}"></script>
|
||||||
<div style="
|
<div style="
|
||||||
width: 100%;
|
width: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;">
|
flex-direction: column;"
|
||||||
|
>
|
||||||
<div>
|
<div>
|
||||||
<br>
|
<br>
|
||||||
<div style="justify-content: center; display: flex;">
|
<div style="justify-content: center; display: flex;">
|
||||||
@ -45,7 +43,7 @@
|
|||||||
th:insert="~{fragments/navbarEntry :: navbarEntry ('multi-tool', 'construction', 'home.multiTool.title', 'home.multiTool.desc', 'multiTool.tags', 'organize')}">
|
th:insert="~{fragments/navbarEntry :: navbarEntry ('multi-tool', 'construction', 'home.multiTool.title', 'home.multiTool.desc', 'multiTool.tags', 'organize')}">
|
||||||
</div>
|
</div>
|
||||||
<div class="newfeature"
|
<div class="newfeature"
|
||||||
th:insert="~{fragments/navbarEntry :: navbarEntry('validate-signature', 'verified', 'home.validateSignature.title', 'home.validateSignature.desc', 'validateSignature.tags', 'security')}">
|
th:insert="~{fragments/navbarEntry :: navbarEntry('compress-pdf', 'zoom_in_map', 'home.compressPdfs.title', 'home.compressPdfs.desc', 'compressPDFs.tags', 'advance')}">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -123,9 +121,10 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
<th:block th:insert="~{fragments/footer.html :: footer}"></th:block>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<th:block th:insert="~{fragments/footer.html :: footer}"></th:block>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
@ -222,7 +221,21 @@
|
|||||||
window.showSurvey = /*[[${showSurveyFromDocker}]]*/ true
|
window.showSurvey = /*[[${showSurveyFromDocker}]]*/ true
|
||||||
</script>
|
</script>
|
||||||
<script th:src="@{'/js/pages/home.js'}" th:inline="javascript"></script>
|
<script th:src="@{'/js/pages/home.js'}" th:inline="javascript"></script>
|
||||||
|
<script>
|
||||||
|
function applyScale() {
|
||||||
|
const baseWidth = 1440;
|
||||||
|
const baseHeight = 1000;
|
||||||
|
const scaleX = window.innerWidth / baseWidth;
|
||||||
|
const scaleY = window.innerHeight / baseHeight;
|
||||||
|
const scale = Math.max(0.9, Math.min(scaleX, scaleY)); // keep aspect ratio, honor minScale
|
||||||
|
const ui = document.getElementById('scale-wrap');
|
||||||
|
ui.style.transform = `scale(${scale*0.75})`;
|
||||||
|
}
|
||||||
|
|
||||||
|
window.addEventListener('resize', applyScale);
|
||||||
|
window.addEventListener('load', applyScale);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
|
@ -41,36 +41,36 @@
|
|||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label class="mb-2" th:text="#{addPassword.selectText.5}"></label>
|
<label class="mb-2" th:text="#{addPassword.selectText.5}"></label>
|
||||||
<div class="form-check ms-3">
|
<div class="form-check ms-3">
|
||||||
<input type="checkbox" id="canAssembleDocument" name="canAssembleDocument">
|
<input type="checkbox" id="preventAssembly" name="preventAssembly">
|
||||||
<label for="canAssembleDocument" th:text="#{addPassword.selectText.6}"></label>
|
<label for="preventAssembly" th:text="#{addPassword.selectText.6}"></label>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-check ms-3">
|
<div class="form-check ms-3">
|
||||||
<input type="checkbox" id="canExtractContent" name="canExtractContent">
|
<input type="checkbox" id="preventExtractContent" name="preventExtractContent">
|
||||||
<label for="canExtractContent" th:text="#{addPassword.selectText.7}"></label>
|
<label for="preventExtractContent" th:text="#{addPassword.selectText.7}"></label>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-check ms-3">
|
<div class="form-check ms-3">
|
||||||
<input type="checkbox" id="canExtractForAccessibility" name="canExtractForAccessibility">
|
<input type="checkbox" id="preventExtractForAccessibility" name="preventExtractForAccessibility">
|
||||||
<label for="canExtractForAccessibility" th:text="#{addPassword.selectText.8}"></label>
|
<label for="preventExtractForAccessibility" th:text="#{addPassword.selectText.8}"></label>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-check ms-3">
|
<div class="form-check ms-3">
|
||||||
<input type="checkbox" id="canFillInForm" name="canFillInForm">
|
<input type="checkbox" id="preventFillInForm" name="preventFillInForm">
|
||||||
<label for="canFillInForm" th:text="#{addPassword.selectText.9}"></label>
|
<label for="preventFillInForm" th:text="#{addPassword.selectText.9}"></label>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-check ms-3">
|
<div class="form-check ms-3">
|
||||||
<input type="checkbox" id="canModify" name="canModify">
|
<input type="checkbox" id="preventModify" name="preventModify">
|
||||||
<label for="canModify" th:text="#{addPassword.selectText.10}"></label>
|
<label for="preventModify" th:text="#{addPassword.selectText.10}"></label>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-check ms-3">
|
<div class="form-check ms-3">
|
||||||
<input type="checkbox" id="canModifyAnnotations" name="canModifyAnnotations">
|
<input type="checkbox" id="preventModifyAnnotations" name="preventModifyAnnotations">
|
||||||
<label for="canModifyAnnotations" th:text="#{addPassword.selectText.11}"></label>
|
<label for="preventModifyAnnotations" th:text="#{addPassword.selectText.11}"></label>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-check ms-3">
|
<div class="form-check ms-3">
|
||||||
<input type="checkbox" id="canPrint" name="canPrint">
|
<input type="checkbox" id="preventPrinting" name="preventPrinting">
|
||||||
<label for="canPrint" th:text="#{addPassword.selectText.12}"></label>
|
<label for="preventPrinting" th:text="#{addPassword.selectText.12}"></label>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-check ms-3">
|
<div class="form-check ms-3">
|
||||||
<input type="checkbox" id="canPrintFaithful" name="canPrintFaithful">
|
<input type="checkbox" id="preventPrintingFaithful" name="preventPrintingFaithful">
|
||||||
<label for="canPrintFaithful" th:text="#{addPassword.selectText.13}"></label>
|
<label for="preventPrintingFaithful" th:text="#{addPassword.selectText.13}"></label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<br>
|
<br>
|
||||||
|
@ -25,36 +25,36 @@
|
|||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label class="mb-2" th:text="#{permissions.selectText.2}"></label>
|
<label class="mb-2" th:text="#{permissions.selectText.2}"></label>
|
||||||
<div class="form-check ms-3">
|
<div class="form-check ms-3">
|
||||||
<input type="checkbox" id="canAssembleDocument" name="canAssembleDocument">
|
<input type="checkbox" id="preventAssembly" name="preventAssembly">
|
||||||
<label for="canAssembleDocument" th:text="#{permissions.selectText.3}"></label>
|
<label for="preventAssembly" th:text="#{permissions.selectText.3}"></label>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-check ms-3">
|
<div class="form-check ms-3">
|
||||||
<input type="checkbox" id="canExtractContent" name="canExtractContent">
|
<input type="checkbox" id="preventExtractContent" name="preventExtractContent">
|
||||||
<label for="canExtractContent" th:text="#{permissions.selectText.4}"></label>
|
<label for="preventExtractContent" th:text="#{permissions.selectText.4}"></label>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-check ms-3">
|
<div class="form-check ms-3">
|
||||||
<input type="checkbox" id="canExtractForAccessibility" name="canExtractForAccessibility">
|
<input type="checkbox" id="preventExtractForAccessibility" name="preventExtractForAccessibility">
|
||||||
<label for="canExtractForAccessibility" th:text="#{permissions.selectText.5}"></label>
|
<label for="preventExtractForAccessibility" th:text="#{permissions.selectText.5}"></label>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-check ms-3">
|
<div class="form-check ms-3">
|
||||||
<input type="checkbox" id="canFillInForm" name="canFillInForm">
|
<input type="checkbox" id="preventFillInForm" name="preventFillInForm">
|
||||||
<label for="canFillInForm" th:text="#{permissions.selectText.6}"></label>
|
<label for="preventFillInForm" th:text="#{permissions.selectText.6}"></label>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-check ms-3">
|
<div class="form-check ms-3">
|
||||||
<input type="checkbox" id="canModify" name="canModify">
|
<input type="checkbox" id="preventModify" name="preventModify">
|
||||||
<label for="canModify" th:text="#{permissions.selectText.7}"></label>
|
<label for="preventModify" th:text="#{permissions.selectText.7}"></label>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-check ms-3">
|
<div class="form-check ms-3">
|
||||||
<input type="checkbox" id="canModifyAnnotations" name="canModifyAnnotations">
|
<input type="checkbox" id="preventModifyAnnotations" name="preventModifyAnnotations">
|
||||||
<label for="canModifyAnnotations" th:text="#{permissions.selectText.8}"></label>
|
<label for="preventModifyAnnotations" th:text="#{permissions.selectText.8}"></label>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-check ms-3">
|
<div class="form-check ms-3">
|
||||||
<input type="checkbox" id="canPrint" name="canPrint">
|
<input type="checkbox" id="preventPrinting" name="preventPrinting">
|
||||||
<label for="canPrint" th:text="#{permissions.selectText.9}"></label>
|
<label for="preventPrinting" th:text="#{permissions.selectText.9}"></label>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-check ms-3">
|
<div class="form-check ms-3">
|
||||||
<input type="checkbox" id="canPrintFaithful" name="canPrintFaithful">
|
<input type="checkbox" id="preventPrintingFaithful" name="preventPrintingFaithful">
|
||||||
<label for="canPrintFaithful" th:text="#{permissions.selectText.10}"></label>
|
<label for="preventPrintingFaithful" th:text="#{permissions.selectText.10}"></label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<br>
|
<br>
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
|
|
||||||
<link rel="stylesheet" th:href="@{'/pdfjs-legacy/css/viewer-redact.css'}">
|
<link rel="stylesheet" th:href="@{'/pdfjs-legacy/css/viewer-redact.css'}">
|
||||||
<script th:src="@{'/pdfjs-legacy/js/viewer.mjs'}" type="module"></script>
|
<script th:src="@{'/pdfjs-legacy/js/viewer.mjs'}" type="module"></script>
|
||||||
<script src='./js/redact.js' type="module"></script>
|
<script th:src="@{'/js/redact.js'}" type="module"></script>
|
||||||
<link rel="stylesheet" th:href="@{'/css/redact.css'}">
|
<link rel="stylesheet" th:href="@{'/css/redact.css'}">
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
@ -695,4 +695,4 @@
|
|||||||
<th:block th:insert="~{fragments/footer.html :: footer}"></th:block>
|
<th:block th:insert="~{fragments/footer.html :: footer}"></th:block>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
|
@ -11,7 +11,6 @@
|
|||||||
# If you want to override with environment parameter follow parameter naming SECURITY_INITIALLOGIN_USERNAME #
|
# If you want to override with environment parameter follow parameter naming SECURITY_INITIALLOGIN_USERNAME #
|
||||||
#############################################################################################################
|
#############################################################################################################
|
||||||
|
|
||||||
|
|
||||||
security:
|
security:
|
||||||
enableLogin: false # set to 'true' to enable login
|
enableLogin: false # set to 'true' to enable login
|
||||||
csrfDisabled: false # set to 'true' to disable CSRF protection (not recommended for production)
|
csrfDisabled: false # set to 'true' to disable CSRF protection (not recommended for production)
|
||||||
@ -62,18 +61,32 @@ security:
|
|||||||
privateKey: classpath:saml-private-key.key # Your private key. Generated from your keypair
|
privateKey: classpath:saml-private-key.key # Your private key. Generated from your keypair
|
||||||
spCert: classpath:saml-public-cert.crt # Your signing certificate. Generated from your keypair
|
spCert: classpath:saml-public-cert.crt # Your signing certificate. Generated from your keypair
|
||||||
|
|
||||||
enterpriseEdition:
|
premium:
|
||||||
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
|
enabled: false # Enable license key checks for pro/enterprise features
|
||||||
CustomMetadata:
|
proFeatures:
|
||||||
autoUpdateMetadata: false # set to 'true' to automatically update metadata with below values
|
SSOAutoLogin: false
|
||||||
author: username # supports text such as 'John Doe' or types such as username to autopopulate with user's username
|
CustomMetadata:
|
||||||
creator: Stirling-PDF # supports text such as 'Company-PDF'
|
autoUpdateMetadata: false # set to 'true' to automatically update metadata with below values
|
||||||
producer: Stirling-PDF # supports text such as 'Company-PDF'
|
author: username # supports text such as 'John Doe' or types such as username to autopopulate with user's username
|
||||||
|
creator: Stirling-PDF # supports text such as 'Company-PDF'
|
||||||
|
producer: Stirling-PDF # supports text such as 'Company-PDF'
|
||||||
|
googleDrive:
|
||||||
|
enabled: false
|
||||||
|
clientId: ''
|
||||||
|
apiKey: ''
|
||||||
|
appId: ''
|
||||||
|
|
||||||
|
mail:
|
||||||
|
enabled: false # set to 'true' to enable sending emails
|
||||||
|
host: smtp.example.com # SMTP server hostname
|
||||||
|
port: 587 # SMTP server port
|
||||||
|
username: '' # SMTP server username
|
||||||
|
password: '' # SMTP server password
|
||||||
|
from: '' # sender email address
|
||||||
|
|
||||||
legal:
|
legal:
|
||||||
termsAndConditions: https://www.stirlingpdf.com/terms-and-conditions # URL to the terms and conditions of your application (e.g. https://example.com/terms). Empty string to disable or filename to load from local file in static folder
|
termsAndConditions: https://www.stirlingpdf.com/terms # URL to the terms and conditions of your application (e.g. https://example.com/terms). Empty string to disable or filename to load from local file in static folder
|
||||||
privacyPolicy: https://www.stirlingpdf.com/privacy-policy # URL to the privacy policy of your application (e.g. https://example.com/privacy). Empty string to disable or filename to load from local file in static folder
|
privacyPolicy: https://www.stirlingpdf.com/privacy-policy # URL to the privacy policy of your application (e.g. https://example.com/privacy). Empty string to disable or filename to load from local file in static folder
|
||||||
accessibilityStatement: '' # URL to the accessibility statement of your application (e.g. https://example.com/accessibility). Empty string to disable or filename to load from local file in static folder
|
accessibilityStatement: '' # URL to the accessibility statement of your application (e.g. https://example.com/accessibility). Empty string to disable or filename to load from local file in static folder
|
||||||
cookiePolicy: '' # URL to the cookie policy of your application (e.g. https://example.com/cookie). Empty string to disable or filename to load from local file in static folder
|
cookiePolicy: '' # URL to the cookie policy of your application (e.g. https://example.com/cookie). Empty string to disable or filename to load from local file in static folder
|
||||||
@ -88,6 +101,7 @@ system:
|
|||||||
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: true # set to 'true' to enable analytics, set to 'false' to disable analytics; for enterprise users, this is set to true
|
||||||
|
enableUrlToPDF: false # Set to 'true' to enable URL to PDF, INTERNAL ONLY, known security issues, should not be used externally
|
||||||
disableSanitize: false # set to true to disable Sanitize HTML; (can lead to injections in HTML)
|
disableSanitize: false # set to true to disable Sanitize HTML; (can lead to injections in HTML)
|
||||||
datasource:
|
datasource:
|
||||||
enableCustomDatabase: false # Enterprise users ONLY, set this property to 'true' if you would like to use your own custom database configuration
|
enableCustomDatabase: false # Enterprise users ONLY, set this property to 'true' if you would like to use your own custom database configuration
|
||||||
@ -100,13 +114,12 @@ system:
|
|||||||
name: postgres # set the name of your database. Should match the name of the database you create
|
name: postgres # set the name of your database. Should match the name of the database you create
|
||||||
customPaths:
|
customPaths:
|
||||||
pipeline:
|
pipeline:
|
||||||
watchedFoldersDir: "" #Defaults to /pipeline/watchedFolders
|
watchedFoldersDir: '' # Defaults to /pipeline/watchedFolders
|
||||||
finishedFoldersDir: "" #Defaults to /pipeline/finishedFolders
|
finishedFoldersDir: '' # Defaults to /pipeline/finishedFolders
|
||||||
operations:
|
operations:
|
||||||
weasyprint: "" #Defaults to /opt/venv/bin/weasyprint
|
weasyprint: '' # Defaults to /opt/venv/bin/weasyprint
|
||||||
unoconvert: "" #Defaults to /opt/venv/bin/unoconvert
|
unoconvert: '' # Defaults to /opt/venv/bin/unoconvert
|
||||||
|
fileUploadLimit: '' # Defaults to "". No limit when string is empty. Set a number, between 0 and 999, followed by one of the following strings to set a limit. "KB", "MB", "GB".
|
||||||
|
|
||||||
|
|
||||||
ui:
|
ui:
|
||||||
appName: '' # application's visible name
|
appName: '' # application's visible name
|
||||||
|
Loading…
Reference in New Issue
Block a user