-
+
+
-
Admin User Control Settings
diff --git a/src/main/resources/templates/licenses.html b/src/main/resources/templates/licenses.html
index 7754fe8c3..5aec42a45 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 1c04334bb..90e130f6c 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 e568b327c..8c1ed05f2 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 000000000..267981d18
--- /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 e696c6bc1..689b5df03 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 0a6898f8a..f6cdfb91a 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 000000000..026a96843
--- /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 000000000..2ddc47e12
--- /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 000000000..2f7e207bc
--- /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 ec316fbc4..b0deefa06 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 000000000..3fd68ad59
--- /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 000000000..4e236756a
--- /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 66902b18a..4633c9f64 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 ac4971deb..3ab9cb477 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 f6003fbaf..ce4b3c964 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 9df08b569..64774be0f 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 e685e7f5c..208259921 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 c140c12c5..b7bfabdb4 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 744cbbd76..7add06f62 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 6717272be..5f20e450c 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 0c0504602..94e668777 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 45bdb032c..3cd8fbb45 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 7ff1c61b7..a1c449587 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 080d9bb37..e8dea1354 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 a98e8ef73..fc26615b0 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 759fae669..895ef8400 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 4ffaec2f7..e8f4f3c10 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 7589e4c52..b9117019d 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 bab67998b..648f16336 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 2a9d3461d..40c48a21b 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 02718c3a0..e0b8aa2f7 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 8597ebd81..84ed25f4f 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 519cc59fd..18017dba5 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 cc7fe4e89..c1a41ff23 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 74246eb6b..f7905ea01 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 836bfc430..b186c4c7a 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 ab7a1ac9d..cbd5c285e 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 6ca3173da..599ef7bae 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 5e0e7ec3b..102fee73f 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 00381ee8b..ecbd13bac 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 4dfe0e190..16e4b5aea 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 2f9356c70..ebe2d9897 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 ce70cb86d..46e46fbc3 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 8bcc59eed..ead961d01 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 000000000..4f6f8a864
--- /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 b9117019d..af37da447 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 000000000..efc1e467e
--- /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 595c11555..a60a66dc7 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 af37da447..88635b9db 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 000000000..029aa318e
--- /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 000000000..f2aa28c0d
--- /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 f2aa28c0d..15ea84df2 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 15ea84df2..6ade1de4f 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 208259921..aa17b39ad 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 4633c9f64..f97377d81 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 3ab9cb477..0895f5f99 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 ce4b3c964..4a37930db 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 64774be0f..36634d3ab 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 aa17b39ad..b135d5101 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 b7bfabdb4..7db7e2742 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 94e668777..daf1172fc 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 3cd8fbb45..29dcc44b4 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 a1c449587..62731ae6b 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 e8dea1354..000e27791 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 fc26615b0..9901e13f8 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 895ef8400..b9b77e5fc 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 e8f4f3c10..38d4dee43 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 88635b9db..dca16d027 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 648f16336..2ac0cf762 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 40c48a21b..b86dca72f 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 e0b8aa2f7..ed2046788 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 84ed25f4f..584cabf1d 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 18017dba5..63dd95e3a 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 c1a41ff23..bf87d427f 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 f7905ea01..a0df21cdf 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 b186c4c7a..1786a47d9 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 cbd5c285e..d632969f4 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 599ef7bae..f6f0cc1cd 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 102fee73f..c20ac0d49 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 ecbd13bac..c67574c67 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 16e4b5aea..321d048f8 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 ebe2d9897..2f68967e8 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 46e46fbc3..f24f092e3 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 ead961d01..6a4b3ac09 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 000000000..485eefb3f
--- /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 a60a66dc7..6be4482bc 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 682b4b4c4..d55e820ac 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 6be4482bc..15c9a24f7 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) |  |