Compare commits

...

13 Commits

Author SHA1 Message Date
github-actions[bot]
d75e4f1318 💾 Update Version (#1755)
💾 Sync Versions
> Made via sync_files.yml

Co-authored-by: GitHub Action action@github.com <GitHub Action action@github.com>
2024-08-24 17:14:47 +01:00
Anthony Stirling
4088132597 Update build.gradle 2024-08-24 17:14:16 +01:00
github-actions[bot]
7b9d419267 Update 3rd Party Licenses (#1754)
Signed-off-by: GitHub Action <action@github.com>
Co-authored-by: GitHub Action <action@github.com>
2024-08-24 17:12:27 +01:00
Anthony Stirling
9b710b489e Fixes #1552 and #1554 (#1753)
* fix

* cleanups!

* fix

* fix for #1552 pipeline not accepting non pdfs

* fix for #1154 font not accepting numbers etc

* Update User.java

---------

Co-authored-by: a <a>
2024-08-24 17:08:51 +01:00
Anthony Stirling
e2ff418c89 Increase linecounts to check #1618 (#1752)
Increase linecounts to check #1618
2024-08-24 15:32:33 +01:00
albanobattistella
be006f08a6 Update messages_it_IT.properties (#1751) 2024-08-24 15:34:02 +02:00
Ludy
b007c805bf Removes double equal signs (#1750) 2024-08-23 22:55:01 +01:00
github-actions[bot]
24be10eed4 Update 3rd Party Licenses (#1746)
Signed-off-by: GitHub Action <action@github.com>
Co-authored-by: GitHub Action <action@github.com>
2024-08-23 22:49:31 +01:00
Dimitris Kaitantzidis
0854a1d26e Fixes LazyInitializationException in User entity (#1749)
Temp integration of playground dist files of pdfme as-is to investigate the result
2024-08-23 21:37:45 +01:00
Ludy
33c7bb7e13 Add: Make Login Attempt Service deactivatable (#1747) 2024-08-23 14:46:09 +01:00
Anthony Stirling
cdf31622e2 Fixes for eager loading (#1748)
* fix

* cleanups!

* fix

---------

Co-authored-by: a <a>
2024-08-23 14:45:53 +01:00
Anthony Stirling
c7e5987342 Cleanup logs (#1739)
* fix

* cleanups!

---------

Co-authored-by: a <a>
2024-08-23 11:52:45 +01:00
Ludy
d3ef335c24 Fix: validations is not a permitted attribute - dropdown (#1745) 2024-08-23 11:52:31 +01:00
53 changed files with 152 additions and 154 deletions

View File

@@ -22,8 +22,6 @@ body:
- Docker ultra lite
- Docker fat
- Local Installation
validations:
required: true
- type: textarea
id: problem

View File

@@ -237,7 +237,7 @@ The Current list of settings is
security:
enableLogin: false # set to 'true' to enable login
csrfDisabled: true # Set to 'true' to disable CSRF protection (not recommended for production)
loginAttemptCount: 5 # lock user account after 5 tries
loginAttemptCount: 5 # lock user account after 5 tries; when using e.g. Fail2Ban you can deactivate the function with -1
loginResetTimeMinutes: 120 # lock account for 2 hours after x attempts
loginMethod: all # 'all' (Login Username/Password and OAuth2[must be enabled and configured]), 'normal'(only Login with Username/Password) or 'oauth2'(only Login with OAuth2)
initialLogin:

View File

@@ -7,6 +7,7 @@ plugins {
id "edu.sc.seis.launch4j" version "3.0.6"
id "com.diffplug.spotless" version "6.25.0"
id "com.github.jk1.dependency-license-report" version "2.9"
//id "nebula.lint" version "19.0.3"
}
import com.github.jk1.license.render.*
@@ -21,7 +22,7 @@ ext {
}
group = "stirling.software"
version = "0.28.2"
version = "0.28.3"
java {
// 17 is lowest but we support and recommend 21
@@ -100,14 +101,20 @@ spotless {
}
}
//gradleLint {
// rules=['unused-dependency']
// }
tasks.wrapper {
gradleVersion = "8.7"
}
//tasks.withType(JavaCompile) {
// options.compilerArgs << "-Xlint:deprecation"
//}
configurations.all {
exclude group: "org.springframework.boot", module: "spring-boot-starter-tomcat"
}
dependencies {
//security updates
implementation "ch.qos.logback:logback-classic:$logbackVersion"
implementation "ch.qos.logback:logback-core:$logbackVersion"
implementation "org.springframework:spring-webmvc:6.1.9"
implementation("io.github.pixee:java-security-toolkit:1.2.0")
@@ -116,21 +123,19 @@ dependencies {
implementation 'com.github.Carleslc.Simple-YAML:Simple-Yaml:1.8.4'
// Exclude Tomcat and include Jetty
implementation("org.springframework.boot:spring-boot-starter-web:$springBootVersion") {
exclude group: "org.springframework.boot", module: "spring-boot-starter-tomcat"
}
implementation("org.springframework.boot:spring-boot-starter-web:$springBootVersion")
implementation "org.springframework.boot:spring-boot-starter-jetty:$springBootVersion"
implementation "org.springframework.boot:spring-boot-starter-thymeleaf:$springBootVersion"
if (System.getenv("DOCKER_ENABLE_SECURITY") != "false") {
implementation "org.springframework.boot:spring-boot-starter-security:$springBootVersion"
implementation "org.thymeleaf.extras:thymeleaf-extras-springsecurity5:3.1.2.RELEASE"
runtimeOnly "org.thymeleaf.extras:thymeleaf-extras-springsecurity5:3.1.2.RELEASE"
implementation "org.springframework.boot:spring-boot-starter-data-jpa:$springBootVersion"
implementation "org.springframework.boot:spring-boot-starter-oauth2-client:$springBootVersion"
//2.2.x requires rebuild of DB file.. need migration path
implementation "com.h2database:h2:2.1.214"
runtimeOnly "com.h2database:h2:2.1.214"
// implementation "com.h2database:h2:2.2.224"
}
@@ -138,28 +143,27 @@ dependencies {
// Batik
implementation "org.apache.xmlgraphics:batik-all:1.17"
// TwelveMonkeys
implementation "com.twelvemonkeys.imageio:imageio-batik:$imageioVersion"
implementation "com.twelvemonkeys.imageio:imageio-bmp:$imageioVersion"
// implementation "com.twelvemonkeys.imageio:imageio-hdr:$imageioVersion"
// implementation "com.twelvemonkeys.imageio:imageio-icns:$imageioVersion"
// implementation "com.twelvemonkeys.imageio:imageio-iff:$imageioVersion"
implementation "com.twelvemonkeys.imageio:imageio-jpeg:$imageioVersion"
// implementation "com.twelvemonkeys.imageio:imageio-pcx:$imageioVersion@
// implementation "com.twelvemonkeys.imageio:imageio-pict:$imageioVersion"
// implementation "com.twelvemonkeys.imageio:imageio-pnm:$imageioVersion"
// implementation "com.twelvemonkeys.imageio:imageio-psd:$imageioVersion"
// implementation "com.twelvemonkeys.imageio:imageio-sgi:$imageioVersion"
// implementation "com.twelvemonkeys.imageio:imageio-tga:$imageioVersion"
// implementation "com.twelvemonkeys.imageio:imageio-thumbsdb:$imageioVersion"
implementation "com.twelvemonkeys.imageio:imageio-tiff:$imageioVersion"
implementation "com.twelvemonkeys.imageio:imageio-webp:$imageioVersion"
// implementation "com.twelvemonkeys.imageio:imageio-xwd:$imageioVersion"
runtimeOnly "com.twelvemonkeys.imageio:imageio-batik:$imageioVersion"
runtimeOnly "com.twelvemonkeys.imageio:imageio-bmp:$imageioVersion"
// runtimeOnly "com.twelvemonkeys.imageio:imageio-hdr:$imageioVersion"
// runtimeOnly "com.twelvemonkeys.imageio:imageio-icns:$imageioVersion"
// runtimeOnly "com.twelvemonkeys.imageio:imageio-iff:$imageioVersion"
runtimeOnly "com.twelvemonkeys.imageio:imageio-jpeg:$imageioVersion"
// runtimeOnly "com.twelvemonkeys.imageio:imageio-pcx:$imageioVersion@
// runtimeOnly "com.twelvemonkeys.imageio:imageio-pict:$imageioVersion"
// runtimeOnly "com.twelvemonkeys.imageio:imageio-pnm:$imageioVersion"
// runtimeOnly "com.twelvemonkeys.imageio:imageio-psd:$imageioVersion"
// runtimeOnly "com.twelvemonkeys.imageio:imageio-sgi:$imageioVersion"
// runtimeOnly "com.twelvemonkeys.imageio:imageio-tga:$imageioVersion"
// runtimeOnly "com.twelvemonkeys.imageio:imageio-thumbsdb:$imageioVersion"
runtimeOnly "com.twelvemonkeys.imageio:imageio-tiff:$imageioVersion"
runtimeOnly "com.twelvemonkeys.imageio:imageio-webp:$imageioVersion"
// runtimeOnly "com.twelvemonkeys.imageio:imageio-xwd:$imageioVersion"
implementation "commons-io:commons-io:2.16.1"
implementation "org.springdoc:springdoc-openapi-starter-webmvc-ui:2.2.0"
//general PDF
// https://mvnrepository.com/artifact/com.opencsv/opencsv
@@ -196,7 +200,7 @@ dependencies {
compileOnly "org.projectlombok:lombok:$lombokVersion"
annotationProcessor "org.projectlombok:lombok:$lombokVersion"
testImplementation 'org.mockito:mockito-inline:5.2.0'
testRuntimeOnly 'org.mockito:mockito-inline:5.2.0'
}
tasks.withType(JavaCompile).configureEach {

View File

@@ -1,5 +1,5 @@
apiVersion: v2
appVersion: 0.28.2
appVersion: 0.28.3
description: locally hosted web application that allows you to perform various operations
on PDF files
home: https://github.com/Stirling-Tools/Stirling-PDF

View File

@@ -65,6 +65,7 @@ public class SPdfApplication {
public static void main(String[] args) throws IOException, InterruptedException {
SpringApplication app = new SpringApplication(SPdfApplication.class);
app.setAdditionalProfiles("default");
app.addInitializers(new ConfigInitializer());
Map<String, String> propertyFiles = new HashMap<>();

View File

@@ -126,13 +126,12 @@ public class AppConfig {
}
@Bean(name = "directoryFilter")
public Predicate<Path> processPDFOnlyFilter() {
public Predicate<Path> processOnlyFiles() {
return path -> {
if (Files.isDirectory(path)) {
return !path.toString().contains("processing");
} else {
String fileName = path.getFileName().toString();
return fileName.endsWith(".pdf");
return true;
}
};
}

View File

@@ -7,21 +7,28 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import jakarta.annotation.PostConstruct;
import lombok.extern.slf4j.Slf4j;
import stirling.software.SPDF.model.ApplicationProperties;
import stirling.software.SPDF.model.AttemptCounter;
@Service
@Slf4j
public class LoginAttemptService {
@Autowired ApplicationProperties applicationProperties;
@Autowired private ApplicationProperties applicationProperties;
private int MAX_ATTEMPT;
private long ATTEMPT_INCREMENT_TIME;
private ConcurrentHashMap<String, AttemptCounter> attemptsCache;
private boolean isBlockedEnabled = true;
@PostConstruct
public void init() {
MAX_ATTEMPT = applicationProperties.getSecurity().getLoginAttemptCount();
if (MAX_ATTEMPT == -1) {
isBlockedEnabled = false;
log.info("Login attempt tracking is disabled.");
}
ATTEMPT_INCREMENT_TIME =
TimeUnit.MINUTES.toMillis(
applicationProperties.getSecurity().getLoginResetTimeMinutes());
@@ -29,14 +36,16 @@ public class LoginAttemptService {
}
public void loginSucceeded(String key) {
if (key == null || key.trim().isEmpty()) {
if (!isBlockedEnabled || key == null || key.trim().isEmpty()) {
return;
}
attemptsCache.remove(key.toLowerCase());
}
public void loginFailed(String key) {
if (key == null || key.trim().isEmpty()) return;
if (!isBlockedEnabled || key == null || key.trim().isEmpty()) {
return;
}
AttemptCounter attemptCounter = attemptsCache.get(key.toLowerCase());
if (attemptCounter == null) {
@@ -51,7 +60,9 @@ public class LoginAttemptService {
}
public boolean isBlocked(String key) {
if (key == null || key.trim().isEmpty()) return false;
if (!isBlockedEnabled || key == null || key.trim().isEmpty()) {
return false;
}
AttemptCounter attemptCounter = attemptsCache.get(key.toLowerCase());
if (attemptCounter == null) {
return false;
@@ -61,7 +72,9 @@ public class LoginAttemptService {
}
public int getRemainingAttempts(String key) {
if (key == null || key.trim().isEmpty()) return MAX_ATTEMPT;
if (!isBlockedEnabled || key == null || key.trim().isEmpty()) {
return Integer.MAX_VALUE; // Arbitrarily high number if tracking is disabled
}
AttemptCounter attemptCounter = attemptsCache.get(key.toLowerCase());
if (attemptCounter == null) {

View File

@@ -10,7 +10,6 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
@@ -150,8 +149,7 @@ public class SecurityConfiguration {
})
.permitAll()
.anyRequest()
.authenticated())
.authenticationProvider(authenticationProvider());
.authenticated());
// Handle OAUTH2 Logins
if (applicationProperties.getSecurity().getOAUTH2() != null
@@ -379,14 +377,6 @@ public class SecurityConfiguration {
return new IPRateLimitingFilter(maxRequestsPerIp, maxRequestsPerIp);
}
@Bean
public DaoAuthenticationProvider authenticationProvider() {
DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
authProvider.setUserDetailsService(userDetailsService);
authProvider.setPasswordEncoder(passwordEncoder());
return authProvider;
}
@Bean
public PersistentTokenRepository persistentTokenRepository() {
return new JPATokenRepositoryImpl();

View File

@@ -1,13 +1,5 @@
package stirling.software.SPDF.config.security;
import java.io.IOException;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.UUID;
import java.util.stream.Collectors;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.context.i18n.LocaleContextHolder;
@@ -21,7 +13,6 @@ import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.core.user.OAuth2User;
import org.springframework.stereotype.Service;
import stirling.software.SPDF.config.DatabaseBackupInterface;
import stirling.software.SPDF.config.security.session.SessionPersistentRegistry;
import stirling.software.SPDF.controller.api.pipeline.UserServiceInterface;
@@ -32,6 +23,10 @@ import stirling.software.SPDF.model.User;
import stirling.software.SPDF.repository.AuthorityRepository;
import stirling.software.SPDF.repository.UserRepository;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;
@Service
public class UserService implements UserServiceInterface {
@@ -221,7 +216,7 @@ public class UserService implements UserServiceInterface {
public void updateUserSettings(String username, Map<String, String> updates)
throws IOException {
Optional<User> userOpt = findByUsernameIgnoreCase(username);
Optional<User> userOpt = findByUsernameIgnoreCaseWithSettings(username);
if (userOpt.isPresent()) {
User user = userOpt.get();
Map<String, String> settingsMap = user.getSettings();
@@ -246,6 +241,10 @@ public class UserService implements UserServiceInterface {
return userRepository.findByUsernameIgnoreCase(username);
}
public Optional<User> findByUsernameIgnoreCaseWithSettings(String username) {
return userRepository.findByUsernameIgnoreCaseWithSettings(username);
}
public Authority findRole(User user) {
return authorityRepository.findByUserId(user.getId());
}

View File

@@ -33,7 +33,7 @@ public class AutoRenameController {
private static final Logger logger = LoggerFactory.getLogger(AutoRenameController.class);
private static final float TITLE_FONT_SIZE_THRESHOLD = 20.0f;
private static final int LINE_LIMIT = 11;
private static final int LINE_LIMIT = 200;
@PostMapping(consumes = "multipart/form-data", value = "/auto-rename")
@Operation(

View File

@@ -43,7 +43,7 @@ public class ApiDocService {
Map<String, List<String>> outputToFileTypes = new HashMap<>();
public List getExtensionTypes(boolean output, String operationName) {
public List<String> getExtensionTypes(boolean output, String operationName) {
if (outputToFileTypes.size() == 0) {
outputToFileTypes.put("PDF", Arrays.asList("pdf"));
outputToFileTypes.put(

View File

@@ -1,15 +1,10 @@
package stirling.software.SPDF.controller.web;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.Authentication;
@@ -18,27 +13,20 @@ import org.springframework.security.oauth2.core.user.OAuth2User;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import stirling.software.SPDF.config.security.session.SessionPersistentRegistry;
import stirling.software.SPDF.model.ApplicationProperties;
import stirling.software.SPDF.model.*;
import stirling.software.SPDF.model.ApplicationProperties.Security.OAUTH2;
import stirling.software.SPDF.model.ApplicationProperties.Security.OAUTH2.Client;
import stirling.software.SPDF.model.Authority;
import stirling.software.SPDF.model.Role;
import stirling.software.SPDF.model.SessionEntity;
import stirling.software.SPDF.model.User;
import stirling.software.SPDF.model.provider.GithubProvider;
import stirling.software.SPDF.model.provider.GoogleProvider;
import stirling.software.SPDF.model.provider.KeycloakProvider;
import stirling.software.SPDF.repository.UserRepository;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.stream.Collectors;
@Controller
@Slf4j
@Tag(name = "Account Security", description = "Account Security APIs")
@@ -361,7 +349,7 @@ public class AccountWebController {
if (username != null) {
// Fetch user details from the database
Optional<User> user =
userRepository.findByUsernameIgnoreCase(
userRepository.findByUsernameIgnoreCaseWithSettings(
username); // Assuming findByUsername method exists
if (!user.isPresent()) {
return "redirect:/error";

View File

@@ -1,5 +1,7 @@
package stirling.software.SPDF.model;
import jakarta.persistence.*;
import java.io.Serializable;
import java.util.HashMap;
import java.util.HashSet;
@@ -7,21 +9,6 @@ import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import jakarta.persistence.CascadeType;
import jakarta.persistence.CollectionTable;
import jakarta.persistence.Column;
import jakarta.persistence.ElementCollection;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.Lob;
import jakarta.persistence.MapKeyColumn;
import jakarta.persistence.OneToMany;
import jakarta.persistence.Table;
@Entity
@Table(name = "users")
public class User implements Serializable {

View File

@@ -9,6 +9,8 @@ import lombok.EqualsAndHashCode;
@EqualsAndHashCode
public class UrlToPdfRequest {
@Schema(description = "The input URL to be converted to a PDF file", required = true)
@Schema(
description = "The input URL to be converted to a PDF file",
requiredMode = Schema.RequiredMode.REQUIRED)
private String urlInput;
}

View File

@@ -10,6 +10,6 @@ import stirling.software.SPDF.model.api.PDFWithPageNums;
@EqualsAndHashCode(callSuper = true)
public class ContainsTextRequest extends PDFWithPageNums {
@Schema(description = "The text to check for", required = true)
@Schema(description = "The text to check for", requiredMode = Schema.RequiredMode.REQUIRED)
private String text;
}

View File

@@ -10,6 +10,6 @@ import stirling.software.SPDF.model.api.PDFComparison;
@EqualsAndHashCode(callSuper = true)
public class FileSizeRequest extends PDFComparison {
@Schema(description = "File Size", required = true)
@Schema(description = "File Size", requiredMode = Schema.RequiredMode.REQUIRED)
private String fileSize;
}

View File

@@ -10,6 +10,6 @@ import stirling.software.SPDF.model.api.PDFComparison;
@EqualsAndHashCode(callSuper = true)
public class PageRotationRequest extends PDFComparison {
@Schema(description = "Rotation in degrees", required = true)
@Schema(description = "Rotation in degrees", requiredMode = Schema.RequiredMode.REQUIRED)
private int rotation;
}

View File

@@ -10,6 +10,6 @@ import stirling.software.SPDF.model.api.PDFComparison;
@EqualsAndHashCode(callSuper = true)
public class PageSizeRequest extends PDFComparison {
@Schema(description = "Standard Page Size", required = true)
@Schema(description = "Standard Page Size", requiredMode = Schema.RequiredMode.REQUIRED)
private String standardPageSize;
}

View File

@@ -20,13 +20,13 @@ public class OverlayPdfsRequest extends PDFFile {
@Schema(
description =
"The mode of overlaying: 'SequentialOverlay' for sequential application, 'InterleavedOverlay' for round-robin application, 'FixedRepeatOverlay' for fixed repetition based on provided counts",
required = true)
requiredMode = Schema.RequiredMode.REQUIRED)
private String overlayMode;
@Schema(
description =
"An array of integers specifying the number of times each corresponding overlay file should be applied in the 'FixedRepeatOverlay' mode. This should match the length of the overlayFiles array.",
required = false)
requiredMode = Schema.RequiredMode.NOT_REQUIRED)
private int[] counts;
@Schema(description = "Overlay position 0 is Foregound, 1 is Background")

View File

@@ -13,14 +13,14 @@ public class SplitPdfBySizeOrCountRequest extends PDFFile {
@Schema(
description =
"Determines the type of split: 0 for size, 1 for page count, 2 for document count",
required = false,
requiredMode = Schema.RequiredMode.NOT_REQUIRED,
defaultValue = "0")
private int splitType;
@Schema(
description =
"Value for split: size in MB (e.g., '10MB') or number of pages (e.g., '5')",
required = false,
requiredMode = Schema.RequiredMode.NOT_REQUIRED,
defaultValue = "10MB")
private String splitValue;
}

View File

@@ -15,7 +15,7 @@ public class AddStampRequest extends PDFWithPageNums {
@Schema(
description = "The stamp type (text or image)",
allowableValues = {"text", "image"},
required = true)
requiredMode = Schema.RequiredMode.REQUIRED)
private String stampType;
@Schema(description = "The stamp text")

View File

@@ -13,7 +13,7 @@ public class AutoSplitPdfRequest extends PDFFile {
@Schema(
description =
"Flag indicating if the duplex mode is active, where the page after the divider also gets removed.",
required = false,
requiredMode = Schema.RequiredMode.NOT_REQUIRED,
defaultValue = "false")
private boolean duplexMode;
}

View File

@@ -13,7 +13,7 @@ public class ExtractHeaderRequest extends PDFFile {
@Schema(
description =
"Flag indicating whether to use the first text as a fallback if no suitable title is found. Defaults to false.",
required = false,
requiredMode = Schema.RequiredMode.NOT_REQUIRED,
defaultValue = "false")
private boolean useFirstTextAsFallback;
}

View File

@@ -10,7 +10,9 @@ import lombok.EqualsAndHashCode;
@Data
@EqualsAndHashCode
public class ExtractImageScansRequest {
@Schema(description = "The input file containing image scans", required = true)
@Schema(
description = "The input file containing image scans",
requiredMode = Schema.RequiredMode.REQUIRED)
private MultipartFile fileInput;
@Schema(

View File

@@ -10,6 +10,8 @@ import stirling.software.SPDF.model.api.PDFFile;
@EqualsAndHashCode(callSuper = true)
public class PrintFileRequest extends PDFFile {
@Schema(description = "Name of printer to match against", required = true)
@Schema(
description = "Name of printer to match against",
requiredMode = Schema.RequiredMode.REQUIRED)
private String printerName;
}

View File

@@ -15,7 +15,7 @@ public class AddWatermarkRequest extends PDFFile {
@Schema(
description = "The watermark type (text or image)",
allowableValues = {"text", "image"},
required = true)
requiredMode = Schema.RequiredMode.REQUIRED)
private String watermarkType;
@Schema(description = "The watermark text")

View File

@@ -10,6 +10,8 @@ import stirling.software.SPDF.model.api.PDFFile;
@EqualsAndHashCode(callSuper = true)
public class PDFPasswordRequest extends PDFFile {
@Schema(description = "The password of the PDF file", required = true)
@Schema(
description = "The password of the PDF file",
requiredMode = Schema.RequiredMode.REQUIRED)
private String password;
}

View File

@@ -10,7 +10,10 @@ import stirling.software.SPDF.model.api.PDFFile;
@EqualsAndHashCode(callSuper = true)
public class RedactPdfRequest extends PDFFile {
@Schema(description = "List of text to redact from the PDF", type = "string", required = true)
@Schema(
description = "List of text to redact from the PDF",
type = "string",
requiredMode = Schema.RequiredMode.REQUIRED)
private String listOfText;
@Schema(description = "Whether to use regex for the listOfText", defaultValue = "false")

View File

@@ -1,16 +1,19 @@
package stirling.software.SPDF.repository;
import java.util.Optional;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;
import stirling.software.SPDF.model.User;
import java.util.Optional;
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
Optional<User> findByUsernameIgnoreCase(String username);
@Query("FROM User u LEFT JOIN FETCH u.settings where upper(u.username) = upper(:username)")
Optional<User> findByUsernameIgnoreCaseWithSettings(String username);
Optional<User> findByUsername(String username);
Optional<User> findByApiKey(String apiKey);

View File

@@ -6,6 +6,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
@@ -77,7 +78,7 @@ public class GeneralUtils {
public static boolean isURLReachable(String urlStr) {
try {
URL url = new URL(urlStr);
URL url = URI.create(urlStr).toURL();
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("HEAD");
int responseCode = connection.getResponseCode();

View File

@@ -1,5 +1,11 @@
multipart.enabled=true
logging.level.org.springframework=WARN
logging.level.org.hibernate=WARN
logging.level.org.eclipse.jetty=WARN
logging.level.com.zaxxer.hikari=WARN
spring.jpa.open-in-view=false
server.forward-headers-strategy=NATIVE
@@ -24,10 +30,8 @@ spring.devtools.livereload.enabled=true
spring.thymeleaf.encoding=UTF-8
server.connection-timeout=${SYSTEM_CONNECTIONTIMEOUTMINUTES:20m}
spring.mvc.async.request-timeout=${SYSTEM_CONNECTIONTIMEOUTMILLISECONDS:1200000}
spring.resources.static-locations=file:customFiles/static/
spring.mvc.async.request-timeout=${SYSTEM_CONNECTIONTIMEOUTMILLISECONDS:1200000}
#spring.thymeleaf.prefix=file:/customFiles/templates/,classpath:/templates/
#spring.thymeleaf.cache=false

View File

@@ -291,7 +291,7 @@ compressPdfs.tags=squish,small,tiny
home.changeMetadata.title=تغيير البيانات الوصفية
home.changeMetadata.desc=تغيير / إزالة / إضافة بيانات أولية من مستند PDF
changeMetadata.tags==Title,author,date,creation,time,publisher,producer,stats
changeMetadata.tags=Title,author,date,creation,time,publisher,producer,stats
home.fileToPDF.title=تحويل الملف إلى PDF
home.fileToPDF.desc=تحويل أي ملف تقريبا إلى PDF (DOCX وPNG وXLS وPPT وTXT والمزيد)

View File

@@ -291,7 +291,7 @@ compressPdfs.tags=squish,small,tiny
home.changeMetadata.title=Canvia Metadades
home.changeMetadata.desc=Canvia/Treu/Afegeix matadades al document PDF.
changeMetadata.tags==Title,author,date,creation,time,publisher,producer,stats
changeMetadata.tags=Title,author,date,creation,time,publisher,producer,stats
home.fileToPDF.title=Converteix arxiu a PDF
home.fileToPDF.desc=Converteix qualsevol arxiu a PDF (DOCX, PNG, XLS, PPT, TXT i més)

View File

@@ -291,7 +291,7 @@ compressPdfs.tags=rozmáčknout,malý,drobný
home.changeMetadata.title=Změnit Metadata
home.changeMetadata.desc=Změnit/Odebrat/Přidat metadata z PDF dokumentu
changeMetadata.tags==Název,autor,datum,tvorba,čas,vydavatel,výrobce,statistiky
changeMetadata.tags=Název,autor,datum,tvorba,čas,vydavatel,výrobce,statistiky
home.fileToPDF.title=Převést soubor do PDF
home.fileToPDF.desc=Převést téměř jakýkoli soubor do PDF (DOCX, PNG, XLS, PPT, TXT a více)

View File

@@ -291,7 +291,7 @@ compressPdfs.tags=squish,small,tiny
home.changeMetadata.title=Change Metadata
home.changeMetadata.desc=Change/Remove/Add metadata from a PDF document
changeMetadata.tags==Title,author,date,creation,time,publisher,producer,stats
changeMetadata.tags=Title,author,date,creation,time,publisher,producer,stats
home.fileToPDF.title=Convert file to PDF
home.fileToPDF.desc=Convert nearly any file to PDF (DOCX, PNG, XLS, PPT, TXT and more)

View File

@@ -4,7 +4,7 @@
# the direction that the language is written (ltr=left to right, rtl = right to left)
language.direction=ltr
pdfPrompt=PDF auswählen
pdfPrompwt=PDF auswählen
multiPdfPrompt=PDFs auswählen(2+)
multiPdfDropPrompt=Wählen Sie alle gewünschten PDFs aus (oder ziehen Sie sie per Drag & Drop hierhin)
imgPrompt=Wählen Sie ein Bild
@@ -291,7 +291,7 @@ compressPdfs.tags=komprimieren,verkleinern,minimieren
home.changeMetadata.title=Metadaten ändern
home.changeMetadata.desc=Ändern/Entfernen/Hinzufügen von Metadaten aus einem PDF-Dokument
changeMetadata.tags==titel,autor,datum,erstellung,uhrzeit,herausgeber,produzent,statistiken
changeMetadata.tags=titel,autor,datum,erstellung,uhrzeit,herausgeber,produzent,statistiken
home.fileToPDF.title=Datei in PDF konvertieren
home.fileToPDF.desc=Konvertieren Sie nahezu jede Datei in PDF (DOCX, PNG, XLS, PPT, TXT und mehr)

View File

@@ -291,7 +291,7 @@ compressPdfs.tags=squish,small,tiny
home.changeMetadata.title=Αλλαγή Μεταδεδομένων
home.changeMetadata.desc=Αλλαγή/Κατάργηση/Προσθήκη μεταδεδομένων από ένα έγγραφο PDF.
changeMetadata.tags==Title,author,date,creation,time,publisher,producer,stats
changeMetadata.tags=Title,author,date,creation,time,publisher,producer,stats
home.fileToPDF.title=Μετατροπή ενός αρχείου σε PDF
home.fileToPDF.desc=Μετατροπή σχεδόν οποιουδήποτε αρχείου σε PDF (DOCX, PNG, XLS, PPT, TXT and more)

View File

@@ -291,7 +291,7 @@ compressPdfs.tags=squish,small,tiny
home.changeMetadata.title=Change Metadata
home.changeMetadata.desc=Change/Remove/Add metadata from a PDF document
changeMetadata.tags==Title,author,date,creation,time,publisher,producer,stats
changeMetadata.tags=Title,author,date,creation,time,publisher,producer,stats
home.fileToPDF.title=Convert file to PDF
home.fileToPDF.desc=Convert nearly any file to PDF (DOCX, PNG, XLS, PPT, TXT and more)

View File

@@ -291,7 +291,7 @@ compressPdfs.tags=squish,small,tiny
home.changeMetadata.title=Change Metadata
home.changeMetadata.desc=Change/Remove/Add metadata from a PDF document
changeMetadata.tags==Title,author,date,creation,time,publisher,producer,stats
changeMetadata.tags=Title,author,date,creation,time,publisher,producer,stats
home.fileToPDF.title=Convert file to PDF
home.fileToPDF.desc=Convert nearly any file to PDF (DOCX, PNG, XLS, PPT, TXT and more)

View File

@@ -291,7 +291,7 @@ compressPdfs.tags=squish,small,tiny
home.changeMetadata.title=Aldatu metadatuak
home.changeMetadata.desc=Aldatu/Ezabatu/Gehitu metadatuak PDF dokumentuari
changeMetadata.tags==Title,author,date,creation,time,publisher,producer,stats
changeMetadata.tags=Title,author,date,creation,time,publisher,producer,stats
home.fileToPDF.title=Fitxategia PDF bihurtu
home.fileToPDF.desc=PDF bihurtu ia edozein fitxategi (DOCX, PNG, XLS, PPT, TXT eta gehiago)

View File

@@ -291,7 +291,7 @@ compressPdfs.tags=squish, beag, beag bídeach
home.changeMetadata.title=Athraigh Meiteashonraí
home.changeMetadata.desc=Athraigh/Bain/Cuir meiteashonraí ó dhoiciméad PDF
changeMetadata.tags==Title,author,date,creation,time,publisher,producer,stats
changeMetadata.tags=Title,author,date,creation,time,publisher,producer,stats
home.fileToPDF.title=Comhad a thiontú go PDF
home.fileToPDF.desc=Tiontaigh beagnach aon chomhad go PDF (DOCX, PNG, XLS, PPT, TXT agus go leor eile)

View File

@@ -291,7 +291,7 @@ compressPdfs.tags=squish, kecil, kecil
home.changeMetadata.title=Ubah Metadata
home.changeMetadata.desc=Mengubah/Menghapus/Menambahkan metadata dari dokumen PDF
changeMetadata.tags==Judul,penulis,tanggal,pembuatan,waktu,penerbit,produser,statistik
changeMetadata.tags=Judul,penulis,tanggal,pembuatan,waktu,penerbit,produser,statistik
home.fileToPDF.title=Mengonversi berkas ke PDF
home.fileToPDF.desc=Mengonversi hampir semua berkas ke PDF (DOCX, PNG, XLS, PPT, TXT dan lain-lain)

View File

@@ -60,7 +60,7 @@ confirmPasswordErrorMessage=La nuova password e la conferma della nuova password
deleteCurrentUserMessage=Impossibile eliminare l'utente attualmente connesso.
deleteUsernameExistsMessage=Il nome utente non esiste e non può essere eliminato.
downgradeCurrentUserMessage=Impossibile declassare il ruolo dell'utente corrente
disabledCurrentUserMessage=The current user cannot be disabled
disabledCurrentUserMessage=L'utente corrente non può essere disabilitato
downgradeCurrentUserLongMessage=Impossibile declassare il ruolo dell'utente corrente. Pertanto, l'utente corrente non verrà visualizzato.
userAlreadyExistsOAuthMessage=L'utente esiste già come utente OAuth2.
userAlreadyExistsWebMessage=L'utente esiste già come utente web.
@@ -291,7 +291,7 @@ compressPdfs.tags=comprimere,piccolo,minuscolo
home.changeMetadata.title=Modifica Proprietà
home.changeMetadata.desc=Modifica/Aggiungi/Rimuovi le proprietà di un documento PDF.
changeMetadata.tags==Titolo,autore,data,creazione,ora,editore,produttore,statistiche
changeMetadata.tags=Titolo,autore,data,creazione,ora,editore,produttore,statistiche
home.fileToPDF.title=Converti file in PDF
home.fileToPDF.desc=Converti quasi ogni file in PDF (DOCX, PNG, XLS, PPT, TXT e altro)

View File

@@ -291,7 +291,7 @@ compressPdfs.tags=squish,small,tiny
home.changeMetadata.title=メタデータの変更
home.changeMetadata.desc=PDFのメタデータを変更/削除/追加します。
changeMetadata.tags==Title,author,date,creation,time,publisher,producer,stats
changeMetadata.tags=Title,author,date,creation,time,publisher,producer,stats
home.fileToPDF.title=ファイルをPDFに変換
home.fileToPDF.desc=ほぼすべてのファイルをPDFに変換します。 (DOCX, PNG, XLS, PPT, TXTなど)

View File

@@ -291,7 +291,7 @@ compressPdfs.tags=squish,small,tiny
home.changeMetadata.title=메타데이터 변경
home.changeMetadata.desc=PDF 문서의 메타데이터를 수정/제거/추가합니다.
changeMetadata.tags==Title,author,date,creation,time,publisher,producer,stats
changeMetadata.tags=Title,author,date,creation,time,publisher,producer,stats
home.fileToPDF.title=파일을 PDF로 변환
home.fileToPDF.desc=거의 모든 파일을 PDF로 변환합니다(DOCX, PNG, XLS, PPT, TXT 등)

View File

@@ -291,7 +291,7 @@ compressPdfs.tags=squish,small,tiny
home.changeMetadata.title=Schimbă Metadatele
home.changeMetadata.desc=Schimbă/Elimină/Adaugă metadate într-un document PDF.
changeMetadata.tags==Title,author,date,creation,time,publisher,producer,stats
changeMetadata.tags=Title,author,date,creation,time,publisher,producer,stats
home.fileToPDF.title=Convertește fișierul în PDF
home.fileToPDF.desc=Convertește aproape orice fișier în format PDF (DOCX, PNG, XLS, PPT, TXT și altele).

View File

@@ -291,7 +291,7 @@ compressPdfs.tags=squish,small,tiny
home.changeMetadata.title=Изменить метаданные
home.changeMetadata.desc=Изменить/удалить/добавить метаданные из документа PDF
changeMetadata.tags==Title,author,date,creation,time,publisher,producer,stats
changeMetadata.tags=Title,author,date,creation,time,publisher,producer,stats
home.fileToPDF.title=Конвертировать файл в PDF
home.fileToPDF.desc=Конвертируйте практически любой файл в PDF (DOCX, PNG, XLS, PPT, TXT и другие)

View File

@@ -291,7 +291,7 @@ compressPdfs.tags=squish,small,tiny
home.changeMetadata.title=Ändra metadata
home.changeMetadata.desc=Ändra/ta bort/lägg till metadata från ett PDF-dokument
changeMetadata.tags==Title,author,date,creation,time,publisher,producer,stats
changeMetadata.tags=Title,author,date,creation,time,publisher,producer,stats
home.fileToPDF.title=Konvertera fil till PDF
home.fileToPDF.desc=Konvertera nästan vilken fil som helst till PDF (DOCX, PNG, XLS, PPT, TXT och mer)

View File

@@ -291,7 +291,7 @@ compressPdfs.tags=壓縮,小,微小
home.changeMetadata.title=變更中繼資料
home.changeMetadata.desc=從 PDF 檔案中變更/移除/新增中繼資料
changeMetadata.tags==標題,作者,日期,建立,時間,出版商,製作人,統計
changeMetadata.tags=標題,作者,日期,建立,時間,出版商,製作人,統計
home.fileToPDF.title=檔案轉 PDF
home.fileToPDF.desc=將幾乎所有格式轉換為 PDFDOCX、PNG、XLS、PPT、TXT 等等)

View File

@@ -14,7 +14,7 @@
security:
enableLogin: false # set to 'true' to enable login
csrfDisabled: true # Set to 'true' to disable CSRF protection (not recommended for production)
loginAttemptCount: 5 # lock user account after 5 tries
loginAttemptCount: 5 # lock user account after 5 tries; when using e.g. Fail2Ban you can deactivate the function with -1
loginResetTimeMinutes: 120 # lock account for 2 hours after x attempts
loginMethod: all # 'all' (Login Username/Password and OAuth2[must be enabled and configured]), 'normal'(only Login with Username/Password) or 'oauth2'(only Login with OAuth2)
initialLogin:

View File

@@ -3,14 +3,14 @@
{
"moduleName": "ch.qos.logback:logback-classic",
"moduleUrl": "http://www.qos.ch",
"moduleVersion": "1.5.7",
"moduleVersion": "1.5.6",
"moduleLicense": "GNU Lesser General Public License",
"moduleLicenseUrl": "http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html"
},
{
"moduleName": "ch.qos.logback:logback-core",
"moduleUrl": "http://www.qos.ch",
"moduleVersion": "1.5.7",
"moduleVersion": "1.5.6",
"moduleLicense": "GNU Lesser General Public License",
"moduleLicenseUrl": "http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html"
},

10
test.sh
View File

@@ -73,8 +73,8 @@ main() {
# Building Docker images
docker build --no-cache --build-arg VERSION_TAG=alpha -t frooodle/s-pdf:latest -f ./Dockerfile .
docker build --no-cache --build-arg VERSION_TAG=alpha -t frooodle/s-pdf:latest-ultra-lite -f ./Dockerfile-ultra-lite .
docker build --no-cache --pull --build-arg VERSION_TAG=alpha -t frooodle/s-pdf:latest -f ./Dockerfile .
docker build --no-cache --pull --build-arg VERSION_TAG=alpha -t frooodle/s-pdf:latest-ultra-lite -f ./Dockerfile-ultra-lite .
# Test each configuration
run_tests "Stirling-PDF-Ultra-Lite" "./exampleYmlFiles/docker-compose-latest-ultra-lite.yml"
@@ -105,9 +105,9 @@ main() {
# Building Docker images with security enabled
docker build --no-cache --build-arg VERSION_TAG=alpha -t frooodle/s-pdf:latest -f ./Dockerfile .
docker build --no-cache --build-arg VERSION_TAG=alpha -t frooodle/s-pdf:latest-ultra-lite -f ./Dockerfile-ultra-lite .
docker build --no-cache --build-arg VERSION_TAG=alpha -t frooodle/s-pdf:latest-fat -f ./Dockerfile-fat .
docker build --no-cache --pull --build-arg VERSION_TAG=alpha -t frooodle/s-pdf:latest -f ./Dockerfile .
docker build --no-cache --pull --build-arg VERSION_TAG=alpha -t frooodle/s-pdf:latest-ultra-lite -f ./Dockerfile-ultra-lite .
docker build --no-cache --pull --build-arg VERSION_TAG=alpha -t frooodle/s-pdf:latest-fat -f ./Dockerfile-fat .
# Test each configuration with security