-
+
+
-
Admin User Control Settings
diff --git a/src/main/resources/templates/licenses.html b/src/main/resources/templates/licenses.html
index 7754fe8c..5aec42a4 100644
--- a/src/main/resources/templates/licenses.html
+++ b/src/main/resources/templates/licenses.html
@@ -11,14 +11,17 @@
-
-
3rd Party licenses
+
+
- | Module |
- Version |
- License |
+ Module |
+ Version |
+ License |
From be05db22f5c1777ef7fb2bf9204f93f6b61146d6 Mon Sep 17 00:00:00 2001
From: Ludy
Date: Fri, 5 Jul 2024 21:48:33 +0200
Subject: [PATCH 24/36] Preparation for Switching to a New Database Version
(#1521)
* preparing to switch to a new database version
* add PreAuthorize
---------
Co-authored-by: Anthony Stirling <77850077+Frooodle@users.noreply.github.com>
---
build.gradle | 3 +
.../SPDF/config/CleanUrlInterceptor.java | 3 +-
.../SPDF/config/DatabaseBackupInterface.java | 16 ++
.../config/security/InitialSecuritySetup.java | 30 +--
.../SPDF/config/security/UserService.java | 33 ++-
.../database/DatabaseBackupHelper.java | 202 ++++++++++++++++++
.../security/database/ScheduledTasks.java | 18 ++
.../controller/api/DatabaseController.java | 144 +++++++++++++
.../SPDF/controller/api/UserController.java | 19 +-
.../controller/web/DatabaseWebController.java | 41 ++++
.../software/SPDF/utils/FileInfo.java | 50 +++++
src/main/resources/messages_ar_AR.properties | 17 ++
src/main/resources/messages_bg_BG.properties | 17 ++
src/main/resources/messages_ca_CA.properties | 17 ++
src/main/resources/messages_cs_CZ.properties | 17 ++
src/main/resources/messages_de_DE.properties | 17 ++
src/main/resources/messages_el_GR.properties | 17 ++
src/main/resources/messages_en_GB.properties | 17 ++
src/main/resources/messages_en_US.properties | 17 ++
src/main/resources/messages_es_ES.properties | 17 ++
src/main/resources/messages_eu_ES.properties | 17 ++
src/main/resources/messages_fr_FR.properties | 17 ++
src/main/resources/messages_hi_IN.properties | 17 ++
src/main/resources/messages_hr_HR.properties | 17 ++
src/main/resources/messages_hu_HU.properties | 17 ++
src/main/resources/messages_id_ID.properties | 17 ++
src/main/resources/messages_it_IT.properties | 17 ++
src/main/resources/messages_ja_JP.properties | 17 ++
src/main/resources/messages_ko_KR.properties | 17 ++
src/main/resources/messages_nl_NL.properties | 17 ++
src/main/resources/messages_no_NB.properties | 17 ++
src/main/resources/messages_pl_PL.properties | 17 ++
src/main/resources/messages_pt_BR.properties | 17 ++
src/main/resources/messages_pt_PT.properties | 17 ++
src/main/resources/messages_ro_RO.properties | 17 ++
src/main/resources/messages_ru_RU.properties | 17 ++
src/main/resources/messages_sk_SK.properties | 17 ++
.../resources/messages_sr_LATN_RS.properties | 17 ++
src/main/resources/messages_sv_SE.properties | 17 ++
src/main/resources/messages_tr_TR.properties | 17 ++
src/main/resources/messages_uk_UA.properties | 17 ++
src/main/resources/messages_zh_CN.properties | 17 ++
src/main/resources/messages_zh_TW.properties | 17 ++
src/main/resources/templates/database.html | 71 ++++++
44 files changed, 1145 insertions(+), 29 deletions(-)
create mode 100644 src/main/java/stirling/software/SPDF/config/DatabaseBackupInterface.java
create mode 100644 src/main/java/stirling/software/SPDF/config/security/database/DatabaseBackupHelper.java
create mode 100644 src/main/java/stirling/software/SPDF/config/security/database/ScheduledTasks.java
create mode 100644 src/main/java/stirling/software/SPDF/controller/api/DatabaseController.java
create mode 100644 src/main/java/stirling/software/SPDF/controller/web/DatabaseWebController.java
create mode 100644 src/main/java/stirling/software/SPDF/utils/FileInfo.java
create mode 100644 src/main/resources/templates/database.html
diff --git a/build.gradle b/build.gradle
index 1c04334b..90e130f6 100644
--- a/build.gradle
+++ b/build.gradle
@@ -36,7 +36,9 @@ sourceSets {
if (System.getenv("DOCKER_ENABLE_SECURITY") == "false") {
exclude "stirling/software/SPDF/config/security/**"
exclude "stirling/software/SPDF/controller/api/UserController.java"
+ exclude "stirling/software/SPDF/controller/api/DatabaseController.java"
exclude "stirling/software/SPDF/controller/web/AccountWebController.java"
+ exclude "stirling/software/SPDF/controller/web/DatabaseWebController.java"
exclude "stirling/software/SPDF/model/ApiKeyAuthenticationToken.java"
exclude "stirling/software/SPDF/model/Authority.java"
exclude "stirling/software/SPDF/model/PersistentLogin.java"
@@ -120,6 +122,7 @@ dependencies {
//2.2.x requires rebuild of DB file.. need migration path
implementation "com.h2database:h2:2.1.214"
+ // implementation "com.h2database:h2:2.2.224"
}
testImplementation "org.springframework.boot:spring-boot-starter-test:$springBootVersion"
diff --git a/src/main/java/stirling/software/SPDF/config/CleanUrlInterceptor.java b/src/main/java/stirling/software/SPDF/config/CleanUrlInterceptor.java
index e568b327..8c1ed05f 100644
--- a/src/main/java/stirling/software/SPDF/config/CleanUrlInterceptor.java
+++ b/src/main/java/stirling/software/SPDF/config/CleanUrlInterceptor.java
@@ -22,7 +22,8 @@ public class CleanUrlInterceptor implements HandlerInterceptor {
"error",
"erroroauth",
"file",
- "messageType");
+ "messageType",
+ "infoMessage");
@Override
public boolean preHandle(
diff --git a/src/main/java/stirling/software/SPDF/config/DatabaseBackupInterface.java b/src/main/java/stirling/software/SPDF/config/DatabaseBackupInterface.java
new file mode 100644
index 00000000..267981d1
--- /dev/null
+++ b/src/main/java/stirling/software/SPDF/config/DatabaseBackupInterface.java
@@ -0,0 +1,16 @@
+package stirling.software.SPDF.config;
+
+import java.io.IOException;
+import java.util.List;
+
+import stirling.software.SPDF.utils.FileInfo;
+
+public interface DatabaseBackupInterface {
+ void exportDatabase() throws IOException;
+
+ boolean importDatabase();
+
+ boolean hasBackup();
+
+ List getBackupList();
+}
diff --git a/src/main/java/stirling/software/SPDF/config/security/InitialSecuritySetup.java b/src/main/java/stirling/software/SPDF/config/security/InitialSecuritySetup.java
index e696c6bc..689b5df0 100644
--- a/src/main/java/stirling/software/SPDF/config/security/InitialSecuritySetup.java
+++ b/src/main/java/stirling/software/SPDF/config/security/InitialSecuritySetup.java
@@ -6,28 +6,33 @@ import java.nio.file.Paths;
import java.util.UUID;
import org.simpleyaml.configuration.file.YamlFile;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import jakarta.annotation.PostConstruct;
+import lombok.extern.slf4j.Slf4j;
+import stirling.software.SPDF.config.DatabaseBackupInterface;
import stirling.software.SPDF.model.ApplicationProperties;
import stirling.software.SPDF.model.Role;
@Component
+@Slf4j
public class InitialSecuritySetup {
@Autowired private UserService userService;
@Autowired private ApplicationProperties applicationProperties;
- private static final Logger logger = LoggerFactory.getLogger(InitialSecuritySetup.class);
+ @Autowired private DatabaseBackupInterface databaseBackupHelper;
@PostConstruct
- public void init() {
- if (!userService.hasUsers()) {
+ public void init() throws IllegalArgumentException, IOException {
+ if (databaseBackupHelper.hasBackup() && !userService.hasUsers()) {
+ databaseBackupHelper.importDatabase();
+ } else if (!userService.hasUsers()) {
initializeAdminUser();
+ } else {
+ databaseBackupHelper.exportDatabase();
}
initializeInternalApiUser();
}
@@ -41,12 +46,11 @@ public class InitialSecuritySetup {
}
}
- private void initializeAdminUser() {
+ private void initializeAdminUser() throws IOException {
String initialUsername =
applicationProperties.getSecurity().getInitialLogin().getUsername();
String initialPassword =
applicationProperties.getSecurity().getInitialLogin().getPassword();
-
if (initialUsername != null
&& !initialUsername.isEmpty()
&& initialPassword != null
@@ -54,9 +58,9 @@ public class InitialSecuritySetup {
&& !userService.findByUsernameIgnoreCase(initialUsername).isPresent()) {
try {
userService.saveUser(initialUsername, initialPassword, Role.ADMIN.getRoleId());
- logger.info("Admin user created: " + initialUsername);
+ log.info("Admin user created: " + initialUsername);
} catch (IllegalArgumentException e) {
- logger.error("Failed to initialize security setup", e);
+ log.error("Failed to initialize security setup", e);
System.exit(1);
}
} else {
@@ -64,23 +68,23 @@ public class InitialSecuritySetup {
}
}
- private void createDefaultAdminUser() {
+ private void createDefaultAdminUser() throws IllegalArgumentException, IOException {
String defaultUsername = "admin";
String defaultPassword = "stirling";
if (!userService.findByUsernameIgnoreCase(defaultUsername).isPresent()) {
userService.saveUser(defaultUsername, defaultPassword, Role.ADMIN.getRoleId(), true);
- logger.info("Default admin user created: " + defaultUsername);
+ log.info("Default admin user created: " + defaultUsername);
}
}
- private void initializeInternalApiUser() {
+ private void initializeInternalApiUser() throws IllegalArgumentException, IOException {
if (!userService.usernameExistsIgnoreCase(Role.INTERNAL_API_USER.getRoleId())) {
userService.saveUser(
Role.INTERNAL_API_USER.getRoleId(),
UUID.randomUUID().toString(),
Role.INTERNAL_API_USER.getRoleId());
userService.addApiKeyToUser(Role.INTERNAL_API_USER.getRoleId());
- logger.info("Internal API user created: " + Role.INTERNAL_API_USER.getRoleId());
+ log.info("Internal API user created: " + Role.INTERNAL_API_USER.getRoleId());
}
}
diff --git a/src/main/java/stirling/software/SPDF/config/security/UserService.java b/src/main/java/stirling/software/SPDF/config/security/UserService.java
index 0a6898f8..f6cdfb91 100644
--- a/src/main/java/stirling/software/SPDF/config/security/UserService.java
+++ b/src/main/java/stirling/software/SPDF/config/security/UserService.java
@@ -1,5 +1,6 @@
package stirling.software.SPDF.config.security;
+import java.io.IOException;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
@@ -19,6 +20,7 @@ import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
+import stirling.software.SPDF.config.DatabaseBackupInterface;
import stirling.software.SPDF.controller.api.pipeline.UserServiceInterface;
import stirling.software.SPDF.model.AuthenticationType;
import stirling.software.SPDF.model.Authority;
@@ -38,8 +40,11 @@ public class UserService implements UserServiceInterface {
@Autowired private MessageSource messageSource;
+ @Autowired DatabaseBackupInterface databaseBackupHelper;
+
// Handle OAUTH2 login and user auto creation.
- public boolean processOAuth2PostLogin(String username, boolean autoCreateUser) {
+ public boolean processOAuth2PostLogin(String username, boolean autoCreateUser)
+ throws IllegalArgumentException, IOException {
if (!isUsernameValid(username)) {
return false;
}
@@ -131,7 +136,7 @@ public class UserService implements UserServiceInterface {
}
public void saveUser(String username, AuthenticationType authenticationType)
- throws IllegalArgumentException {
+ throws IllegalArgumentException, IOException {
if (!isUsernameValid(username)) {
throw new IllegalArgumentException(getInvalidUsernameMessage());
}
@@ -142,9 +147,11 @@ public class UserService implements UserServiceInterface {
user.addAuthority(new Authority(Role.USER.getRoleId(), user));
user.setAuthenticationType(authenticationType);
userRepository.save(user);
+ databaseBackupHelper.exportDatabase();
}
- public void saveUser(String username, String password) throws IllegalArgumentException {
+ public void saveUser(String username, String password)
+ throws IllegalArgumentException, IOException {
if (!isUsernameValid(username)) {
throw new IllegalArgumentException(getInvalidUsernameMessage());
}
@@ -154,10 +161,11 @@ public class UserService implements UserServiceInterface {
user.setEnabled(true);
user.setAuthenticationType(AuthenticationType.WEB);
userRepository.save(user);
+ databaseBackupHelper.exportDatabase();
}
public void saveUser(String username, String password, String role, boolean firstLogin)
- throws IllegalArgumentException {
+ throws IllegalArgumentException, IOException {
if (!isUsernameValid(username)) {
throw new IllegalArgumentException(getInvalidUsernameMessage());
}
@@ -169,10 +177,11 @@ public class UserService implements UserServiceInterface {
user.setAuthenticationType(AuthenticationType.WEB);
user.setFirstLogin(firstLogin);
userRepository.save(user);
+ databaseBackupHelper.exportDatabase();
}
public void saveUser(String username, String password, String role)
- throws IllegalArgumentException {
+ throws IllegalArgumentException, IOException {
saveUser(username, password, role, false);
}
@@ -206,7 +215,8 @@ public class UserService implements UserServiceInterface {
return userCount > 0;
}
- public void updateUserSettings(String username, Map updates) {
+ public void updateUserSettings(String username, Map updates)
+ throws IOException {
Optional userOpt = userRepository.findByUsernameIgnoreCase(username);
if (userOpt.isPresent()) {
User user = userOpt.get();
@@ -220,6 +230,7 @@ public class UserService implements UserServiceInterface {
user.setSettings(settingsMap);
userRepository.save(user);
+ databaseBackupHelper.exportDatabase();
}
}
@@ -235,22 +246,26 @@ public class UserService implements UserServiceInterface {
return authorityRepository.findByUserId(user.getId());
}
- public void changeUsername(User user, String newUsername) throws IllegalArgumentException {
+ public void changeUsername(User user, String newUsername)
+ throws IllegalArgumentException, IOException {
if (!isUsernameValid(newUsername)) {
throw new IllegalArgumentException(getInvalidUsernameMessage());
}
user.setUsername(newUsername);
userRepository.save(user);
+ databaseBackupHelper.exportDatabase();
}
- public void changePassword(User user, String newPassword) {
+ public void changePassword(User user, String newPassword) throws IOException {
user.setPassword(passwordEncoder.encode(newPassword));
userRepository.save(user);
+ databaseBackupHelper.exportDatabase();
}
- public void changeFirstUse(User user, boolean firstUse) {
+ public void changeFirstUse(User user, boolean firstUse) throws IOException {
user.setFirstLogin(firstUse);
userRepository.save(user);
+ databaseBackupHelper.exportDatabase();
}
public void changeRole(User user, String newRole) {
diff --git a/src/main/java/stirling/software/SPDF/config/security/database/DatabaseBackupHelper.java b/src/main/java/stirling/software/SPDF/config/security/database/DatabaseBackupHelper.java
new file mode 100644
index 00000000..026a9684
--- /dev/null
+++ b/src/main/java/stirling/software/SPDF/config/security/database/DatabaseBackupHelper.java
@@ -0,0 +1,202 @@
+package stirling.software.SPDF.config.security.database;
+
+import java.io.IOException;
+import java.nio.file.DirectoryStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.time.LocalDateTime;
+import java.time.ZoneId;
+import java.time.format.DateTimeFormatter;
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Configuration;
+
+import lombok.extern.slf4j.Slf4j;
+import stirling.software.SPDF.config.DatabaseBackupInterface;
+import stirling.software.SPDF.utils.FileInfo;
+
+@Slf4j
+@Configuration
+public class DatabaseBackupHelper implements DatabaseBackupInterface {
+
+ @Value("${spring.datasource.url}")
+ private String url;
+
+ private Path backupPath = Paths.get("configs/db/backup/");
+
+ @Override
+ public boolean hasBackup() {
+ // Check if there is at least one backup
+ return !getBackupList().isEmpty();
+ }
+
+ @Override
+ public List getBackupList() {
+ // Check if the backup directory exists, and create it if it does not
+ ensureBackupDirectoryExists();
+
+ List backupFiles = new ArrayList<>();
+
+ // Read the backup directory and filter for files with the prefix "backup_" and suffix
+ // ".sql"
+ try (DirectoryStream stream =
+ Files.newDirectoryStream(
+ backupPath,
+ path ->
+ path.getFileName().toString().startsWith("backup_")
+ && path.getFileName().toString().endsWith(".sql"))) {
+ for (Path entry : stream) {
+ BasicFileAttributes attrs = Files.readAttributes(entry, BasicFileAttributes.class);
+ LocalDateTime modificationDate =
+ LocalDateTime.ofInstant(
+ attrs.lastModifiedTime().toInstant(), ZoneId.systemDefault());
+ LocalDateTime creationDate =
+ LocalDateTime.ofInstant(
+ attrs.creationTime().toInstant(), ZoneId.systemDefault());
+ long fileSize = attrs.size();
+ backupFiles.add(
+ new FileInfo(
+ entry.getFileName().toString(),
+ entry.toString(),
+ modificationDate,
+ fileSize,
+ creationDate));
+ }
+ } catch (IOException e) {
+ log.error("Error reading backup directory: {}", e.getMessage(), e);
+ }
+ return backupFiles;
+ }
+
+ // Imports a database backup from the specified file.
+ public boolean importDatabaseFromUI(String fileName) throws IOException {
+ return this.importDatabaseFromUI(getBackupFilePath(fileName));
+ }
+
+ // Imports a database backup from the specified path.
+ public boolean importDatabaseFromUI(Path tempTemplatePath) throws IOException {
+ boolean success = executeDatabaseScript(tempTemplatePath);
+ if (success) {
+ LocalDateTime dateNow = LocalDateTime.now();
+ DateTimeFormatter myFormatObj = DateTimeFormatter.ofPattern("yyyyMMddHHmm");
+ Path insertOutputFilePath =
+ this.getBackupFilePath("backup_user_" + dateNow.format(myFormatObj) + ".sql");
+ Files.copy(tempTemplatePath, insertOutputFilePath);
+ Files.deleteIfExists(tempTemplatePath);
+ }
+ return success;
+ }
+
+ @Override
+ public boolean importDatabase() {
+ if (!this.hasBackup()) return false;
+
+ List backupList = this.getBackupList();
+ backupList.sort(Comparator.comparing(FileInfo::getModificationDate).reversed());
+
+ return executeDatabaseScript(Paths.get(backupList.get(0).getFilePath()));
+ }
+
+ @Override
+ public void exportDatabase() throws IOException {
+ // Check if the backup directory exists, and create it if it does not
+ ensureBackupDirectoryExists();
+
+ // Filter and delete old backups if there are more than 5
+ List filteredBackupList =
+ this.getBackupList().stream()
+ .filter(backup -> !backup.getFileName().startsWith("backup_user_"))
+ .collect(Collectors.toList());
+
+ if (filteredBackupList.size() > 5) {
+ filteredBackupList.sort(
+ Comparator.comparing(
+ p -> p.getFileName().substring(7, p.getFileName().length() - 4)));
+ Files.deleteIfExists(Paths.get(filteredBackupList.get(0).getFilePath()));
+ log.info("Deleted oldest backup: {}", filteredBackupList.get(0).getFileName());
+ }
+
+ LocalDateTime dateNow = LocalDateTime.now();
+ DateTimeFormatter myFormatObj = DateTimeFormatter.ofPattern("yyyyMMddHHmm");
+ Path insertOutputFilePath =
+ this.getBackupFilePath("backup_" + dateNow.format(myFormatObj) + ".sql");
+ String query = "SCRIPT SIMPLE COLUMNS DROP to '" + insertOutputFilePath.toString() + "';";
+
+ try (Connection conn = DriverManager.getConnection(url, "sa", "");
+ Statement stmt = conn.createStatement()) {
+ stmt.execute(query);
+ log.info("Database export completed: {}", insertOutputFilePath);
+ } catch (SQLException e) {
+ log.error("Error during database export: {}", e.getMessage(), e);
+ }
+ }
+
+ // Retrieves the H2 database version.
+ public String getH2Version() {
+ String version = "Unknown";
+ try (Connection conn = DriverManager.getConnection(url, "sa", "")) {
+ try (Statement stmt = conn.createStatement();
+ ResultSet rs = stmt.executeQuery("SELECT H2VERSION() AS version")) {
+ if (rs.next()) {
+ version = rs.getString("version");
+ log.info("H2 Database Version: {}", version);
+ }
+ }
+ } catch (SQLException e) {
+ log.error("Error retrieving H2 version: {}", e.getMessage(), e);
+ }
+ return version;
+ }
+
+ // Deletes a backup file.
+ public boolean deleteBackupFile(String fileName) throws IOException {
+ Path filePath = this.getBackupFilePath(fileName);
+ if (Files.deleteIfExists(filePath)) {
+ log.info("Deleted backup file: {}", fileName);
+ return true;
+ } else {
+ log.error("File not found or could not be deleted: {}", fileName);
+ return false;
+ }
+ }
+
+ // Gets the Path object for a given backup file name.
+ public Path getBackupFilePath(String fileName) {
+ return Paths.get(backupPath.toString(), fileName);
+ }
+
+ private boolean executeDatabaseScript(Path scriptPath) {
+ try (Connection conn = DriverManager.getConnection(url, "sa", "");
+ Statement stmt = conn.createStatement()) {
+
+ String query = "RUNSCRIPT from '" + scriptPath.toString() + "';";
+ stmt.execute(query);
+ log.info("Database import completed: {}", scriptPath);
+ return true;
+ } catch (SQLException e) {
+ log.error("Error during database import: {}", e.getMessage(), e);
+ return false;
+ }
+ }
+
+ private void ensureBackupDirectoryExists() {
+ if (Files.notExists(backupPath)) {
+ try {
+ Files.createDirectories(backupPath);
+ } catch (IOException e) {
+ log.error("Error creating directories: {}", e.getMessage());
+ }
+ }
+ }
+}
diff --git a/src/main/java/stirling/software/SPDF/config/security/database/ScheduledTasks.java b/src/main/java/stirling/software/SPDF/config/security/database/ScheduledTasks.java
new file mode 100644
index 00000000..2ddc47e1
--- /dev/null
+++ b/src/main/java/stirling/software/SPDF/config/security/database/ScheduledTasks.java
@@ -0,0 +1,18 @@
+package stirling.software.SPDF.config.security.database;
+
+import java.io.IOException;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+@Component
+public class ScheduledTasks {
+
+ @Autowired private DatabaseBackupHelper databaseBackupService;
+
+ @Scheduled(cron = "0 0 0 * * ?")
+ public void performBackup() throws IOException {
+ databaseBackupService.exportDatabase();
+ }
+}
diff --git a/src/main/java/stirling/software/SPDF/controller/api/DatabaseController.java b/src/main/java/stirling/software/SPDF/controller/api/DatabaseController.java
new file mode 100644
index 00000000..2f7e207b
--- /dev/null
+++ b/src/main/java/stirling/software/SPDF/controller/api/DatabaseController.java
@@ -0,0 +1,144 @@
+package stirling.software.SPDF.controller.api;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URI;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.StandardCopyOption;
+
+import org.eclipse.jetty.http.HttpStatus;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.io.InputStreamResource;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.multipart.MultipartFile;
+import org.springframework.web.servlet.mvc.support.RedirectAttributes;
+
+import io.swagger.v3.oas.annotations.Hidden;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.tags.Tag;
+
+import lombok.extern.slf4j.Slf4j;
+import stirling.software.SPDF.config.security.database.DatabaseBackupHelper;
+
+@Slf4j
+@Controller
+@RequestMapping("/api/v1/database")
+@PreAuthorize("hasRole('ROLE_ADMIN')")
+@Tag(name = "Database", description = "Database APIs")
+public class DatabaseController {
+
+ @Autowired DatabaseBackupHelper databaseBackupHelper;
+
+ @Hidden
+ @PostMapping(consumes = "multipart/form-data", value = "import-database")
+ @Operation(
+ summary = "Import database backup",
+ description = "This endpoint imports a database backup from a SQL file.")
+ public String importDatabase(
+ @RequestParam("fileInput") MultipartFile file, RedirectAttributes redirectAttributes)
+ throws IllegalArgumentException, IOException {
+ if (file == null || file.isEmpty()) {
+ redirectAttributes.addAttribute("error", "fileNullOrEmpty");
+ return "redirect:/database";
+ }
+ log.info("Received file: {}", file.getOriginalFilename());
+ Path tempTemplatePath = Files.createTempFile("backup_", ".sql");
+ try (InputStream in = file.getInputStream()) {
+ Files.copy(in, tempTemplatePath, StandardCopyOption.REPLACE_EXISTING);
+ boolean importSuccess = databaseBackupHelper.importDatabaseFromUI(tempTemplatePath);
+ if (importSuccess) {
+ redirectAttributes.addAttribute("infoMessage", "importIntoDatabaseSuccessed");
+ } else {
+ redirectAttributes.addAttribute("error", "failedImportFile");
+ }
+ } catch (Exception e) {
+ log.error("Error importing database: {}", e.getMessage());
+ redirectAttributes.addAttribute("error", "failedImportFile");
+ }
+ return "redirect:/database";
+ }
+
+ @Hidden
+ @GetMapping("/import-database-file/{fileName}")
+ public String importDatabaseFromBackupUI(@PathVariable String fileName)
+ throws IllegalArgumentException, IOException {
+ if (fileName == null || fileName.isEmpty()) {
+ return "redirect:/database?error=fileNullOrEmpty";
+ }
+
+ // Check if the file exists in the backup list
+ boolean fileExists =
+ databaseBackupHelper.getBackupList().stream()
+ .anyMatch(backup -> backup.getFileName().equals(fileName));
+ if (!fileExists) {
+ log.error("File {} not found in backup list", fileName);
+ return "redirect:/database?error=fileNotFound";
+ }
+ log.info("Received file: {}", fileName);
+ if (databaseBackupHelper.importDatabaseFromUI(fileName)) {
+ log.info("File {} imported to database", fileName);
+ return "redirect:/database?infoMessage=importIntoDatabaseSuccessed";
+ }
+ return "redirect:/database?error=failedImportFile";
+ }
+
+ @Hidden
+ @GetMapping("/delete/{fileName}")
+ @Operation(
+ summary = "Delete a database backup file",
+ description =
+ "This endpoint deletes a database backup file with the specified file name.")
+ public String deleteFile(@PathVariable String fileName) {
+ if (fileName == null || fileName.isEmpty()) {
+ throw new IllegalArgumentException("File must not be null or empty");
+ }
+ try {
+ if (databaseBackupHelper.deleteBackupFile(fileName)) {
+ log.info("Deleted file: {}", fileName);
+ } else {
+ log.error("Failed to delete file: {}", fileName);
+ return "redirect:/database?error=failedToDeleteFile";
+ }
+ } catch (IOException e) {
+ log.error("Error deleting file: {}", e.getMessage());
+ return "redirect:/database?error=" + e.getMessage();
+ }
+ return "redirect:/database";
+ }
+
+ @Hidden
+ @GetMapping("/download/{fileName}")
+ @Operation(
+ summary = "Download a database backup file",
+ description =
+ "This endpoint downloads a database backup file with the specified file name.")
+ public ResponseEntity> downloadFile(@PathVariable String fileName) {
+ if (fileName == null || fileName.isEmpty()) {
+ throw new IllegalArgumentException("File must not be null or empty");
+ }
+ try {
+ Path filePath = databaseBackupHelper.getBackupFilePath(fileName);
+ InputStreamResource resource = new InputStreamResource(Files.newInputStream(filePath));
+ return ResponseEntity.ok()
+ .header(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=" + fileName)
+ .contentType(MediaType.APPLICATION_OCTET_STREAM)
+ .contentLength(Files.size(filePath))
+ .body(resource);
+ } catch (IOException e) {
+ log.error("Error downloading file: {}", e.getMessage());
+ return ResponseEntity.status(HttpStatus.SEE_OTHER_303)
+ .location(URI.create("/database?error=downloadFailed"))
+ .build();
+ }
+ }
+}
diff --git a/src/main/java/stirling/software/SPDF/controller/api/UserController.java b/src/main/java/stirling/software/SPDF/controller/api/UserController.java
index ec316fbc..b0deefa0 100644
--- a/src/main/java/stirling/software/SPDF/controller/api/UserController.java
+++ b/src/main/java/stirling/software/SPDF/controller/api/UserController.java
@@ -1,5 +1,6 @@
package stirling.software.SPDF.controller.api;
+import java.io.IOException;
import java.security.Principal;
import java.util.HashMap;
import java.util.Map;
@@ -42,7 +43,8 @@ public class UserController {
@PreAuthorize("!hasAuthority('ROLE_DEMO_USER')")
@PostMapping("/register")
- public String register(@ModelAttribute UsernameAndPass requestModel, Model model) {
+ public String register(@ModelAttribute UsernameAndPass requestModel, Model model)
+ throws IOException {
if (userService.usernameExistsIgnoreCase(requestModel.getUsername())) {
model.addAttribute("error", "Username already exists");
return "register";
@@ -63,7 +65,8 @@ public class UserController {
@RequestParam(name = "newUsername") String newUsername,
HttpServletRequest request,
HttpServletResponse response,
- RedirectAttributes redirectAttributes) {
+ RedirectAttributes redirectAttributes)
+ throws IOException {
if (!userService.isUsernameValid(newUsername)) {
return new RedirectView("/account?messageType=invalidUsername", true);
@@ -116,7 +119,8 @@ public class UserController {
@RequestParam(name = "newPassword") String newPassword,
HttpServletRequest request,
HttpServletResponse response,
- RedirectAttributes redirectAttributes) {
+ RedirectAttributes redirectAttributes)
+ throws IOException {
if (principal == null) {
return new RedirectView("/change-creds?messageType=notAuthenticated", true);
}
@@ -149,7 +153,8 @@ public class UserController {
@RequestParam(name = "newPassword") String newPassword,
HttpServletRequest request,
HttpServletResponse response,
- RedirectAttributes redirectAttributes) {
+ RedirectAttributes redirectAttributes)
+ throws IOException {
if (principal == null) {
return new RedirectView("/account?messageType=notAuthenticated", true);
}
@@ -176,7 +181,8 @@ public class UserController {
@PreAuthorize("!hasAuthority('ROLE_DEMO_USER')")
@PostMapping("/updateUserSettings")
- public String updateUserSettings(HttpServletRequest request, Principal principal) {
+ public String updateUserSettings(HttpServletRequest request, Principal principal)
+ throws IOException {
Map paramMap = request.getParameterMap();
Map updates = new HashMap<>();
@@ -201,7 +207,8 @@ public class UserController {
@RequestParam(name = "password") String password,
@RequestParam(name = "role") String role,
@RequestParam(name = "forceChange", required = false, defaultValue = "false")
- boolean forceChange) {
+ boolean forceChange)
+ throws IllegalArgumentException, IOException {
if (!userService.isUsernameValid(username)) {
return new RedirectView("/addUsers?messageType=invalidUsername", true);
diff --git a/src/main/java/stirling/software/SPDF/controller/web/DatabaseWebController.java b/src/main/java/stirling/software/SPDF/controller/web/DatabaseWebController.java
new file mode 100644
index 00000000..3fd68ad5
--- /dev/null
+++ b/src/main/java/stirling/software/SPDF/controller/web/DatabaseWebController.java
@@ -0,0 +1,41 @@
+package stirling.software.SPDF.controller.web;
+
+import java.util.List;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.security.core.Authentication;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.GetMapping;
+
+import io.swagger.v3.oas.annotations.tags.Tag;
+
+import jakarta.servlet.http.HttpServletRequest;
+import stirling.software.SPDF.config.security.database.DatabaseBackupHelper;
+import stirling.software.SPDF.utils.FileInfo;
+
+@Controller
+@Tag(name = "Database Management", description = "Database management and security APIs")
+public class DatabaseWebController {
+
+ @Autowired private DatabaseBackupHelper databaseBackupHelper;
+
+ @PreAuthorize("hasRole('ROLE_ADMIN')")
+ @GetMapping("/database")
+ public String database(HttpServletRequest request, Model model, Authentication authentication) {
+ String error = request.getParameter("error");
+ String confirmed = request.getParameter("infoMessage");
+
+ if (error != null) {
+ model.addAttribute("error", error);
+ } else if (confirmed != null) {
+ model.addAttribute("infoMessage", confirmed);
+ }
+
+ List backupList = databaseBackupHelper.getBackupList();
+ model.addAttribute("systemUpdate", backupList);
+
+ return "database";
+ }
+}
diff --git a/src/main/java/stirling/software/SPDF/utils/FileInfo.java b/src/main/java/stirling/software/SPDF/utils/FileInfo.java
new file mode 100644
index 00000000..4e236756
--- /dev/null
+++ b/src/main/java/stirling/software/SPDF/utils/FileInfo.java
@@ -0,0 +1,50 @@
+package stirling.software.SPDF.utils;
+
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+
+@AllArgsConstructor
+@Data
+public class FileInfo {
+ private String fileName;
+ private String filePath;
+ private LocalDateTime modificationDate;
+ private long fileSize;
+ private LocalDateTime creationDate;
+
+ private static final DateTimeFormatter DATE_FORMATTER =
+ DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+
+ // Converts the file path string to a Path object.
+ public Path getFilePathAsPath() {
+ return Paths.get(filePath);
+ }
+
+ // Formats the file size into a human-readable string.
+ public String getFormattedFileSize() {
+ if (fileSize >= 1024 * 1024 * 1024) {
+ return String.format("%.2f GB", fileSize / (1024.0 * 1024 * 1024));
+ } else if (fileSize >= 1024 * 1024) {
+ return String.format("%.2f MB", fileSize / (1024.0 * 1024));
+ } else if (fileSize >= 1024) {
+ return String.format("%.2f KB", fileSize / 1024.0);
+ } else {
+ return String.format("%d Bytes", fileSize);
+ }
+ }
+
+ // Formats the modification date to a string.
+ public String getFormattedModificationDate() {
+ return modificationDate.format(DATE_FORMATTER);
+ }
+
+ // Formats the creation date to a string.
+ public String getFormattedCreationDate() {
+ return creationDate.format(DATE_FORMATTER);
+ }
+}
diff --git a/src/main/resources/messages_ar_AR.properties b/src/main/resources/messages_ar_AR.properties
index 66902b18..4633c9f6 100644
--- a/src/main/resources/messages_ar_AR.properties
+++ b/src/main/resources/messages_ar_AR.properties
@@ -191,6 +191,23 @@ adminUserSettings.submit=Save User
adminUserSettings.changeUserRole=تغيير دور المستخدم
adminUserSettings.authenticated=Authenticated
+
+database.title=Database Import/Export
+database.header=Database Import/Export
+database.fileName=File Name
+database.creationDate=Creation Date
+database.fileSize=File Size
+database.deleteBackupFile=Delete Backup File
+database.importBackupFile=Import Backup File
+database.downloadBackupFile=Download Backup File
+database.info_1=When importing data, it is crucial to ensure the correct structure. If you are unsure of what you are doing, seek advice and support from a professional. An error in the structure can cause application malfunctions, up to and including the complete inability to run the application.
+database.info_2=The file name does not matter when uploading. It will be renamed afterward to follow the format backup_user_yyyyMMddHHmm.sql, ensuring a consistent naming convention.
+database.submit=Import Backup
+database.importIntoDatabaseSuccessed=Import into database successed
+database.fileNotFound=File not Found
+database.fileNullOrEmpty=File must not be null or empty
+database.failedImportFile=Failed Import File
+
#############
# HOME-PAGE #
#############
diff --git a/src/main/resources/messages_bg_BG.properties b/src/main/resources/messages_bg_BG.properties
index ac4971de..3ab9cb47 100644
--- a/src/main/resources/messages_bg_BG.properties
+++ b/src/main/resources/messages_bg_BG.properties
@@ -191,6 +191,23 @@ adminUserSettings.submit=Съхранете потребителя
adminUserSettings.changeUserRole=Промяна на ролята на потребителя
adminUserSettings.authenticated=Удостоверен
+
+database.title=Database Import/Export
+database.header=Database Import/Export
+database.fileName=File Name
+database.creationDate=Creation Date
+database.fileSize=File Size
+database.deleteBackupFile=Delete Backup File
+database.importBackupFile=Import Backup File
+database.downloadBackupFile=Download Backup File
+database.info_1=When importing data, it is crucial to ensure the correct structure. If you are unsure of what you are doing, seek advice and support from a professional. An error in the structure can cause application malfunctions, up to and including the complete inability to run the application.
+database.info_2=The file name does not matter when uploading. It will be renamed afterward to follow the format backup_user_yyyyMMddHHmm.sql, ensuring a consistent naming convention.
+database.submit=Import Backup
+database.importIntoDatabaseSuccessed=Import into database successed
+database.fileNotFound=File not Found
+database.fileNullOrEmpty=File must not be null or empty
+database.failedImportFile=Failed Import File
+
#############
# HOME-PAGE #
#############
diff --git a/src/main/resources/messages_ca_CA.properties b/src/main/resources/messages_ca_CA.properties
index f6003fba..ce4b3c96 100644
--- a/src/main/resources/messages_ca_CA.properties
+++ b/src/main/resources/messages_ca_CA.properties
@@ -191,6 +191,23 @@ adminUserSettings.submit=Desar Usuari
adminUserSettings.changeUserRole=Canvia el rol de l'usuari
adminUserSettings.authenticated=Authenticated
+
+database.title=Database Import/Export
+database.header=Database Import/Export
+database.fileName=File Name
+database.creationDate=Creation Date
+database.fileSize=File Size
+database.deleteBackupFile=Delete Backup File
+database.importBackupFile=Import Backup File
+database.downloadBackupFile=Download Backup File
+database.info_1=When importing data, it is crucial to ensure the correct structure. If you are unsure of what you are doing, seek advice and support from a professional. An error in the structure can cause application malfunctions, up to and including the complete inability to run the application.
+database.info_2=The file name does not matter when uploading. It will be renamed afterward to follow the format backup_user_yyyyMMddHHmm.sql, ensuring a consistent naming convention.
+database.submit=Import Backup
+database.importIntoDatabaseSuccessed=Import into database successed
+database.fileNotFound=File not Found
+database.fileNullOrEmpty=File must not be null or empty
+database.failedImportFile=Failed Import File
+
#############
# HOME-PAGE #
#############
diff --git a/src/main/resources/messages_cs_CZ.properties b/src/main/resources/messages_cs_CZ.properties
index 9df08b56..64774be0 100644
--- a/src/main/resources/messages_cs_CZ.properties
+++ b/src/main/resources/messages_cs_CZ.properties
@@ -191,6 +191,23 @@ adminUserSettings.submit=Uložit Uživatele
adminUserSettings.changeUserRole=Zmenit Roli Uživatele
adminUserSettings.authenticated=Ověřeno
+
+database.title=Database Import/Export
+database.header=Database Import/Export
+database.fileName=File Name
+database.creationDate=Creation Date
+database.fileSize=File Size
+database.deleteBackupFile=Delete Backup File
+database.importBackupFile=Import Backup File
+database.downloadBackupFile=Download Backup File
+database.info_1=When importing data, it is crucial to ensure the correct structure. If you are unsure of what you are doing, seek advice and support from a professional. An error in the structure can cause application malfunctions, up to and including the complete inability to run the application.
+database.info_2=The file name does not matter when uploading. It will be renamed afterward to follow the format backup_user_yyyyMMddHHmm.sql, ensuring a consistent naming convention.
+database.submit=Import Backup
+database.importIntoDatabaseSuccessed=Import into database successed
+database.fileNotFound=File not Found
+database.fileNullOrEmpty=File must not be null or empty
+database.failedImportFile=Failed Import File
+
#############
# HOME-PAGE #
#############
diff --git a/src/main/resources/messages_de_DE.properties b/src/main/resources/messages_de_DE.properties
index e685e7f5..20825992 100644
--- a/src/main/resources/messages_de_DE.properties
+++ b/src/main/resources/messages_de_DE.properties
@@ -191,6 +191,23 @@ adminUserSettings.submit=Benutzer speichern
adminUserSettings.changeUserRole=Benutzerrolle ändern
adminUserSettings.authenticated=Authentifiziert
+
+database.title=Datenbank Import/Export
+database.header=Datenbank Import/Export
+database.fileName=Dateiname
+database.creationDate=Erstellungsdatum
+database.fileSize=Dateigröße
+database.deleteBackupFile=Sicherungsdatei löschen
+database.importBackupFile=Sicherungsdatei importieren
+database.downloadBackupFile=Sicherungsdatei herunterladen
+database.info_1=Beim Importieren der Daten ist es von größter Bedeutung, die korrekte Struktur zu gewährleisten. Wenn Sie nicht sicher sind, was Sie tun, suchen Sie Rat und Unterstützung von einem Fachmann. Ein Fehler in der Struktur kann zu Fehlfunktionen der Anwendung führen, bis hin zur vollständigen Nicht-Lauffähigkeit der Anwendung.
+database.info_2=Der Dateiname spielt beim Hochladen keine Rolle. Dieser wird nachträglich in das Format backup_user_yyyyMMddHHmm.sql geändert, um eine einheitliche Benennung zu gewährleisten.
+database.submit=Sicherungsdatei importieren
+database.importIntoDatabaseSuccessed=Import in die Datenbank erfolgreich
+database.fileNotFound=Datei nicht gefunden
+database.fileNullOrEmpty=Datei darf nicht null oder leer sein
+database.failedImportFile=Dateiimport fehlgeschlagen
+
#############
# HOME-PAGE #
#############
diff --git a/src/main/resources/messages_el_GR.properties b/src/main/resources/messages_el_GR.properties
index c140c12c..b7bfabdb 100644
--- a/src/main/resources/messages_el_GR.properties
+++ b/src/main/resources/messages_el_GR.properties
@@ -191,6 +191,23 @@ adminUserSettings.submit=Αποθήκευση Χρήστη
adminUserSettings.changeUserRole=Αλλαγή ρόλου χρήστη
adminUserSettings.authenticated=Authenticated
+
+database.title=Database Import/Export
+database.header=Database Import/Export
+database.fileName=File Name
+database.creationDate=Creation Date
+database.fileSize=File Size
+database.deleteBackupFile=Delete Backup File
+database.importBackupFile=Import Backup File
+database.downloadBackupFile=Download Backup File
+database.info_1=When importing data, it is crucial to ensure the correct structure. If you are unsure of what you are doing, seek advice and support from a professional. An error in the structure can cause application malfunctions, up to and including the complete inability to run the application.
+database.info_2=The file name does not matter when uploading. It will be renamed afterward to follow the format backup_user_yyyyMMddHHmm.sql, ensuring a consistent naming convention.
+database.submit=Import Backup
+database.importIntoDatabaseSuccessed=Import into database successed
+database.fileNotFound=File not Found
+database.fileNullOrEmpty=File must not be null or empty
+database.failedImportFile=Failed Import File
+
#############
# HOME-PAGE #
#############
diff --git a/src/main/resources/messages_en_GB.properties b/src/main/resources/messages_en_GB.properties
index 744cbbd7..7add06f6 100644
--- a/src/main/resources/messages_en_GB.properties
+++ b/src/main/resources/messages_en_GB.properties
@@ -191,6 +191,23 @@ adminUserSettings.submit=Save User
adminUserSettings.changeUserRole=Change User's Role
adminUserSettings.authenticated=Authenticated
+
+database.title=Database Import/Export
+database.header=Database Import/Export
+database.fileName=File Name
+database.creationDate=Creation Date
+database.fileSize=File Size
+database.deleteBackupFile=Delete Backup File
+database.importBackupFile=Import Backup File
+database.downloadBackupFile=Download Backup File
+database.info_1=When importing data, it is crucial to ensure the correct structure. If you are unsure of what you are doing, seek advice and support from a professional. An error in the structure can cause application malfunctions, up to and including the complete inability to run the application.
+database.info_2=The file name does not matter when uploading. It will be renamed afterward to follow the format backup_user_yyyyMMddHHmm.sql, ensuring a consistent naming convention.
+database.submit=Import Backup
+database.importIntoDatabaseSuccessed=Import into database successed
+database.fileNotFound=File not found
+database.fileNullOrEmpty=File must not be null or empty
+database.failedImportFile=Failed to import file
+
#############
# HOME-PAGE #
#############
diff --git a/src/main/resources/messages_en_US.properties b/src/main/resources/messages_en_US.properties
index 6717272b..5f20e450 100644
--- a/src/main/resources/messages_en_US.properties
+++ b/src/main/resources/messages_en_US.properties
@@ -191,6 +191,23 @@ adminUserSettings.submit=Save User
adminUserSettings.changeUserRole=Change User's Role
adminUserSettings.authenticated=Authenticated
+
+database.title=Database Import/Export
+database.header=Database Import/Export
+database.fileName=File Name
+database.creationDate=Creation Date
+database.fileSize=File Size
+database.deleteBackupFile=Delete Backup File
+database.importBackupFile=Import Backup File
+database.downloadBackupFile=Download Backup File
+database.info_1=When importing data, it is crucial to ensure the correct structure. If you are unsure of what you are doing, seek advice and support from a professional. An error in the structure can cause application malfunctions, up to and including the complete inability to run the application.
+database.info_2=The file name does not matter when uploading. It will be renamed afterward to follow the format backup_user_yyyyMMddHHmm.sql, ensuring a consistent naming convention.
+database.submit=Import Backup
+database.importIntoDatabaseSuccessed=Import into database successed
+database.fileNotFound=File not Found
+database.fileNullOrEmpty=File must not be null or empty
+database.failedImportFile=Failed Import File
+
#############
# HOME-PAGE #
#############
diff --git a/src/main/resources/messages_es_ES.properties b/src/main/resources/messages_es_ES.properties
index 0c050460..94e66877 100644
--- a/src/main/resources/messages_es_ES.properties
+++ b/src/main/resources/messages_es_ES.properties
@@ -191,6 +191,23 @@ adminUserSettings.submit=Guardar Usuario
adminUserSettings.changeUserRole=Cambiar rol de usuario
adminUserSettings.authenticated=Authenticated
+
+database.title=Database Import/Export
+database.header=Database Import/Export
+database.fileName=File Name
+database.creationDate=Creation Date
+database.fileSize=File Size
+database.deleteBackupFile=Delete Backup File
+database.importBackupFile=Import Backup File
+database.downloadBackupFile=Download Backup File
+database.info_1=When importing data, it is crucial to ensure the correct structure. If you are unsure of what you are doing, seek advice and support from a professional. An error in the structure can cause application malfunctions, up to and including the complete inability to run the application.
+database.info_2=The file name does not matter when uploading. It will be renamed afterward to follow the format backup_user_yyyyMMddHHmm.sql, ensuring a consistent naming convention.
+database.submit=Import Backup
+database.importIntoDatabaseSuccessed=Import into database successed
+database.fileNotFound=File not Found
+database.fileNullOrEmpty=File must not be null or empty
+database.failedImportFile=Failed Import File
+
#############
# HOME-PAGE #
#############
diff --git a/src/main/resources/messages_eu_ES.properties b/src/main/resources/messages_eu_ES.properties
index 45bdb032..3cd8fbb4 100644
--- a/src/main/resources/messages_eu_ES.properties
+++ b/src/main/resources/messages_eu_ES.properties
@@ -191,6 +191,23 @@ adminUserSettings.submit=Gorde Erabiltzailea
adminUserSettings.changeUserRole=Erabiltzailearen rola aldatu
adminUserSettings.authenticated=Authenticated
+
+database.title=Database Import/Export
+database.header=Database Import/Export
+database.fileName=File Name
+database.creationDate=Creation Date
+database.fileSize=File Size
+database.deleteBackupFile=Delete Backup File
+database.importBackupFile=Import Backup File
+database.downloadBackupFile=Download Backup File
+database.info_1=When importing data, it is crucial to ensure the correct structure. If you are unsure of what you are doing, seek advice and support from a professional. An error in the structure can cause application malfunctions, up to and including the complete inability to run the application.
+database.info_2=The file name does not matter when uploading. It will be renamed afterward to follow the format backup_user_yyyyMMddHHmm.sql, ensuring a consistent naming convention.
+database.submit=Import Backup
+database.importIntoDatabaseSuccessed=Import into database successed
+database.fileNotFound=File not Found
+database.fileNullOrEmpty=File must not be null or empty
+database.failedImportFile=Failed Import File
+
#############
# HOME-PAGE #
#############
diff --git a/src/main/resources/messages_fr_FR.properties b/src/main/resources/messages_fr_FR.properties
index 7ff1c61b..a1c44958 100644
--- a/src/main/resources/messages_fr_FR.properties
+++ b/src/main/resources/messages_fr_FR.properties
@@ -191,6 +191,23 @@ adminUserSettings.submit=Ajouter
adminUserSettings.changeUserRole=Changer le rôle de l'utilisateur
adminUserSettings.authenticated=Authentifié
+
+database.title=Database Import/Export
+database.header=Database Import/Export
+database.fileName=File Name
+database.creationDate=Creation Date
+database.fileSize=File Size
+database.deleteBackupFile=Delete Backup File
+database.importBackupFile=Import Backup File
+database.downloadBackupFile=Download Backup File
+database.info_1=When importing data, it is crucial to ensure the correct structure. If you are unsure of what you are doing, seek advice and support from a professional. An error in the structure can cause application malfunctions, up to and including the complete inability to run the application.
+database.info_2=The file name does not matter when uploading. It will be renamed afterward to follow the format backup_user_yyyyMMddHHmm.sql, ensuring a consistent naming convention.
+database.submit=Import Backup
+database.importIntoDatabaseSuccessed=Import into database successed
+database.fileNotFound=File not Found
+database.fileNullOrEmpty=File must not be null or empty
+database.failedImportFile=Failed Import File
+
#############
# HOME-PAGE #
#############
diff --git a/src/main/resources/messages_hi_IN.properties b/src/main/resources/messages_hi_IN.properties
index 080d9bb3..e8dea135 100644
--- a/src/main/resources/messages_hi_IN.properties
+++ b/src/main/resources/messages_hi_IN.properties
@@ -191,6 +191,23 @@ adminUserSettings.submit=उपयोगकर्ता को सहेजे
adminUserSettings.changeUserRole=यूज़र की भूमिका बदलें
adminUserSettings.authenticated=Authenticated
+
+database.title=Database Import/Export
+database.header=Database Import/Export
+database.fileName=File Name
+database.creationDate=Creation Date
+database.fileSize=File Size
+database.deleteBackupFile=Delete Backup File
+database.importBackupFile=Import Backup File
+database.downloadBackupFile=Download Backup File
+database.info_1=When importing data, it is crucial to ensure the correct structure. If you are unsure of what you are doing, seek advice and support from a professional. An error in the structure can cause application malfunctions, up to and including the complete inability to run the application.
+database.info_2=The file name does not matter when uploading. It will be renamed afterward to follow the format backup_user_yyyyMMddHHmm.sql, ensuring a consistent naming convention.
+database.submit=Import Backup
+database.importIntoDatabaseSuccessed=Import into database successed
+database.fileNotFound=File not Found
+database.fileNullOrEmpty=File must not be null or empty
+database.failedImportFile=Failed Import File
+
#############
# HOME-PAGE #
#############
diff --git a/src/main/resources/messages_hr_HR.properties b/src/main/resources/messages_hr_HR.properties
index a98e8ef7..fc26615b 100644
--- a/src/main/resources/messages_hr_HR.properties
+++ b/src/main/resources/messages_hr_HR.properties
@@ -191,6 +191,23 @@ adminUserSettings.submit=Spremi korisnika
adminUserSettings.changeUserRole=Promijenite korisničku ulogu
adminUserSettings.authenticated=Autentificirano
+
+database.title=Database Import/Export
+database.header=Database Import/Export
+database.fileName=File Name
+database.creationDate=Creation Date
+database.fileSize=File Size
+database.deleteBackupFile=Delete Backup File
+database.importBackupFile=Import Backup File
+database.downloadBackupFile=Download Backup File
+database.info_1=When importing data, it is crucial to ensure the correct structure. If you are unsure of what you are doing, seek advice and support from a professional. An error in the structure can cause application malfunctions, up to and including the complete inability to run the application.
+database.info_2=The file name does not matter when uploading. It will be renamed afterward to follow the format backup_user_yyyyMMddHHmm.sql, ensuring a consistent naming convention.
+database.submit=Import Backup
+database.importIntoDatabaseSuccessed=Import into database successed
+database.fileNotFound=File not Found
+database.fileNullOrEmpty=File must not be null or empty
+database.failedImportFile=Failed Import File
+
#############
# HOME-PAGE #
#############
diff --git a/src/main/resources/messages_hu_HU.properties b/src/main/resources/messages_hu_HU.properties
index 759fae66..895ef840 100644
--- a/src/main/resources/messages_hu_HU.properties
+++ b/src/main/resources/messages_hu_HU.properties
@@ -191,6 +191,23 @@ adminUserSettings.submit=Felhasználó mentése
adminUserSettings.changeUserRole=Felhasználó szerepkörének módosítása
adminUserSettings.authenticated=Authenticated
+
+database.title=Database Import/Export
+database.header=Database Import/Export
+database.fileName=File Name
+database.creationDate=Creation Date
+database.fileSize=File Size
+database.deleteBackupFile=Delete Backup File
+database.importBackupFile=Import Backup File
+database.downloadBackupFile=Download Backup File
+database.info_1=When importing data, it is crucial to ensure the correct structure. If you are unsure of what you are doing, seek advice and support from a professional. An error in the structure can cause application malfunctions, up to and including the complete inability to run the application.
+database.info_2=The file name does not matter when uploading. It will be renamed afterward to follow the format backup_user_yyyyMMddHHmm.sql, ensuring a consistent naming convention.
+database.submit=Import Backup
+database.importIntoDatabaseSuccessed=Import into database successed
+database.fileNotFound=File not Found
+database.fileNullOrEmpty=File must not be null or empty
+database.failedImportFile=Failed Import File
+
#############
# HOME-PAGE #
#############
diff --git a/src/main/resources/messages_id_ID.properties b/src/main/resources/messages_id_ID.properties
index 4ffaec2f..e8f4f3c1 100644
--- a/src/main/resources/messages_id_ID.properties
+++ b/src/main/resources/messages_id_ID.properties
@@ -191,6 +191,23 @@ adminUserSettings.submit=Simpan Pengguna
adminUserSettings.changeUserRole=Ubah Peran Pengguna
adminUserSettings.authenticated=Authenticated
+
+database.title=Database Import/Export
+database.header=Database Import/Export
+database.fileName=File Name
+database.creationDate=Creation Date
+database.fileSize=File Size
+database.deleteBackupFile=Delete Backup File
+database.importBackupFile=Import Backup File
+database.downloadBackupFile=Download Backup File
+database.info_1=When importing data, it is crucial to ensure the correct structure. If you are unsure of what you are doing, seek advice and support from a professional. An error in the structure can cause application malfunctions, up to and including the complete inability to run the application.
+database.info_2=The file name does not matter when uploading. It will be renamed afterward to follow the format backup_user_yyyyMMddHHmm.sql, ensuring a consistent naming convention.
+database.submit=Import Backup
+database.importIntoDatabaseSuccessed=Import into database successed
+database.fileNotFound=File not Found
+database.fileNullOrEmpty=File must not be null or empty
+database.failedImportFile=Failed Import File
+
#############
# HOME-PAGE #
#############
diff --git a/src/main/resources/messages_it_IT.properties b/src/main/resources/messages_it_IT.properties
index 7589e4c5..b9117019 100644
--- a/src/main/resources/messages_it_IT.properties
+++ b/src/main/resources/messages_it_IT.properties
@@ -191,6 +191,23 @@ adminUserSettings.submit=Salva utente
adminUserSettings.changeUserRole=Cambia il ruolo dell'utente
adminUserSettings.authenticated=Autenticato
+
+database.title=Database Import/Export
+database.header=Database Import/Export
+database.fileName=File Name
+database.creationDate=Creation Date
+database.fileSize=File Size
+database.deleteBackupFile=Delete Backup File
+database.importBackupFile=Import Backup File
+database.downloadBackupFile=Download Backup File
+database.info_1=When importing data, it is crucial to ensure the correct structure. If you are unsure of what you are doing, seek advice and support from a professional. An error in the structure can cause application malfunctions, up to and including the complete inability to run the application.
+database.info_2=The file name does not matter when uploading. It will be renamed afterward to follow the format backup_user_yyyyMMddHHmm.sql, ensuring a consistent naming convention.
+database.submit=Import Backup
+database.importIntoDatabaseSuccessed=Import into database successed
+database.fileNotFound=File not Found
+database.fileNullOrEmpty=File must not be null or empty
+database.failedImportFile=Failed Import File
+
#############
# HOME-PAGE #
#############
diff --git a/src/main/resources/messages_ja_JP.properties b/src/main/resources/messages_ja_JP.properties
index bab67998..648f1633 100644
--- a/src/main/resources/messages_ja_JP.properties
+++ b/src/main/resources/messages_ja_JP.properties
@@ -191,6 +191,23 @@ adminUserSettings.submit=ユーザーの保存
adminUserSettings.changeUserRole=ユーザーの役割を変更する
adminUserSettings.authenticated=認証済
+
+database.title=Database Import/Export
+database.header=Database Import/Export
+database.fileName=File Name
+database.creationDate=Creation Date
+database.fileSize=File Size
+database.deleteBackupFile=Delete Backup File
+database.importBackupFile=Import Backup File
+database.downloadBackupFile=Download Backup File
+database.info_1=When importing data, it is crucial to ensure the correct structure. If you are unsure of what you are doing, seek advice and support from a professional. An error in the structure can cause application malfunctions, up to and including the complete inability to run the application.
+database.info_2=The file name does not matter when uploading. It will be renamed afterward to follow the format backup_user_yyyyMMddHHmm.sql, ensuring a consistent naming convention.
+database.submit=Import Backup
+database.importIntoDatabaseSuccessed=Import into database successed
+database.fileNotFound=File not Found
+database.fileNullOrEmpty=File must not be null or empty
+database.failedImportFile=Failed Import File
+
#############
# HOME-PAGE #
#############
diff --git a/src/main/resources/messages_ko_KR.properties b/src/main/resources/messages_ko_KR.properties
index 2a9d3461..40c48a21 100644
--- a/src/main/resources/messages_ko_KR.properties
+++ b/src/main/resources/messages_ko_KR.properties
@@ -191,6 +191,23 @@ adminUserSettings.submit=사용자 저장
adminUserSettings.changeUserRole=사용자의 역할 변경
adminUserSettings.authenticated=Authenticated
+
+database.title=Database Import/Export
+database.header=Database Import/Export
+database.fileName=File Name
+database.creationDate=Creation Date
+database.fileSize=File Size
+database.deleteBackupFile=Delete Backup File
+database.importBackupFile=Import Backup File
+database.downloadBackupFile=Download Backup File
+database.info_1=When importing data, it is crucial to ensure the correct structure. If you are unsure of what you are doing, seek advice and support from a professional. An error in the structure can cause application malfunctions, up to and including the complete inability to run the application.
+database.info_2=The file name does not matter when uploading. It will be renamed afterward to follow the format backup_user_yyyyMMddHHmm.sql, ensuring a consistent naming convention.
+database.submit=Import Backup
+database.importIntoDatabaseSuccessed=Import into database successed
+database.fileNotFound=File not Found
+database.fileNullOrEmpty=File must not be null or empty
+database.failedImportFile=Failed Import File
+
#############
# HOME-PAGE #
#############
diff --git a/src/main/resources/messages_nl_NL.properties b/src/main/resources/messages_nl_NL.properties
index 02718c3a..e0b8aa2f 100644
--- a/src/main/resources/messages_nl_NL.properties
+++ b/src/main/resources/messages_nl_NL.properties
@@ -191,6 +191,23 @@ adminUserSettings.submit=Gebruiker opslaan
adminUserSettings.changeUserRole=De rol van de gebruiker wijzigen
adminUserSettings.authenticated=Geauthenticeerd
+
+database.title=Database Import/Export
+database.header=Database Import/Export
+database.fileName=File Name
+database.creationDate=Creation Date
+database.fileSize=File Size
+database.deleteBackupFile=Delete Backup File
+database.importBackupFile=Import Backup File
+database.downloadBackupFile=Download Backup File
+database.info_1=When importing data, it is crucial to ensure the correct structure. If you are unsure of what you are doing, seek advice and support from a professional. An error in the structure can cause application malfunctions, up to and including the complete inability to run the application.
+database.info_2=The file name does not matter when uploading. It will be renamed afterward to follow the format backup_user_yyyyMMddHHmm.sql, ensuring a consistent naming convention.
+database.submit=Import Backup
+database.importIntoDatabaseSuccessed=Import into database successed
+database.fileNotFound=File not Found
+database.fileNullOrEmpty=File must not be null or empty
+database.failedImportFile=Failed Import File
+
#############
# HOME-PAGE #
#############
diff --git a/src/main/resources/messages_no_NB.properties b/src/main/resources/messages_no_NB.properties
index 8597ebd8..84ed25f4 100644
--- a/src/main/resources/messages_no_NB.properties
+++ b/src/main/resources/messages_no_NB.properties
@@ -191,6 +191,23 @@ adminUserSettings.submit=Lagre Bruker
adminUserSettings.changeUserRole=Endre Brukerens Rolle
adminUserSettings.authenticated=Autentisert
+
+database.title=Database Import/Export
+database.header=Database Import/Export
+database.fileName=File Name
+database.creationDate=Creation Date
+database.fileSize=File Size
+database.deleteBackupFile=Delete Backup File
+database.importBackupFile=Import Backup File
+database.downloadBackupFile=Download Backup File
+database.info_1=When importing data, it is crucial to ensure the correct structure. If you are unsure of what you are doing, seek advice and support from a professional. An error in the structure can cause application malfunctions, up to and including the complete inability to run the application.
+database.info_2=The file name does not matter when uploading. It will be renamed afterward to follow the format backup_user_yyyyMMddHHmm.sql, ensuring a consistent naming convention.
+database.submit=Import Backup
+database.importIntoDatabaseSuccessed=Import into database successed
+database.fileNotFound=File not Found
+database.fileNullOrEmpty=File must not be null or empty
+database.failedImportFile=Failed Import File
+
#############
# HOME-PAGE #
#############
diff --git a/src/main/resources/messages_pl_PL.properties b/src/main/resources/messages_pl_PL.properties
index 519cc59f..18017dba 100755
--- a/src/main/resources/messages_pl_PL.properties
+++ b/src/main/resources/messages_pl_PL.properties
@@ -191,6 +191,23 @@ adminUserSettings.submit=Zapisz użytkownika
adminUserSettings.changeUserRole=Zmień rolę użytkownika
adminUserSettings.authenticated=Zalogowany
+
+database.title=Database Import/Export
+database.header=Database Import/Export
+database.fileName=File Name
+database.creationDate=Creation Date
+database.fileSize=File Size
+database.deleteBackupFile=Delete Backup File
+database.importBackupFile=Import Backup File
+database.downloadBackupFile=Download Backup File
+database.info_1=When importing data, it is crucial to ensure the correct structure. If you are unsure of what you are doing, seek advice and support from a professional. An error in the structure can cause application malfunctions, up to and including the complete inability to run the application.
+database.info_2=The file name does not matter when uploading. It will be renamed afterward to follow the format backup_user_yyyyMMddHHmm.sql, ensuring a consistent naming convention.
+database.submit=Import Backup
+database.importIntoDatabaseSuccessed=Import into database successed
+database.fileNotFound=File not Found
+database.fileNullOrEmpty=File must not be null or empty
+database.failedImportFile=Failed Import File
+
#############
# HOME-PAGE #
#############
diff --git a/src/main/resources/messages_pt_BR.properties b/src/main/resources/messages_pt_BR.properties
index cc7fe4e8..c1a41ff2 100644
--- a/src/main/resources/messages_pt_BR.properties
+++ b/src/main/resources/messages_pt_BR.properties
@@ -191,6 +191,23 @@ adminUserSettings.submit=Save User
adminUserSettings.changeUserRole=Alterar Função de Usuário
adminUserSettings.authenticated=Authenticated
+
+database.title=Database Import/Export
+database.header=Database Import/Export
+database.fileName=File Name
+database.creationDate=Creation Date
+database.fileSize=File Size
+database.deleteBackupFile=Delete Backup File
+database.importBackupFile=Import Backup File
+database.downloadBackupFile=Download Backup File
+database.info_1=When importing data, it is crucial to ensure the correct structure. If you are unsure of what you are doing, seek advice and support from a professional. An error in the structure can cause application malfunctions, up to and including the complete inability to run the application.
+database.info_2=The file name does not matter when uploading. It will be renamed afterward to follow the format backup_user_yyyyMMddHHmm.sql, ensuring a consistent naming convention.
+database.submit=Import Backup
+database.importIntoDatabaseSuccessed=Import into database successed
+database.fileNotFound=File not Found
+database.fileNullOrEmpty=File must not be null or empty
+database.failedImportFile=Failed Import File
+
#############
# HOME-PAGE #
#############
diff --git a/src/main/resources/messages_pt_PT.properties b/src/main/resources/messages_pt_PT.properties
index 74246eb6..f7905ea0 100644
--- a/src/main/resources/messages_pt_PT.properties
+++ b/src/main/resources/messages_pt_PT.properties
@@ -191,6 +191,23 @@ adminUserSettings.submit=Save User
adminUserSettings.changeUserRole=Alterar usuário
adminUserSettings.authenticated=Authenticated
+
+database.title=Database Import/Export
+database.header=Database Import/Export
+database.fileName=File Name
+database.creationDate=Creation Date
+database.fileSize=File Size
+database.deleteBackupFile=Delete Backup File
+database.importBackupFile=Import Backup File
+database.downloadBackupFile=Download Backup File
+database.info_1=When importing data, it is crucial to ensure the correct structure. If you are unsure of what you are doing, seek advice and support from a professional. An error in the structure can cause application malfunctions, up to and including the complete inability to run the application.
+database.info_2=The file name does not matter when uploading. It will be renamed afterward to follow the format backup_user_yyyyMMddHHmm.sql, ensuring a consistent naming convention.
+database.submit=Import Backup
+database.importIntoDatabaseSuccessed=Import into database successed
+database.fileNotFound=File not Found
+database.fileNullOrEmpty=File must not be null or empty
+database.failedImportFile=Failed Import File
+
#############
# HOME-PAGE #
#############
diff --git a/src/main/resources/messages_ro_RO.properties b/src/main/resources/messages_ro_RO.properties
index 836bfc43..b186c4c7 100644
--- a/src/main/resources/messages_ro_RO.properties
+++ b/src/main/resources/messages_ro_RO.properties
@@ -191,6 +191,23 @@ adminUserSettings.submit=Save User
adminUserSettings.changeUserRole=Schimbați rolul utilizatorului
adminUserSettings.authenticated=Authenticated
+
+database.title=Database Import/Export
+database.header=Database Import/Export
+database.fileName=File Name
+database.creationDate=Creation Date
+database.fileSize=File Size
+database.deleteBackupFile=Delete Backup File
+database.importBackupFile=Import Backup File
+database.downloadBackupFile=Download Backup File
+database.info_1=When importing data, it is crucial to ensure the correct structure. If you are unsure of what you are doing, seek advice and support from a professional. An error in the structure can cause application malfunctions, up to and including the complete inability to run the application.
+database.info_2=The file name does not matter when uploading. It will be renamed afterward to follow the format backup_user_yyyyMMddHHmm.sql, ensuring a consistent naming convention.
+database.submit=Import Backup
+database.importIntoDatabaseSuccessed=Import into database successed
+database.fileNotFound=File not Found
+database.fileNullOrEmpty=File must not be null or empty
+database.failedImportFile=Failed Import File
+
#############
# HOME-PAGE #
#############
diff --git a/src/main/resources/messages_ru_RU.properties b/src/main/resources/messages_ru_RU.properties
index ab7a1ac9..cbd5c285 100644
--- a/src/main/resources/messages_ru_RU.properties
+++ b/src/main/resources/messages_ru_RU.properties
@@ -191,6 +191,23 @@ adminUserSettings.submit=Сохранить пользователя
adminUserSettings.changeUserRole=Изменить роль пользователя
adminUserSettings.authenticated=Authenticated
+
+database.title=Database Import/Export
+database.header=Database Import/Export
+database.fileName=File Name
+database.creationDate=Creation Date
+database.fileSize=File Size
+database.deleteBackupFile=Delete Backup File
+database.importBackupFile=Import Backup File
+database.downloadBackupFile=Download Backup File
+database.info_1=When importing data, it is crucial to ensure the correct structure. If you are unsure of what you are doing, seek advice and support from a professional. An error in the structure can cause application malfunctions, up to and including the complete inability to run the application.
+database.info_2=The file name does not matter when uploading. It will be renamed afterward to follow the format backup_user_yyyyMMddHHmm.sql, ensuring a consistent naming convention.
+database.submit=Import Backup
+database.importIntoDatabaseSuccessed=Import into database successed
+database.fileNotFound=File not Found
+database.fileNullOrEmpty=File must not be null or empty
+database.failedImportFile=Failed Import File
+
#############
# HOME-PAGE #
#############
diff --git a/src/main/resources/messages_sk_SK.properties b/src/main/resources/messages_sk_SK.properties
index 6ca3173d..599ef7ba 100644
--- a/src/main/resources/messages_sk_SK.properties
+++ b/src/main/resources/messages_sk_SK.properties
@@ -191,6 +191,23 @@ adminUserSettings.submit=Uložiť používateľa
adminUserSettings.changeUserRole=Zmeniť rolu používateľa
adminUserSettings.authenticated=Authenticated
+
+database.title=Database Import/Export
+database.header=Database Import/Export
+database.fileName=File Name
+database.creationDate=Creation Date
+database.fileSize=File Size
+database.deleteBackupFile=Delete Backup File
+database.importBackupFile=Import Backup File
+database.downloadBackupFile=Download Backup File
+database.info_1=When importing data, it is crucial to ensure the correct structure. If you are unsure of what you are doing, seek advice and support from a professional. An error in the structure can cause application malfunctions, up to and including the complete inability to run the application.
+database.info_2=The file name does not matter when uploading. It will be renamed afterward to follow the format backup_user_yyyyMMddHHmm.sql, ensuring a consistent naming convention.
+database.submit=Import Backup
+database.importIntoDatabaseSuccessed=Import into database successed
+database.fileNotFound=File not Found
+database.fileNullOrEmpty=File must not be null or empty
+database.failedImportFile=Failed Import File
+
#############
# HOME-PAGE #
#############
diff --git a/src/main/resources/messages_sr_LATN_RS.properties b/src/main/resources/messages_sr_LATN_RS.properties
index 5e0e7ec3..102fee73 100644
--- a/src/main/resources/messages_sr_LATN_RS.properties
+++ b/src/main/resources/messages_sr_LATN_RS.properties
@@ -191,6 +191,23 @@ adminUserSettings.submit=Sačuvaj korisnika
adminUserSettings.changeUserRole=Promenite ulogu korisnika
adminUserSettings.authenticated=Authenticated
+
+database.title=Database Import/Export
+database.header=Database Import/Export
+database.fileName=File Name
+database.creationDate=Creation Date
+database.fileSize=File Size
+database.deleteBackupFile=Delete Backup File
+database.importBackupFile=Import Backup File
+database.downloadBackupFile=Download Backup File
+database.info_1=When importing data, it is crucial to ensure the correct structure. If you are unsure of what you are doing, seek advice and support from a professional. An error in the structure can cause application malfunctions, up to and including the complete inability to run the application.
+database.info_2=The file name does not matter when uploading. It will be renamed afterward to follow the format backup_user_yyyyMMddHHmm.sql, ensuring a consistent naming convention.
+database.submit=Import Backup
+database.importIntoDatabaseSuccessed=Import into database successed
+database.fileNotFound=File not Found
+database.fileNullOrEmpty=File must not be null or empty
+database.failedImportFile=Failed Import File
+
#############
# HOME-PAGE #
#############
diff --git a/src/main/resources/messages_sv_SE.properties b/src/main/resources/messages_sv_SE.properties
index 00381ee8..ecbd13ba 100644
--- a/src/main/resources/messages_sv_SE.properties
+++ b/src/main/resources/messages_sv_SE.properties
@@ -191,6 +191,23 @@ adminUserSettings.submit=Save User
adminUserSettings.changeUserRole=Ändra användarens roll
adminUserSettings.authenticated=Authenticated
+
+database.title=Database Import/Export
+database.header=Database Import/Export
+database.fileName=File Name
+database.creationDate=Creation Date
+database.fileSize=File Size
+database.deleteBackupFile=Delete Backup File
+database.importBackupFile=Import Backup File
+database.downloadBackupFile=Download Backup File
+database.info_1=When importing data, it is crucial to ensure the correct structure. If you are unsure of what you are doing, seek advice and support from a professional. An error in the structure can cause application malfunctions, up to and including the complete inability to run the application.
+database.info_2=The file name does not matter when uploading. It will be renamed afterward to follow the format backup_user_yyyyMMddHHmm.sql, ensuring a consistent naming convention.
+database.submit=Import Backup
+database.importIntoDatabaseSuccessed=Import into database successed
+database.fileNotFound=File not Found
+database.fileNullOrEmpty=File must not be null or empty
+database.failedImportFile=Failed Import File
+
#############
# HOME-PAGE #
#############
diff --git a/src/main/resources/messages_tr_TR.properties b/src/main/resources/messages_tr_TR.properties
index 4dfe0e19..16e4b5ae 100644
--- a/src/main/resources/messages_tr_TR.properties
+++ b/src/main/resources/messages_tr_TR.properties
@@ -191,6 +191,23 @@ adminUserSettings.submit=Kullanıcıyı Kaydet
adminUserSettings.changeUserRole=Kullanıcı rolünü değiştir
adminUserSettings.authenticated=Onaylandı
+
+database.title=Database Import/Export
+database.header=Database Import/Export
+database.fileName=File Name
+database.creationDate=Creation Date
+database.fileSize=File Size
+database.deleteBackupFile=Delete Backup File
+database.importBackupFile=Import Backup File
+database.downloadBackupFile=Download Backup File
+database.info_1=When importing data, it is crucial to ensure the correct structure. If you are unsure of what you are doing, seek advice and support from a professional. An error in the structure can cause application malfunctions, up to and including the complete inability to run the application.
+database.info_2=The file name does not matter when uploading. It will be renamed afterward to follow the format backup_user_yyyyMMddHHmm.sql, ensuring a consistent naming convention.
+database.submit=Import Backup
+database.importIntoDatabaseSuccessed=Import into database successed
+database.fileNotFound=File not Found
+database.fileNullOrEmpty=File must not be null or empty
+database.failedImportFile=Failed Import File
+
#############
# HOME-PAGE #
#############
diff --git a/src/main/resources/messages_uk_UA.properties b/src/main/resources/messages_uk_UA.properties
index 2f9356c7..ebe2d989 100644
--- a/src/main/resources/messages_uk_UA.properties
+++ b/src/main/resources/messages_uk_UA.properties
@@ -191,6 +191,23 @@ adminUserSettings.submit=Зберегти користувача
adminUserSettings.changeUserRole=Змінити роль користувача
adminUserSettings.authenticated=Автентифіковано
+
+database.title=Database Import/Export
+database.header=Database Import/Export
+database.fileName=File Name
+database.creationDate=Creation Date
+database.fileSize=File Size
+database.deleteBackupFile=Delete Backup File
+database.importBackupFile=Import Backup File
+database.downloadBackupFile=Download Backup File
+database.info_1=When importing data, it is crucial to ensure the correct structure. If you are unsure of what you are doing, seek advice and support from a professional. An error in the structure can cause application malfunctions, up to and including the complete inability to run the application.
+database.info_2=The file name does not matter when uploading. It will be renamed afterward to follow the format backup_user_yyyyMMddHHmm.sql, ensuring a consistent naming convention.
+database.submit=Import Backup
+database.importIntoDatabaseSuccessed=Import into database successed
+database.fileNotFound=File not Found
+database.fileNullOrEmpty=File must not be null or empty
+database.failedImportFile=Failed Import File
+
#############
# HOME-PAGE #
#############
diff --git a/src/main/resources/messages_zh_CN.properties b/src/main/resources/messages_zh_CN.properties
index ce70cb86..46e46fbc 100644
--- a/src/main/resources/messages_zh_CN.properties
+++ b/src/main/resources/messages_zh_CN.properties
@@ -191,6 +191,23 @@ adminUserSettings.submit=保存用户
adminUserSettings.changeUserRole=更改用户角色
adminUserSettings.authenticated=已验证
+
+database.title=Database Import/Export
+database.header=Database Import/Export
+database.fileName=File Name
+database.creationDate=Creation Date
+database.fileSize=File Size
+database.deleteBackupFile=Delete Backup File
+database.importBackupFile=Import Backup File
+database.downloadBackupFile=Download Backup File
+database.info_1=When importing data, it is crucial to ensure the correct structure. If you are unsure of what you are doing, seek advice and support from a professional. An error in the structure can cause application malfunctions, up to and including the complete inability to run the application.
+database.info_2=The file name does not matter when uploading. It will be renamed afterward to follow the format backup_user_yyyyMMddHHmm.sql, ensuring a consistent naming convention.
+database.submit=Import Backup
+database.importIntoDatabaseSuccessed=Import into database successed
+database.fileNotFound=File not Found
+database.fileNullOrEmpty=File must not be null or empty
+database.failedImportFile=Failed Import File
+
#############
# HOME-PAGE #
#############
diff --git a/src/main/resources/messages_zh_TW.properties b/src/main/resources/messages_zh_TW.properties
index 8bcc59ee..ead961d0 100644
--- a/src/main/resources/messages_zh_TW.properties
+++ b/src/main/resources/messages_zh_TW.properties
@@ -191,6 +191,23 @@ adminUserSettings.submit=儲存
adminUserSettings.changeUserRole=更改使用者身份
adminUserSettings.authenticated=已驗證
+
+database.title=Database Import/Export
+database.header=Database Import/Export
+database.fileName=File Name
+database.creationDate=Creation Date
+database.fileSize=File Size
+database.deleteBackupFile=Delete Backup File
+database.importBackupFile=Import Backup File
+database.downloadBackupFile=Download Backup File
+database.info_1=When importing data, it is crucial to ensure the correct structure. If you are unsure of what you are doing, seek advice and support from a professional. An error in the structure can cause application malfunctions, up to and including the complete inability to run the application.
+database.info_2=The file name does not matter when uploading. It will be renamed afterward to follow the format backup_user_yyyyMMddHHmm.sql, ensuring a consistent naming convention.
+database.submit=Import Backup
+database.importIntoDatabaseSuccessed=Import into database successed
+database.fileNotFound=File not Found
+database.fileNullOrEmpty=File must not be null or empty
+database.failedImportFile=Failed Import File
+
#############
# HOME-PAGE #
#############
diff --git a/src/main/resources/templates/database.html b/src/main/resources/templates/database.html
new file mode 100644
index 00000000..4f6f8a86
--- /dev/null
+++ b/src/main/resources/templates/database.html
@@ -0,0 +1,71 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
From 31ce5b1221f0f8fc19e4e065e8d37694a9210765 Mon Sep 17 00:00:00 2001
From: albanobattistella <34811668+albanobattistella@users.noreply.github.com>
Date: Fri, 5 Jul 2024 21:50:22 +0200
Subject: [PATCH 25/36] Update messages_it_IT.properties (#1526)
Co-authored-by: Anthony Stirling <77850077+Frooodle@users.noreply.github.com>
---
src/main/resources/messages_it_IT.properties | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/main/resources/messages_it_IT.properties b/src/main/resources/messages_it_IT.properties
index b9117019..af37da44 100644
--- a/src/main/resources/messages_it_IT.properties
+++ b/src/main/resources/messages_it_IT.properties
@@ -116,7 +116,7 @@ navbar.multiTool=Strumenti multipli
navbar.sections.organize=Organizza
navbar.sections.convertTo=Converti in PDF
navbar.sections.convertFrom=Converti da PDF
-navbar.sections.security=Firma Firma & Sicurezza
+navbar.sections.security=Firma & Sicurezza
navbar.sections.advance=Avanzate
navbar.sections.edit=Visualizza & Modifica
From 4088208fc8137c2bbc51e39a4407c1fad179584f Mon Sep 17 00:00:00 2001
From: Ludy
Date: Sat, 6 Jul 2024 14:24:32 +0200
Subject: [PATCH 26/36] adding documentation for database import and export
(#1528)
* adding documentation for database import and export
* Update DATABASE.md
---
DATABASE.md | 40 +++++++++++++++++++++++++++++++
README.md | 68 +++++++++++++++++++++++++++--------------------------
2 files changed, 75 insertions(+), 33 deletions(-)
create mode 100644 DATABASE.md
diff --git a/DATABASE.md b/DATABASE.md
new file mode 100644
index 00000000..efc1e467
--- /dev/null
+++ b/DATABASE.md
@@ -0,0 +1,40 @@
+# New Database Backup and Import Functionality
+
+**Full activation will take place on approximately January 5th, 2025!**
+
+Why is the waiting time six months?
+
+There are users who only install updates sporadically; if they skip the preparation, it can/will lead to data loss in the database.
+
+## Functionality Overview
+
+The newly introduced feature enhances the application with robust database backup and import capabilities. This feature is designed to ensure data integrity and provide a straightforward way to manage database backups. Here's how it works:
+
+1. Automatic Backup Creation
+ - The system automatically creates a database backup every day at midnight. This ensures that there is always a recent backup available, minimizing the risk of data loss.
+2. Manual Backup Export
+ - Admin actions that modify the user database trigger a manual export of the database. This keeps the backup up-to-date with the latest changes and provides an extra layer of data security.
+3. Importing Database Backups
+ - Admin users can import a database backup either via the web interface or API endpoints. This allows for easy restoration of the database to a previous state in case of data corruption or other issues.
+ - The import process ensures that the database structure and data are correctly restored, maintaining the integrity of the application.
+4. Managing Backup Files
+ - Admins can view a list of all existing backup files, along with their creation dates and sizes. This helps in managing storage and identifying the most recent or relevant backups.
+ - Backup files can be downloaded for offline storage or transferred to other environments, providing flexibility in database management.
+ - Unnecessary backup files can be deleted through the interface to free up storage space and maintain an organized backup directory.
+
+## User Interface
+
+### Web Interface
+
+1. Upload SQL files to import database backups.
+2. View details of existing backups, such as file names, creation dates, and sizes.
+3. Download backup files for offline storage.
+4. Delete outdated or unnecessary backup files.
+
+### API Endpoints
+
+1. Import database backups by uploading SQL files.
+2. Download backup files.
+3. Delete backup files.
+
+This new functionality streamlines database management, ensuring that backups are always available and easy to manage, thus improving the reliability and resilience of the application.
diff --git a/README.md b/README.md
index 595c1155..a60a66dc 100644
--- a/README.md
+++ b/README.md
@@ -26,6 +26,7 @@ All files and PDFs exist either exclusively on the client side, reside in server
- Parallel file processing and downloads
- API for integration with external scripts
- Optional Login and Authentication support (see [here](https://github.com/Stirling-Tools/Stirling-PDF/tree/main#login-authentication) for documentation)
+- Database Backup and Import (see [here](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DATABASE.md) for documentation)
## **PDF Features**
@@ -234,35 +235,36 @@ security:
csrfDisabled: true # Set to 'true' to disable CSRF protection (not recommended for production)
loginAttemptCount: 5 # lock user account after 5 tries
loginResetTimeMinutes: 120 # lock account for 2 hours after x attempts
-# initialLogin:
-# username: "admin" # Initial username for the first login
-# password: "stirling" # Initial password for the first login
-# oauth2:
-# enabled: false # set to 'true' to enable login (Note: enableLogin must also be 'true' for this to work)
-# issuer: "" # set to any provider that supports OpenID Connect Discovery (/.well-known/openid-configuration) end-point
-# clientId: "" # Client ID from your provider
-# clientSecret: "" # Client Secret from your provider
-# autoCreateUser: false # set to 'true' to allow auto-creation of non-existing users
-# useAsUsername: "email" # Default is 'email'; custom fields can be used as the username
-# scopes: "openid, profile, email" # Specify the scopes for which the application will request permissions
-# provider: "google" # Set this to your OAuth provider's name, e.g., 'google' or 'keycloak'
-# client:
-# google:
-# clientId: "" # Client ID for Google OAuth2
-# clientSecret: "" # Client Secret for Google OAuth2
-# scopes: "https://www.googleapis.com/auth/userinfo.email, https://www.googleapis.com/auth/userinfo.profile" # Scopes for Google OAuth2
-# useAsUsername: "email" # Field to use as the username for Google OAuth2
-# github:
-# clientId: "" # Client ID for GitHub OAuth2
-# clientSecret: "" # Client Secret for GitHub OAuth2
-# scopes: "read:user" # Scope for GitHub OAuth2
-# useAsUsername: "login" # Field to use as the username for GitHub OAuth2
-# keycloak:
-# issuer: "http://192.168.0.123:8888/realms/stirling-pdf" # URL of the Keycloak realm's OpenID Connect Discovery endpoint
-# clientId: "stirling-pdf" # Client ID for Keycloak OAuth2
-# clientSecret: "" # Client Secret for Keycloak OAuth2
-# scopes: "openid, profile, email" # Scopes for Keycloak OAuth2
-# useAsUsername: "email" # Field to use as the username for Keycloak OAuth2
+ 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:
+ username: '' # Initial username for the first login
+ password: '' # Initial password for the first login
+ oauth2:
+ enabled: false # set to 'true' to enable login (Note: enableLogin must also be 'true' for this to work)
+ client:
+ keycloak:
+ issuer: '' # URL of the Keycloak realm's OpenID Connect Discovery endpoint
+ clientId: '' # Client ID for Keycloak OAuth2
+ clientSecret: '' # Client Secret for Keycloak OAuth2
+ scopes: openid, profile, email # Scopes for Keycloak OAuth2
+ useAsUsername: preferred_username # Field to use as the username for Keycloak OAuth2
+ google:
+ clientId: '' # Client ID for Google OAuth2
+ clientSecret: '' # Client Secret for Google OAuth2
+ scopes: https://www.googleapis.com/auth/userinfo.email, https://www.googleapis.com/auth/userinfo.profile # Scopes for Google OAuth2
+ useAsUsername: email # Field to use as the username for Google OAuth2
+ github:
+ clientId: '' # Client ID for GitHub OAuth2
+ clientSecret: '' # Client Secret for GitHub OAuth2
+ scopes: read:user # Scope for GitHub OAuth2
+ useAsUsername: login # Field to use as the username for GitHub OAuth2
+ issuer: '' # set to any provider that supports OpenID Connect Discovery (/.well-known/openid-configuration) end-point
+ clientId: '' # Client ID from your provider
+ clientSecret: '' # Client Secret from your provider
+ autoCreateUser: false # set to 'true' to allow auto-creation of non-existing users
+ useAsUsername: email # Default is 'email'; custom fields can be used as the username
+ scopes: openid, profile, email # Specify the scopes for which the application will request permissions
+ provider: google # Set this to your OAuth provider's name, e.g., 'google' or 'keycloak'
system:
defaultLocale: 'en-US' # Set the default language (e.g. 'de-DE', 'fr-FR', etc)
@@ -273,9 +275,9 @@ system:
customHTMLFiles: false # enable to have files placed in /customFiles/templates override the existing template html files
ui:
- appName: null # Application's visible name
- homeDescription: null # Short description or tagline shown on homepage.
- appNameNavbar: null # Name displayed on the navigation bar
+ appName: '' # Application's visible name
+ homeDescription: '' # Short description or tagline shown on homepage.
+ appNameNavbar: '' # Name displayed on the navigation bar
endpoints:
toRemove: [] # List endpoints to disable (e.g. ['img-to-pdf', 'remove-pages'])
@@ -309,7 +311,7 @@ For those wanting to use Stirling-PDFs backend API to link with their own custom

-### Prerequisites:
+### Prerequisites
- User must have the folder ./configs volumed within docker so that it is retained during updates.
- Docker users must download the security jar version by setting ``DOCKER_ENABLE_SECURITY`` to ``true`` in environment variables.
From e426d991457c4f293efdd7d717cb6534e2c05ea8 Mon Sep 17 00:00:00 2001
From: albanobattistella <34811668+albanobattistella@users.noreply.github.com>
Date: Sat, 6 Jul 2024 14:27:19 +0200
Subject: [PATCH 27/36] Update messages_it_IT.properties (#1527)
---
src/main/resources/messages_it_IT.properties | 34 ++++++++++----------
1 file changed, 17 insertions(+), 17 deletions(-)
diff --git a/src/main/resources/messages_it_IT.properties b/src/main/resources/messages_it_IT.properties
index af37da44..88635b9d 100644
--- a/src/main/resources/messages_it_IT.properties
+++ b/src/main/resources/messages_it_IT.properties
@@ -35,7 +35,7 @@ sizes.large=Largo
sizes.x-large=Extra-Large
error.pdfPassword=Il documento PDF è protetto da password e la password non è stata fornita oppure non era corretta
delete=Elimina
-username=Username
+username=Nome utente
password=Password
welcome=Benvenuto
property=Proprietà
@@ -192,21 +192,21 @@ adminUserSettings.changeUserRole=Cambia il ruolo dell'utente
adminUserSettings.authenticated=Autenticato
-database.title=Database Import/Export
-database.header=Database Import/Export
-database.fileName=File Name
-database.creationDate=Creation Date
-database.fileSize=File Size
-database.deleteBackupFile=Delete Backup File
-database.importBackupFile=Import Backup File
-database.downloadBackupFile=Download Backup File
-database.info_1=When importing data, it is crucial to ensure the correct structure. If you are unsure of what you are doing, seek advice and support from a professional. An error in the structure can cause application malfunctions, up to and including the complete inability to run the application.
-database.info_2=The file name does not matter when uploading. It will be renamed afterward to follow the format backup_user_yyyyMMddHHmm.sql, ensuring a consistent naming convention.
-database.submit=Import Backup
-database.importIntoDatabaseSuccessed=Import into database successed
-database.fileNotFound=File not Found
-database.fileNullOrEmpty=File must not be null or empty
-database.failedImportFile=Failed Import File
+database.title=Importazione/Esportazione database
+database.header=Importazione/esportazione database
+database.fileName=Nome file
+database.creationDate=Data di creazione
+database.fileSize=Dimensione
+database.deleteBackupFile=Elimina file di backup
+database.importBackupFile=Importa file di backup
+database.downloadBackupFile=Scarica il file di backup
+database.info_1=Quando si importano i dati, è fondamentale garantire la struttura corretta. Se non sei sicuro di quello che stai facendo, chiedi consiglio e supporto a un professionista. Un errore nella struttura può causare malfunzionamenti dell'applicazione, fino alla completa impossibilità di eseguire l'applicazione.
+database.info_2=Il nome del file non ha importanza durante il caricamento. Verrà rinominato in seguito per seguire il formato backup_user__yyyyMMddHHmm.sql,garantendo una convenzione di denominazione coerente.
+database.submit=Importa Backup
+database.importIntoDatabaseSuccessed=L'importazione nel database è avvenuta con successo
+database.fileNotFound=File non trovato
+database.fileNullOrEmpty=Il file non deve essere nullo o vuoto
+database.failedImportFile=Importazione file non riuscita
#############
# HOME-PAGE #
@@ -251,7 +251,7 @@ pdfOrganiser.tags=duplex,pari,dispari,ordinamento,spostamento
home.addImage.title=Aggiungi Immagine
home.addImage.desc=Aggiungi un'immagine in un punto specifico del PDF (Lavori in corso)
-addImage.tags=img,jpg,immagine,photo
+addImage.tags=img,jpg,immagine,foto
home.watermark.title=Aggiungi Filigrana
home.watermark.desc=Aggiungi una filigrana al tuo PDF.
From 19831c050cbd2b8760fd2132d4e0cc0d6c4c53a9 Mon Sep 17 00:00:00 2001
From: Ludy
Date: Sat, 6 Jul 2024 16:43:53 +0200
Subject: [PATCH 28/36] Add labeler action for pull requests (#1529)
* Automatically label PRs
* Update labeler-config.yml
---
.github/labeler-config.yml | 20 ++++++++++++++++++++
.github/workflows/labeler.yml | 17 +++++++++++++++++
2 files changed, 37 insertions(+)
create mode 100644 .github/labeler-config.yml
create mode 100644 .github/workflows/labeler.yml
diff --git a/.github/labeler-config.yml b/.github/labeler-config.yml
new file mode 100644
index 00000000..029aa318
--- /dev/null
+++ b/.github/labeler-config.yml
@@ -0,0 +1,20 @@
+translation:
+ - changed-files:
+ - any-glob-to-any-file: 'src/main/resources/messages_*_*.properties'
+
+Front End:
+ - changed-files:
+ - any-glob-to-any-file: 'src/main/resources/templates/**'
+
+java:
+ - changed-files:
+ - any-glob-to-any-file: 'src/main/java/**/*.java'
+
+documentation:
+ - changed-files:
+ - any-glob-to-any-file: '**/*.md'
+
+docker:
+ - changed-files:
+ - any-glob-to-any-file: 'Dockerfile'
+ - any-glob-to-any-file: 'Dockerfile-*'
\ No newline at end of file
diff --git a/.github/workflows/labeler.yml b/.github/workflows/labeler.yml
new file mode 100644
index 00000000..f2aa28c0
--- /dev/null
+++ b/.github/workflows/labeler.yml
@@ -0,0 +1,17 @@
+name: "Pull Request Labeler"
+on:
+ pull_request:
+ types: [opened, synchronize]
+
+jobs:
+ labeler:
+ permissions:
+ contents: read
+ pull-requests: write
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/labeler@v5
+ with:
+ repo-token: ${{ secrets.GITHUB_TOKEN }}
+ configuration-path: .github/labeler-config.yml
+ sync-labels: true
From 5189708d253a981b8c67c729964bcf77490cecb3 Mon Sep 17 00:00:00 2001
From: Ludy
Date: Sat, 6 Jul 2024 18:48:06 +0200
Subject: [PATCH 29/36] Fix labeler (#1533)
* Update labeler.yml
* Update labeler.yml
---
.github/workflows/labeler.yml | 1 +
1 file changed, 1 insertion(+)
diff --git a/.github/workflows/labeler.yml b/.github/workflows/labeler.yml
index f2aa28c0..15ea84df 100644
--- a/.github/workflows/labeler.yml
+++ b/.github/workflows/labeler.yml
@@ -10,6 +10,7 @@ jobs:
pull-requests: write
runs-on: ubuntu-latest
steps:
+ - uses: actions/checkout@v4
- uses: actions/labeler@v5
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
From ab62a93a0db28d0deb5377198a2bfa5fd66dab89 Mon Sep 17 00:00:00 2001
From: Ludy
Date: Sat, 6 Jul 2024 20:15:19 +0200
Subject: [PATCH 30/36] Fix labeler 2 (#1534)
---
.github/workflows/labeler.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/labeler.yml b/.github/workflows/labeler.yml
index 15ea84df..6ade1de4 100644
--- a/.github/workflows/labeler.yml
+++ b/.github/workflows/labeler.yml
@@ -1,6 +1,6 @@
name: "Pull Request Labeler"
on:
- pull_request:
+ pull_request_target:
types: [opened, synchronize]
jobs:
From 3c0d2b908f88c3ae97202f340f84cbc493e7ad7b Mon Sep 17 00:00:00 2001
From: Ludy
Date: Sat, 6 Jul 2024 20:17:30 +0200
Subject: [PATCH 31/36] Update messages_de_DE.properties (#1532)
Co-authored-by: Anthony Stirling <77850077+Frooodle@users.noreply.github.com>
---
src/main/resources/messages_de_DE.properties | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/src/main/resources/messages_de_DE.properties b/src/main/resources/messages_de_DE.properties
index 20825992..aa17b39a 100644
--- a/src/main/resources/messages_de_DE.properties
+++ b/src/main/resources/messages_de_DE.properties
@@ -86,7 +86,7 @@ pipeline.defaultOption=Benutzerdefiniert
pipeline.submitButton=Speichern
pipeline.help=Hilfe für Pipeline
pipeline.scanHelp=Hilfe zum Ordnerscan
-pipeline.deletePrompt=Are you sure you want to delete pipeline
+pipeline.deletePrompt=Möchten Sie die Pipeline wirklich löschen?
######################
# Pipeline Options #
@@ -1101,13 +1101,13 @@ licenses.version=Version
licenses.license=Lizenz
#survey
-survey.nav=Survey
-survey.title=Stirling-PDF Survey
-survey.description=Stirling-PDF has no tracking so we want to hear from our users to improve Stirling-PDF!
-survey.please=Please consider taking our survey!
-survey.disabled=(Survey popup will be disabled in following updates but available at foot of page)
-survey.button=Take Survey
-survey.dontShowAgain=Don't show again
+survey.nav=Umfrage
+survey.title=Stirling-PDF-Umfrage
+survey.description=Stirling-PDF hat kein Tracking, daher möchten wir von unseren Benutzern hören, wie wir Stirling-PDF verbessern können!
+survey.please=Bitte nehmen Sie an unserer Umfrage teil!
+survey.disabled=(Das Umfrage-Popup wird in folgenden Updates deaktiviert, ist aber am Fuß der Seite verfügbar.)
+survey.button=Umfrage durchführen
+survey.dontShowAgain=Nicht mehr anzeigen
#error
From 32ac38e93f9705e5db06cfbc1f01e2ee64bebad1 Mon Sep 17 00:00:00 2001
From: Ludy
Date: Sat, 6 Jul 2024 20:48:39 +0200
Subject: [PATCH 32/36] Add missing translations strings (#1535)
* Add missing translations strings
* Update messages_de_DE.properties
---
src/main/resources/messages_ar_AR.properties | 2 ++
src/main/resources/messages_bg_BG.properties | 2 ++
src/main/resources/messages_ca_CA.properties | 2 ++
src/main/resources/messages_cs_CZ.properties | 2 ++
src/main/resources/messages_de_DE.properties | 2 ++
src/main/resources/messages_el_GR.properties | 2 ++
src/main/resources/messages_es_ES.properties | 2 ++
src/main/resources/messages_eu_ES.properties | 2 ++
src/main/resources/messages_fr_FR.properties | 2 ++
src/main/resources/messages_hi_IN.properties | 2 ++
src/main/resources/messages_hr_HR.properties | 2 ++
src/main/resources/messages_hu_HU.properties | 2 ++
src/main/resources/messages_id_ID.properties | 2 ++
src/main/resources/messages_it_IT.properties | 2 ++
src/main/resources/messages_ja_JP.properties | 2 ++
src/main/resources/messages_ko_KR.properties | 2 ++
src/main/resources/messages_nl_NL.properties | 2 ++
src/main/resources/messages_no_NB.properties | 2 ++
src/main/resources/messages_pl_PL.properties | 2 ++
src/main/resources/messages_pt_BR.properties | 2 ++
src/main/resources/messages_pt_PT.properties | 2 ++
src/main/resources/messages_ro_RO.properties | 2 ++
src/main/resources/messages_ru_RU.properties | 2 ++
src/main/resources/messages_sk_SK.properties | 2 ++
src/main/resources/messages_sr_LATN_RS.properties | 2 ++
src/main/resources/messages_sv_SE.properties | 2 ++
src/main/resources/messages_tr_TR.properties | 2 ++
src/main/resources/messages_uk_UA.properties | 2 ++
src/main/resources/messages_zh_CN.properties | 2 ++
src/main/resources/messages_zh_TW.properties | 2 ++
30 files changed, 60 insertions(+)
diff --git a/src/main/resources/messages_ar_AR.properties b/src/main/resources/messages_ar_AR.properties
index 4633c9f6..f97377d8 100644
--- a/src/main/resources/messages_ar_AR.properties
+++ b/src/main/resources/messages_ar_AR.properties
@@ -706,6 +706,8 @@ removeAnnotations.submit=إزالة
#compare
compare.title=يقارن
compare.header=قارن ملفات PDF
+compare.highlightColor.1=Highlight Color 1:
+compare.highlightColor.2=Highlight Color 2:
compare.document.1=المستند 1
compare.document.2=المستند 2
compare.submit=يقارن
diff --git a/src/main/resources/messages_bg_BG.properties b/src/main/resources/messages_bg_BG.properties
index 3ab9cb47..0895f5f9 100644
--- a/src/main/resources/messages_bg_BG.properties
+++ b/src/main/resources/messages_bg_BG.properties
@@ -706,6 +706,8 @@ removeAnnotations.submit=Премахване
#compare
compare.title=Сравнявай
compare.header=Сравнявай PDF-и
+compare.highlightColor.1=Highlight Color 1:
+compare.highlightColor.2=Highlight Color 2:
compare.document.1=Документ 1
compare.document.2=Документ 2
compare.submit=Сравнявай
diff --git a/src/main/resources/messages_ca_CA.properties b/src/main/resources/messages_ca_CA.properties
index ce4b3c96..4a37930d 100644
--- a/src/main/resources/messages_ca_CA.properties
+++ b/src/main/resources/messages_ca_CA.properties
@@ -706,6 +706,8 @@ removeAnnotations.submit=Remove
#compare
compare.title=Comparar
compare.header=Compara PDF
+compare.highlightColor.1=Highlight Color 1:
+compare.highlightColor.2=Highlight Color 2:
compare.document.1=Document 1
compare.document.2=Document 2
compare.submit=Comparar
diff --git a/src/main/resources/messages_cs_CZ.properties b/src/main/resources/messages_cs_CZ.properties
index 64774be0..36634d3a 100644
--- a/src/main/resources/messages_cs_CZ.properties
+++ b/src/main/resources/messages_cs_CZ.properties
@@ -706,6 +706,8 @@ removeAnnotations.submit=Odebrat
#compare
compare.title=Porovnat
compare.header=Porovnat PDF
+compare.highlightColor.1=Highlight Color 1:
+compare.highlightColor.2=Highlight Color 2:
compare.document.1=Dokument 1
compare.document.2=Dokument 2
compare.submit=Porovnat
diff --git a/src/main/resources/messages_de_DE.properties b/src/main/resources/messages_de_DE.properties
index aa17b39a..b135d510 100644
--- a/src/main/resources/messages_de_DE.properties
+++ b/src/main/resources/messages_de_DE.properties
@@ -706,6 +706,8 @@ removeAnnotations.submit=Entfernen
#compare
compare.title=Vergleichen
compare.header=PDFs vergleichen
+compare.highlightColor.1=Highlight-Farbe 1:
+compare.highlightColor.2=Highlight-Farbe 2:
compare.document.1=Dokument 1
compare.document.2=Dokument 2
compare.submit=Vergleichen
diff --git a/src/main/resources/messages_el_GR.properties b/src/main/resources/messages_el_GR.properties
index b7bfabdb..7db7e274 100644
--- a/src/main/resources/messages_el_GR.properties
+++ b/src/main/resources/messages_el_GR.properties
@@ -706,6 +706,8 @@ removeAnnotations.submit=Κατάργηση
#compare
compare.title=Σύγκριση
compare.header=Σύγκριση PDFs
+compare.highlightColor.1=Highlight Color 1:
+compare.highlightColor.2=Highlight Color 2:
compare.document.1=Έγγραφο 1
compare.document.2=Έγγραφο 2
compare.submit=Σύγκριση
diff --git a/src/main/resources/messages_es_ES.properties b/src/main/resources/messages_es_ES.properties
index 94e66877..daf1172f 100644
--- a/src/main/resources/messages_es_ES.properties
+++ b/src/main/resources/messages_es_ES.properties
@@ -706,6 +706,8 @@ removeAnnotations.submit=Eliminar
#compare
compare.title=Comparar
compare.header=Comparar archivos PDF
+compare.highlightColor.1=Highlight Color 1:
+compare.highlightColor.2=Highlight Color 2:
compare.document.1=Documento 1
compare.document.2=Documento 2
compare.submit=Comparar
diff --git a/src/main/resources/messages_eu_ES.properties b/src/main/resources/messages_eu_ES.properties
index 3cd8fbb4..29dcc44b 100644
--- a/src/main/resources/messages_eu_ES.properties
+++ b/src/main/resources/messages_eu_ES.properties
@@ -706,6 +706,8 @@ removeAnnotations.submit=Remove
#compare
compare.title=Konparatu
compare.header=Konparatu PDF fitxategiak
+compare.highlightColor.1=Highlight Color 1:
+compare.highlightColor.2=Highlight Color 2:
compare.document.1=1. dokumentua
compare.document.2=2. dokumentua
compare.submit=Konparatu
diff --git a/src/main/resources/messages_fr_FR.properties b/src/main/resources/messages_fr_FR.properties
index a1c44958..62731ae6 100644
--- a/src/main/resources/messages_fr_FR.properties
+++ b/src/main/resources/messages_fr_FR.properties
@@ -706,6 +706,8 @@ removeAnnotations.submit=Supprimer
#compare
compare.title=Comparer
compare.header=Comparer
+compare.highlightColor.1=Highlight Color 1:
+compare.highlightColor.2=Highlight Color 2:
compare.document.1=Document 1
compare.document.2=Document 2
compare.submit=Comparer
diff --git a/src/main/resources/messages_hi_IN.properties b/src/main/resources/messages_hi_IN.properties
index e8dea135..000e2779 100644
--- a/src/main/resources/messages_hi_IN.properties
+++ b/src/main/resources/messages_hi_IN.properties
@@ -706,6 +706,8 @@ removeAnnotations.submit=हटाएं
#compare
compare.title=तुलना करें
compare.header=पीडीएफ़ तुलना करें
+compare.highlightColor.1=Highlight Color 1:
+compare.highlightColor.2=Highlight Color 2:
compare.document.1=दस्तावेज़ 1
compare.document.2=दस्तावेज़ 2
compare.submit=तुलना करें
diff --git a/src/main/resources/messages_hr_HR.properties b/src/main/resources/messages_hr_HR.properties
index fc26615b..9901e13f 100644
--- a/src/main/resources/messages_hr_HR.properties
+++ b/src/main/resources/messages_hr_HR.properties
@@ -706,6 +706,8 @@ removeAnnotations.submit=Ukloni
#compare
compare.title=Uporedite
compare.header=Usporedite PDF-ove
+compare.highlightColor.1=Highlight Color 1:
+compare.highlightColor.2=Highlight Color 2:
compare.document.1=Dokument 1
compare.document.2=Dokument 2
compare.submit=Uporedi
diff --git a/src/main/resources/messages_hu_HU.properties b/src/main/resources/messages_hu_HU.properties
index 895ef840..b9b77e5f 100644
--- a/src/main/resources/messages_hu_HU.properties
+++ b/src/main/resources/messages_hu_HU.properties
@@ -706,6 +706,8 @@ removeAnnotations.submit=Remove
#compare
compare.title=Összehasonlítás
compare.header=PDF-ek összehasonlítása
+compare.highlightColor.1=Highlight Color 1:
+compare.highlightColor.2=Highlight Color 2:
compare.document.1=Dokumentum 1
compare.document.2=Dokumentum 2
compare.submit=Összehasonlítás
diff --git a/src/main/resources/messages_id_ID.properties b/src/main/resources/messages_id_ID.properties
index e8f4f3c1..38d4dee4 100644
--- a/src/main/resources/messages_id_ID.properties
+++ b/src/main/resources/messages_id_ID.properties
@@ -706,6 +706,8 @@ removeAnnotations.submit=Hapus
#compare
compare.title=Bandingkan
compare.header=Bandingkan PDF
+compare.highlightColor.1=Highlight Color 1:
+compare.highlightColor.2=Highlight Color 2:
compare.document.1=Dokumen 1
compare.document.2=Dokumen 2
compare.submit=Bandingkan
diff --git a/src/main/resources/messages_it_IT.properties b/src/main/resources/messages_it_IT.properties
index 88635b9d..dca16d02 100644
--- a/src/main/resources/messages_it_IT.properties
+++ b/src/main/resources/messages_it_IT.properties
@@ -706,6 +706,8 @@ removeAnnotations.submit=Rimuovi
#compare
compare.title=Compara
compare.header=Compara PDF
+compare.highlightColor.1=Highlight Color 1:
+compare.highlightColor.2=Highlight Color 2:
compare.document.1=Documento 1
compare.document.2=Documento 2
compare.submit=Compara
diff --git a/src/main/resources/messages_ja_JP.properties b/src/main/resources/messages_ja_JP.properties
index 648f1633..2ac0cf76 100644
--- a/src/main/resources/messages_ja_JP.properties
+++ b/src/main/resources/messages_ja_JP.properties
@@ -706,6 +706,8 @@ removeAnnotations.submit=削除
#compare
compare.title=比較
compare.header=PDFの比較
+compare.highlightColor.1=Highlight Color 1:
+compare.highlightColor.2=Highlight Color 2:
compare.document.1=ドキュメント 1
compare.document.2=ドキュメント 2
compare.submit=比較
diff --git a/src/main/resources/messages_ko_KR.properties b/src/main/resources/messages_ko_KR.properties
index 40c48a21..b86dca72 100644
--- a/src/main/resources/messages_ko_KR.properties
+++ b/src/main/resources/messages_ko_KR.properties
@@ -706,6 +706,8 @@ removeAnnotations.submit=제거하다
#compare
compare.title=비교
compare.header=PDF 문서 비교
+compare.highlightColor.1=Highlight Color 1:
+compare.highlightColor.2=Highlight Color 2:
compare.document.1=문서 1
compare.document.2=문서 2
compare.submit=비교
diff --git a/src/main/resources/messages_nl_NL.properties b/src/main/resources/messages_nl_NL.properties
index e0b8aa2f..ed204678 100644
--- a/src/main/resources/messages_nl_NL.properties
+++ b/src/main/resources/messages_nl_NL.properties
@@ -706,6 +706,8 @@ removeAnnotations.submit=Verwijderen
#compare
compare.title=Vergelijken
compare.header=PDF's vergelijken
+compare.highlightColor.1=Highlight Color 1:
+compare.highlightColor.2=Highlight Color 2:
compare.document.1=Document 1
compare.document.2=Document 2
compare.submit=Vergelijken
diff --git a/src/main/resources/messages_no_NB.properties b/src/main/resources/messages_no_NB.properties
index 84ed25f4..584cabf1 100644
--- a/src/main/resources/messages_no_NB.properties
+++ b/src/main/resources/messages_no_NB.properties
@@ -706,6 +706,8 @@ removeAnnotations.submit=Fjern
#compare
compare.title=Sammenlign
compare.header=Sammenlign PDF-er
+compare.highlightColor.1=Highlight Color 1:
+compare.highlightColor.2=Highlight Color 2:
compare.document.1=Dokument 1
compare.document.2=Dokument 2
compare.submit=Sammenlign
diff --git a/src/main/resources/messages_pl_PL.properties b/src/main/resources/messages_pl_PL.properties
index 18017dba..63dd95e3 100755
--- a/src/main/resources/messages_pl_PL.properties
+++ b/src/main/resources/messages_pl_PL.properties
@@ -706,6 +706,8 @@ removeAnnotations.submit=Usuń
#compare
compare.title=Porównaj
compare.header=Porównaj PDF(y)
+compare.highlightColor.1=Highlight Color 1:
+compare.highlightColor.2=Highlight Color 2:
compare.document.1=Dokument 1
compare.document.2=Dokument 2
compare.submit=Porównaj
diff --git a/src/main/resources/messages_pt_BR.properties b/src/main/resources/messages_pt_BR.properties
index c1a41ff2..bf87d427 100644
--- a/src/main/resources/messages_pt_BR.properties
+++ b/src/main/resources/messages_pt_BR.properties
@@ -706,6 +706,8 @@ removeAnnotations.submit=Remove
#compare
compare.title=Comparar
compare.header=Comparar PDFs
+compare.highlightColor.1=Highlight Color 1:
+compare.highlightColor.2=Highlight Color 2:
compare.document.1=Documento 1
compare.document.2=Documento 2
compare.submit=Comparar
diff --git a/src/main/resources/messages_pt_PT.properties b/src/main/resources/messages_pt_PT.properties
index f7905ea0..a0df21cd 100644
--- a/src/main/resources/messages_pt_PT.properties
+++ b/src/main/resources/messages_pt_PT.properties
@@ -706,6 +706,8 @@ removeAnnotations.submit=Remover
#compare
compare.title=Comparar
compare.header=Comparar PDFs
+compare.highlightColor.1=Highlight Color 1:
+compare.highlightColor.2=Highlight Color 2:
compare.document.1=Documento 1
compare.document.2=Documento 2
compare.submit=Comparar
diff --git a/src/main/resources/messages_ro_RO.properties b/src/main/resources/messages_ro_RO.properties
index b186c4c7..1786a47d 100644
--- a/src/main/resources/messages_ro_RO.properties
+++ b/src/main/resources/messages_ro_RO.properties
@@ -706,6 +706,8 @@ removeAnnotations.submit=Remove
#compare
compare.title=Compară
compare.header=Compară PDF-uri
+compare.highlightColor.1=Highlight Color 1:
+compare.highlightColor.2=Highlight Color 2:
compare.document.1=Document 1
compare.document.2=Document 2
compare.submit=Compară
diff --git a/src/main/resources/messages_ru_RU.properties b/src/main/resources/messages_ru_RU.properties
index cbd5c285..d632969f 100644
--- a/src/main/resources/messages_ru_RU.properties
+++ b/src/main/resources/messages_ru_RU.properties
@@ -706,6 +706,8 @@ removeAnnotations.submit=Удалить
#compare
compare.title=Сравнение
compare.header=Сравнение PDFы
+compare.highlightColor.1=Highlight Color 1:
+compare.highlightColor.2=Highlight Color 2:
compare.document.1=Документ 1
compare.document.2=Документ 2
compare.submit=Сравнить
diff --git a/src/main/resources/messages_sk_SK.properties b/src/main/resources/messages_sk_SK.properties
index 599ef7ba..f6f0cc1c 100644
--- a/src/main/resources/messages_sk_SK.properties
+++ b/src/main/resources/messages_sk_SK.properties
@@ -706,6 +706,8 @@ removeAnnotations.submit=Odstrániť
#compare
compare.title=Porovnať
compare.header=Porovnať PDF
+compare.highlightColor.1=Highlight Color 1:
+compare.highlightColor.2=Highlight Color 2:
compare.document.1=Dokument 1
compare.document.2=Dokument 2
compare.submit=Porovnať
diff --git a/src/main/resources/messages_sr_LATN_RS.properties b/src/main/resources/messages_sr_LATN_RS.properties
index 102fee73..c20ac0d4 100644
--- a/src/main/resources/messages_sr_LATN_RS.properties
+++ b/src/main/resources/messages_sr_LATN_RS.properties
@@ -706,6 +706,8 @@ removeAnnotations.submit=Ukloni
#compare
compare.title=Uporedi
compare.header=Uporedi PDF fajlove
+compare.highlightColor.1=Highlight Color 1:
+compare.highlightColor.2=Highlight Color 2:
compare.document.1=Dokument 1
compare.document.2=Dokument 2
compare.submit=Uporedi
diff --git a/src/main/resources/messages_sv_SE.properties b/src/main/resources/messages_sv_SE.properties
index ecbd13ba..c67574c6 100644
--- a/src/main/resources/messages_sv_SE.properties
+++ b/src/main/resources/messages_sv_SE.properties
@@ -706,6 +706,8 @@ removeAnnotations.submit=Remove
#compare
compare.title=Jämför
compare.header=Jämför PDF-filer
+compare.highlightColor.1=Highlight Color 1:
+compare.highlightColor.2=Highlight Color 2:
compare.document.1=Dokument 1
compare.document.2=Dokument 2
compare.submit=Jämför
diff --git a/src/main/resources/messages_tr_TR.properties b/src/main/resources/messages_tr_TR.properties
index 16e4b5ae..321d048f 100644
--- a/src/main/resources/messages_tr_TR.properties
+++ b/src/main/resources/messages_tr_TR.properties
@@ -706,6 +706,8 @@ removeAnnotations.submit=Kaldır
#compare
compare.title=Karşılaştır
compare.header=PDF'leri Karşılaştır
+compare.highlightColor.1=Highlight Color 1:
+compare.highlightColor.2=Highlight Color 2:
compare.document.1=Belge 1
compare.document.2=Belge 2
compare.submit=Karşılaştır
diff --git a/src/main/resources/messages_uk_UA.properties b/src/main/resources/messages_uk_UA.properties
index ebe2d989..2f68967e 100644
--- a/src/main/resources/messages_uk_UA.properties
+++ b/src/main/resources/messages_uk_UA.properties
@@ -706,6 +706,8 @@ removeAnnotations.submit=Видалити
#compare
compare.title=Порівняння
compare.header=Порівняння PDF
+compare.highlightColor.1=Highlight Color 1:
+compare.highlightColor.2=Highlight Color 2:
compare.document.1=Документ 1
compare.document.2=Документ 2
compare.submit=Порівняти
diff --git a/src/main/resources/messages_zh_CN.properties b/src/main/resources/messages_zh_CN.properties
index 46e46fbc..f24f092e 100644
--- a/src/main/resources/messages_zh_CN.properties
+++ b/src/main/resources/messages_zh_CN.properties
@@ -706,6 +706,8 @@ removeAnnotations.submit=删除
#compare
compare.title=比较
compare.header=比较PDF
+compare.highlightColor.1=Highlight Color 1:
+compare.highlightColor.2=Highlight Color 2:
compare.document.1=文档 1
compare.document.2=文档 2
compare.submit=比较
diff --git a/src/main/resources/messages_zh_TW.properties b/src/main/resources/messages_zh_TW.properties
index ead961d0..6a4b3ac0 100644
--- a/src/main/resources/messages_zh_TW.properties
+++ b/src/main/resources/messages_zh_TW.properties
@@ -706,6 +706,8 @@ removeAnnotations.submit=移除
#compare
compare.title=比較
compare.header=比較 PDF
+compare.highlightColor.1=Highlight Color 1:
+compare.highlightColor.2=Highlight Color 2:
compare.document.1=文件 1
compare.document.2=文件 2
compare.submit=比較
From a17105e650e93527273669971b07a9a11351e1ed Mon Sep 17 00:00:00 2001
From: Ludy
Date: Sat, 6 Jul 2024 22:25:38 +0200
Subject: [PATCH 33/36] Create stale.yml (#1530)
* Create stale.yml
* Update stale.yml
---
.github/workflows/stale.yml | 32 ++++++++++++++++++++++++++++++++
1 file changed, 32 insertions(+)
create mode 100644 .github/workflows/stale.yml
diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml
new file mode 100644
index 00000000..485eefb3
--- /dev/null
+++ b/.github/workflows/stale.yml
@@ -0,0 +1,32 @@
+name: Close stale issues
+
+on:
+ schedule:
+ - cron: "30 0 * * *"
+ workflow_dispatch:
+
+jobs:
+ stale:
+ runs-on: ubuntu-latest
+ permissions:
+ issues: write
+ pull-requests: write
+ steps:
+ - name: 30 days stale issues
+ uses: actions/stale@v9
+ with:
+ repo-token: ${{ secrets.GITHUB_TOKEN }}
+ days-before-stale: 30
+ days-before-close: 7
+ stale-issue-message: >
+ This issue has been automatically marked as stale because it has had no recent activity.
+ It will be closed if no further activity occurs. Thank you for your contributions.
+ close-issue-message: >
+ This issue has been automatically closed because it has had no recent activity after being marked as stale.
+ Please reopen if you need further assistance.
+ stale-issue-label: "Stale"
+ remove-stale-when-updated: true
+ only-issue-labels: "more-info-needed"
+ days-before-pr-stale: -1 # Prevents PRs from being marked as stale
+ days-before-pr-close: -1 # Prevents PRs from being closed
+ start-date: '2024-07-06T00:00:00Z' # ISO 8601 Format
From 695fbb015010ada624874afaba118065f4dc8aaf Mon Sep 17 00:00:00 2001
From: "github-actions[bot]"
<41898282+github-actions[bot]@users.noreply.github.com>
Date: Sat, 6 Jul 2024 21:48:53 +0000
Subject: [PATCH 34/36] :memo: Update README: Translation Progress Table
(#1536)
:memo: Sync README
> Made via sync_files.yml
Co-authored-by: GitHub Action action@github.com
---
README.md | 56 +++++++++++++++++++++++++++----------------------------
1 file changed, 28 insertions(+), 28 deletions(-)
diff --git a/README.md b/README.md
index a60a66dc..6be4482b 100644
--- a/README.md
+++ b/README.md
@@ -171,36 +171,36 @@ Stirling PDF currently supports 32!
| ------------------------------------------- | -------------------------------------- |
| English (English) (en_GB) |  |
| English (US) (en_US) |  |
-| Arabic (العربية) (ar_AR) |  |
-| German (Deutsch) (de_DE) |  |
-| French (Français) (fr_FR) |  |
-| Spanish (Español) (es_ES) |  |
-| Simplified Chinese (简体中文) (zh_CN) |  |
-| Traditional Chinese (繁體中文) (zh_TW) |  |
-| Catalan (Català) (ca_CA) |  |
+| Arabic (العربية) (ar_AR) |  |
+| German (Deutsch) (de_DE) |  |
+| French (Français) (fr_FR) |  |
+| Spanish (Español) (es_ES) |  |
+| Simplified Chinese (简体中文) (zh_CN) |  |
+| Traditional Chinese (繁體中文) (zh_TW) |  |
+| Catalan (Català) (ca_CA) |  |
| Italian (Italiano) (it_IT) |  |
-| Swedish (Svenska) (sv_SE) |  |
-| Polish (Polski) (pl_PL) |  |
+| Swedish (Svenska) (sv_SE) |  |
+| Polish (Polski) (pl_PL) |  |
| Romanian (Română) (ro_RO) |  |
-| Korean (한국어) (ko_KR) |  |
-| Portuguese Brazilian (Português) (pt_BR) |  |
-| Portuguese (Português) (pt_PT) |  |
-| Russian (Русский) (ru_RU) |  |
-| Basque (Euskara) (eu_ES) |  |
-| Japanese (日本語) (ja_JP) |  |
-| Dutch (Nederlands) (nl_NL) |  |
-| Greek (Ελληνικά) (el_GR) |  |
-| Turkish (Türkçe) (tr_TR) |  |
-| Indonesia (Bahasa Indonesia) (id_ID) |  |
-| Hindi (हिंदी) (hi_IN) |  |
-| Hungarian (Magyar) (hu_HU) |  |
-| Bulgarian (Български) (bg_BG) |  |
-| Sebian Latin alphabet (Srpski) (sr_LATN_RS) |  |
-| Ukrainian (Українська) (uk_UA) |  |
-| Slovakian (Slovensky) (sk_SK) |  |
-| Czech (Česky) (cs_CZ) |  |
-| Croatian (Hrvatski) (hr_HR) |  |
-| Norwegian (Norsk) (no_NB) |  |
+| Korean (한국어) (ko_KR) |  |
+| Portuguese Brazilian (Português) (pt_BR) |  |
+| Portuguese (Português) (pt_PT) |  |
+| Russian (Русский) (ru_RU) |  |
+| Basque (Euskara) (eu_ES) |  |
+| Japanese (日本語) (ja_JP) |  |
+| Dutch (Nederlands) (nl_NL) |  |
+| Greek (Ελληνικά) (el_GR) |  |
+| Turkish (Türkçe) (tr_TR) |  |
+| Indonesia (Bahasa Indonesia) (id_ID) |  |
+| Hindi (हिंदी) (hi_IN) |  |
+| Hungarian (Magyar) (hu_HU) |  |
+| Bulgarian (Български) (bg_BG) |  |
+| Sebian Latin alphabet (Srpski) (sr_LATN_RS) |  |
+| Ukrainian (Українська) (uk_UA) |  |
+| Slovakian (Slovensky) (sk_SK) |  |
+| Czech (Česky) (cs_CZ) |  |
+| Croatian (Hrvatski) (hr_HR) |  |
+| Norwegian (Norsk) (no_NB) |  |
## Contributing (creating issues, translations, fixing bugs, etc.)
From 422264a28813ca2cf86df3ee146fc8d4127cc9fd Mon Sep 17 00:00:00 2001
From: Ludy
Date: Sat, 6 Jul 2024 23:54:04 +0200
Subject: [PATCH 35/36] added non-translatable strings (#1537)
Co-authored-by: Anthony Stirling <77850077+Frooodle@users.noreply.github.com>
---
scripts/ignore_translation.toml | 39 +++++++++++++++++++++++++++++++++
1 file changed, 39 insertions(+)
diff --git a/scripts/ignore_translation.toml b/scripts/ignore_translation.toml
index 682b4b4c..d55e820a 100644
--- a/scripts/ignore_translation.toml
+++ b/scripts/ignore_translation.toml
@@ -10,7 +10,11 @@ ignore = [
[ca_CA]
ignore = [
+ 'PDFToText.tags',
+ 'adminUserSettings.admin',
'language.direction',
+ 'survey.button',
+ 'watermark.type.1',
]
[cs_CZ]
@@ -48,6 +52,7 @@ ignore = [
ignore = [
'adminUserSettings.roles',
'color',
+ 'error',
'language.direction',
'no',
'showJS.tags',
@@ -60,8 +65,26 @@ ignore = [
[fr_FR]
ignore = [
+ 'AddStampRequest.alphabet',
+ 'AddStampRequest.position',
+ 'AddStampRequest.rotation',
+ 'PDFToBook.selectText.1',
+ 'addPageNumbers.selectText.3',
+ 'adminUserSettings.actions',
+ 'alphabet',
+ 'compare.document.1',
+ 'compare.document.2',
+ 'info',
'language.direction',
+ 'licenses.license',
+ 'licenses.module',
+ 'licenses.nav',
+ 'licenses.version',
+ 'pdfOrganiser.mode',
+ 'pipeline.title',
+ 'pipelineOptions.pipelineHeader',
'sponsor',
+ 'watermark.type.2',
]
[hi_IN]
@@ -71,6 +94,7 @@ ignore = [
[hr_HR]
ignore = [
+ 'PDFToBook.selectText.1',
'font',
'home.pipeline.title',
'info',
@@ -115,6 +139,7 @@ ignore = [
[nl_NL]
ignore = [
'HTMLToPDF.print',
+ 'adjustContrast.contrast',
'compare.document.1',
'compare.document.2',
'error',
@@ -130,11 +155,17 @@ ignore = [
[no_NB]
ignore = [
+ 'PDFToBook.selectText.1',
+ 'adminUserSettings.admin',
+ 'info',
'language.direction',
+ 'oops',
+ 'sponsor',
]
[pl_PL]
ignore = [
+ 'PDFToBook.selectText.1',
'language.direction',
]
@@ -160,12 +191,20 @@ ignore = [
[sk_SK]
ignore = [
+ 'adminUserSettings.admin',
+ 'home.multiTool.title',
+ 'info',
'language.direction',
+ 'navbar.sections.security',
+ 'text',
+ 'watermark.type.1',
]
[sr_LATN_RS]
ignore = [
'language.direction',
+ 'licenses.version',
+ 'poweredBy',
]
[sv_SE]
From 2a65fd08257c3128d9518496d6578ae5ca626272 Mon Sep 17 00:00:00 2001
From: "github-actions[bot]"
<41898282+github-actions[bot]@users.noreply.github.com>
Date: Sun, 7 Jul 2024 11:45:50 +0100
Subject: [PATCH 36/36] :memo: Update README: Translation Progress Table
(#1538)
:memo: Sync README
> Made via sync_files.yml
Co-authored-by: GitHub Action action@github.com
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index 6be4482b..15c9a24f 100644
--- a/README.md
+++ b/README.md
@@ -173,7 +173,7 @@ Stirling PDF currently supports 32!
| English (US) (en_US) |  |
| Arabic (العربية) (ar_AR) |  |
| German (Deutsch) (de_DE) |  |
-| French (Français) (fr_FR) |  |
+| French (Français) (fr_FR) |  |
| Spanish (Español) (es_ES) |  |
| Simplified Chinese (简体中文) (zh_CN) |  |
| Traditional Chinese (繁體中文) (zh_TW) |  |