mirror of
https://github.com/Frooodle/Stirling-PDF.git
synced 2025-09-08 17:51:20 +02:00
Add internal legal policy pages and config support
This commit is contained in:
parent
4b6ac87419
commit
7c503eea6d
@ -106,6 +106,14 @@ public class ApplicationProperties {
|
|||||||
private String accessibilityStatement;
|
private String accessibilityStatement;
|
||||||
private String cookiePolicy;
|
private String cookiePolicy;
|
||||||
private String impressum;
|
private String impressum;
|
||||||
|
private ApiContact apiContact = new ApiContact();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public static class ApiContact {
|
||||||
|
private String company;
|
||||||
|
private String website;
|
||||||
|
private String email;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
package stirling.software.SPDF.config;
|
package stirling.software.SPDF.config;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Qualifier;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
@ -11,57 +14,90 @@ 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;
|
||||||
|
|
||||||
import lombok.RequiredArgsConstructor;
|
|
||||||
|
|
||||||
import stirling.software.common.model.ApplicationProperties;
|
import stirling.software.common.model.ApplicationProperties;
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
@RequiredArgsConstructor
|
|
||||||
public class OpenApiConfig {
|
public class OpenApiConfig {
|
||||||
|
|
||||||
private final ApplicationProperties applicationProperties;
|
private final ApplicationProperties applicationProperties;
|
||||||
|
private final boolean runningProOrHigher;
|
||||||
|
|
||||||
private static final String DEFAULT_TITLE = "Stirling PDF API";
|
public OpenApiConfig(
|
||||||
|
ApplicationProperties applicationProperties,
|
||||||
|
@Qualifier("runningProOrHigher") boolean runningProOrHigher) {
|
||||||
|
this.applicationProperties = applicationProperties;
|
||||||
|
this.runningProOrHigher = runningProOrHigher;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final String DEFAULT_COMPANY = "Stirling Software";
|
||||||
private static final String DEFAULT_DESCRIPTION =
|
private static final String DEFAULT_DESCRIPTION =
|
||||||
"API documentation for all Server-Side processing.\n"
|
"API documentation for all Server-Side processing.\n"
|
||||||
+ "Please note some functionality might be UI only and missing from here.";
|
+ "Please note some functionality might be UI only and missing from here.";
|
||||||
|
private static final String DEFAULT_EMAIL = "contact@stirlingpdf.com";
|
||||||
|
private static final String DEFAULT_TERMS_OF_SERVICE = "https://www.stirlingpdf.com/terms";
|
||||||
|
private static final String DEFAULT_TITLE = "Stirling PDF API";
|
||||||
|
private static final String DEFAULT_WEBSITE = "https://www.stirlingpdf.com";
|
||||||
|
private static final String DEFAULT_VERSION = "1.0.0";
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public OpenAPI customOpenAPI() {
|
public OpenAPI customOpenAPI() {
|
||||||
String version = getClass().getPackage().getImplementationVersion();
|
String version =
|
||||||
if (version == null) {
|
Optional.ofNullable(applicationProperties.getAutomaticallyGenerated())
|
||||||
// default version if all else fails
|
.map(ApplicationProperties.AutomaticallyGenerated::getAppVersion)
|
||||||
version = "1.0.0";
|
.filter(v -> !v.isBlank())
|
||||||
|
.orElseGet(
|
||||||
|
() -> {
|
||||||
|
String v = getClass().getPackage().getImplementationVersion();
|
||||||
|
return v != null ? v : DEFAULT_VERSION;
|
||||||
|
});
|
||||||
|
String title = DEFAULT_TITLE;
|
||||||
|
String description = DEFAULT_DESCRIPTION;
|
||||||
|
String termsOfService = DEFAULT_TERMS_OF_SERVICE;
|
||||||
|
String company = DEFAULT_COMPANY;
|
||||||
|
String email = DEFAULT_EMAIL;
|
||||||
|
String website = DEFAULT_WEBSITE;
|
||||||
|
|
||||||
|
License license =
|
||||||
|
new License()
|
||||||
|
.name("MIT License")
|
||||||
|
.url(
|
||||||
|
"https://raw.githubusercontent.com/Stirling-Tools/Stirling-PDF/refs/heads/main/LICENSE")
|
||||||
|
.identifier("MIT");
|
||||||
|
|
||||||
|
if (runningProOrHigher) {
|
||||||
|
ApplicationProperties.Ui ui = applicationProperties.getUi();
|
||||||
|
ApplicationProperties.Legal legal = applicationProperties.getLegal();
|
||||||
|
|
||||||
|
ApplicationProperties.ApiContact apiContact = legal.getApiContact();
|
||||||
|
title = Optional.ofNullable(ui.getAppName()).orElse(title);
|
||||||
|
description = Optional.ofNullable(ui.getHomeDescription()).orElse(description);
|
||||||
|
termsOfService =
|
||||||
|
Optional.ofNullable(legal.getTermsAndConditions()).orElse(termsOfService);
|
||||||
|
company = Optional.ofNullable(apiContact.getCompany()).orElse(company);
|
||||||
|
website = Optional.ofNullable(apiContact.getWebsite()).orElse(website);
|
||||||
|
email = Optional.ofNullable(apiContact.getEmail()).orElse(email);
|
||||||
}
|
}
|
||||||
|
Contact contact = new Contact().name(company).url(website).email(email);
|
||||||
|
|
||||||
Info info =
|
Info info =
|
||||||
new Info()
|
new Info()
|
||||||
.title(DEFAULT_TITLE)
|
.title(title)
|
||||||
.version(version)
|
.version(version)
|
||||||
.license(
|
.license(license)
|
||||||
new License()
|
.termsOfService(termsOfService)
|
||||||
.name("MIT")
|
.contact(contact)
|
||||||
.url(
|
.description(description);
|
||||||
"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().components(new Components()).info(info);
|
return new OpenAPI().components(new Components()).info(info);
|
||||||
} else {
|
|
||||||
SecurityScheme apiKeyScheme =
|
|
||||||
new SecurityScheme()
|
|
||||||
.type(SecurityScheme.Type.APIKEY)
|
|
||||||
.in(SecurityScheme.In.HEADER)
|
|
||||||
.name("X-API-KEY");
|
|
||||||
return new OpenAPI()
|
|
||||||
.components(new Components().addSecuritySchemes("apiKey", apiKeyScheme))
|
|
||||||
.info(info)
|
|
||||||
.addSecurityItem(new SecurityRequirement().addList("apiKey"));
|
|
||||||
}
|
}
|
||||||
|
SecurityScheme apiKeyScheme =
|
||||||
|
new SecurityScheme()
|
||||||
|
.type(SecurityScheme.Type.APIKEY)
|
||||||
|
.in(SecurityScheme.In.HEADER)
|
||||||
|
.name("X-API-KEY");
|
||||||
|
return new OpenAPI()
|
||||||
|
.components(new Components().addSecuritySchemes("apiKey", apiKeyScheme))
|
||||||
|
.info(info)
|
||||||
|
.addSecurityItem(new SecurityRequirement().addList("apiKey"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,11 +8,13 @@ import java.util.Map;
|
|||||||
|
|
||||||
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.http.HttpStatus;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
import org.springframework.ui.Model;
|
import org.springframework.ui.Model;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.ResponseBody;
|
import org.springframework.web.bind.annotation.ResponseBody;
|
||||||
|
import org.springframework.web.server.ResponseStatusException;
|
||||||
|
|
||||||
import com.fasterxml.jackson.core.type.TypeReference;
|
import com.fasterxml.jackson.core.type.TypeReference;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
@ -44,8 +46,7 @@ public class HomeWebController {
|
|||||||
public String licensesForm(Model model) {
|
public String licensesForm(Model model) {
|
||||||
model.addAttribute("currentPage", "licenses");
|
model.addAttribute("currentPage", "licenses");
|
||||||
Resource resource = new ClassPathResource("static/3rdPartyLicenses.json");
|
Resource resource = new ClassPathResource("static/3rdPartyLicenses.json");
|
||||||
try {
|
try (InputStream is = resource.getInputStream()) {
|
||||||
InputStream is = resource.getInputStream();
|
|
||||||
String json = new String(is.readAllBytes(), StandardCharsets.UTF_8);
|
String json = new String(is.readAllBytes(), StandardCharsets.UTF_8);
|
||||||
ObjectMapper mapper = new ObjectMapper();
|
ObjectMapper mapper = new ObjectMapper();
|
||||||
Map<String, List<Dependency>> data = mapper.readValue(json, new TypeReference<>() {});
|
Map<String, List<Dependency>> data = mapper.readValue(json, new TypeReference<>() {});
|
||||||
@ -56,6 +57,42 @@ public class HomeWebController {
|
|||||||
return "licenses";
|
return "licenses";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GetMapping("/impressum")
|
||||||
|
@Hidden
|
||||||
|
public String impressum() {
|
||||||
|
String impressum = applicationProperties.getLegal().getImpressum();
|
||||||
|
return internalPage(impressum, "impressum");
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/cookiePolicy")
|
||||||
|
@Hidden
|
||||||
|
public String cookiePolicy() {
|
||||||
|
String cookiePolicy = applicationProperties.getLegal().getCookiePolicy();
|
||||||
|
return internalPage(cookiePolicy, "cookiePolicy");
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/privacyPolicy")
|
||||||
|
@Hidden
|
||||||
|
public String privacyPolicy() {
|
||||||
|
String privacyPolicy = applicationProperties.getLegal().getPrivacyPolicy();
|
||||||
|
return internalPage(privacyPolicy, "privacyPolicy");
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/termsAndConditions")
|
||||||
|
@Hidden
|
||||||
|
public String termsAndConditions() {
|
||||||
|
String termsAndConditions = applicationProperties.getLegal().getTermsAndConditions();
|
||||||
|
return internalPage(termsAndConditions, "termsAndConditions");
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/accessibilityStatement")
|
||||||
|
@Hidden
|
||||||
|
public String accessibilityStatement() {
|
||||||
|
String accessibilityStatement =
|
||||||
|
applicationProperties.getLegal().getAccessibilityStatement();
|
||||||
|
return internalPage(accessibilityStatement, "accessibilityStatement");
|
||||||
|
}
|
||||||
|
|
||||||
@GetMapping("/releases")
|
@GetMapping("/releases")
|
||||||
public String getReleaseNotes(Model model) {
|
public String getReleaseNotes(Model model) {
|
||||||
return "releases";
|
return "releases";
|
||||||
@ -91,4 +128,11 @@ public class HomeWebController {
|
|||||||
return "User-agent: Googlebot\nDisallow: /\n\nUser-agent: *\nDisallow: /";
|
return "User-agent: Googlebot\nDisallow: /\n\nUser-agent: *\nDisallow: /";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String internalPage(String configured, String view) {
|
||||||
|
if (configured != null && (("/" + view).equals(configured) || view.equals(configured))) {
|
||||||
|
return view;
|
||||||
|
}
|
||||||
|
throw new ResponseStatusException(HttpStatus.NOT_FOUND);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -95,12 +95,33 @@ mail:
|
|||||||
password: '' # SMTP server password
|
password: '' # SMTP server password
|
||||||
from: '' # sender email address
|
from: '' # sender email address
|
||||||
|
|
||||||
|
#############################################################################################################
|
||||||
|
# Declaration of settings for URLs #
|
||||||
|
# #
|
||||||
|
# To disable, set termsAndConditions, privacyPolicy, accessibilityStatement, cookiePolicy, impressum to '/' #
|
||||||
|
# #
|
||||||
|
# If you want to use an internal file, place the file in the 'customFiles/templates/' folder #
|
||||||
|
# For termsAndConditions, the file must be named termsAndConditions.html #
|
||||||
|
# For privacyPolicy, the file must be named privacyPolicy.html #
|
||||||
|
# For accessibilityStatement, the file must be named accessibilityStatement.html #
|
||||||
|
# For cookiePolicy, the file must be named cookiePolicy.html #
|
||||||
|
# For impressum, the file must be named impressum.html #
|
||||||
|
# To use an internal URL, it must be entered without `.html` #
|
||||||
|
# #
|
||||||
|
# For example: termsAndConditions: /termsAndConditions #
|
||||||
|
# #
|
||||||
|
# You can also use external URLs, for example: https://example.com/terms #
|
||||||
|
#############################################################################################################
|
||||||
legal:
|
legal:
|
||||||
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
|
termsAndConditions: / # URL to the terms and conditions of your application
|
||||||
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: / # URL to the privacy policy of your application
|
||||||
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
|
||||||
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
|
||||||
impressum: '' # URL to the impressum of your application (e.g. https://example.com/impressum). Empty string to disable or filename to load from local file in static folder
|
impressum: /impressum # URL to the impressum of your application
|
||||||
|
apiContact: # ONLY pro/enterprise features
|
||||||
|
company: Stirling Software
|
||||||
|
email: contact@stirlingpdf.com
|
||||||
|
website: https://www.stirlingpdf.com
|
||||||
|
|
||||||
system:
|
system:
|
||||||
defaultLocale: en-US # set the default language (e.g. 'de-DE', 'fr-FR', etc)
|
defaultLocale: en-US # set the default language (e.g. 'de-DE', 'fr-FR', etc)
|
||||||
|
@ -0,0 +1,58 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html th:lang="${#locale.language}"
|
||||||
|
th:dir="#{language.direction}"
|
||||||
|
th:data-language="${#locale.toString()}"
|
||||||
|
xmlns:th="https://www.thymeleaf.org">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<th:block th:insert="~{fragments/common :: head(title=#{legal.accessibility}, header=#{legal.accessibility})}"></th:block>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div id="page-container">
|
||||||
|
<div id="content-wrap">
|
||||||
|
<th:block th:insert="~{fragments/navbar.html :: navbar}"></th:block>
|
||||||
|
<br><br>
|
||||||
|
<div class="container">
|
||||||
|
<div class="row justify-content-center">
|
||||||
|
<div class="col-md-8 bg-card">
|
||||||
|
<div class="tool-header">
|
||||||
|
<span class="material-symbols-rounded tool-header-icon organize">accessibility</span>
|
||||||
|
<span class="tool-header-text"
|
||||||
|
th:text="#{legal.accessibility}">Accessibility</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- start Note: sample page -->
|
||||||
|
<section id="note-sample-page">
|
||||||
|
<div class="alert alert-warning"
|
||||||
|
role="alert">
|
||||||
|
<strong>Note:</strong> This is a <em>sample page</em>; all information is placeholder content for
|
||||||
|
demonstration purposes only.
|
||||||
|
<br>
|
||||||
|
<br>
|
||||||
|
<li>Enable <code>customHTMLFiles</code> in the configuration to use custom HTML files, which can be found <a
|
||||||
|
href="https://docs.stirlingpdf.com/Advanced%20Configuration/UI%20Customisation#custom-files"
|
||||||
|
target="_blank">here</a>.</li>
|
||||||
|
<li>Create a file named <code>accessibilityStatement.html</code> in the folder
|
||||||
|
<code>customFiles/templates</code>.</li>
|
||||||
|
<li>Copy the content of this file from <a
|
||||||
|
href="https://raw.githubusercontent.com/Stirling-Tools/Stirling-PDF/refs/heads/main/app/core/src/main/resources/templates/accessibilityStatement.html"
|
||||||
|
target="_blank">accessibilityStatement.html</a> into the newly created file.</li>
|
||||||
|
<li>Customize the layout and design of the page.</li>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<!-- end Note: sample page -->
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<h2>Accessibility Statement</h2>
|
||||||
|
<p>This is the accessibility statement for our application.</p>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<th:block th:insert="~{fragments/footer.html :: footer}"></th:block>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
58
app/core/src/main/resources/templates/cookiePolicy.html
Normal file
58
app/core/src/main/resources/templates/cookiePolicy.html
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html th:lang="${#locale.language}"
|
||||||
|
th:dir="#{language.direction}"
|
||||||
|
th:data-language="${#locale.toString()}"
|
||||||
|
xmlns:th="https://www.thymeleaf.org">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<th:block th:insert="~{fragments/common :: head(title=#{legal.cookie}, header=#{legal.cookie})}"></th:block>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div id="page-container">
|
||||||
|
<div id="content-wrap">
|
||||||
|
<th:block th:insert="~{fragments/navbar.html :: navbar}"></th:block>
|
||||||
|
<br><br>
|
||||||
|
<div class="container">
|
||||||
|
<div class="row justify-content-center">
|
||||||
|
<div class="col-md-8 bg-card p-4">
|
||||||
|
<div class="tool-header">
|
||||||
|
<span class="material-symbols-rounded tool-header-icon">cookie</span>
|
||||||
|
<span class="tool-header-text"
|
||||||
|
th:text="#{legal.cookie}">Cookie Policy</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- start Note: sample page -->
|
||||||
|
<section id="note-sample-page">
|
||||||
|
<div class="alert alert-warning"
|
||||||
|
role="alert">
|
||||||
|
<strong>Note:</strong> This is a <em>sample page</em>; all information is placeholder content for
|
||||||
|
demonstration purposes only.
|
||||||
|
<br>
|
||||||
|
<br>
|
||||||
|
<li>Enable <code>customHTMLFiles</code> in the configuration to use custom HTML files, which can be found <a
|
||||||
|
href="https://docs.stirlingpdf.com/Advanced%20Configuration/UI%20Customisation#custom-files"
|
||||||
|
target="_blank">here</a>.</li>
|
||||||
|
<li>Create a file named <code>cookiePolicy.html</code> in the folder <code>customFiles/templates</code>.</li>
|
||||||
|
<li>Copy the content of this file from <a
|
||||||
|
href="https://raw.githubusercontent.com/Stirling-Tools/Stirling-PDF/refs/heads/main/app/core/src/main/resources/templates/cookiePolicy.html"
|
||||||
|
target="_blank">cookiePolicy.html</a> into the newly created file.</li>
|
||||||
|
<li>Customize the layout and design of the page.</li>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<!-- end Note: sample page -->
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<h2>Cookie Policy</h2>
|
||||||
|
<p>This application uses cookies to enhance your browsing experience. By continuing to use the site, you agree
|
||||||
|
to the use of cookies.</p>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<th:block th:insert="~{fragments/footer.html :: footer}"></th:block>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
@ -8,11 +8,11 @@
|
|||||||
<li><a class="footer-link px-2" id="licenses" target="_blank" th:href="@{'/licenses'}" th:text="#{licenses.nav}">Licenses</a></li>
|
<li><a class="footer-link px-2" id="licenses" target="_blank" th:href="@{'/licenses'}" th:text="#{licenses.nav}">Licenses</a></li>
|
||||||
<li><a class="footer-link px-2" id="releases" target="_blank" th:href="@{'/releases'}" th:text="#{releases.footer}">Releases</a></li>
|
<li><a class="footer-link px-2" id="releases" target="_blank" th:href="@{'/releases'}" th:text="#{releases.footer}">Releases</a></li>
|
||||||
<li><a class="footer-link px-2" id="survey" target="_blank" href="https://stirlingpdf.info/s/cm28y3niq000o56dv7liv8wsu" th:text="#{survey.nav}">Survey</a></li>
|
<li><a class="footer-link px-2" id="survey" target="_blank" href="https://stirlingpdf.info/s/cm28y3niq000o56dv7liv8wsu" th:text="#{survey.nav}">Survey</a></li>
|
||||||
<li th:if="${@privacyPolicy != ''}"><a class="footer-link px-2" target="_blank" th:href="${@privacyPolicy}" th:text="#{legal.privacy}">privacyPolicy</a></li>
|
<li th:if="${@privacyPolicy != '/'}"><a class="footer-link px-2" target="_blank" th:href="${@privacyPolicy}" th:text="#{legal.privacy}">privacyPolicy</a></li>
|
||||||
<li th:if="${@termsAndConditions != ''}"><a class="footer-link px-2" target="_blank" th:href="${@termsAndConditions}" th:text="#{legal.terms}">termsAndConditions</a></li>
|
<li th:if="${@termsAndConditions != '/'}"><a class="footer-link px-2" target="_blank" th:href="${@termsAndConditions}" th:text="#{legal.terms}">termsAndConditions</a></li>
|
||||||
<li th:if="${@accessibilityStatement != ''}"><a class="footer-link px-2" target="_blank" th:href="${@accessibilityStatement}" th:text="#{legal.accessibility}">accessibilityStatement</a></li>
|
<li th:if="${@accessibilityStatement != '/'}"><a class="footer-link px-2" target="_blank" th:href="${@accessibilityStatement}" th:text="#{legal.accessibility}">accessibilityStatement</a></li>
|
||||||
<li th:if="${@cookiePolicy != ''}"><a class="footer-link px-2" target="_blank" th:href="${@cookiePolicy}" th:text="#{legal.cookie}">cookiePolicy</a></li>
|
<li th:if="${@cookiePolicy != '/'}"><a class="footer-link px-2" target="_blank" th:href="${@cookiePolicy}" th:text="#{legal.cookie}">cookiePolicy</a></li>
|
||||||
<li th:if="${@impressum != ''}"><a class="footer-link px-2" target="_blank" th:href="${@impressum}" th:text="#{legal.impressum}">impressum</a></li>
|
<li th:if="${@impressum != '/'}"><a class="footer-link px-2" target="_blank" th:href="${@impressum}" th:text="#{legal.impressum}">impressum</a></li>
|
||||||
<li th:if="${@analyticsEnabled}"><a class="footer-link px-2" id="cookieBanner" target="_blank" th:text="#{legal.showCookieBanner}" onClick="CookieConsent.show(true)">Cookie Preferences</a></li>
|
<li th:if="${@analyticsEnabled}"><a class="footer-link px-2" id="cookieBanner" target="_blank" th:text="#{legal.showCookieBanner}" onClick="CookieConsent.show(true)">Cookie Preferences</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
75
app/core/src/main/resources/templates/impressum.html
Normal file
75
app/core/src/main/resources/templates/impressum.html
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html th:lang="${#locale.language}"
|
||||||
|
th:dir="#{language.direction}"
|
||||||
|
th:data-language="${#locale.toString()}"
|
||||||
|
xmlns:th="https://www.thymeleaf.org">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<th:block th:insert="~{fragments/common :: head(title=#{legal.impressum}, header=#{legal.impressum})}">
|
||||||
|
</th:block>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div id="page-container">
|
||||||
|
<div id="content-wrap">
|
||||||
|
<th:block th:insert="~{fragments/navbar.html :: navbar}"></th:block>
|
||||||
|
<br><br>
|
||||||
|
<div class="container">
|
||||||
|
<div class="row justify-content-center">
|
||||||
|
<div class="col-md-8 bg-card">
|
||||||
|
<div class="tool-header">
|
||||||
|
<span class="material-symbols-rounded tool-header-icon">info</span>
|
||||||
|
<span class="tool-header-text"
|
||||||
|
th:text="#{legal.impressum}">Impressum / Legal Notice</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- start Note: sample page -->
|
||||||
|
<section id="note-sample-page">
|
||||||
|
<div class="alert alert-warning"
|
||||||
|
role="alert">
|
||||||
|
<strong>Note:</strong> This is a <em>sample page</em>; all information is placeholder content for
|
||||||
|
demonstration purposes only.
|
||||||
|
<br>
|
||||||
|
<br>
|
||||||
|
<li>Enable <code>customHTMLFiles</code> in the configuration to use custom HTML files, which can be found <a
|
||||||
|
href="https://docs.stirlingpdf.com/Advanced%20Configuration/UI%20Customisation#custom-files"
|
||||||
|
target="_blank">here</a>.</li>
|
||||||
|
<li>Create a file named <code>impressum.html</code> in the folder <code>customFiles/templates</code>.</li>
|
||||||
|
<li>Copy the content of this file from <a
|
||||||
|
href="https://raw.githubusercontent.com/Stirling-Tools/Stirling-PDF/refs/heads/main/app/core/src/main/resources/templates/impressum.html"
|
||||||
|
target="_blank">impressum.html</a> into the newly created file.</li>
|
||||||
|
<li>Customize the layout and design of the page.</li>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<!-- end Note: sample page -->
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<h2>Company Information</h2>
|
||||||
|
<p>Company Name<br>Street Address<br>City, Postal Code<br>Country</p>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<h2>Contact</h2>
|
||||||
|
<p>Telephone: +00 000 0000<br>Email: <a href="mailto:info@example.com">info@example.com</a></p>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<h2>Representatives</h2>
|
||||||
|
<p>Authorized to represent: Jane Doe, John Doe</p>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<h2>Registration & VAT</h2>
|
||||||
|
<p>Commercial Register: Local Court of Exampletown, HRB 00000<br>VAT ID: XX000000000</p>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<h2>Disclaimer</h2>
|
||||||
|
<p>This page provides general company and contact information for international use. Legal requirements vary by
|
||||||
|
jurisdiction; please ensure compliance with local laws.</p>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<th:block th:insert="~{fragments/footer.html :: footer}"></th:block>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
59
app/core/src/main/resources/templates/privacyPolicy.html
Normal file
59
app/core/src/main/resources/templates/privacyPolicy.html
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html th:lang="${#locale.language}"
|
||||||
|
th:dir="#{language.direction}"
|
||||||
|
th:data-language="${#locale.toString()}"
|
||||||
|
xmlns:th="https://www.thymeleaf.org">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<th:block th:insert="~{fragments/common :: head(title=#{legal.privacy}, header=#{legal.privacy})}"></th:block>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div id="page-container">
|
||||||
|
<div id="content-wrap">
|
||||||
|
<th:block th:insert="~{fragments/navbar.html :: navbar}"></th:block>
|
||||||
|
<br><br>
|
||||||
|
<div class="container">
|
||||||
|
<div class="row justify-content-center">
|
||||||
|
<div class="col-md-8 bg-card">
|
||||||
|
<div class="tool-header">
|
||||||
|
<span class="material-symbols-rounded tool-header-icon">privacy_tip</span>
|
||||||
|
<span class="tool-header-text"
|
||||||
|
th:text="#{legal.privacy}">Privacy Policy</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- start Note: sample page -->
|
||||||
|
<section id="note-sample-page">
|
||||||
|
<div class="alert alert-warning"
|
||||||
|
role="alert">
|
||||||
|
<strong>Note:</strong> This is a <em>sample page</em>; all information is placeholder content for
|
||||||
|
demonstration purposes only.
|
||||||
|
<br>
|
||||||
|
<br>
|
||||||
|
<li>Enable <code>customHTMLFiles</code> in the configuration to use custom HTML files, which can be found <a
|
||||||
|
href="https://docs.stirlingpdf.com/Advanced%20Configuration/UI%20Customisation#custom-files"
|
||||||
|
target="_blank">here</a>.</li>
|
||||||
|
<li>Create a file named <code>privacyPolicy.html</code> in the folder <code>customFiles/templates</code>.
|
||||||
|
</li>
|
||||||
|
<li>Copy the content of this file from <a
|
||||||
|
href="https://raw.githubusercontent.com/Stirling-Tools/Stirling-PDF/refs/heads/main/app/core/src/main/resources/templates/privacyPolicy.html"
|
||||||
|
target="_blank">privacyPolicy.html</a> into the newly created file.</li>
|
||||||
|
<li>Customize the layout and design of the page.</li>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<!-- end Note: sample page -->
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<h2>Privacy Policy</h2>
|
||||||
|
<p>This Privacy Policy explains how we handle your data. No personal information is stored beyond the scope of
|
||||||
|
providing our services.</p>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<th:block th:insert="~{fragments/footer.html :: footer}"></th:block>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
@ -0,0 +1,58 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html th:lang="${#locale.language}"
|
||||||
|
th:dir="#{language.direction}"
|
||||||
|
th:data-language="${#locale.toString()}"
|
||||||
|
xmlns:th="https://www.thymeleaf.org">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<th:block th:insert="~{fragments/common :: head(title=#{legal.terms}, header=#{legal.terms})}"></th:block>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div id="page-container">
|
||||||
|
<div id="content-wrap">
|
||||||
|
<th:block th:insert="~{fragments/navbar.html :: navbar}"></th:block>
|
||||||
|
<br><br>
|
||||||
|
<div class="container">
|
||||||
|
<div class="row justify-content-center">
|
||||||
|
<div class="col-md-8 bg-card">
|
||||||
|
<div class="tool-header">
|
||||||
|
<span class="material-symbols-rounded tool-header-icon">gavel</span>
|
||||||
|
<span class="tool-header-text"
|
||||||
|
th:text="#{legal.terms}">Terms and Conditions</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- start Note: sample page -->
|
||||||
|
<section id="note-sample-page">
|
||||||
|
<div class="alert alert-warning"
|
||||||
|
role="alert">
|
||||||
|
<strong>Note:</strong> This is a <em>sample page</em>; all information is placeholder content for
|
||||||
|
demonstration purposes only.
|
||||||
|
<br>
|
||||||
|
<br>
|
||||||
|
<li>Enable <code>customHTMLFiles</code> in the configuration to use custom HTML files, which can be found <a
|
||||||
|
href="https://docs.stirlingpdf.com/Advanced%20Configuration/UI%20Customisation#custom-files"
|
||||||
|
target="_blank">here</a>.</li>
|
||||||
|
<li>Create a file named <code>termsAndConditions.html</code> in the folder
|
||||||
|
<code>customFiles/templates</code>.</li>
|
||||||
|
<li>Copy the content of this file from <a
|
||||||
|
href="https://raw.githubusercontent.com/Stirling-Tools/Stirling-PDF/refs/heads/main/app/core/src/main/resources/templates/termsAndConditions.html"
|
||||||
|
target="_blank">termsAndConditions.html</a> into the newly created file.</li>
|
||||||
|
<li>Customize the layout and design of the page.</li>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<!-- end Note: sample page -->
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<h2>Terms and Conditions</h2>
|
||||||
|
<p>This Terms and Conditions document outlines the rules and regulations for using our services.</p>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<th:block th:insert="~{fragments/footer.html :: footer}"></th:block>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
@ -81,6 +81,11 @@ public class AccountWebController {
|
|||||||
return "redirect:/";
|
return "redirect:/";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean enableLogin = applicationProperties.getSecurity().getEnableLogin();
|
||||||
|
if (!enableLogin) {
|
||||||
|
return "redirect:/";
|
||||||
|
}
|
||||||
|
|
||||||
Map<String, String> providerList = new HashMap<>();
|
Map<String, String> providerList = new HashMap<>();
|
||||||
Security securityProps = applicationProperties.getSecurity();
|
Security securityProps = applicationProperties.getSecurity();
|
||||||
OAUTH2 oauth = securityProps.getOauth2();
|
OAUTH2 oauth = securityProps.getOauth2();
|
||||||
|
@ -223,6 +223,22 @@ public class SecurityConfiguration {
|
|||||||
.rememberMeCookieName( // Cookie name
|
.rememberMeCookieName( // Cookie name
|
||||||
"remember-me")
|
"remember-me")
|
||||||
.alwaysRemember(false));
|
.alwaysRemember(false));
|
||||||
|
String impressumUrl = appConfig.impressum();
|
||||||
|
boolean internalImpressum = impressumUrl != null && impressumUrl.equals("/impressum");
|
||||||
|
String accessibilityStatementUrl = appConfig.accessibilityStatement();
|
||||||
|
boolean internalAccessibilityStatement =
|
||||||
|
accessibilityStatementUrl != null
|
||||||
|
&& accessibilityStatementUrl.equals("/accessibilityStatement");
|
||||||
|
String cookiePolicyUrl = appConfig.cookiePolicy();
|
||||||
|
boolean internalCookiePolicy =
|
||||||
|
cookiePolicyUrl != null && cookiePolicyUrl.equals("/cookiePolicy");
|
||||||
|
String termsAndConditionsUrl = appConfig.termsAndConditions();
|
||||||
|
boolean internalTermsAndConditions =
|
||||||
|
termsAndConditionsUrl != null
|
||||||
|
&& termsAndConditionsUrl.equals("/termsAndConditions");
|
||||||
|
String privacyPolicyUrl = appConfig.privacyPolicy();
|
||||||
|
boolean internalPrivacyPolicy =
|
||||||
|
privacyPolicyUrl != null && privacyPolicyUrl.equals("/privacyPolicy");
|
||||||
http.authorizeHttpRequests(
|
http.authorizeHttpRequests(
|
||||||
authz ->
|
authz ->
|
||||||
authz.requestMatchers(
|
authz.requestMatchers(
|
||||||
@ -250,6 +266,21 @@ public class SecurityConfiguration {
|
|||||||
|| trimmedUri.startsWith("/pdfjs/")
|
|| trimmedUri.startsWith("/pdfjs/")
|
||||||
|| trimmedUri.startsWith("/pdfjs-legacy/")
|
|| trimmedUri.startsWith("/pdfjs-legacy/")
|
||||||
|| trimmedUri.startsWith("/favicon")
|
|| trimmedUri.startsWith("/favicon")
|
||||||
|
|| (internalAccessibilityStatement
|
||||||
|
&& trimmedUri.startsWith(
|
||||||
|
"/accessibilityStatement"))
|
||||||
|
|| (internalImpressum
|
||||||
|
&& trimmedUri.startsWith(
|
||||||
|
"/impressum"))
|
||||||
|
|| (internalCookiePolicy
|
||||||
|
&& trimmedUri.startsWith(
|
||||||
|
"/cookiePolicy"))
|
||||||
|
|| (internalTermsAndConditions
|
||||||
|
&& trimmedUri.startsWith(
|
||||||
|
"/termsAndConditions"))
|
||||||
|
|| (internalPrivacyPolicy
|
||||||
|
&& trimmedUri.startsWith(
|
||||||
|
"/privacyPolicy"))
|
||||||
|| trimmedUri.startsWith(
|
|| trimmedUri.startsWith(
|
||||||
"/api/v1/info/status")
|
"/api/v1/info/status")
|
||||||
|| trimmedUri.startsWith("/v1/api-docs")
|
|| trimmedUri.startsWith("/v1/api-docs")
|
||||||
|
@ -230,6 +230,11 @@ public class UserAuthenticationFilter extends OncePerRequestFilter {
|
|||||||
contextPath + "/error",
|
contextPath + "/error",
|
||||||
contextPath + "/images/",
|
contextPath + "/images/",
|
||||||
contextPath + "/public/",
|
contextPath + "/public/",
|
||||||
|
contextPath + "/impressum",
|
||||||
|
contextPath + "/privacyPolicy",
|
||||||
|
contextPath + "/accessibilityStatement",
|
||||||
|
contextPath + "/cookiePolicy",
|
||||||
|
contextPath + "/termsAndConditions",
|
||||||
contextPath + "/css/",
|
contextPath + "/css/",
|
||||||
contextPath + "/fonts/",
|
contextPath + "/fonts/",
|
||||||
contextPath + "/js/",
|
contextPath + "/js/",
|
||||||
|
@ -1,54 +1,56 @@
|
|||||||
|
|
||||||
/
|
/
|
||||||
/multi-tool
|
/accessibilityStatement
|
||||||
/merge-pdfs
|
|
||||||
/split-pdfs
|
|
||||||
/rotate-pdf
|
|
||||||
/remove-pages
|
|
||||||
/pdf-organizer
|
|
||||||
/multi-page-layout
|
|
||||||
/scale-pages
|
|
||||||
/crop
|
|
||||||
/extract-page
|
|
||||||
/pdf-to-single-page
|
|
||||||
/img-to-pdf
|
|
||||||
/pdf-to-img
|
|
||||||
/pdf-to-text
|
|
||||||
/pdf-to-csv
|
|
||||||
/sign
|
|
||||||
/add-password
|
|
||||||
/remove-password
|
|
||||||
/change-permissions
|
|
||||||
/add-watermark
|
|
||||||
/cert-sign
|
|
||||||
/validate-signature
|
|
||||||
/remove-cert-sign
|
|
||||||
/sanitize-pdf
|
|
||||||
/auto-redact
|
|
||||||
/redact
|
|
||||||
/stamp
|
|
||||||
/view-pdf
|
|
||||||
/add-page-numbers
|
|
||||||
/add-image
|
/add-image
|
||||||
|
/add-page-numbers
|
||||||
|
/add-password
|
||||||
|
/add-watermark
|
||||||
|
/adjust-contrast
|
||||||
|
/auto-redact
|
||||||
|
/auto-rename
|
||||||
|
/auto-split-pdf
|
||||||
|
/cert-sign
|
||||||
|
/change-metadata
|
||||||
|
/change-permissions
|
||||||
|
/compare
|
||||||
|
/cookiePolicy
|
||||||
|
/crop
|
||||||
/extract-images
|
/extract-images
|
||||||
|
/extract-page
|
||||||
/flatten
|
/flatten
|
||||||
|
/get-info-on-pdf
|
||||||
|
/img-to-pdf
|
||||||
|
/impressum
|
||||||
|
/licenses
|
||||||
|
/merge-pdfs
|
||||||
|
/multi-page-layout
|
||||||
|
/multi-tool
|
||||||
|
/overlay-pdf
|
||||||
|
/pdf-organizer
|
||||||
|
/pdf-to-csv
|
||||||
|
/pdf-to-img
|
||||||
|
/pdf-to-single-page
|
||||||
|
/pdf-to-text
|
||||||
|
/privacyPolicy
|
||||||
|
/redact
|
||||||
|
/releases
|
||||||
/remove-annotations
|
/remove-annotations
|
||||||
/remove-blanks
|
/remove-blanks
|
||||||
/compare
|
/remove-cert-sign
|
||||||
/change-metadata
|
|
||||||
/get-info-on-pdf
|
|
||||||
/remove-image-pdf
|
/remove-image-pdf
|
||||||
|
/remove-pages
|
||||||
|
/remove-password
|
||||||
/replace-and-invert-color-pdf
|
/replace-and-invert-color-pdf
|
||||||
/pipeline
|
/rotate-pdf
|
||||||
/auto-rename
|
/sanitize-pdf
|
||||||
/adjust-contrast
|
/scale-pages
|
||||||
/overlay-pdf
|
|
||||||
/auto-split-pdf
|
|
||||||
/split-pdf-by-sections
|
|
||||||
/split-pdf-by-chapters
|
|
||||||
/split-by-size-or-count
|
|
||||||
/show-javascript
|
/show-javascript
|
||||||
|
/sign
|
||||||
|
/split-by-size-or-count
|
||||||
|
/split-pdf
|
||||||
|
/split-pdf-by-chapters
|
||||||
|
/split-pdf-by-sections
|
||||||
|
/stamp
|
||||||
/swagger-ui/index.html
|
/swagger-ui/index.html
|
||||||
/licenses
|
/termsAndConditions
|
||||||
/releases
|
/validate-signature
|
||||||
/add-attachments
|
/view-pdf
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
|
|
||||||
/
|
/
|
||||||
|
/accessibilityStatement
|
||||||
/add-image
|
/add-image
|
||||||
/add-page-numbers
|
/add-page-numbers
|
||||||
/add-password
|
/add-password
|
||||||
@ -13,6 +14,7 @@
|
|||||||
/change-permissions
|
/change-permissions
|
||||||
/compare
|
/compare
|
||||||
/compress-pdf
|
/compress-pdf
|
||||||
|
/cookiePolicy
|
||||||
/crop
|
/crop
|
||||||
/extract-image-scans
|
/extract-image-scans
|
||||||
/extract-images
|
/extract-images
|
||||||
@ -22,6 +24,7 @@
|
|||||||
/get-info-on-pdf
|
/get-info-on-pdf
|
||||||
/html-to-pdf
|
/html-to-pdf
|
||||||
/img-to-pdf
|
/img-to-pdf
|
||||||
|
/impressum
|
||||||
/licenses
|
/licenses
|
||||||
/markdown-to-pdf
|
/markdown-to-pdf
|
||||||
/merge-pdfs
|
/merge-pdfs
|
||||||
@ -40,6 +43,7 @@
|
|||||||
/pdf-to-word
|
/pdf-to-word
|
||||||
/pdf-to-xml
|
/pdf-to-xml
|
||||||
/pipeline
|
/pipeline
|
||||||
|
/privacyPolicy
|
||||||
/redact
|
/redact
|
||||||
/releases
|
/releases
|
||||||
/remove-annotations
|
/remove-annotations
|
||||||
@ -60,6 +64,7 @@
|
|||||||
/split-pdf-by-sections
|
/split-pdf-by-sections
|
||||||
/split-pdfs
|
/split-pdfs
|
||||||
/stamp
|
/stamp
|
||||||
|
/termsAndConditions
|
||||||
/validate-signature
|
/validate-signature
|
||||||
/view-pdf
|
/view-pdf
|
||||||
/swagger-ui/index.html
|
/swagger-ui/index.html
|
Loading…
Reference in New Issue
Block a user