From 5a832198b4d623a1474848b7a180c8d2e35a4427 Mon Sep 17 00:00:00 2001 From: Anthony Stirling <77850077+Frooodle@users.noreply.github.com> Date: Thu, 23 May 2024 21:17:20 +0100 Subject: [PATCH 01/13] Update build.gradle --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 89dea8aabd..4c4bfaaf7c 100644 --- a/build.gradle +++ b/build.gradle @@ -12,7 +12,7 @@ plugins { import com.github.jk1.license.render.* group = 'stirling.software' -version = '0.24.5' +version = '0.24.6' //17 is lowest but we support and recommend 21 sourceCompatibility = '17' From 4190aa20a66471bfd0fc5065611d38c8a666e201 Mon Sep 17 00:00:00 2001 From: "GitHub Action action@github.com" Date: Thu, 23 May 2024 20:17:48 +0000 Subject: [PATCH 02/13] :floppy_disk: Sync Versions > Made via sync_files.yml --- chart/stirling-pdf/Chart.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chart/stirling-pdf/Chart.yaml b/chart/stirling-pdf/Chart.yaml index a16ee64730..aa960f02c8 100644 --- a/chart/stirling-pdf/Chart.yaml +++ b/chart/stirling-pdf/Chart.yaml @@ -1,5 +1,5 @@ apiVersion: v2 -appVersion: 0.24.5 +appVersion: 0.24.6 description: locally hosted web application that allows you to perform various operations on PDF files home: https://github.com/Stirling-Tools/Stirling-PDF From 94445bceb16d51ba35ca17249ccd7b1a0d72456c Mon Sep 17 00:00:00 2001 From: Thomas BERNARD Date: Fri, 24 May 2024 19:20:06 +0200 Subject: [PATCH 03/13] fix fr translation of "Sign" To Sign is "Signer" not "Signaliser" --- src/main/resources/messages_fr_FR.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/messages_fr_FR.properties b/src/main/resources/messages_fr_FR.properties index 26afdb0e2f..ba46975070 100644 --- a/src/main/resources/messages_fr_FR.properties +++ b/src/main/resources/messages_fr_FR.properties @@ -114,7 +114,7 @@ navbar.multiTool=Multi Outils navbar.sections.organize=Oragnisation navbar.sections.convertTo=Convertir en PDF navbar.sections.convertFrom=Convertir depuis PDF -navbar.sections.security=Signalisation et sécurité +navbar.sections.security=Signature et sécurité navbar.sections.advance=Mode avancé navbar.sections.edit=Voir la modification From c2179ccd63bd476aeeb2b5e265a28ac3147b5455 Mon Sep 17 00:00:00 2001 From: Ludy87 Date: Sat, 25 May 2024 18:19:03 +0200 Subject: [PATCH 04/13] add multi OAuth2 Provider --- .../SPDF/config/ConfigInitializer.java | 36 +- .../security/SecurityConfiguration.java | 147 +- .../security/UserAuthenticationFilter.java | 1 + ...tomOAuth2AuthenticationFailureHandler.java | 1 + .../CustomOAuth2LogoutSuccessHandler.java | 61 +- .../oauth2/CustomOAuthUserService.java | 57 - .../controller/web/AccountWebController.java | 49 + .../SPDF/model/ApplicationProperties.java | 405 +++++- .../software/SPDF/model/Provider.java | 87 ++ .../SPDF/model/ProviderInterface.java | 26 + .../software/SPDF/utils/RequestUriUtils.java | 1 + .../software/SPDF/utils/UrlUtils.java | 15 + src/main/resources/messages_ar_AR.properties | 5 + src/main/resources/messages_bg_BG.properties | 5 + src/main/resources/messages_ca_CA.properties | 5 + src/main/resources/messages_cs_CZ.properties | 1191 +++++++++-------- src/main/resources/messages_de_DE.properties | 6 + src/main/resources/messages_el_GR.properties | 5 + src/main/resources/messages_en_GB.properties | 6 + src/main/resources/messages_en_US.properties | 5 + src/main/resources/messages_es_ES.properties | 5 + src/main/resources/messages_eu_ES.properties | 5 + src/main/resources/messages_fr_FR.properties | 5 + src/main/resources/messages_hi_IN.properties | 5 + src/main/resources/messages_hu_HU.properties | 5 + src/main/resources/messages_id_ID.properties | 5 + src/main/resources/messages_it_IT.properties | 5 + src/main/resources/messages_ja_JP.properties | 5 + src/main/resources/messages_ko_KR.properties | 5 + src/main/resources/messages_nl_NL.properties | 5 + src/main/resources/messages_pl_PL.properties | 5 + src/main/resources/messages_pt_BR.properties | 5 + src/main/resources/messages_pt_PT.properties | 5 + src/main/resources/messages_ro_RO.properties | 5 + src/main/resources/messages_ru_RU.properties | 5 + src/main/resources/messages_sk_SK.properties | 5 + .../resources/messages_sr_LATN_RS.properties | 5 + src/main/resources/messages_sv_SE.properties | 5 + src/main/resources/messages_tr_TR.properties | 5 + src/main/resources/messages_uk_UA.properties | 5 + src/main/resources/messages_zh_CN.properties | 5 + src/main/resources/messages_zh_TW.properties | 5 + src/main/resources/settings.yml.template | 17 + src/main/resources/templates/login.html | 28 +- 44 files changed, 1553 insertions(+), 716 deletions(-) delete mode 100644 src/main/java/stirling/software/SPDF/config/security/oauth2/CustomOAuthUserService.java create mode 100644 src/main/java/stirling/software/SPDF/model/Provider.java create mode 100644 src/main/java/stirling/software/SPDF/model/ProviderInterface.java create mode 100644 src/main/java/stirling/software/SPDF/utils/UrlUtils.java diff --git a/src/main/java/stirling/software/SPDF/config/ConfigInitializer.java b/src/main/java/stirling/software/SPDF/config/ConfigInitializer.java index e843358813..d258ea51bb 100644 --- a/src/main/java/stirling/software/SPDF/config/ConfigInitializer.java +++ b/src/main/java/stirling/software/SPDF/config/ConfigInitializer.java @@ -8,11 +8,7 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; import java.util.List; -import java.util.Map; -import java.util.Set; import org.springframework.context.ApplicationContextInitializer; import org.springframework.context.ConfigurableApplicationContext; @@ -62,7 +58,7 @@ public class ConfigInitializer Files.exists(userPath) ? Files.readAllLines(userPath) : new ArrayList<>(); List resultLines = new ArrayList<>(); - + int position = 0; for (String templateLine : templateLines) { // Check if the line is a comment if (templateLine.trim().startsWith("#")) { @@ -70,7 +66,7 @@ public class ConfigInitializer if (!entry.isEmpty()) { // Check if this comment has been uncommented in userLines String key = entry.split(":")[0].trim(); - addLine(resultLines, userLines, templateLine, key); + addLine(resultLines, userLines, templateLine, key, position); } else { resultLines.add(templateLine); } @@ -78,15 +74,16 @@ public class ConfigInitializer // Check if the line is a key-value pair else if (templateLine.contains(":")) { String key = templateLine.split(":")[0].trim(); - addLine(resultLines, userLines, templateLine, key); + addLine(resultLines, userLines, templateLine, key, position); } // Handle empty lines else if (templateLine.trim().length() == 0) { resultLines.add(""); } + position++; } - - // Write the result to the user settings file + + // Write the result to the user settings file Files.write(userPath, resultLines); } @@ -95,15 +92,19 @@ public class ConfigInitializer Files.createFile(customSettingsPath); } } - - - - //TODO check parent value instead of just indent lines for duplicate keys (like enabled etc) - private static void addLine(List resultLines, List userLines, String templateLine, String key) { + + // TODO check parent value instead of just indent lines for duplicate keys (like enabled etc) + private static void addLine( + List resultLines, + List userLines, + String templateLine, + String key, + int position) { boolean added = false; int templateIndentationLevel = getIndentationLevel(templateLine); + int pos = 0; for (String settingsLine : userLines) { - if (settingsLine.trim().startsWith(key + ":")) { + if (settingsLine.trim().startsWith(key + ":") && position == pos) { int settingsIndentationLevel = getIndentationLevel(settingsLine); // Check if it is correct settingsLine and has the same parent as templateLine if (settingsIndentationLevel == templateIndentationLevel) { @@ -112,17 +113,18 @@ public class ConfigInitializer break; } } + pos++; } if (!added) { resultLines.add(templateLine); } - } + } private static int getIndentationLevel(String line) { int indentationLevel = 0; String trimmedLine = line.trim(); if (trimmedLine.startsWith("#")) { - line = trimmedLine.substring(1); + line = trimmedLine.substring(1); } for (char c : line.toCharArray()) { if (c == ' ') { diff --git a/src/main/java/stirling/software/SPDF/config/security/SecurityConfiguration.java b/src/main/java/stirling/software/SPDF/config/security/SecurityConfiguration.java index 3b3cdaf3e0..ce6ce79972 100644 --- a/src/main/java/stirling/software/SPDF/config/security/SecurityConfiguration.java +++ b/src/main/java/stirling/software/SPDF/config/security/SecurityConfiguration.java @@ -2,6 +2,8 @@ package stirling.software.SPDF.config.security; import java.util.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; @@ -36,7 +38,11 @@ import stirling.software.SPDF.config.security.oauth2.CustomOAuth2AuthenticationS import stirling.software.SPDF.config.security.oauth2.CustomOAuth2LogoutSuccessHandler; import stirling.software.SPDF.config.security.oauth2.CustomOAuth2UserService; import stirling.software.SPDF.model.ApplicationProperties; +import stirling.software.SPDF.model.ApplicationProperties.GithubProvider; +import stirling.software.SPDF.model.ApplicationProperties.GoogleProvider; +import stirling.software.SPDF.model.ApplicationProperties.KeycloakProvider; import stirling.software.SPDF.model.ApplicationProperties.Security.OAUTH2; +import stirling.software.SPDF.model.ApplicationProperties.Security.OAUTH2.Client; import stirling.software.SPDF.model.User; import stirling.software.SPDF.repository.JPATokenRepositoryImpl; @@ -47,6 +53,8 @@ public class SecurityConfiguration { @Autowired private CustomUserDetailsService userDetailsService; + private static final Logger logger = LoggerFactory.getLogger(SecurityConfiguration.class); + @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); @@ -140,6 +148,7 @@ public class SecurityConfiguration { || trimmedUri.startsWith("/images/") || trimmedUri.startsWith("/public/") || trimmedUri.startsWith("/css/") + || trimmedUri.startsWith("/fonts/") || trimmedUri.startsWith("/js/") || trimmedUri.startsWith( "/api/v1/info/status"); @@ -150,7 +159,8 @@ public class SecurityConfiguration { .authenticationProvider(authenticationProvider()); // Handle OAUTH2 Logins - if (applicationProperties.getSecurity().getOAUTH2().getEnabled()) { + if (applicationProperties.getSecurity().getOAUTH2() != null + && applicationProperties.getSecurity().getOAUTH2().getEnabled()) { http.oauth2Login( oauth2 -> @@ -181,9 +191,10 @@ public class SecurityConfiguration { .logout( logout -> logout.logoutSuccessHandler( - new CustomOAuth2LogoutSuccessHandler( - this.applicationProperties, - sessionRegistry()))); + new CustomOAuth2LogoutSuccessHandler( + this.applicationProperties, + sessionRegistry())) + .invalidateHttpSession(true)); } } else { http.csrf(csrf -> csrf.disable()) @@ -200,19 +211,127 @@ public class SecurityConfiguration { havingValue = "true", matchIfMissing = false) public ClientRegistrationRepository clientRegistrationRepository() { - return new InMemoryClientRegistrationRepository(this.oidcClientRegistration()); + List registrations = new ArrayList<>(); + + githubClientRegistration().ifPresent(registrations::add); + oidcClientRegistration().ifPresent(registrations::add); + googleClientRegistration().ifPresent(registrations::add); + keycloakClientRegistration().ifPresent(registrations::add); + + if (registrations.isEmpty()) { + logger.error("At least one OAuth2 provider must be configured"); + System.exit(1); + } + + return new InMemoryClientRegistrationRepository(registrations); } - private ClientRegistration oidcClientRegistration() { + private Optional googleClientRegistration() { OAUTH2 oauth = applicationProperties.getSecurity().getOAUTH2(); - return ClientRegistrations.fromIssuerLocation(oauth.getIssuer()) - .registrationId("oidc") - .clientId(oauth.getClientId()) - .clientSecret(oauth.getClientSecret()) - .scope(oauth.getScopes()) - .userNameAttributeName(oauth.getUseAsUsername()) - .clientName("OIDC") - .build(); + if (oauth == null || !oauth.getEnabled()) { + return Optional.empty(); + } + Client client = oauth.getClient(); + if (client == null) { + return Optional.empty(); + } + GoogleProvider google = client.getGoogle(); + return google != null && google.isSettingsValid() + ? Optional.of( + ClientRegistration.withRegistrationId("google") + .clientId(google.getClientId()) + .clientSecret(google.getClientSecret()) + .scope(google.getScopes()) + .authorizationUri(google.getAuthorizationuri()) + .tokenUri(google.getTokenuri()) + .userInfoUri(google.getUserinfouri()) + .userNameAttributeName(google.getUseAsUsername()) + .clientName("Google") + .redirectUri("{baseUrl}/login/oauth2/code/google") + .authorizationGrantType( + org.springframework.security.oauth2.core + .AuthorizationGrantType.AUTHORIZATION_CODE) + .build()) + : Optional.empty(); + } + + private Optional keycloakClientRegistration() { + OAUTH2 oauth = applicationProperties.getSecurity().getOAUTH2(); + if (oauth == null || !oauth.getEnabled()) { + return Optional.empty(); + } + Client client = oauth.getClient(); + if (client == null) { + return Optional.empty(); + } + KeycloakProvider keycloak = client.getKeycloak(); + + return keycloak != null && keycloak.isSettingsValid() + ? Optional.of( + ClientRegistrations.fromIssuerLocation(keycloak.getIssuer()) + .registrationId("keycloak") + .clientId(keycloak.getClientId()) + .clientSecret(keycloak.getClientSecret()) + .scope(keycloak.getScopes()) + .userNameAttributeName(keycloak.getUseAsUsername()) + .clientName("Keycloak") + .build()) + : Optional.empty(); + } + + private Optional githubClientRegistration() { + OAUTH2 oauth = applicationProperties.getSecurity().getOAUTH2(); + if (oauth == null || !oauth.getEnabled()) { + return Optional.empty(); + } + Client client = oauth.getClient(); + if (client == null) { + return Optional.empty(); + } + GithubProvider github = client.getGithub(); + return github != null && github.isSettingsValid() + ? Optional.of( + ClientRegistration.withRegistrationId("github") + .clientId(github.getClientId()) + .clientSecret(github.getClientSecret()) + .scope(github.getScopes()) + .authorizationUri(github.getAuthorizationuri()) + .tokenUri(github.getTokenuri()) + .userInfoUri(github.getUserinfouri()) + .userNameAttributeName(github.getUseAsUsername()) + .clientName("GitHub") + .redirectUri("{baseUrl}/login/oauth2/code/github") + .authorizationGrantType( + org.springframework.security.oauth2.core + .AuthorizationGrantType.AUTHORIZATION_CODE) + .build()) + : Optional.empty(); + } + + private Optional oidcClientRegistration() { + OAUTH2 oauth = applicationProperties.getSecurity().getOAUTH2(); + if (oauth == null + || oauth.getIssuer() == null + || oauth.getIssuer().isEmpty() + || oauth.getClientId() == null + || oauth.getClientId().isEmpty() + || oauth.getClientSecret() == null + || oauth.getClientSecret().isEmpty() + || oauth.getScopes() == null + || oauth.getScopes().isEmpty() + || oauth.getUseAsUsername() == null + || oauth.getUseAsUsername().isEmpty()) { + return Optional.empty(); + } + return Optional.of( + ClientRegistrations.fromIssuerLocation(oauth.getIssuer()) + .registrationId("oidc") + .clientId(oauth.getClientId()) + .clientSecret(oauth.getClientSecret()) + .scope(oauth.getScopes()) + .userNameAttributeName(oauth.getUseAsUsername()) + .clientName("OIDC") + .build()); } /* diff --git a/src/main/java/stirling/software/SPDF/config/security/UserAuthenticationFilter.java b/src/main/java/stirling/software/SPDF/config/security/UserAuthenticationFilter.java index 244efed37e..c4748ff960 100644 --- a/src/main/java/stirling/software/SPDF/config/security/UserAuthenticationFilter.java +++ b/src/main/java/stirling/software/SPDF/config/security/UserAuthenticationFilter.java @@ -101,6 +101,7 @@ public class UserAuthenticationFilter extends OncePerRequestFilter { contextPath + "/images/", contextPath + "/public/", contextPath + "/css/", + contextPath + "/fonts/", contextPath + "/js/", contextPath + "/pdfjs/", contextPath + "/api/v1/info/status", diff --git a/src/main/java/stirling/software/SPDF/config/security/oauth2/CustomOAuth2AuthenticationFailureHandler.java b/src/main/java/stirling/software/SPDF/config/security/oauth2/CustomOAuth2AuthenticationFailureHandler.java index 6b6a72c147..c3827bf3a6 100644 --- a/src/main/java/stirling/software/SPDF/config/security/oauth2/CustomOAuth2AuthenticationFailureHandler.java +++ b/src/main/java/stirling/software/SPDF/config/security/oauth2/CustomOAuth2AuthenticationFailureHandler.java @@ -41,6 +41,7 @@ public class CustomOAuth2AuthenticationFailureHandler } else if (exception instanceof LockedException) { logger.error("Account locked: ", exception); getRedirectStrategy().sendRedirect(request, response, "/logout?error=locked"); + return; } else { logger.error("Unhandled authentication exception", exception); super.onAuthenticationFailure(request, response, exception); diff --git a/src/main/java/stirling/software/SPDF/config/security/oauth2/CustomOAuth2LogoutSuccessHandler.java b/src/main/java/stirling/software/SPDF/config/security/oauth2/CustomOAuth2LogoutSuccessHandler.java index ea1b05b205..1dca2df9f3 100644 --- a/src/main/java/stirling/software/SPDF/config/security/oauth2/CustomOAuth2LogoutSuccessHandler.java +++ b/src/main/java/stirling/software/SPDF/config/security/oauth2/CustomOAuth2LogoutSuccessHandler.java @@ -6,6 +6,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.security.core.Authentication; import org.springframework.security.core.session.SessionRegistry; +import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken; import org.springframework.security.web.authentication.logout.SimpleUrlLogoutSuccessHandler; import jakarta.servlet.ServletException; @@ -14,6 +15,8 @@ import jakarta.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpSession; import stirling.software.SPDF.model.ApplicationProperties; import stirling.software.SPDF.model.ApplicationProperties.Security.OAUTH2; +import stirling.software.SPDF.model.Provider; +import stirling.software.SPDF.utils.UrlUtils; public class CustomOAuth2LogoutSuccessHandler extends SimpleUrlLogoutSuccessHandler { @@ -33,11 +36,33 @@ public class CustomOAuth2LogoutSuccessHandler extends SimpleUrlLogoutSuccessHand public void onLogoutSuccess( HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException { - String param = "logout=true"; + String provider = null; + String issuer = null; + String clientId = null; OAUTH2 oauth = applicationProperties.getSecurity().getOAUTH2(); - String provider = oauth.getProvider() != null ? oauth.getProvider() : ""; + + if (authentication instanceof OAuth2AuthenticationToken) { + OAuth2AuthenticationToken oauthToken = (OAuth2AuthenticationToken) authentication; + String registrationId = oauthToken.getAuthorizedClientRegistrationId(); + + provider = registrationId; + logger.info(registrationId); + Provider pro; + try { + pro = oauth.getClient().get(registrationId); + issuer = pro.getIssuer(); + clientId = pro.getClientId(); + } catch (Exception e) { + e.printStackTrace(); + } + + } else { + provider = oauth.getProvider() != null ? oauth.getProvider() : ""; + issuer = oauth.getIssuer(); + clientId = oauth.getClientId(); + } if (request.getParameter("oauth2AuthenticationErrorWeb") != null) { param = "erroroauth=oauth2AuthenticationErrorWeb"; @@ -49,36 +74,46 @@ public class CustomOAuth2LogoutSuccessHandler extends SimpleUrlLogoutSuccessHand param = "error=oauth2AutoCreateDisabled"; } + String redirect_url = UrlUtils.getOrigin(request) + "/login?" + param; + HttpSession session = request.getSession(false); if (session != null) { String sessionId = session.getId(); sessionRegistry.removeSessionInformation(sessionId); session.invalidate(); - logger.debug("Session invalidated: " + sessionId); + logger.info("Session invalidated: " + sessionId); } switch (provider) { case "keycloak": + // Add Keycloak specific logout URL if needed String logoutUrl = - oauth.getIssuer() + issuer + "/protocol/openid-connect/logout" + "?client_id=" - + oauth.getClientId() + + clientId + "&post_logout_redirect_uri=" - + response.encodeRedirectURL( - request.getScheme() - + "://" - + request.getHeader("host") - + "/login?" - + param); - logger.debug("Redirecting to Keycloak logout URL: " + logoutUrl); + + response.encodeRedirectURL(redirect_url); + logger.info("Redirecting to Keycloak logout URL: " + logoutUrl); response.sendRedirect(logoutUrl); break; + case "github": + // Add GitHub specific logout URL if needed + String githubLogoutUrl = "https://github.com/logout"; + logger.info("Redirecting to GitHub logout URL: " + githubLogoutUrl); + response.sendRedirect(githubLogoutUrl); + break; case "google": // Add Google specific logout URL if needed + // String googleLogoutUrl = + // "https://accounts.google.com/Logout?continue=https://appengine.google.com/_ah/logout?continue=" + // + response.encodeRedirectURL(redirect_url); + // logger.info("Redirecting to Google logout URL: " + googleLogoutUrl); + // response.sendRedirect(googleLogoutUrl); + // break; default: String redirectUrl = request.getContextPath() + "/login?" + param; - logger.debug("Redirecting to default logout URL: " + redirectUrl); + logger.info("Redirecting to default logout URL: " + redirectUrl); response.sendRedirect(redirectUrl); break; } diff --git a/src/main/java/stirling/software/SPDF/config/security/oauth2/CustomOAuthUserService.java b/src/main/java/stirling/software/SPDF/config/security/oauth2/CustomOAuthUserService.java deleted file mode 100644 index 69900b4a02..0000000000 --- a/src/main/java/stirling/software/SPDF/config/security/oauth2/CustomOAuthUserService.java +++ /dev/null @@ -1,57 +0,0 @@ -package stirling.software.SPDF.config.security.oauth2; - -import java.util.HashMap; -import java.util.Map; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.security.oauth2.client.oidc.userinfo.OidcUserRequest; -import org.springframework.security.oauth2.client.oidc.userinfo.OidcUserService; -import org.springframework.security.oauth2.client.userinfo.OAuth2UserService; -import org.springframework.security.oauth2.core.OAuth2AuthenticationException; -import org.springframework.security.oauth2.core.OAuth2Error; -import org.springframework.security.oauth2.core.oidc.user.DefaultOidcUser; -import org.springframework.security.oauth2.core.oidc.user.OidcUser; - -import stirling.software.SPDF.model.ApplicationProperties; - -public class CustomOAuthUserService implements OAuth2UserService { - - private static final Logger logger = LoggerFactory.getLogger(CustomOAuthUserService.class); - - private final OidcUserService delegate = new OidcUserService(); - - private ApplicationProperties applicationProperties; - - public CustomOAuthUserService(ApplicationProperties applicationProperties) { - this.applicationProperties = applicationProperties; - } - - @Override - public OidcUser loadUser(OidcUserRequest userRequest) throws OAuth2AuthenticationException { - String usernameAttribute = - applicationProperties.getSecurity().getOAUTH2().getUseAsUsername(); - try { - - OidcUser user = delegate.loadUser(userRequest); - Map attributes = new HashMap<>(user.getAttributes()); - - // Ensure the preferred username attribute is present - if (!attributes.containsKey(usernameAttribute)) { - attributes.put(usernameAttribute, attributes.getOrDefault("email", "")); - usernameAttribute = "email"; - logger.info("Adjusted username attribute to use email"); - } - - // Return a new OidcUser with adjusted attributes - return new DefaultOidcUser( - user.getAuthorities(), - userRequest.getIdToken(), - user.getUserInfo(), - usernameAttribute); - } catch (java.lang.IllegalArgumentException e) { - throw new OAuth2AuthenticationException( - new OAuth2Error(e.getMessage()), e.getMessage(), e); - } - } -} diff --git a/src/main/java/stirling/software/SPDF/controller/web/AccountWebController.java b/src/main/java/stirling/software/SPDF/controller/web/AccountWebController.java index 3a2074a733..b0490fb5c5 100644 --- a/src/main/java/stirling/software/SPDF/controller/web/AccountWebController.java +++ b/src/main/java/stirling/software/SPDF/controller/web/AccountWebController.java @@ -1,10 +1,13 @@ package stirling.software.SPDF.controller.web; +import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Optional; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.core.Authentication; @@ -21,6 +24,11 @@ import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.servlet.http.HttpServletRequest; import stirling.software.SPDF.model.ApplicationProperties; +import stirling.software.SPDF.model.ApplicationProperties.GithubProvider; +import stirling.software.SPDF.model.ApplicationProperties.GoogleProvider; +import stirling.software.SPDF.model.ApplicationProperties.KeycloakProvider; +import stirling.software.SPDF.model.ApplicationProperties.Security.OAUTH2; +import stirling.software.SPDF.model.ApplicationProperties.Security.OAUTH2.Client; import stirling.software.SPDF.model.Authority; import stirling.software.SPDF.model.Role; import stirling.software.SPDF.model.User; @@ -31,6 +39,7 @@ import stirling.software.SPDF.repository.UserRepository; public class AccountWebController { @Autowired ApplicationProperties applicationProperties; + private static final Logger logger = LoggerFactory.getLogger(AccountWebController.class); @GetMapping("/login") public String login(HttpServletRequest request, Model model, Authentication authentication) { @@ -38,6 +47,33 @@ public class AccountWebController { return "redirect:/"; } + Map providerList = new HashMap<>(); + + OAUTH2 oauth = applicationProperties.getSecurity().getOAUTH2(); + if (oauth != null) { + if (oauth.isSettingsValid()) { + providerList.put("oidc", "OpenID Connect"); + } + Client client = oauth.getClient(); + if (client != null) { + GoogleProvider google = client.getGoogle(); + if (google.isSettingsValid()) { + providerList.put("google", "Google"); + } + + GithubProvider github = client.getGithub(); + if (github.isSettingsValid()) { + providerList.put("github", "Github"); + } + + KeycloakProvider keycloak = client.getKeycloak(); + if (keycloak.isSettingsValid()) { + providerList.put("keycloak", "Keycloak"); + } + } + } + model.addAttribute("providerlist", providerList); + model.addAttribute( "oAuth2Enabled", applicationProperties.getSecurity().getOAUTH2().getEnabled()); @@ -80,6 +116,19 @@ public class AccountWebController { break; case "invalid_token_response": erroroauth = "login.oauth2InvalidTokenResponse"; + break; + case "authorization_request_not_found": + erroroauth = "login.oauth2RequestNotFound"; + break; + case "access_denied": + erroroauth = "login.oauth2AccessDenied"; + break; + case "invalid_user_info_response": + erroroauth = "login.oauth2InvalidUserInfoResponse"; + break; + case "invalid_request": + erroroauth = "login.oauth2invalidRequest"; + break; default: break; } diff --git a/src/main/java/stirling/software/SPDF/model/ApplicationProperties.java b/src/main/java/stirling/software/SPDF/model/ApplicationProperties.java index ae96d07b38..c8e74e4064 100644 --- a/src/main/java/stirling/software/SPDF/model/ApplicationProperties.java +++ b/src/main/java/stirling/software/SPDF/model/ApplicationProperties.java @@ -6,6 +6,8 @@ import java.util.Collection; import java.util.List; import java.util.stream.Collectors; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.PropertySource; @@ -23,6 +25,7 @@ public class ApplicationProperties { private Metrics metrics; private AutomaticallyGenerated automaticallyGenerated; private AutoPipeline autoPipeline; + private static final Logger logger = LoggerFactory.getLogger(ApplicationProperties.class); public AutoPipeline getAutoPipeline() { return autoPipeline != null ? autoPipeline : new AutoPipeline(); @@ -182,13 +185,12 @@ public class ApplicationProperties { + oauth2 + ", initialLogin=" + initialLogin - + ", csrfDisabled=" + + ", csrfDisabled=" + csrfDisabled + "]"; } public static class InitialLogin { - private String username; private String password; @@ -219,22 +221,21 @@ public class ApplicationProperties { } public static class OAUTH2 { - - private boolean enabled; + private Boolean enabled = false; private String issuer; private String clientId; private String clientSecret; - private boolean autoCreateUser; + private Boolean autoCreateUser = false; private String useAsUsername; + private Collection scopes = new ArrayList<>(); private String provider; + private Client client = new Client(); - private Collection scopes = new ArrayList(); - - public boolean getEnabled() { + public Boolean getEnabled() { return enabled; } - public void setEnabled(boolean enabled) { + public void setEnabled(Boolean enabled) { this.enabled = enabled; } @@ -262,19 +263,16 @@ public class ApplicationProperties { this.clientSecret = clientSecret; } - public boolean getAutoCreateUser() { + public Boolean getAutoCreateUser() { return autoCreateUser; } - public void setAutoCreateUser(boolean autoCreateUser) { + public void setAutoCreateUser(Boolean autoCreateUser) { this.autoCreateUser = autoCreateUser; } public String getUseAsUsername() { - if (useAsUsername != null && useAsUsername.trim().length() > 0) { - return useAsUsername; - } - return "email"; + return useAsUsername; } public void setUseAsUsername(String useAsUsername) { @@ -293,14 +291,44 @@ public class ApplicationProperties { return scopes; } - public void setScopes(String scpoes) { + public void setScopes(String scopes) { List scopesList = - Arrays.stream(scpoes.split(",")) + Arrays.stream(scopes.split(",")) .map(String::trim) .collect(Collectors.toList()); this.scopes.addAll(scopesList); } + public Client getClient() { + return client; + } + + public void setClient(Client client) { + this.client = client; + } + + protected boolean isValid(String value, String name) { + if (value != null && !value.trim().isEmpty()) { + return true; + } + return false; + } + + protected boolean isValid(Collection value, String name) { + if (value != null && !value.isEmpty()) { + return true; + } + return false; + } + + public boolean isSettingsValid() { + return isValid(this.getIssuer(), "issuer") + && isValid(this.getClientId(), "clientId") + && isValid(this.getClientSecret(), "clientSecret") + && isValid(this.getScopes(), "scopes") + && isValid(this.getUseAsUsername(), "useAsUsername"); + } + @Override public String toString() { return "OAUTH2 [enabled=" @@ -315,12 +343,353 @@ public class ApplicationProperties { + autoCreateUser + ", useAsUsername=" + useAsUsername - + ", provider" + + ", provider=" + provider + ", scopes=" + scopes + "]"; } + + public static class Client { + private GoogleProvider google = new GoogleProvider(); + private GithubProvider github = new GithubProvider(); + private KeycloakProvider keycloak = new KeycloakProvider(); + + public Provider get(String registrationId) throws Exception { + switch (registrationId) { + case "gogole": + return getGoogle(); + case "github": + return getGithub(); + case "keycloak": + return getKeycloak(); + default: + break; + } + throw new Exception("Provider not supported, use custom setting."); + } + + public GoogleProvider getGoogle() { + return google; + } + + public void setGoogle(GoogleProvider google) { + this.google = google; + } + + public GithubProvider getGithub() { + return github; + } + + public void setGithub(GithubProvider github) { + this.github = github; + } + + public KeycloakProvider getKeycloak() { + return keycloak; + } + + public void setKeycloak(KeycloakProvider keycloak) { + this.keycloak = keycloak; + } + + @Override + public String toString() { + return "Client [google=" + + google + + ", github=" + + github + + ", keycloak=" + + keycloak + + "]"; + } + } + } + } + + public static class GoogleProvider extends Provider { + + private static final String authorizationUri = + "https://accounts.google.com/o/oauth2/v2/auth"; + private static final String tokenUri = "https://www.googleapis.com/oauth2/v4/token"; + private static final String userInfoUri = + "https://www.googleapis.com/oauth2/v3/userinfo?alt=json"; + + public String getAuthorizationuri() { + return authorizationUri; + } + + public String getTokenuri() { + return tokenUri; + } + + public String getUserinfouri() { + return userInfoUri; + } + + private String clientId; + private String clientSecret; + private Collection scopes = new ArrayList<>(); + private String useAsUsername = "email"; + + @Override + public String getClientId() { + return this.clientId; + } + + @Override + public void setClientId(String clientId) { + this.clientId = clientId; + } + + @Override + public String getClientSecret() { + return this.clientSecret; + } + + @Override + public void setClientSecret(String clientSecret) { + this.clientSecret = clientSecret; + } + + @Override + public Collection getScopes() { + if (scopes == null || scopes.isEmpty()) { + scopes.add("https://www.googleapis.com/auth/userinfo.email"); + scopes.add("https://www.googleapis.com/auth/userinfo.profile"); + } + return scopes; + } + + @Override + public void setScopes(String scopes) { + this.scopes = + Arrays.stream(scopes.split(",")).map(String::trim).collect(Collectors.toList()); + } + + @Override + public String getUseAsUsername() { + return this.useAsUsername; + } + + @Override + public void setUseAsUsername(String useAsUsername) { + this.useAsUsername = useAsUsername; + } + + @Override + public String toString() { + return "Google [clientId=" + + clientId + + ", clientSecret=" + + (clientSecret != null && !clientSecret.isEmpty() ? "MASKED" : "NULL") + + ", scopes=" + + scopes + + ", useAsUsername=" + + useAsUsername + + "]"; + } + + @Override + public String getName() { + return "google"; + } + + public boolean isSettingsValid() { + return super.isValid(this.getClientId(), "clientId") + && super.isValid(this.getClientSecret(), "clientSecret") + && super.isValid(this.getScopes(), "scopes") + && isValid(this.getUseAsUsername(), "useAsUsername"); + } + } + + public static class GithubProvider extends Provider { + private static final String authorizationUri = "https://github.com/login/oauth/authorize"; + private static final String tokenUri = "https://github.com/login/oauth/access_token"; + private static final String userInfoUri = "https://api.github.com/user"; + + public String getAuthorizationuri() { + return authorizationUri; + } + + public String getTokenuri() { + return tokenUri; + } + + public String getUserinfouri() { + return userInfoUri; + } + + private String clientId; + private String clientSecret; + private Collection scopes = new ArrayList<>(); + private String useAsUsername = "login"; + + @Override + public String getIssuer() { + return new String(); + } + + @Override + public void setIssuer(String issuer) {} + + @Override + public String getClientId() { + return this.clientId; + } + + @Override + public void setClientId(String clientId) { + this.clientId = clientId; + } + + @Override + public String getClientSecret() { + return this.clientSecret; + } + + @Override + public void setClientSecret(String clientSecret) { + this.clientSecret = clientSecret; + } + + public Collection getScopes() { + if (scopes == null || scopes.isEmpty()) { + scopes.add("read:user"); + } + return scopes; + } + + @Override + public void setScopes(String scopes) { + this.scopes = + Arrays.stream(scopes.split(",")).map(String::trim).collect(Collectors.toList()); + } + + @Override + public String getUseAsUsername() { + return this.useAsUsername; + } + + @Override + public void setUseAsUsername(String useAsUsername) { + this.useAsUsername = useAsUsername; + } + + @Override + public String toString() { + return "GitHub [clientId=" + + clientId + + ", clientSecret=" + + (clientSecret != null && !clientSecret.isEmpty() ? "MASKED" : "NULL") + + ", scopes=" + + scopes + + ", useAsUsername=" + + useAsUsername + + "]"; + } + + @Override + public String getName() { + return "github"; + } + + public boolean isSettingsValid() { + return super.isValid(this.getClientId(), "clientId") + && super.isValid(this.getClientSecret(), "clientSecret") + && super.isValid(this.getScopes(), "scopes") + && isValid(this.getUseAsUsername(), "useAsUsername"); + } + } + + public static class KeycloakProvider extends Provider { + private String issuer; + private String clientId; + private String clientSecret; + private Collection scopes = new ArrayList<>(); + private String useAsUsername = "email"; + + @Override + public String getIssuer() { + return this.issuer; + } + + @Override + public void setIssuer(String issuer) { + this.issuer = issuer; + } + + @Override + public String getClientId() { + return this.clientId; + } + + @Override + public void setClientId(String clientId) { + this.clientId = clientId; + } + + @Override + public String getClientSecret() { + return this.clientSecret; + } + + @Override + public void setClientSecret(String clientSecret) { + this.clientSecret = clientSecret; + } + + @Override + public Collection getScopes() { + if (scopes == null || scopes.isEmpty()) { + scopes.add("openid"); + scopes.add("profile"); + scopes.add("email"); + } + return scopes; + } + + public void setScopes(String scopes) { + this.scopes = + Arrays.stream(scopes.split(",")).map(String::trim).collect(Collectors.toList()); + } + + @Override + public String getUseAsUsername() { + return this.useAsUsername; + } + + @Override + public void setUseAsUsername(String useAsUsername) { + this.useAsUsername = useAsUsername; + } + + @Override + public String toString() { + return "Keycloak [issuer=" + + issuer + + ", clientId=" + + clientId + + ", clientSecret=" + + (clientSecret != null && !clientSecret.isEmpty() ? "MASKED" : "NULL") + + ", scopes=" + + scopes + + ", useAsUsername=" + + useAsUsername + + "]"; + } + + @Override + public String getName() { + return "keycloak"; + } + + public boolean isSettingsValid() { + return isValid(this.getIssuer(), "issuer") + && isValid(this.getClientId(), "clientId") + && isValid(this.getClientSecret(), "clientSecret") + && isValid(this.getScopes(), "scopes") + && isValid(this.getUseAsUsername(), "useAsUsername"); } } diff --git a/src/main/java/stirling/software/SPDF/model/Provider.java b/src/main/java/stirling/software/SPDF/model/Provider.java new file mode 100644 index 0000000000..a8dce44652 --- /dev/null +++ b/src/main/java/stirling/software/SPDF/model/Provider.java @@ -0,0 +1,87 @@ +package stirling.software.SPDF.model; + +import java.util.Collection; + +public class Provider implements ProviderInterface { + private String name; + + public String getName() { + return name; + } + + protected boolean isValid(String value, String name) { + if (value != null && !value.trim().isEmpty()) { + return true; + } + return false; + // throw new IllegalArgumentException(getName() + ": " + name + " is required!"); + } + + protected boolean isValid(Collection value, String name) { + if (value != null && !value.isEmpty()) { + return true; + } + return false; + // throw new IllegalArgumentException(getName() + ": " + name + " is required!"); + } + + @Override + public Collection getScopes() { + // TODO Auto-generated method stub + throw new UnsupportedOperationException("Unimplemented method 'getScope'"); + } + + @Override + public void setScopes(String scopes) { + // TODO Auto-generated method stub + throw new UnsupportedOperationException("Unimplemented method 'setScope'"); + } + + @Override + public String getUseAsUsername() { + // TODO Auto-generated method stub + throw new UnsupportedOperationException("Unimplemented method 'getUseAsUsername'"); + } + + @Override + public void setUseAsUsername(String useAsUsername) { + // TODO Auto-generated method stub + throw new UnsupportedOperationException("Unimplemented method 'setUseAsUsername'"); + } + + @Override + public String getIssuer() { + // TODO Auto-generated method stub + throw new UnsupportedOperationException("Unimplemented method 'getIssuer'"); + } + + @Override + public void setIssuer(String issuer) { + // TODO Auto-generated method stub + throw new UnsupportedOperationException("Unimplemented method 'setIssuer'"); + } + + @Override + public String getClientSecret() { + // TODO Auto-generated method stub + throw new UnsupportedOperationException("Unimplemented method 'getClientSecret'"); + } + + @Override + public void setClientSecret(String clientSecret) { + // TODO Auto-generated method stub + throw new UnsupportedOperationException("Unimplemented method 'setClientSecret'"); + } + + @Override + public String getClientId() { + // TODO Auto-generated method stub + throw new UnsupportedOperationException("Unimplemented method 'getClientId'"); + } + + @Override + public void setClientId(String clientId) { + // TODO Auto-generated method stub + throw new UnsupportedOperationException("Unimplemented method 'setClientId'"); + } +} diff --git a/src/main/java/stirling/software/SPDF/model/ProviderInterface.java b/src/main/java/stirling/software/SPDF/model/ProviderInterface.java new file mode 100644 index 0000000000..d0d54827a8 --- /dev/null +++ b/src/main/java/stirling/software/SPDF/model/ProviderInterface.java @@ -0,0 +1,26 @@ +package stirling.software.SPDF.model; + +import java.util.Collection; + +public interface ProviderInterface { + + public Collection getScopes(); + + public void setScopes(String scopes); + + public String getUseAsUsername(); + + public void setUseAsUsername(String useAsUsername); + + public String getIssuer(); + + public void setIssuer(String issuer); + + public String getClientSecret(); + + public void setClientSecret(String clientSecret); + + public String getClientId(); + + public void setClientId(String clientId); +} diff --git a/src/main/java/stirling/software/SPDF/utils/RequestUriUtils.java b/src/main/java/stirling/software/SPDF/utils/RequestUriUtils.java index 21324a9ce5..e0c4a51ede 100644 --- a/src/main/java/stirling/software/SPDF/utils/RequestUriUtils.java +++ b/src/main/java/stirling/software/SPDF/utils/RequestUriUtils.java @@ -5,6 +5,7 @@ public class RequestUriUtils { public static boolean isStaticResource(String requestURI) { return requestURI.startsWith("/css/") + || requestURI.startsWith("/fonts/") || requestURI.startsWith("/js/") || requestURI.startsWith("/images/") || requestURI.startsWith("/public/") diff --git a/src/main/java/stirling/software/SPDF/utils/UrlUtils.java b/src/main/java/stirling/software/SPDF/utils/UrlUtils.java new file mode 100644 index 0000000000..991713deff --- /dev/null +++ b/src/main/java/stirling/software/SPDF/utils/UrlUtils.java @@ -0,0 +1,15 @@ +package stirling.software.SPDF.utils; + +import jakarta.servlet.http.HttpServletRequest; + +public class UrlUtils { + + public static String getOrigin(HttpServletRequest request) { + String scheme = request.getScheme(); // http or https + String serverName = request.getServerName(); // localhost + int serverPort = request.getServerPort(); // 8080 + String contextPath = request.getContextPath(); // /myapp + + return scheme + "://" + serverName + ":" + serverPort + contextPath; + } +} diff --git a/src/main/resources/messages_ar_AR.properties b/src/main/resources/messages_ar_AR.properties index ec327fcd36..c38d74bb45 100644 --- a/src/main/resources/messages_ar_AR.properties +++ b/src/main/resources/messages_ar_AR.properties @@ -452,6 +452,11 @@ login.locked=Your account has been locked. login.signinTitle=Please sign in login.ssoSignIn=تسجيل الدخول عبر تسجيل الدخول الأحادي login.oauth2AutoCreateDisabled=تم تعطيل مستخدم الإنشاء التلقائي لـ OAuth2 +login.oauth2RequestNotFound=Authorization request not found +login.oauth2InvalidUserInfoResponse=Invalid User Info Response +login.oauth2invalidRequest=Invalid Request +login.oauth2AccessDenied=Access Denied +login.oauth2InvalidTokenResponse=Invalid Token Response #auto-redact diff --git a/src/main/resources/messages_bg_BG.properties b/src/main/resources/messages_bg_BG.properties index 69c63c6027..3bf590bca8 100644 --- a/src/main/resources/messages_bg_BG.properties +++ b/src/main/resources/messages_bg_BG.properties @@ -452,6 +452,11 @@ login.locked=Вашият акаунт е заключен. login.signinTitle=Моля впишете се login.ssoSignIn=Влизане чрез еднократно влизане login.oauth2AutoCreateDisabled=OAUTH2 Автоматично създаване на потребител е деактивирано +login.oauth2RequestNotFound=Authorization request not found +login.oauth2InvalidUserInfoResponse=Invalid User Info Response +login.oauth2invalidRequest=Invalid Request +login.oauth2AccessDenied=Access Denied +login.oauth2InvalidTokenResponse=Invalid Token Response #auto-redact diff --git a/src/main/resources/messages_ca_CA.properties b/src/main/resources/messages_ca_CA.properties index 938de9b4d6..1b1da16487 100644 --- a/src/main/resources/messages_ca_CA.properties +++ b/src/main/resources/messages_ca_CA.properties @@ -452,6 +452,11 @@ login.locked=Compte bloquejat login.signinTitle=Autenticat login.ssoSignIn=Inicia sessió mitjançant l'inici de sessió ún login.oauth2AutoCreateDisabled=L'usuari de creació automàtica OAUTH2 està desactivat +login.oauth2RequestNotFound=Authorization request not found +login.oauth2InvalidUserInfoResponse=Invalid User Info Response +login.oauth2invalidRequest=Invalid Request +login.oauth2AccessDenied=Access Denied +login.oauth2InvalidTokenResponse=Invalid Token Response #auto-redact diff --git a/src/main/resources/messages_cs_CZ.properties b/src/main/resources/messages_cs_CZ.properties index 70ace06fa4..7518de8e56 100644 --- a/src/main/resources/messages_cs_CZ.properties +++ b/src/main/resources/messages_cs_CZ.properties @@ -4,71 +4,71 @@ # the direction that the language is written (ltr = left to right, rtl = right to left) language.direction=ltr -pdfPrompt=Vyberte PDF soubry -multiPdfPrompt=Vyberte PDF soubry (2+) -multiPdfDropPrompt=Vyberte (nebo p?etáhn?te) v?echny po?adované PDF soubory -imgPrompt=Vyberte obrázek(y) +pdfPrompt=Vyberte PDF soubory +multiPdfPrompt=Vyberte PDF soubory (2+) +multiPdfDropPrompt=Vyberte (nebo přetáhněte) všechny požadované PDF soubory +imgPrompt=Vyberte obrázek(y) genericSubmit=Odeslat -processTimeWarning=Varování: Tento proces m??e trvat a? minutu, v závislosti na velikosti souboru -pageOrderPrompt=Vlastní po?adí stránek (Zadejte seznam ?ísel stránek odd?lených ?árkou nebo funkci jako nap?. 2n+1): -pageSelectionPrompt=Vlastní po?adí stránek (Zadejte seznam ?ísel stránek odd?lených ?árkou jako 1,5,6 nebo funkci jako nap?. 2n+1): -goToPage=Jít +processTimeWarning=Varování: Tento proces může trvat až minutu, v závislosti na velikosti souboru +pageOrderPrompt=Vlastní pořadí stránek (Zadejte seznam čísel stránek oddělených čárkou nebo funkci jako např. 2n+1): +pageSelectionPrompt=Vlastní pořadí stránek (Zadejte seznam čísel stránek oddělených čárkou jako 1,5,6 nebo funkci jako např. 2n+1): +goToPage=Jít true=Pravda -false=Le? -unknown=Neznámý -save=Ulo?it -saveToBrowser=Ulo?it do prohlí?e?e -close=Zav?ít -filesSelected=vybrané soubory -noFavourites=?ádné oblíbené polo?ky -downloadComplete=Stahování dokon?eno -bored=Nudíte se p?i ?ekání? +false=Lež +unknown=Neznámý +save=Uložit +saveToBrowser=Uložit do prohlížeče +close=Zavřít +filesSelected=vybrané soubory +noFavourites=Žádné oblíbené položky +downloadComplete=Stahování dokončeno +bored=Nudíte se při čekání? alphabet=Abeceda -downloadPdf=Stáhnout PDF +downloadPdf=Stáhnout PDF text=Text font=Font selectFillter=-- Vyberte -- -pageNum=?íslo stránky -sizes.small=Malé -sizes.medium=St?ední -sizes.large=Velké -sizes.x-large=Extra velké -error.pdfPassword=PDF dokument je chrán?ný heslem a bu? heslo nebylo zadné, nebo bylo nesprávné. +pageNum=Číslo stránky +sizes.small=Malé +sizes.medium=Střední +sizes.large=Velké +sizes.x-large=Extra velké +error.pdfPassword=PDF dokument je chráněný heslem a buď heslo nebylo zadáno, nebo bylo nesprávné. delete=Smazat -username=Ui?vatelské jméno +username=Uživatelské jméno password=Heslo -welcome=Vítejte +welcome=Vítejte property=Vlastnost -black=?erná -white=Bílá -red=?ervená -green=Zelená -blue=Modrá -custom=Vlastní... -WorkInProgess=Nedokon?ené, nemusí fungovat nebo m??e d?lat chyby, prosím, hla?te jakékoliv problémy! -poweredBy=Poskytované +black=Černá +white=Bílá +red=Červená +green=Zelená +blue=Modrá +custom=Vlastní... +WorkInProgess=Nedokončené, nemusí fungovat nebo může dělat chyby, prosím, hlaste jakékoliv problémy! +poweredBy=Poskytované yes=Ano no=Ne -changedCredsMessage=Údaje zm?n?ny! -notAuthenticatedMessage=U?ivatel není p?ihlá?ený. -userNotFoundMessage=U?ivatel nenalezen. -incorrectPasswordMessage=Sou?asné heslo není správné. -usernameExistsMessage=Nové u?ivatelské jméno ji? existuje. -invalidUsernameMessage=Nesprávné u?ivatelské jméno, smí obsahovat pouze písmena, ?íslice a následující speciální znaky @._+- nebo musí být validní emailová adresa. -deleteCurrentUserMessage=Nelze smazat aktuální p?ihlá?eného u?ivatele. -deleteUsernameExistsMessage=U?ivatelské jméno neexistuje a nelze ho smazat. -downgradeCurrentUserMessage=Nelze sní?it roli aktuálního u?ivatele. -downgradeCurrentUserLongMessage=Nelze sní?it roli aktuálního u?ivatele. Proto nebude aktuální u?ivatel zobrazen. -userAlreadyExistsOAuthMessage=U?ivatel ji? existuje jako OAuth2 u?ivatel. -userAlreadyExistsWebMessage=U?ivatel ji? existuje jako webový u?ivatel. +changedCredsMessage=Údaje změněny! +notAuthenticatedMessage=Uživatel není přihlášený. +userNotFoundMessage=Uživatel nenalezen. +incorrectPasswordMessage=Současné heslo není správné. +usernameExistsMessage=Nové uživatelské jméno již existuje. +invalidUsernameMessage=Nesprávné uživatelské jméno, smí obsahovat pouze písmena, číslice a následující speciální znaky @._+- nebo musí být validní emailová adresa. +deleteCurrentUserMessage=Nelze smazat aktuální přihlášeného uživatele. +deleteUsernameExistsMessage=Uživatelské jméno neexistuje a nelze ho smazat. +downgradeCurrentUserMessage=Nelze snížit roli aktuálního uživatele. +downgradeCurrentUserLongMessage=Nelze snížit roli aktuálního uživatele. Proto nebude aktuální uživatel zobrazen. +userAlreadyExistsOAuthMessage=Uživatel již existuje jako OAuth2 uživatel. +userAlreadyExistsWebMessage=Uživatel již existuje jako webový uživatel. error=Chyba oops=Ups! help=Pomoc -goHomepage=Jít na domovskou stránku -joinDiscord=P?ipojte se k na?emu Discordu -seeDockerHub=Podívejte se na Docker Hub -visitGithub=Nav?tivte Github repozitá? -donate=P?isp?jte +goHomepage=Jít na domovskou stránku +joinDiscord=Připojte se k našemu Discordu +seeDockerHub=Podívejte se na Docker Hub +visitGithub=Navštivte Github repozitář +donate=Přispějte color=Barva sponsor=Sponzor info=Info @@ -79,25 +79,25 @@ info=Info # Pipeline # ############### pipeline.header=Pipeline Menu (Beta) -pipeline.uploadButton=Nahrát vlastní +pipeline.uploadButton=Nahrát vlastní pipeline.configureButton=Konfigurovat -pipeline.defaultOption=Vlastní +pipeline.defaultOption=Vlastní pipeline.submitButton=Odeslat pipeline.help=Pomoc s pipeline -pipeline.scanHelp=Pomoc se skenováním adresá?e +pipeline.scanHelp=Pomoc se skenováním adresáře ###################### # Pipeline Options # ###################### -pipelineOptions.header=Nastavení pipeline -pipelineOptions.pipelineNameLabel=Název pipeline -pipelineOptions.saveSettings=Ulo?it nastavení operace -pipelineOptions.pipelineNamePrompt=Zadejte zde název pipeline +pipelineOptions.header=Nastavení pipeline +pipelineOptions.pipelineNameLabel=Název pipeline +pipelineOptions.saveSettings=Uložit nastavení operace +pipelineOptions.pipelineNamePrompt=Zadejte zde název pipeline pipelineOptions.selectOperation=Vybrat operaci -pipelineOptions.addOperationButton=P?idat operaci +pipelineOptions.addOperationButton=Přidat operaci pipelineOptions.pipelineHeader=Pipeline: -pipelineOptions.saveButton=Stáhnout -pipelineOptions.validateButton=Ov??it +pipelineOptions.saveButton=Stáhnout +pipelineOptions.validateButton=Ověřit @@ -105,335 +105,335 @@ pipelineOptions.validateButton=Ov??it ############# # NAVBAR # ############# -navbar.favorite=Oblíbené -navbar.darkmode=Tmavý re?im +navbar.favorite=Oblíbené +navbar.darkmode=Tmavý režim navbar.language=Jazyky -navbar.settings=Nastavení -navbar.allTools=Nástroje -navbar.multiTool=Multifunk?ní nástroje +navbar.settings=Nastavení +navbar.allTools=Nástroje +navbar.multiTool=Multifunkční nástroje navbar.sections.organize=Organizovat -navbar.sections.convertTo=P?evést do PDF -navbar.sections.convertFrom=P?evést z PDF -navbar.sections.security=Podpis a Bezpe?nost -navbar.sections.advance=Pokro?ilé -navbar.sections.edit=Prohlédnout a Upravit +navbar.sections.convertTo=Převést do PDF +navbar.sections.convertFrom=Převést z PDF +navbar.sections.security=Podpis a Bezpečnost +navbar.sections.advance=Pokročilé +navbar.sections.edit=Prohlédnout a Upravit ############# # SETTINGS # ############# -settings.title=Nastavení -settings.update=Dostupná aktualizace -settings.updateAvailable={0} je aktuáln? nainstalovaná verze. Nová verze({1}) je dostupná. +settings.title=Nastavení +settings.update=Dostupná aktualizace +settings.updateAvailable={0} je aktuálně nainstalovaná verze. Nová verze({1}) je dostupná. settings.appVersion=Verze Aplikace: -settings.downloadOption.title=Vyberte mo?nost stahování (Pro stahování jednoho souboru bez zipu): -settings.downloadOption.1=Otev?ít ve stejném okn? -settings.downloadOption.2=Otev?ít v novém okn? -settings.downloadOption.3=Stáhnout soubor -settings.zipThreshold=Zazipuj soubory, kdy? p?ekro?í po?et sta?ených soubor? -settings.signOut=Odhlásit -settings.accountSettings=Nastavení Ú?tu -settings.bored.help=Umo??uje hru s easter eggy +settings.downloadOption.title=Vyberte možnost stahování (Pro stahování jednoho souboru bez zipu): +settings.downloadOption.1=Otevřít ve stejném okně +settings.downloadOption.2=Otevřít v novém okně +settings.downloadOption.3=Stáhnout soubor +settings.zipThreshold=Zazipuj soubory, když překročí počet stažených souborů +settings.signOut=Odhlásit +settings.accountSettings=Nastavení Účtu +settings.bored.help=Umožňuje hru s easter eggy settings.cacheInputs.name=Save form inputs -settings.cacheInputs.help=Umo??uje ulo?it d?íve pou?ité vstupy pro budoucí pou?ití +settings.cacheInputs.help=Umožňuje uložit dříve použité vstupy pro budoucí použití -changeCreds.title=Zm?nit pov??ení -changeCreds.header=Aktualizovat Detaily Va?eho Ú?tu -changeCreds.changePassword=Pou?íváte výchozí p?ihla?ovací údaje. Prosím zadejte nové heslo -changeCreds.newUsername=Nové U?ivatelské Jméno -changeCreds.oldPassword=Aktuální Heslo -changeCreds.newPassword=Nové Heslo -changeCreds.confirmNewPassword=Potvrdit Nové Heslo -changeCreds.submit=Potvrdit Zm?ny +changeCreds.title=Změnit pověření +changeCreds.header=Aktualizovat Detaily Vašeho Účtu +changeCreds.changePassword=Používáte výchozí přihlašovací údaje. Prosím zadejte nové heslo +changeCreds.newUsername=Nové Uživatelské Jméno +changeCreds.oldPassword=Aktuální Heslo +changeCreds.newPassword=Nové Heslo +changeCreds.confirmNewPassword=Potvrdit Nové Heslo +changeCreds.submit=Potvrdit Změny -account.title=Nastavení Ú?tu -account.accountSettings=Nastavení Ú?tu -account.adminSettings=Nastavení admina - Zobrazit a P?idat U?ivatele -account.userControlSettings=User Control Settings U?ivatelské Nastavení Ovládání -account.changeUsername=Zm?nit U?ivatelské Jméno -account.newUsername=Nové U?ivatelské Jméno -account.password=Potvrzovací Heslo -account.oldPassword=Staré Heslo -account.newPassword=Nové Heslo -account.changePassword=Zm?nit Heslo -account.confirmNewPassword=Potvrdit Nové Heslo -account.signOut=Odhlásit -account.yourApiKey=Vá? API Klí? -account.syncTitle=Synchronizovat nastavení prohlí?e?e s Ú?tem -account.settingsCompare=Porovnání Nastavení: +account.title=Nastavení Účtu +account.accountSettings=Nastavení Účtu +account.adminSettings=Nastavení admina - Zobrazit a Přidat Uživatele +account.userControlSettings=User Control Settings Uživatelské Nastavení Ovládání +account.changeUsername=Změnit Uživatelské Jméno +account.newUsername=Nové Uživatelské Jméno +account.password=Potvrzovací Heslo +account.oldPassword=Staré Heslo +account.newPassword=Nové Heslo +account.changePassword=Změnit Heslo +account.confirmNewPassword=Potvrdit Nové Heslo +account.signOut=Odhlásit +account.yourApiKey=Váš API Klíč +account.syncTitle=Synchronizovat nastavení prohlížeče s Účtem +account.settingsCompare=Porovnání Nastavení: account.property=Majetek -account.webBrowserSettings=Nastavení Webového Prohlí?e?e -account.syncToBrowser=Synchronizovat Ú?et -> Prohlí?e? -account.syncToAccount=Synchronizovat Ú?et <- Prohlí?e? +account.webBrowserSettings=Nastavení Webového Prohlížeče +account.syncToBrowser=Synchronizovat Účet -> Prohlížeč +account.syncToAccount=Synchronizovat Účet <- Prohlížeč -adminUserSettings.title=Nastavení U?ivatelského Nastavení +adminUserSettings.title=Nastavení Uživatelského Nastavení adminUserSettings.header=Admin User Control Settings adminUserSettings.admin=Admin -adminUserSettings.user=U?ivatel -adminUserSettings.addUser=P?idat Nového U?ivatele -adminUserSettings.usernameInfo=U?ivatelské Jméno m??e obsahovat pouze písmena, ?ísla a následující speciální znaky @._+- nebo musí být správná emailová adresa. +adminUserSettings.user=Uživatel +adminUserSettings.addUser=Přidat Nového Uživatele +adminUserSettings.usernameInfo=Uživatelské Jméno může obsahovat pouze písmena, čísla a následující speciální znaky @._+- nebo musí být správná emailová adresa. adminUserSettings.roles=Role adminUserSettings.role=Role adminUserSettings.actions=Akce -adminUserSettings.apiUser=Limitovaný API U?ivatel -adminUserSettings.extraApiUser=Dal?í Limitovaný API U?ivatel -adminUserSettings.webOnlyUser=Pouze Webový U?ivatel -adminUserSettings.demoUser=Demo U?ivatel (?ádná vlastní nastavení) -adminUserSettings.internalApiUser=Vnit?ní API U?ivatel -adminUserSettings.forceChange=Vynutit u?ivateli zm?nu hesla p?i p?ihlá?ení -adminUserSettings.submit=Ulo?it U?ivatele -adminUserSettings.changeUserRole=Zmenit Roli U?ivatele -adminUserSettings.authenticated=Ov??eno +adminUserSettings.apiUser=Limitovaný API Uživatel +adminUserSettings.extraApiUser=Další Limitovaný API Uživatel +adminUserSettings.webOnlyUser=Pouze Webový Uživatel +adminUserSettings.demoUser=Demo Uživatel (Žádná vlastní nastavení) +adminUserSettings.internalApiUser=Vnitřní API Uživatel +adminUserSettings.forceChange=Vynutit uživateli změnu hesla při přihlášení +adminUserSettings.submit=Uložit Uživatele +adminUserSettings.changeUserRole=Zmenit Roli Uživatele +adminUserSettings.authenticated=Ověřeno ############# # HOME-PAGE # ############# -home.desc= Va?e lokáln? hostované jednotné kontaktní místo pro v?echny va?e pot?eby ve formátu PDF +home.desc= Vaše lokálně hostované jednotné kontaktní místo pro všechny vaše potřeby ve formátu PDF home.searchBar=Hledej funkce... home.viewPdf.title=Zobrazit PDF -home.viewPdf.desc=Zobrazit, Opat?it vysv?tlivkami, p?idat text nebo obrázky -viewPdf.tags=zobrazit,p?e?íst,opat?it vysv?tlivkami,text,obrázek +home.viewPdf.desc=Zobrazit, Opatřit vysvětlivkami, přidat text nebo obrázky +viewPdf.tags=zobrazit,přečíst,opatřit vysvětlivkami,text,obrázek -home.multiTool.title=PDF Multifunk?ní nástroj -home.multiTool.desc=Slou?it, Rotovat, P?eskupit, a Odstranit stránky -multiTool.tags=Multifunk?ní nástroj,Multifunk?ní operace,UI,klepnout na p?eta?ení,p?ední konec,strana klienta,interaktivní,ne?e?itelný,p?esunout +home.multiTool.title=PDF Multifunkční nástroj +home.multiTool.desc=Sloučit, Rotovat, Přeskupit, a Odstranit stránky +multiTool.tags=Multifunkční nástroj,Multifunkční operace,UI,klepnout na přetažení,přední konec,strana klienta,interaktivní,neřešitelný,přesunout home.merge.title=Seskupit -home.merge.desc=Lehce seskupit více PDF do jednoho -merge.tags=Seskupit,Operace stránky,Zadní konec,Strana serveru +home.merge.desc=Lehce seskupit více PDF do jednoho +merge.tags=Seskupit,Operace stránky,Zadní konec,Strana serveru -home.split.title=Rozd?lit -home.split.desc=Rozd?lit PDF do více dokument? -split.tags=Operace stránky,rozd?lit,Multi stránka,vyjmout,strana serveru +home.split.title=Rozdělit +home.split.desc=Rozdělit PDF do více dokumentů +split.tags=Operace stránky,rozdělit,Multi stránka,vyjmout,strana serveru -home.rotate.title=Oto?it -home.rotate.desc=Lehce oto?te svoje PDF +home.rotate.title=Otočit +home.rotate.desc=Lehce otočte svoje PDF rotate.tags=strana serveru -home.imageToPdf.title=Obrázek do PDF -home.imageToPdf.desc=Konvertovat obrázek (PNG, JPEG, GIF) do PDF. -imageToPdf.tags=konverze,img,jpg,obrázek,fotka +home.imageToPdf.title=Obrázek do PDF +home.imageToPdf.desc=Konvertovat obrázek (PNG, JPEG, GIF) do PDF. +imageToPdf.tags=konverze,img,jpg,obrázek,fotka -home.pdfToImage.title=PDF na obrázek -home.pdfToImage.desc=Konvertovat PDF na obrázek. (PNG, JPEG, GIF) -pdfToImage.tags=konverze,img,jpg,obrázek,fotka +home.pdfToImage.title=PDF na obrázek +home.pdfToImage.desc=Konvertovat PDF na obrázek. (PNG, JPEG, GIF) +pdfToImage.tags=konverze,img,jpg,obrázek,fotka home.pdfOrganiser.title=Organizovat -home.pdfOrganiser.desc=Odebrat/P?eskupit stránky v jakémkoli po?adí -pdfOrganiser.tags=dvojitý,sudý,lichý,se?adit,p?esunout +home.pdfOrganiser.desc=Odebrat/Přeskupit stránky v jakémkoli pořadí +pdfOrganiser.tags=dvojitý,sudý,lichý,seřadit,přesunout -home.addImage.title=P?idat obrázek -home.addImage.desc=P?idá obrázek na dané místo v PDF -addImage.tags=img,jpg,obrázek,fotka +home.addImage.title=Přidat obrázek +home.addImage.desc=Přidá obrázek na dané místo v PDF +addImage.tags=img,jpg,obrázek,fotka -home.watermark.title=P?idat vodoznak -home.watermark.desc=P?idat vlastní vodoznak do Va?eho PDF dokumentu. -watermark.tags=Text,opakování,ozna?ení,vlastní,autorská práva,obchodní známka,img,jpg,obrázek,fotka +home.watermark.title=Přidat vodoznak +home.watermark.desc=Přidat vlastní vodoznak do Vašeho PDF dokumentu. +watermark.tags=Text,opakování,označení,vlastní,autorská práva,obchodní známka,img,jpg,obrázek,fotka -home.permissions.title=Zm?nit Opravn?ní -home.permissions.desc=Zm?nit oprávn?ní va?eho PDF dokumentu -permissions.tags=p?e?íst,psát,editovat,tisknout +home.permissions.title=Změnit Oprávnění +home.permissions.desc=Změnit oprávnění vašeho PDF dokumentu +permissions.tags=přečíst,psát,editovat,tisknout home.removePages.title=Odebrat -home.removePages.desc=Odstranit necht?né stránky z Va?eho PDF dokumentu -removePages.tags=Odebrat stránky,Odstranit stránky +home.removePages.desc=Odstranit nechtěné stránky z Vašeho PDF dokumentu +removePages.tags=Odebrat stránky,Odstranit stránky -home.addPassword.title=P?idat hesl -home.addPassword.desc=Za?ifrovat Vá? PDF dokument heslem -addPassword.tags=zabezpe?it,zabezpe?ení +home.addPassword.title=Přidat heslo +home.addPassword.desc=Zašifrovat Váš PDF dokument heslem +addPassword.tags=zabezpečit,zabezpečení home.removePassword.title=Odebrat heslo -home.removePassword.desc=Odebrat ochranu heslem z Va?eho PDF dokumentu -removePassword.tags=zabezpe?it,de?ifrovat,zabezpe?ení,zru?it heslo,odstranit heslo +home.removePassword.desc=Odebrat ochranu heslem z Vašeho PDF dokumentu +removePassword.tags=zabezpečit,dešifrovat,zabezpečení,zrušit heslo,odstranit heslo home.compressPdfs.title=Komprimovat -home.compressPdfs.desc=Komprimujte soubory PDF, abyste sní?ili jejich velikost -compressPdfs.tags=rozmá?knout,malý,drobný +home.compressPdfs.desc=Komprimujte soubory PDF, abyste snížili jejich velikost +compressPdfs.tags=rozmáčknout,malý,drobný -home.changeMetadata.title=Zm?nit Metadata -home.changeMetadata.desc=Zm?nit/Odebrat/P?idat metadata z PDF dokumentu -changeMetadata.tags==Název,autor,datum,tvorba,?as,vydavatel,výrobce,statistiky +home.changeMetadata.title=Změnit Metadata +home.changeMetadata.desc=Změnit/Odebrat/Přidat metadata z PDF dokumentu +changeMetadata.tags==Název,autor,datum,tvorba,čas,vydavatel,výrobce,statistiky -home.fileToPDF.title=P?evést soubor do PDF -home.fileToPDF.desc=P?evést tém?? jakýkoli soubor do PDF (DOCX, PNG, XLS, PPT, TXT a více) -fileToPDF.tags=prom?na,formát,dokument,obrázek,snímek,text,p?evedení,office,docs,word,excel,powerpoint +home.fileToPDF.title=Převést soubor do PDF +home.fileToPDF.desc=Převést téměř jakýkoli soubor do PDF (DOCX, PNG, XLS, PPT, TXT a více) +fileToPDF.tags=proměna,formát,dokument,obrázek,snímek,text,převedení,office,docs,word,excel,powerpoint -home.ocr.title=OCR / Vy?istit skeny -home.ocr.desc=Vy?istit skeny a detekuje text z obrázk? v rámci PDF a znovu je p?idá jako text -ocr.tags=uznání,text,obrázek,sken,p?e?íst,identifikovat,detekovat,upravitelný +home.ocr.title=OCR / Vyčistit skeny +home.ocr.desc=Vyčistit skeny a detekuje text z obrázků v rámci PDF a znovu je přidá jako text +ocr.tags=uznání,text,obrázek,sken,přečíst,identifikovat,detekovat,upravitelný -home.extractImages.title=Extrahovat obrázky -home.extractImages.desc=Extrahuje v?echny obrázky z PDF a ulo?í je jako zip -extractImages.tags=obrázek,fotka,ulo?it,archivovat,zazipovat,zachytit,popadnout +home.extractImages.title=Extrahovat obrázky +home.extractImages.desc=Extrahuje všechny obrázky z PDF a uloží je jako zip +extractImages.tags=obrázek,fotka,uložit,archivovat,zazipovat,zachytit,popadnout home.pdfToPDFA.title=PDF na PDF/A -home.pdfToPDFA.desc=P?evod PDF na PDF/A pro dlouhodobé ulo?ení -pdfToPDFA.tags=archiv,dlouhodobý,standard,konverze,úlo?i?t?,zachování +home.pdfToPDFA.desc=Převod PDF na PDF/A pro dlouhodobé uložení +pdfToPDFA.tags=archiv,dlouhodobý,standard,konverze,úložiště,zachování home.PDFToWord.title=PDF na Word -home.PDFToWord.desc=P?evod PDF do formát? Wordu (DOC, DOCX a ODT) -PDFToWord.tags=doc,docx,odt,word,transformace,formát,konverze,kancelá?,microsoft,docfile +home.PDFToWord.desc=Převod PDF do formátů Wordu (DOC, DOCX a ODT) +PDFToWord.tags=doc,docx,odt,word,transformace,formát,konverze,kancelář,microsoft,docfile home.PDFToPresentation.title=PDF na Prezentaci -home.PDFToPresentation.desc=P?evod PDF do formát? prezentace (PPT, PPTX a ODP) -PDFToPresentation.tags=snímky,p?ehled,kancelá?,microsoft +home.PDFToPresentation.desc=Převod PDF do formátů prezentace (PPT, PPTX a ODP) +PDFToPresentation.tags=snímky,přehled,kancelář,microsoft home.PDFToText.title=PDF na RTF (Text) -home.PDFToText.desc=P?evod PDF do formátu Textu nebo RTF +home.PDFToText.desc=Převod PDF do formátu Textu nebo RTF PDFToText.tags=richformat,richtextformat,rich text format home.PDFToHTML.title=PDF na HTML -home.PDFToHTML.desc=P?evod PDF do formátu HTML -PDFToHTML.tags=obsah pro web,p?átelský pro prohlí?e? +home.PDFToHTML.desc=Převod PDF do formátu HTML +PDFToHTML.tags=obsah pro web,přátelský pro prohlížeč home.PDFToXML.title=PDF na XML -home.PDFToXML.desc=P?evod PDF do formátu XML -PDFToXML.tags=extrakce-dat,strukturovaný obsah,interop,konverze +home.PDFToXML.desc=Převod PDF do formátu XML +PDFToXML.tags=extrakce-dat,strukturovaný obsah,interop,konverze -home.ScannerImageSplit.title=Detekce/Rozd?lení skenovaných fotografií -home.ScannerImageSplit.desc=Rozd?luje více fotografií ze skenované fotografie/PDF -ScannerImageSplit.tags=odd?lení,automatická detekce,skeny,více fotografií,organizace +home.ScannerImageSplit.title=Detekce/Rozdělení skenovaných fotografií +home.ScannerImageSplit.desc=Rozděluje více fotografií ze skenované fotografie/PDF +ScannerImageSplit.tags=oddělení,automatická detekce,skeny,více fotografií,organizace home.sign.title=Podpis -home.sign.desc=P?idá podpis do PDF kreslením, textem nebo obrázkem -sign.tags=autorizovat,po?áte?ní,malovaný podpis,textový podpis,obrazový podpis +home.sign.desc=Přidá podpis do PDF kreslením, textem nebo obrázkem +sign.tags=autorizovat,počáteční,malovaný podpis,textový podpis,obrazový podpis -home.flatten.title=Zplo?t?ní -home.flatten.desc=Odstraní ve?keré interaktivní prvky a formulá?e z PDF -flatten.tags=statické,deaktivovat,neinteraktivní,zjednodu?it +home.flatten.title=Zploštění +home.flatten.desc=Odstraní veškeré interaktivní prvky a formuláře z PDF +flatten.tags=statické,deaktivovat,neinteraktivní,zjednodušit home.repair.title=Oprava -home.repair.desc=Pokusí se opravit po?kozený/rozbitý PDF -repair.tags=opravit,obnovit,korekce,obnovení +home.repair.desc=Pokusí se opravit poškozený/rozbitý PDF +repair.tags=opravit,obnovit,korekce,obnovení -home.removeBlanks.title=Odstranit prázdné stránky -home.removeBlanks.desc=Detekuje a odstraní prázdné stránky z dokumentu -removeBlanks.tags=úklid,zjednodu?it,neobsahové,organizovat +home.removeBlanks.title=Odstranit prázdné stránky +home.removeBlanks.desc=Detekuje a odstraní prázdné stránky z dokumentu +removeBlanks.tags=úklid,zjednodušit,neobsahové,organizovat -home.removeAnnotations.title=Odstranit poznámky -home.removeAnnotations.desc=Odstraní ve?keré komentá?e/poznámky z PDF -removeAnnotations.tags=komentá?e,zvýrazn?ní,poznámky,ozna?ení,odstranit +home.removeAnnotations.title=Odstranit poznámky +home.removeAnnotations.desc=Odstraní veškeré komentáře/poznámky z PDF +removeAnnotations.tags=komentáře,zvýraznění,poznámky,označení,odstranit home.compare.title=Porovnat -home.compare.desc=Porovná a uká?e rozdíly mezi 2 PDF dokumenty -compare.tags=odli?ení,kontrast,zm?ny,analýza +home.compare.desc=Porovná a ukáže rozdíly mezi 2 PDF dokumenty +compare.tags=odlišení,kontrast,změny,analýza -home.certSign.title=Podpis s certifikátem -home.certSign.desc=Podpis PDF s certifikátem/klí?em (PEM/P12) -certSign.tags=autentizace,PEM,P12,oficiální,?ifrování +home.certSign.title=Podpis s certifikátem +home.certSign.desc=Podpis PDF s certifikátem/klíčem (PEM/P12) +certSign.tags=autentizace,PEM,P12,oficiální,šifrování -home.pageLayout.title=Vícestránkové rozlo?ení -home.pageLayout.desc=Slou?ení více stránek dokumentu PDF do jedné stránky -pageLayout.tags=slou?it,kompozitní,jedno zobrazení,organizovat +home.pageLayout.title=Vícestránkové rozložení +home.pageLayout.desc=Sloučení více stránek dokumentu PDF do jedné stránky +pageLayout.tags=sloučit,kompozitní,jedno zobrazení,organizovat -home.scalePages.title=Upravit velikost/?kálu stránky -home.scalePages.desc=Zm?nit velikost/?kálu stránky a/nebo její obsah. -scalePages.tags=zm?nit velikost,upravit,rozm?r,p?izp?sobit +home.scalePages.title=Upravit velikost/škálu stránky +home.scalePages.desc=Změnit velikost/škálu stránky a/nebo její obsah. +scalePages.tags=změnit velikost,upravit,rozměr,přizpůsobit -home.pipeline.title=Potrubí (Pokro?ilé) -home.pipeline.desc=Spustit více akcí na PDF s definicí skript? potrubí -pipeline.tags=automatizovat,sekvence,skriptované,dávkové zpracování +home.pipeline.title=Potrubí (Pokročilé) +home.pipeline.desc=Spustit více akcí na PDF s definicí skriptů potrubí +pipeline.tags=automatizovat,sekvence,skriptované,dávkové zpracování -home.add-page-numbers.title=P?idat ?ísla stránek -home.add-page-numbers.desc=P?idat ?ísla stránek do dokumentu na ur?eném míst? -add-page-numbers.tags=stránkovat,ozna?it,organizovat,index +home.add-page-numbers.title=Přidat čísla stránek +home.add-page-numbers.desc=Přidat čísla stránek do dokumentu na určeném místě +add-page-numbers.tags=stránkovat,označit,organizovat,index -home.auto-rename.title=Automaticky p?ejmenovat PDF soubor -home.auto-rename.desc=Automaticky p?ejmenovat soubor PDF na základ? detekované hlavi?ky -auto-rename.tags=automatické rozpoznání,zalo?ené na hlavi?ce,organizovat,p?ejmenovat +home.auto-rename.title=Automaticky přejmenovat PDF soubor +home.auto-rename.desc=Automaticky přejmenovat soubor PDF na základě detekované hlavičky +auto-rename.tags=automatické rozpoznání,založené na hlavičce,organizovat,přejmenovat home.adjust-contrast.title=Upravit barvy/kontrast home.adjust-contrast.desc=Upravit kontrast, saturaci a jas dokumentu PDF -adjust-contrast.tags=korekce barev,naladit,upravit,zlep?it +adjust-contrast.tags=korekce barev,naladit,upravit,zlepšit -home.crop.title=O?íznout PDF -home.crop.desc=O?íznout PDF pro sní?ení jeho velikosti (zachovává text!) -crop.tags=?ezat,zmen?it,upravit,tvar +home.crop.title=Oříznout PDF +home.crop.desc=Oříznout PDF pro snížení jeho velikosti (zachovává text!) +crop.tags=řezat,zmenšit,upravit,tvar -home.autoSplitPDF.title=Automatické rozd?lení stránek -home.autoSplitPDF.desc=Automaticky rozd?lit naskenovaný PDF s fyzickým skenerem stránky pomocí QR kódu -autoSplitPDF.tags=zalo?ené na QR,odd?lit,scan-segment,organizovat +home.autoSplitPDF.title=Automatické rozdělení stránek +home.autoSplitPDF.desc=Automaticky rozdělit naskenovaný PDF s fyzickým skenerem stránky pomocí QR kódu +autoSplitPDF.tags=založené na QR,oddělit,scan-segment,organizovat home.sanitizePdf.title=Sanitizace -home.sanitizePdf.desc=Odstran?ní skript? a dal?ích prvk? z PDF soubor? -sanitizePdf.tags=?istit,zabezpe?it,bezpe?né,odstranit-hrozby +home.sanitizePdf.desc=Odstranění skriptů a dalších prvků z PDF souborů +sanitizePdf.tags=čistit,zabezpečit,bezpečné,odstranit-hrozby -home.URLToPDF.title=URL/Webová stránka na PDF -home.URLToPDF.desc=P?evádí libovolnou http(s) URL adresu na PDF -URLToPDF.tags=úchvat-webu,ulo?it-stránku,web-to-doc,archiv +home.URLToPDF.title=URL/Webová stránka na PDF +home.URLToPDF.desc=Převádí libovolnou http(s) URL adresu na PDF +URLToPDF.tags=úchvat-webu,uložit-stránku,web-to-doc,archiv home.HTMLToPDF.title=HTML na PDF -home.HTMLToPDF.desc=P?evádí libovolný HTML soubor nebo zip na PDF +home.HTMLToPDF.desc=Převádí libovolný HTML soubor nebo zip na PDF HTMLToPDF.tags=markup,obsah-webu,transformace,konvertovat home.MarkdownToPDF.title=Markdown na PDF -home.MarkdownToPDF.desc=P?evádí libovolný soubor Markdown na PDF +home.MarkdownToPDF.desc=Převádí libovolný soubor Markdown na PDF MarkdownToPDF.tags=markup,obsah-webu,transformace,konvertovat -home.getPdfInfo.title=Získat V?ECHNY informace o PDF -home.getPdfInfo.desc=Získání v?ech mo?ných informací o PDF +home.getPdfInfo.title=Získat VŠECHNY informace o PDF +home.getPdfInfo.desc=Získání všech možných informací o PDF getPdfInfo.tags=informace,data,statistiky,statistiky -home.extractPage.title=Extrahovat stránky -home.extractPage.desc=Extrahuje vybrané stránky z PDF +home.extractPage.title=Extrahovat stránky +home.extractPage.desc=Extrahuje vybrané stránky z PDF extractPage.tags=extrahovat -home.PdfToSinglePage.title=PDF na Jednu Velkou Stránku -home.PdfToSinglePage.desc=Slou?í v?echny stránky PDF do jedné velké jediné stránky -PdfToSinglePage.tags=jedna stránka +home.PdfToSinglePage.title=PDF na Jednu Velkou Stránku +home.PdfToSinglePage.desc=Slouží všechny stránky PDF do jedné velké jediné stránky +PdfToSinglePage.tags=jedna stránka home.showJS.title=Zobrazit JavaScript -home.showJS.desc=Hledá a zobrazuje jakýkoli JavaScript vlo?ený do PDF +home.showJS.desc=Hledá a zobrazuje jakýkoli JavaScript vložený do PDF showJS.tags=JS -home.autoRedact.title=Automatické odstran?ní -home.autoRedact.desc=Automaticky zakrývá text v PDF na základ? vstupního textu -autoRedact.tags=Odstranit,Skrytý,?ern?,zakrýt,zna?ka,skrytý +home.autoRedact.title=Automatické odstranění +home.autoRedact.desc=Automaticky zakrývá text v PDF na základě vstupního textu +autoRedact.tags=Odstranit,Skrytý,černý,zakrýt,značka,skrytý home.tableExtraxt.title=PDF na CSV -home.tableExtraxt.desc=Extrahuje tabulky z PDF a konvertuje je do formátu CSV +home.tableExtraxt.desc=Extrahuje tabulky z PDF a konvertuje je do formátu CSV tableExtraxt.tags=CSV,Extrakce tabulky,extrahovat,konvertovat -home.autoSizeSplitPDF.title=Automatické rozd?lení podle velikosti/po?tu -home.autoSizeSplitPDF.desc=Rozd?lí jeden PDF na n?kolik dokument? podle velikosti, po?tu stránek nebo po?tu dokument? -autoSizeSplitPDF.tags=pdf,rozd?lit,dokument,organizace +home.autoSizeSplitPDF.title=Automatické rozdělení podle velikosti/počtu +home.autoSizeSplitPDF.desc=Rozdělí jeden PDF na několik dokumentů podle velikosti, počtu stránek nebo počtu dokumentů +autoSizeSplitPDF.tags=pdf,rozdělit,dokument,organizace -home.overlay-pdfs.title=P?ekrýt PDF -home.overlay-pdfs.desc=P?ekrývá PDF na jiném PDF -overlay-pdfs.tags=P?ekrýt +home.overlay-pdfs.title=Překrýt PDF +home.overlay-pdfs.desc=Překrývá PDF na jiném PDF +overlay-pdfs.tags=Překrýt -home.split-by-sections.title=Rozd?lit PDF na Sekce -home.split-by-sections.desc=Rozd?lí ka?dou stránku PDF na men?í horizontální a vertikální sekce -split-by-sections.tags=Rozd?lení sekce,Rozd?lit,P?izp?sobit +home.split-by-sections.title=Rozdělit PDF na Sekce +home.split-by-sections.desc=Rozdělí každou stránku PDF na menší horizontální a vertikální sekce +split-by-sections.tags=Rozdělení sekce,Rozdělit,Přizpůsobit -home.AddStampRequest.title=P?idat razítko do PDF -home.AddStampRequest.desc=P?idá textová nebo obrazová razítka na ur?ená místa -AddStampRequest.tags=Razítko,P?idat obraz,P?idat text,Vodoznak,PDF,Vlo?it,P?izp?sobit +home.AddStampRequest.title=Přidat razítko do PDF +home.AddStampRequest.desc=Přidá textová nebo obrazová razítka na určená místa +AddStampRequest.tags=Razítko,Přidat obraz,Přidat text,Vodoznak,PDF,Vložit,Přizpůsobit home.PDFToBook.title=PDF na Knihu -home.PDFToBook.desc=P?evádí PDF do formát? knih/komiks? pomocí calibre +home.PDFToBook.desc=Převádí PDF do formátů knih/komiksů pomocí calibre PDFToBook.tags=Kniha,Komiks,Calibre,Konvertovat,manga,amazon,kindle,epub,mobi,azw3,docx,rtf,txt,html,lit,fb2,pdb,lrf home.BookToPDF.title=Kniha na PDF -home.BookToPDF.desc=P?evádí formáty knih/komiks? do PDF pomocí calibre +home.BookToPDF.desc=Převádí formáty knih/komiksů do PDF pomocí calibre BookToPDF.tags=Kniha,Komiks,Calibre,Konvertovat,manga,amazon,kindle,epub,mobi,azw3,docx,rtf,txt,html,lit,fb2,pdb,lrf @@ -452,6 +452,11 @@ login.locked=Your account has been locked. login.signinTitle=Please sign in login.ssoSignIn=Login via Single Sign-on login.oauth2AutoCreateDisabled=OAUTH2 Auto-Create User Disabled +login.oauth2RequestNotFound=Authorization Request not found +login.oauth2InvalidUserInfoResponse=Invalid User Info Response +login.oauth2invalidRequest=Invalid Request +login.oauth2AccessDenied=Access Denied +login.oauth2InvalidTokenResponse=Invalid Token Response #auto-redact @@ -475,77 +480,77 @@ showJS.submit=Show #pdfToSinglePage -pdfToSinglePage.title=PDF na jednu stránku -pdfToSinglePage.header=PDF na jednu stránku -pdfToSinglePage.submit=P?evést na jednu stránku +pdfToSinglePage.title=PDF na jednu stránku +pdfToSinglePage.header=PDF na jednu stránku +pdfToSinglePage.submit=Převést na jednu stránku #pageExtracter -pageExtracter.title=Extrahovat stránky -pageExtracter.header=Extrahovat stránky +pageExtracter.title=Extrahovat stránky +pageExtracter.header=Extrahovat stránky pageExtracter.submit=Extrahovat -pageExtracter.placeholder=(nap?. 1,2,8 nebo 4,7,12-16 nebo 2n-1) +pageExtracter.placeholder=(např. 1,2,8 nebo 4,7,12-16 nebo 2n-1) #getPdfInfo -getPdfInfo.title=Získat informace o PDF -getPdfInfo.header=Získat informace o PDF -getPdfInfo.submit=Získat informace -getPdfInfo.downloadJson=Stáhnout JSON +getPdfInfo.title=Získat informace o PDF +getPdfInfo.header=Získat informace o PDF +getPdfInfo.submit=Získat informace +getPdfInfo.downloadJson=Stáhnout JSON #markdown-to-pdf MarkdownToPDF.title=Markdown na PDF MarkdownToPDF.header=Markdown na PDF -MarkdownToPDF.submit=P?evést -MarkdownToPDF.help=Práce v pr?b?hu -MarkdownToPDF.credit=Vyu?ívá WeasyPrint +MarkdownToPDF.submit=Převést +MarkdownToPDF.help=Práce v průběhu +MarkdownToPDF.credit=Využívá WeasyPrint #url-to-pdf URLToPDF.title=URL na PDF URLToPDF.header=URL na PDF -URLToPDF.submit=P?evést -URLToPDF.credit=Vyu?ívá WeasyPrint +URLToPDF.submit=Převést +URLToPDF.credit=Využívá WeasyPrint #html-to-pdf HTMLToPDF.title=HTML na PDF HTMLToPDF.header=HTML na PDF -HTMLToPDF.help=P?ijímá soubory HTML a ZIPy obsahující html/css/obrázky atd. -HTMLToPDF.submit=P?evést -HTMLToPDF.credit=Vyu?ívá WeasyPrint -HTMLToPDF.zoom=Úrove? zv?t?ení pro zobrazení webové stránky. -HTMLToPDF.pageWidth=?í?ka stránky v centimetrech. (Prázdné pro výchozí) -HTMLToPDF.pageHeight=Vý?ka stránky v centimetrech. (Prázdné pro výchozí) -HTMLToPDF.marginTop=Horní okraj stránky v milimetrech. (Prázdné pro výchozí) -HTMLToPDF.marginBottom=Dolní okraj stránky v milimetrech. (Prázdné pro výchozí) -HTMLToPDF.marginLeft=Levý okraj stránky v milimetrech. (Prázdné pro výchozí) -HTMLToPDF.marginRight=Pravý okraj stránky v milimetrech. (Prázdné pro výchozí) -HTMLToPDF.printBackground=Zobrazit pozadí webových stránek. -HTMLToPDF.defaultHeader=Povolit výchozí záhlaví (název a ?íslo stránky) -HTMLToPDF.cssMediaType=Zm?nit typ médií CSS stránky. -HTMLToPDF.none=?ádné +HTMLToPDF.help=Přijímá soubory HTML a ZIPy obsahující html/css/obrázky atd. +HTMLToPDF.submit=Převést +HTMLToPDF.credit=Využívá WeasyPrint +HTMLToPDF.zoom=Úroveň zvětšení pro zobrazení webové stránky. +HTMLToPDF.pageWidth=Šířka stránky v centimetrech. (Prázdné pro výchozí) +HTMLToPDF.pageHeight=Výška stránky v centimetrech. (Prázdné pro výchozí) +HTMLToPDF.marginTop=Horní okraj stránky v milimetrech. (Prázdné pro výchozí) +HTMLToPDF.marginBottom=Dolní okraj stránky v milimetrech. (Prázdné pro výchozí) +HTMLToPDF.marginLeft=Levý okraj stránky v milimetrech. (Prázdné pro výchozí) +HTMLToPDF.marginRight=Pravý okraj stránky v milimetrech. (Prázdné pro výchozí) +HTMLToPDF.printBackground=Zobrazit pozadí webových stránek. +HTMLToPDF.defaultHeader=Povolit výchozí záhlaví (název a číslo stránky) +HTMLToPDF.cssMediaType=Změnit typ médií CSS stránky. +HTMLToPDF.none=Žádné HTMLToPDF.print=Tisk HTMLToPDF.screen=Obrazovka #AddStampRequest -AddStampRequest.header=Razítko PDF -AddStampRequest.title=Razítko PDF -AddStampRequest.stampType=Typ razítka -AddStampRequest.stampText=Text razítka -AddStampRequest.stampImage=Obrázek razítka +AddStampRequest.header=Razítko PDF +AddStampRequest.title=Razítko PDF +AddStampRequest.stampType=Typ razítka +AddStampRequest.stampText=Text razítka +AddStampRequest.stampImage=Obrázek razítka AddStampRequest.alphabet=Abeceda -AddStampRequest.fontSize=Velikost písma/obrázku -AddStampRequest.rotation=Oto?ení -AddStampRequest.opacity=Pr?hlednost +AddStampRequest.fontSize=Velikost písma/obrázku +AddStampRequest.rotation=Otočení +AddStampRequest.opacity=Průhlednost AddStampRequest.position=Pozice -AddStampRequest.overrideX=P?epsat sou?adnici X -AddStampRequest.overrideY=P?epsat sou?adnici Y -AddStampRequest.customMargin=Vlastní okraj -AddStampRequest.customColor=Vlastní barva textu +AddStampRequest.overrideX=Přepsat souřadnici X +AddStampRequest.overrideY=Přepsat souřadnici Y +AddStampRequest.customMargin=Vlastní okraj +AddStampRequest.customColor=Vlastní barva textu AddStampRequest.submit=Odeslat @@ -553,32 +558,32 @@ AddStampRequest.submit=Odeslat sanitizePDF.title=Sanitizace PDF sanitizePDF.header=Sanitizace PDF souboru sanitizePDF.selectText.1=Odstranit akce JavaScriptu -sanitizePDF.selectText.2=Odstranit vlo?ené soubory +sanitizePDF.selectText.2=Odstranit vložené soubory sanitizePDF.selectText.3=Odstranit metadata sanitizePDF.selectText.4=Odstranit odkazy -sanitizePDF.selectText.5=Odstranit písma +sanitizePDF.selectText.5=Odstranit písma sanitizePDF.submit=Sanitizovat PDF #addPageNumbers -addPageNumbers.title=P?idat ?ísla stránek -addPageNumbers.header=P?idat ?ísla stránek +addPageNumbers.title=Přidat čísla stránek +addPageNumbers.header=Přidat čísla stránek addPageNumbers.selectText.1=Vyberte soubor PDF: addPageNumbers.selectText.2=Velikost okraje addPageNumbers.selectText.3=Pozice -addPageNumbers.selectText.4=Po?áte?ní ?íslo -addPageNumbers.selectText.5=Stránky k ?íslování -addPageNumbers.selectText.6=Vlastní text -addPageNumbers.customTextDesc=Vlastní text -addPageNumbers.numberPagesDesc=Které stránky ?íslovat, výchozí je 'v?e', p?ijímá také 1-5 nebo 2,5,9 atd. -addPageNumbers.customNumberDesc=Výchozí je {n}, p?ijímá také 'Stránka {n} z {celkem}', 'Text-{n}', '{n} - {n} -addPageNumbers.submit=P?idat ?ísla stránek +addPageNumbers.selectText.4=Počáteční číslo +addPageNumbers.selectText.5=Stránky k číslování +addPageNumbers.selectText.6=Vlastní text +addPageNumbers.customTextDesc=Vlastní text +addPageNumbers.numberPagesDesc=Které stránky číslovat, výchozí je 'vše', přijímá také 1-5 nebo 2,5,9 atd. +addPageNumbers.customNumberDesc=Výchozí je {n}, přijímá také 'Stránka {n} z {celkem}', 'Text-{n}', '{n} - {n}' +addPageNumbers.submit=Přidat čísla stránek #auto-rename -auto-rename.title=Automatické p?ejmenování -auto-rename.header=Automatické p?ejmenování PDF -auto-rename.submit=Automaticky p?ejmenovat +auto-rename.title=Automatické přejmenování +auto-rename.header=Automatické přejmenování PDF +auto-rename.submit=Automaticky přejmenovat #adjustContrast @@ -587,27 +592,27 @@ adjustContrast.header=Upravit kontrast adjustContrast.contrast=Kontrast: adjustContrast.brightness=Jas: adjustContrast.saturation=Saturace: -adjustContrast.download=Stáhnout +adjustContrast.download=Stáhnout #crop -crop.title=O?íznout -crop.header=O?íznout obrázek +crop.title=Oříznout +crop.header=Oříznout obrázek crop.submit=Odeslat #autoSplitPDF -autoSplitPDF.title=Automatické rozd?lení PDF -autoSplitPDF.header=Automatické rozd?lení PDF -autoSplitPDF.description=Tiskn?te, vlo?te, naskenujte, nahrajte a nechte nás automaticky odd?lit va?e dokumenty. Nevy?aduje manuální t?íd?ní. -autoSplitPDF.selectText.1=Vytiskn?te n?kolik odd?lova?? ze seznamu ní?e -autoSplitPDF.selectText.2=Naskenujte v?echny va?e dokumenty najednou s pou?itím odd?lovací stránky mezi n?. -autoSplitPDF.selectText.3=Nahrajte jeden velký naskenovaný PDF soubor a nechte StirlingPDF vy?e?it v?e ostatní. -autoSplitPDF.selectText.4=Odd?lovací stránky jsou automaticky detekovány a odstran?ny, co? zaru?uje úhledný finální dokument. -autoSplitPDF.formPrompt=Vyberte PDF soubor obsahující odd?lova?e: -autoSplitPDF.duplexMode=Oboustranný re?im (Skenování z obou stran) -autoSplitPDF.dividerDownload1=Stáhnout 'Automatický odd?lova? minimální.pdf' -autoSplitPDF.dividerDownload2=Stáhnout 'Automatický odd?lova? (v?.instrukcí).pdf' +autoSplitPDF.title=Automatické rozdělení PDF +autoSplitPDF.header=Automatické rozdělení PDF +autoSplitPDF.description=Tiskněte, vložte, naskenujte, nahrajte a nechte nás automaticky oddělit vaše dokumenty. Nevyžaduje manuální třídění. +autoSplitPDF.selectText.1=Vytiskněte několik oddělovačů ze seznamu níže +autoSplitPDF.selectText.2=Naskenujte všechny vaše dokumenty najednou s použitím oddělovací stránky mezi ně. +autoSplitPDF.selectText.3=Nahrajte jeden velký naskenovaný PDF soubor a nechte StirlingPDF vyřešit vše ostatní. +autoSplitPDF.selectText.4=Oddělovací stránky jsou automaticky detekovány a odstraněny, což zaručuje úhledný finální dokument. +autoSplitPDF.formPrompt=Vyberte PDF soubor obsahující oddělovače: +autoSplitPDF.duplexMode=Oboustranný režim (Skenování z obou stran) +autoSplitPDF.dividerDownload1=Stáhnout 'Automatický oddělovač minimální.pdf' +autoSplitPDF.dividerDownload2=Stáhnout 'Automatický oddělovač (vč.instrukcí).pdf' autoSplitPDF.submit=Odeslat @@ -616,46 +621,46 @@ pipeline.title=Pipeline #pageLayout -pageLayout.title=Vícestránkové rozvr?ení -pageLayout.header=Vícestránkové rozvr?ení -pageLayout.pagesPerSheet=Stránek na list: -pageLayout.addBorder=P?idat ráme?ky +pageLayout.title=Vícestránkové rozvržení +pageLayout.header=Vícestránkové rozvržení +pageLayout.pagesPerSheet=Stránek na list: +pageLayout.addBorder=Přidat rámečky pageLayout.submit=Odeslat #scalePages -scalePages.title=Upravit m??ítko stránky -scalePages.header=Upravit m??ítko stránky -scalePages.pageSize=Velikost stránky dokumentu. -scalePages.scaleFactor=Úrove? p?iblí?ení (o?íznutí) stránky. +scalePages.title=Upravit měřítko stránky +scalePages.header=Upravit měřítko stránky +scalePages.pageSize=Velikost stránky dokumentu. +scalePages.scaleFactor=Úroveň přiblížení (oříznutí) stránky. scalePages.submit=Odeslat #certSign -certSign.title=Podepisování certifikátem -certSign.header=Podepsat PDF soubor s certifikátem (Probíhá vývoj) +certSign.title=Podepisování certifikátem +certSign.header=Podepsat PDF soubor s certifikátem (Probíhá vývoj) certSign.selectPDF=Vyberte PDF soubor k podpisu: -certSign.jksNote=Poznámka: Pokud typ va?eho certifikátu není na seznamu ní?e, prosím, p?eve?te ho na typ Java Keystore (.jks) pou?itím keytool command line tool. Poté vyberte .jks jako typ certifikátu. -certSign.selectKey=Vyberte vá? soubor s privátním klí?em (formát PKCS#8, m??e být .pem nebo .der): -certSign.selectCert=Vyberte vá? soubor s certifikátem (X.509 formát, m??e být .pem or .der): -certSign.selectP12=Vyberte vá? soubor s PKCS#12 Keystore (.p12 nebo .pfx) (Volitelné, m?l by obsahovat vá? privátní klí? a certifikát): -certSign.selectJKS=Vyberte vá? Java Keystore soubor (.jks nebo .keystore): -certSign.certType=Typ certifikátu -certSign.password=Zadejte heslo k va?emu privátnímu klí?i (pokud je zaheslovaný): -certSign.showSig=Ukázat podpis -certSign.reason=D?vod -certSign.location=Umíst?ní -certSign.name=Název +certSign.jksNote=Poznámka: Pokud typ vašeho certifikátu není na seznamu níže, prosím, převeďte ho na typ Java Keystore (.jks) použitím keytool command line tool. Poté vyberte .jks jako typ certifikátu. +certSign.selectKey=Vyberte váš soubor s privátním klíčem (formát PKCS#8, může být .pem nebo .der): +certSign.selectCert=Vyberte váš soubor s certifikátem (X.509 formát, může být .pem or .der): +certSign.selectP12=Vyberte váš soubor s PKCS#12 Keystore (.p12 nebo .pfx) (Volitelné, měl by obsahovat váš privátní klíč a certifikát): +certSign.selectJKS=Vyberte váš Java Keystore soubor (.jks nebo .keystore): +certSign.certType=Typ certifikátu +certSign.password=Zadejte heslo k vašemu privátnímu klíči (pokud je zaheslovaný): +certSign.showSig=Ukázat podpis +certSign.reason=Důvod +certSign.location=Umístění +certSign.name=Název certSign.submit=Podepsat PDF #removeBlanks -removeBlanks.title=Odebrat prázdné stránky -removeBlanks.header=Odebrat prázdné stránky -removeBlanks.threshold=Práh b?losti pixel?: -removeBlanks.thresholdDesc=Práh pro zji?t?ní jak bílý musí být bílý pixel aby byl klasifikován jako 'bílý'. 0 = ?erná, 255 = ?ist? bílá. -removeBlanks.whitePercent=Procenta b?losti (%): -removeBlanks.whitePercentDesc=Procenta, kolik pixel? na stránce musí být bílých aby byla odstran?na. +removeBlanks.title=Odebrat prázdné stránky +removeBlanks.header=Odebrat prázdné stránky +removeBlanks.threshold=Práh bělosti pixelů: +removeBlanks.thresholdDesc=Práh pro zjištění jak bílý musí být bílý pixel aby byl klasifikován jako 'bílý'. 0 = černá, 255 = čistě bílá. +removeBlanks.whitePercent=Procenta bělosti (%): +removeBlanks.whitePercentDesc=Procenta, kolik pixelů na stránce musí být bílých aby byla odstraněna. removeBlanks.submit=Odebrat @@ -675,24 +680,24 @@ compare.submit=Porovnat #BookToPDF BookToPDF.title=Knihy a komiksy do PDF BookToPDF.header=Knihy do PDF -BookToPDF.credit=Vyu?ívá Calibre -BookToPDF.submit=P?evést +BookToPDF.credit=Využívá Calibre +BookToPDF.submit=Převést #PDFToBook PDFToBook.title=PDF na knihu PDFToBook.header=PDF na knihu -PDFToBook.selectText.1=Formát -PDFToBook.credit=Vyu?ívá Calibre -PDFToBook.submit=P?evést +PDFToBook.selectText.1=Formát +PDFToBook.credit=Využívá Calibre +PDFToBook.submit=Převést #sign sign.title=Podpis sign.header=Podpis PDF -sign.upload=Nahrát obrázek +sign.upload=Nahrát obrázek sign.draw=Nakreslit podpis sign.text=Vstup textu sign.clear=Vymazat -sign.add=P?idat +sign.add=Přidat #repair @@ -702,374 +707,374 @@ repair.submit=Opravit #flatten -flatten.title=Zplo?tit -flatten.header=Zplo?tit PDF -flatten.flattenOnlyForms=Zplo?tit pouze formulá?e -flatten.submit=Zplo?tit +flatten.title=Zploštit +flatten.header=Zploštit PDF +flatten.flattenOnlyForms=Zploštit pouze formuláře +flatten.submit=Zploštit #ScannerImageSplit -ScannerImageSplit.selectText.1=Práh úhlu: -ScannerImageSplit.selectText.2=Nastaví minimální absolutní úhel, který je vy?adován k oto?ení obrázku (výchozí: 10). +ScannerImageSplit.selectText.1=Práh úhlu: +ScannerImageSplit.selectText.2=Nastaví minimální absolutní úhel, který je vyžadován k otočení obrázku (výchozí: 10). ScannerImageSplit.selectText.3=Tolerance: -ScannerImageSplit.selectText.4=Ur?uje rozsah barevné variace kolem odhadované barvy pozadí (výchozí: 30). -ScannerImageSplit.selectText.5=Minimální plocha: -ScannerImageSplit.selectText.6=Nastaví minimální plo?ný prah pro fotografii (výchozí: 10000). -ScannerImageSplit.selectText.7=Minimální plocha kontury: -ScannerImageSplit.selectText.8=Nastaví minimální plo?ný prah kontury pro fotografii +ScannerImageSplit.selectText.4=Určuje rozsah barevné variace kolem odhadované barvy pozadí (výchozí: 30). +ScannerImageSplit.selectText.5=Minimální plocha: +ScannerImageSplit.selectText.6=Nastaví minimální plošný práh pro fotografii (výchozí: 10000). +ScannerImageSplit.selectText.7=Minimální plocha kontury: +ScannerImageSplit.selectText.8=Nastaví minimální plošný práh kontury pro fotografii ScannerImageSplit.selectText.9=Velikost okraje: -ScannerImageSplit.selectText.10=Nastaví velikost okraje p?idaného a odebraného k zabrán?ní bílých ohrani?ení ve výstupu (výchozí: 1). +ScannerImageSplit.selectText.10=Nastaví velikost okraje přidaného a odebraného k zabránění bílých ohraničení ve výstupu (výchozí: 1). #OCR -ocr.title=OCR / Úprava sken? -ocr.header=Úprava sken? / OCR (Optické rozpoznávání znak?) -ocr.selectText.1=Vyberte jazyky, které mají být detekovány ve formátu PDF (Aktuáln? detekované): -ocr.selectText.2=Vytvo?it textový soubor obsahující text OCR spolu s PDF s OCR -ocr.selectText.3=Opraveny jsou stránky naskenovány pod ?ikmým úhlem tím, ?e jsou zp?tn? oto?eny na místo -ocr.selectText.4=O?istit stránku, aby bylo mén? pravd?podobné, ?e OCR najde text ve zvukovém ?umu. (?ádná zm?na výstupu) -ocr.selectText.5=O?istit stránku, aby bylo mén? pravd?podobné, ?e OCR najde text ve zvukovém ?umu, udr?uje ?istotu výstupu. -ocr.selectText.6=Ignorovat stránky, které obsahují interaktivní text, provádí pouze OCR na stránkách, které jsou obrázky -ocr.selectText.7=Vynutit OCR, provede OCR na ka?dé stránce a odeber ve?keré p?vodní textové prvky -ocr.selectText.8=Normální (Chyba, pokud PDF obsahuje text) -ocr.selectText.9=Dal?í nastavení -ocr.selectText.10=Re?im OCR -ocr.selectText.11=Odstranit obrázky po OCR (Odstraní V?ECHNY obrázky, u?ite?né pouze jako sou?ást kroku konverze) -ocr.selectText.12=Typ vykreslení (Pokro?ilé) -ocr.help=Prosím, p?e?t?te si tuto dokumentaci o pou?ití pro jiné jazyky a/nebo pou?ití mimo Docker -ocr.credit=Tato slu?ba pou?ívá OCRmyPDF a Tesseract pro OCR. +ocr.title=OCR / Úprava skenů +ocr.header=Úprava skenů / OCR (Optické rozpoznávání znaků) +ocr.selectText.1=Vyberte jazyky, které mají být detekovány ve formátu PDF (Aktuálně detekované): +ocr.selectText.2=Vytvořit textový soubor obsahující text OCR spolu s PDF s OCR +ocr.selectText.3=Opraveny jsou stránky naskenovány pod šikmým úhlem tím, že jsou zpětně otočeny na místo +ocr.selectText.4=Očistit stránku, aby bylo méně pravděpodobné, že OCR najde text ve zvukovém šumu. (Žádná změna výstupu) +ocr.selectText.5=Očistit stránku, aby bylo méně pravděpodobné, že OCR najde text ve zvukovém šumu, udržuje čistotu výstupu. +ocr.selectText.6=Ignorovat stránky, které obsahují interaktivní text, provádí pouze OCR na stránkách, které jsou obrázky +ocr.selectText.7=Vynutit OCR, provede OCR na každé stránce a odeber veškeré původní textové prvky +ocr.selectText.8=Normální (Chyba, pokud PDF obsahuje text) +ocr.selectText.9=Další nastavení +ocr.selectText.10=Režim OCR +ocr.selectText.11=Odstranit obrázky po OCR (Odstraní VŠECHNY obrázky, užitečné pouze jako součást kroku konverze) +ocr.selectText.12=Typ vykreslení (Pokročilé) +ocr.help=Prosím, přečtěte si tuto dokumentaci o použití pro jiné jazyky a/nebo použití mimo Docker +ocr.credit=Tato služba používá OCRmyPDF a Tesseract pro OCR. ocr.submit=Zpracovat PDF s OCR #extractImages -extractImages.title=Extrahovat obrázky -extractImages.header=Extrahovat obrázky -extractImages.selectText=Vyberte formát obrázku pro extrahované obrázky +extractImages.title=Extrahovat obrázky +extractImages.header=Extrahovat obrázky +extractImages.selectText=Vyberte formát obrázku pro extrahované obrázky extractImages.submit=Extrahovat #File to PDF fileToPDF.title=Soubor na PDF -fileToPDF.header=P?evést jakýkoli soubor na PDF -fileToPDF.credit=Tato slu?ba pou?ívá LibreOffice a Unoconv pro konverzi soubor?. -fileToPDF.supportedFileTypesInfo=Podporované typy soubor? -fileToPDF.supportedFileTypes=Podporované typy soubor? by m?ly zahrnovat ní?e uvedené, av?ak pro úplný aktualizovaný seznam podporovaných formát? se obra?te na dokumentaci LibreOffice. -fileToPDF.submit=P?evést na PDF +fileToPDF.header=Převést jakýkoli soubor na PDF +fileToPDF.credit=Tato služba používá LibreOffice a Unoconv pro konverzi souborů. +fileToPDF.supportedFileTypesInfo=Podporované typy souborů +fileToPDF.supportedFileTypes=Podporované typy souborů by měly zahrnovat níže uvedené, avšak pro úplný aktualizovaný seznam podporovaných formátů se obraťte na dokumentaci LibreOffice. +fileToPDF.submit=Převést na PDF #compress compress.title=Komprese compress.header=Komprimovat PDF -compress.credit=Tato slu?ba pou?ívá Ghostscript pro kompresi/optimalizaci PDF. -compress.selectText.1=Ru?ní re?im - Od 1 do 4 -compress.selectText.2=Úrove? optimalizace: -compress.selectText.3=4 (Hrozné pro textové obrázky) -compress.selectText.4=Automatický re?im - Automaticky upravuje kvalitu pro dosa?ení p?esné velikosti PDF -compress.selectText.5=O?ekávaná velikost PDF (nap?. 25 MB, 10,8 MB, 25 KB) +compress.credit=Tato služba používá Ghostscript pro kompresi/optimalizaci PDF. +compress.selectText.1=Ruční režim - Od 1 do 4 +compress.selectText.2=Úroveň optimalizace: +compress.selectText.3=4 (Hrozné pro textové obrázky) +compress.selectText.4=Automatický režim - Automaticky upravuje kvalitu pro dosažení přesné velikosti PDF +compress.selectText.5=Očekávaná velikost PDF (např. 25 MB, 10,8 MB, 25 KB) compress.submit=Komprimovat #Add image -addImage.title=P?idat obrázek -addImage.header=P?idat obrázek do PDF -addImage.everyPage=Ka?dá stránka? -addImage.upload=P?idat obrázek -addImage.submit=P?idat obrázek +addImage.title=Přidat obrázek +addImage.header=Přidat obrázek do PDF +addImage.everyPage=Každá stránka? +addImage.upload=Přidat obrázek +addImage.submit=Přidat obrázek #merge -merge.title=Slou?it -merge.header=Slou?it více PDF (2+) -merge.sortByName=Se?adit podle názvu -merge.sortByDate=Se?adit podle data -merge.submit=Slou?it +merge.title=Sloučit +merge.header=Sloučit více PDF (2+) +merge.sortByName=Seřadit podle názvu +merge.sortByDate=Seřadit podle data +merge.submit=Sloučit #pdfOrganiser -pdfOrganiser.title=Organizér stránek -pdfOrganiser.header=Organizér stránek PDF -pdfOrganiser.submit=P?euspo?ádat stránky -pdfOrganiser.mode=Mód -pdfOrganiser.mode.1=Vlastní po?adí stránek -pdfOrganiser.mode.2=Obrácené po?adí -pdfOrganiser.mode.3=Duplexní ?azení -pdfOrganiser.mode.4=?azení do bro?ury -pdfOrganiser.mode.5=?azení do bo?ní bro?ury -pdfOrganiser.mode.6=Liché-Sudé rozd?lení -pdfOrganiser.mode.7=Odstranit první -pdfOrganiser.mode.8=Odstranit poslední -pdfOrganiser.mode.9=Odstranit první a poslední -pdfOrganiser.placeholder=(nap?. 1,3,2 nebo 4-8,2,10-12 nebo 2n-1) +pdfOrganiser.title=Organizér stránek +pdfOrganiser.header=Organizér stránek PDF +pdfOrganiser.submit=Přeuspořádat stránky +pdfOrganiser.mode=Mód +pdfOrganiser.mode.1=Vlastní pořadí stránek +pdfOrganiser.mode.2=Obrácené pořadí +pdfOrganiser.mode.3=Duplexní řazení +pdfOrganiser.mode.4=Řazení do brožury +pdfOrganiser.mode.5=Řazení do boční brožury +pdfOrganiser.mode.6=Liché-Sudé rozdělení +pdfOrganiser.mode.7=Odstranit první +pdfOrganiser.mode.8=Odstranit poslední +pdfOrganiser.mode.9=Odstranit první a poslední +pdfOrganiser.placeholder=(např. 1,3,2 nebo 4-8,2,10-12 nebo 2n-1) #multiTool -multiTool.title=Vícefunk?ní nástroj pro PDF -multiTool.header=Vícefunk?ní nástroj pro PDF -multiTool.uploadPrompts=Název souboru +multiTool.title=Vícefunkční nástroj pro PDF +multiTool.header=Vícefunkční nástroj pro PDF +multiTool.uploadPrompts=Název souboru #view pdf viewPdf.title=Zobrazit PDF viewPdf.header=Zobrazit PDF #pageRemover -pageRemover.title=Odstran?ní stránek -pageRemover.header=Odstran?ní stránek z PDF -pageRemover.pagesToDelete=Stránky k odstran?ní (Zadejte ?árkami odd?lený seznam ?ísel stránek) : -pageRemover.submit=Odstranit stránky -pageRemover.placeholder=(nap?. 1,2,6 nebo 1-10,15-30) +pageRemover.title=Odstranění stránek +pageRemover.header=Odstranění stránek z PDF +pageRemover.pagesToDelete=Stránky k odstranění (Zadejte čárkami oddělený seznam čísel stránek) : +pageRemover.submit=Odstranit stránky +pageRemover.placeholder=(např. 1,2,6 nebo 1-10,15-30) #rotate -rotate.title=Oto?it PDF -rotate.header=Oto?it PDF -rotate.selectAngle=Vyberte úhel oto?ení (v násobcích 90 stup??): -rotate.submit=Oto?it +rotate.title=Otočit PDF +rotate.header=Otočit PDF +rotate.selectAngle=Vyberte úhel otočení (v násobcích 90 stupňů): +rotate.submit=Otočit #split-pdfs -split.title=Rozd?lit PDF -split.header=Rozd?lit PDF -split.desc.1=?ísla, která vyberete, jsou ?íslo stránky, na které chcete provést rozd?lení -split.desc.2=Jako takový výb?r 1,3,7-9 by rozd?lil 10stránkový dokument na 6 samostatných PDF soubor? s: -split.desc.3=Dokument ?. 1: Stránka 1 -split.desc.4=Dokument ?. 2: Stránky 2 a 3 -split.desc.5=Dokument ?. 3: Stránky 4, 5, 6 a 7 -split.desc.6=Dokument ?. 4: Stránka 8 -split.desc.7=Dokument ?. 5: Stránka 9 -split.desc.8=Dokument ?. 6: Stránka 10 -split.splitPages=Zadejte stránky, na které se má rozd?lit: -split.submit=Rozd?lit +split.title=Rozdělit PDF +split.header=Rozdělit PDF +split.desc.1=Čísla, která vyberete, jsou číslo stránky, na které chcete provést rozdělení +split.desc.2=Jako takový výběr 1,3,7-9 by rozdělil 10stránkový dokument na 6 samostatných PDF souborů s: +split.desc.3=Dokument č. 1: Stránka 1 +split.desc.4=Dokument č. 2: Stránky 2 a 3 +split.desc.5=Dokument č. 3: Stránky 4, 5, 6 a 7 +split.desc.6=Dokument č. 4: Stránka 8 +split.desc.7=Dokument č. 5: Stránka 9 +split.desc.8=Dokument č. 6: Stránka 10 +split.splitPages=Zadejte stránky, na které se má rozdělit: +split.submit=Rozdělit #merge -imageToPDF.title=Obrázek na PDF -imageToPDF.header=Obrázek na PDF -imageToPDF.submit=P?evést -imageToPDF.selectLabel=Mo?nosti p?izp?sobení obrázku -imageToPDF.fillPage=Vyplnit stránku -imageToPDF.fitDocumentToImage=P?izp?sobit stránku obrázku -imageToPDF.maintainAspectRatio=Zachovat pom?r stran -imageToPDF.selectText.2=Automaticky oto?it PDF -imageToPDF.selectText.3=Více soubor? (Pouze pokud je vlo?eno více obrázk?) -imageToPDF.selectText.4=Slou?it do jednoho PDF -imageToPDF.selectText.5=Rozd?lit na jednotlivé PDF soubory +imageToPDF.title=Obrázek na PDF +imageToPDF.header=Obrázek na PDF +imageToPDF.submit=Převést +imageToPDF.selectLabel=Možnosti přizpůsobení obrázku +imageToPDF.fillPage=Vyplnit stránku +imageToPDF.fitDocumentToImage=Přizpůsobit stránku obrázku +imageToPDF.maintainAspectRatio=Zachovat poměr stran +imageToPDF.selectText.2=Automaticky otočit PDF +imageToPDF.selectText.3=Více souborů (Pouze pokud je vloženo více obrázků) +imageToPDF.selectText.4=Sloučit do jednoho PDF +imageToPDF.selectText.5=Rozdělit na jednotlivé PDF soubory #pdfToImage -pdfToImage.title=PDF na obrázek -pdfToImage.header=PDF na obrázek -pdfToImage.selectText=Formát obrázku -pdfToImage.singleOrMultiple=Typ výsledku stránky na obrázek -pdfToImage.single=Jeden velký obrázek spojující v?echny stránky -pdfToImage.multi=Více obrázk?, jeden obrázek na stránku +pdfToImage.title=PDF na obrázek +pdfToImage.header=PDF na obrázek +pdfToImage.selectText=Formát obrázku +pdfToImage.singleOrMultiple=Typ výsledku stránky na obrázek +pdfToImage.single=Jeden velký obrázek spojující všechny stránky +pdfToImage.multi=Více obrázků, jeden obrázek na stránku pdfToImage.colorType=Typ barev -pdfToImage.color=Barevný -pdfToImage.grey=Stupn? ?edi -pdfToImage.blackwhite=?ernobílý (M??e dojít k ztrát? dat!) -pdfToImage.submit=P?evést +pdfToImage.color=Barevný +pdfToImage.grey=Stupně šedi +pdfToImage.blackwhite=Černobílý (Může dojít k ztrátě dat!) +pdfToImage.submit=Převést #addPassword -addPassword.title=P?idat heslo -addPassword.header=P?idat heslo (?ifrovat) -addPassword.selectText.1=Vyberte PDF k ?ifrování -addPassword.selectText.2=U?ivatelské heslo -addPassword.selectText.3=Délka ?ifrovacího klí?e -addPassword.selectText.4=Vy??í hodnoty jsou siln?j?í, ale ni??í hodnoty mají lep?í kompatibilitu. -addPassword.selectText.5=Povolená oprávn?ní (Doporu?uje se pou?ívat spole?n? s heslem vlastníka) -addPassword.selectText.6=Zabra?te sestavení dokumentu -addPassword.selectText.7=Zabránit extrakci obsahu -addPassword.selectText.8=Zabra?te extrakci pro p?ístupnost -addPassword.selectText.9=Zabránit vypl?ování formulá?e -addPassword.selectText.10=Zabra?te úpravám -addPassword.selectText.11=Zabránit úprav? poznámek -addPassword.selectText.12=Zabránit tisku -addPassword.selectText.13=Zabránit tisku r?zných formát? -addPassword.selectText.14=Heslo vlastníka -addPassword.selectText.15=Omezí, co lze s dokumentem provád?t po jeho otev?ení (Není podporováno v?emi ?te?kami) -addPassword.selectText.16=Omezí samotné otev?ení dokumentu -addPassword.submit=?ifrovat +addPassword.title=Přidat heslo +addPassword.header=Přidat heslo (šifrovat) +addPassword.selectText.1=Vyberte PDF k šifrování +addPassword.selectText.2=Uživatelské heslo +addPassword.selectText.3=Délka šifrovacího klíče +addPassword.selectText.4=Vyšší hodnoty jsou silnější, ale nižší hodnoty mají lepší kompatibilitu. +addPassword.selectText.5=Povolená oprávnění (Doporučuje se používat společně s heslem vlastníka) +addPassword.selectText.6=Zabraňte sestavení dokumentu +addPassword.selectText.7=Zabránit extrakci obsahu +addPassword.selectText.8=Zabraňte extrakci pro přístupnost +addPassword.selectText.9=Zabránit vyplňování formuláře +addPassword.selectText.10=Zabraňte úpravám +addPassword.selectText.11=Zabránit úpravě poznámek +addPassword.selectText.12=Zabránit tisku +addPassword.selectText.13=Zabránit tisku různých formátů +addPassword.selectText.14=Heslo vlastníka +addPassword.selectText.15=Omezí, co lze s dokumentem provádět po jeho otevření (Není podporováno všemi čtečkami) +addPassword.selectText.16=Omezí samotné otevření dokumentu +addPassword.submit=Šifrovat #watermark -watermark.title=P?idat vodoznak -watermark.header=P?idat vodoznak -watermark.selectText.1=Vyberte PDF, ke kterému chcete p?idat vodoznak: +watermark.title=Přidat vodoznak +watermark.header=Přidat vodoznak +watermark.selectText.1=Vyberte PDF, ke kterému chcete přidat vodoznak: watermark.selectText.2=Text vodoznaku: -watermark.selectText.3=Velikost písma: +watermark.selectText.3=Velikost písma: watermark.selectText.4=Rotace (0-360): -watermark.selectText.5=?í?ka mezery (Mezera mezi ka?dým vodoznakem vodorovn?): -watermark.selectText.6=Vý?ka mezery (Mezera mezi ka?dým vodoznakem svisle): -watermark.selectText.7=Pr?hlednost (0% - 100%): +watermark.selectText.5=Šířka mezery (Mezera mezi každým vodoznakem vodorovně): +watermark.selectText.6=Výška mezery (Mezera mezi každým vodoznakem svisle): +watermark.selectText.7=Průhlednost (0% - 100%): watermark.selectText.8=Typ vodoznaku: -watermark.selectText.9=Obrázek vodoznaku: -watermark.submit=P?idat vodoznak +watermark.selectText.9=Obrázek vodoznaku: +watermark.submit=Přidat vodoznak watermark.type.1=Text -watermark.type.2=Obrázek +watermark.type.2=Obrázek #Change permissions -permissions.title=Zm?nit oprávn?ní -permissions.header=Zm?nit oprávn?ní -permissions.warning=Upozorn?ní: Chcete-li mít tato oprávn?ní nezm?nitelná, doporu?uje se je nastavit heslem prost?ednictvím stránky P?idat heslo. -permissions.selectText.1=Vyberte PDF ke zm?n? oprávn?ní -permissions.selectText.2=Oprávn?ní k nastavení -permissions.selectText.3=Zabránit sestavení dokumentu -permissions.selectText.4=Zabránit extrakci obsahu -permissions.selectText.5=Zabránit extrakci pro p?ístupnost -permissions.selectText.6=Zabránit vypl?ování formulá?e -permissions.selectText.7=Zabránit úpravám -permissions.selectText.8=Zabránit úprav? poznámek -permissions.selectText.9=Zabránit tisku -permissions.selectText.10=Zabránit tisku r?zných formát? -permissions.submit=Zm?nit +permissions.title=Změnit oprávnění +permissions.header=Změnit oprávnění +permissions.warning=Upozornění: Chcete-li mít tato oprávnění nezměnitelná, doporučuje se je nastavit heslem prostřednictvím stránky Přidat heslo. +permissions.selectText.1=Vyberte PDF ke změně oprávnění +permissions.selectText.2=Oprávnění k nastavení +permissions.selectText.3=Zabránit sestavení dokumentu +permissions.selectText.4=Zabránit extrakci obsahu +permissions.selectText.5=Zabránit extrakci pro přístupnost +permissions.selectText.6=Zabránit vyplňování formuláře +permissions.selectText.7=Zabránit úpravám +permissions.selectText.8=Zabránit úpravě poznámek +permissions.selectText.9=Zabránit tisku +permissions.selectText.10=Zabránit tisku různých formátů +permissions.submit=Změnit #remove password removePassword.title=Odstranit heslo -removePassword.header=Odstranit heslo (De?ifrovat) -removePassword.selectText.1=Vyberte PDF k de?ifrování +removePassword.header=Odstranit heslo (Dešifrovat) +removePassword.selectText.1=Vyberte PDF k dešifrování removePassword.selectText.2=Heslo removePassword.submit=Odstranit #changeMetadata -changeMetadata.title=Zm?nit metadat -changeMetadata.header=Zm?nit metadat -changeMetadata.selectText.1=Upravte prom?nné, které chcete zm?nit -changeMetadata.selectText.2=Smazat v?echna metadata -changeMetadata.selectText.3=Zobrazit vlastní metadata: +changeMetadata.title=Změnit metadat +changeMetadata.header=Změnit metadat +changeMetadata.selectText.1=Upravte proměnné, které chcete změnit +changeMetadata.selectText.2=Smazat všechna metadata +changeMetadata.selectText.3=Zobrazit vlastní metadata: changeMetadata.author=Autor: -changeMetadata.creationDate=Datum vytvo?ení (rrrr/MM/dd HH:mm:ss): -changeMetadata.creator=Tv?rce: -changeMetadata.keywords=Klí?ová slova: -changeMetadata.modDate=Datum úpravy (rrrr/MM/dd HH:mm:ss): +changeMetadata.creationDate=Datum vytvoření (rrrr/MM/dd HH:mm:ss): +changeMetadata.creator=Tvořce: +changeMetadata.keywords=Klíčová slova: +changeMetadata.modDate=Datum úpravy (rrrr/MM/dd HH:mm:ss): changeMetadata.producer=Producent: -changeMetadata.subject=P?edm?t: -changeMetadata.trapped=Zabraný: -changeMetadata.selectText.4=Ostatní metadata: -changeMetadata.selectText.5=P?idat vlastní polo?ku metadata -changeMetadata.submit=Zm?nit +changeMetadata.subject=Předmět: +changeMetadata.trapped=Zabraný: +changeMetadata.selectText.4=Ostatní metadata: +changeMetadata.selectText.5=Přidat vlastní položku metadata +changeMetadata.submit=Změnit #pdfToPDFA pdfToPDFA.title=PDF na PDF/A pdfToPDFA.header=PDF na PDF/A -pdfToPDFA.credit=Tato slu?ba pou?ívá OCRmyPDF pro konverzi do formátu PDF/A -pdfToPDFA.submit=P?evést -pdfToPDFA.tip=V sou?asné dob? nepracuje pro více vstup? najednou -pdfToPDFA.outputFormat=Výstupní formát +pdfToPDFA.credit=Tato služba používá OCRmyPDF pro konverzi do formátu PDF/A +pdfToPDFA.submit=Převést +pdfToPDFA.tip=V současné době nepracuje pro více vstupů najednou +pdfToPDFA.outputFormat=Výstupní formát #PDFToWord PDFToWord.title=PDF do Wordu PDFToWord.header=PDF do Wordu -PDFToWord.selectText.1=Formát výstupního souboru -PDFToWord.credit=Tato slu?ba pou?ívá LibreOffice pro konverzi soubor?. -PDFToWord.submit=P?evést +PDFToWord.selectText.1=Formát výstupního souboru +PDFToWord.credit=Tato služba používá LibreOffice pro konverzi souborů. +PDFToWord.submit=Převést #PDFToPresentation PDFToPresentation.title=PDF na prezentaci PDFToPresentation.header=PDF na prezentaci -PDFToPresentation.selectText.1=Formát výstupního souboru -PDFToPresentation.credit=Tato slu?ba pou?ívá LibreOffice pro konverzi soubor?. -PDFToPresentation.submit=P?evést +PDFToPresentation.selectText.1=Formát výstupního souboru +PDFToPresentation.credit=Tato služba používá LibreOffice pro konverzi souborů. +PDFToPresentation.submit=Převést #PDFToText PDFToText.title=PDF na RTF (Text) PDFToText.header=PDF na RTF (Text) -PDFToText.selectText.1=Formát výstupního souboru -PDFToText.credit=Tato slu?ba pou?ívá LibreOffice pro konverzi soubor?. -PDFToText.submit=P?evést +PDFToText.selectText.1=Formát výstupního souboru +PDFToText.credit=Tato služba používá LibreOffice pro konverzi souborů. +PDFToText.submit=Převést #PDFToHTML PDFToHTML.title=PDF na HTML PDFToHTML.header=PDF na HTML -PDFToHTML.credit=Tato slu?ba pou?ívá pdftohtml pro konverzi soubor?. -PDFToHTML.submit=P?evést +PDFToHTML.credit=Tato služba používá pdftohtml pro konverzi souborů. +PDFToHTML.submit=Převést #PDFToXML PDFToXML.title=PDF na XML PDFToXML.header=PDF na XML -PDFToXML.credit=Tato slu?ba pou?ívá LibreOffice pro konverzi soubor?. -PDFToXML.submit=P?evést +PDFToXML.credit=Tato služba používá LibreOffice pro konverzi souborů. +PDFToXML.submit=Převést #PDFToCSV PDFToCSV.title=PDF na CSV PDFToCSV.header=PDF na CSV -PDFToCSV.prompt=Vyberte stránku pro extrakci tabulky +PDFToCSV.prompt=Vyberte stránku pro extrakci tabulky PDFToCSV.submit=Extrahovat #split-by-size-or-count -split-by-size-or-count.title=Rozd?lit PDF podle velikosti nebo po?tu -split-by-size-or-count.header=Rozd?lit PDF podle velikosti nebo po?tu -split-by-size-or-count.type.label=Vyberte typ rozd?lení +split-by-size-or-count.title=Rozdělit PDF podle velikosti nebo počtu +split-by-size-or-count.header=Rozdělit PDF podle velikosti nebo počtu +split-by-size-or-count.type.label=Vyberte typ rozdělení split-by-size-or-count.type.size=Podle velikosti -split-by-size-or-count.type.pageCount=Podle po?tu stránek -split-by-size-or-count.type.docCount=Podle po?tu dokument? +split-by-size-or-count.type.pageCount=Podle počtu stránek +split-by-size-or-count.type.docCount=Podle počtu dokumentů split-by-size-or-count.value.label=Zadejte hodnotu -split-by-size-or-count.value.placeholder=Zadejte velikost (nap?. 2 MB nebo 3 KB) nebo po?et (nap?. 5) +split-by-size-or-count.value.placeholder=Zadejte velikost (např. 2 MB nebo 3 KB) nebo počet (např. 5) split-by-size-or-count.submit=Odeslat #overlay-pdfs -overlay-pdfs.header=P?ekrýt soubory PDF -overlay-pdfs.baseFile.label=Vyberte základní soubor PDF -overlay-pdfs.overlayFiles.label=Vyberte soubory PDF pro p?ekrytí -overlay-pdfs.mode.label=Vyberte re?im p?ekrytí -overlay-pdfs.mode.sequential=Postupné p?ekrytí -overlay-pdfs.mode.interleaved=St?ídavé p?ekrytí -overlay-pdfs.mode.fixedRepeat=Pevné opakování p?ekrytí -overlay-pdfs.counts.label=P?ekrytí po?et (pro re?im pevného opakování) -overlay-pdfs.counts.placeholder=Zadejte po?ty odd?lené ?árkami (nap?. 2,3,1) -overlay-pdfs.position.label=Vyberte pozici p?ekrytí -overlay-pdfs.position.foreground=P?ední plán -overlay-pdfs.position.background=Pozadí +overlay-pdfs.header=Překrýt soubory PDF +overlay-pdfs.baseFile.label=Vyberte základní soubor PDF +overlay-pdfs.overlayFiles.label=Vyberte soubory PDF pro překrytí +overlay-pdfs.mode.label=Vyberte režim překrytí +overlay-pdfs.mode.sequential=Postupné překrytí +overlay-pdfs.mode.interleaved=Střídavé překrytí +overlay-pdfs.mode.fixedRepeat=Pevné opakování překrytí +overlay-pdfs.counts.label=Překrytí počet (pro režim pevného opakování) +overlay-pdfs.counts.placeholder=Zadejte počty oddělené čárkami (např. 2,3,1) +overlay-pdfs.position.label=Vyberte pozici překrytí +overlay-pdfs.position.foreground=Přední plán +overlay-pdfs.position.background=Pozadí overlay-pdfs.submit=Odeslat #split-by-sections -split-by-sections.title=Rozd?lit PDF podle sekcí -split-by-sections.header=Rozd?lit PDF do sekcí -split-by-sections.horizontal.label=Horizontální d?lení -split-by-sections.vertical.label=Vertikální d?lení -split-by-sections.horizontal.placeholder=Zadejte po?et horizontálních d?lení -split-by-sections.vertical.placeholder=Zadejte po?et vertikálních d?lení -split-by-sections.submit=Rozd?lit PDF -split-by-sections.merge=Slou?it do jednoho PDF +split-by-sections.title=Rozdělit PDF podle sekcí +split-by-sections.header=Rozdělit PDF do sekcí +split-by-sections.horizontal.label=Horizontální dělení +split-by-sections.vertical.label=Vertikální dělení +split-by-sections.horizontal.placeholder=Zadejte počet horizontálních dělení +split-by-sections.vertical.placeholder=Zadejte počet vertikálních dělení +split-by-sections.submit=Rozdělit PDF +split-by-sections.merge=Sloučit do jednoho PDF #printFile printFile.title=Tisk souboru -printFile.header=Tisknout soubor na tiskárnu +printFile.header=Tisknout soubor na tiskárnu printFile.selectText.1=Vyberte soubor k tisku -printFile.selectText.2=Zadejte název tiskárny +printFile.selectText.2=Zadejte název tiskárny printFile.submit=Tisknout #licenses -licenses.nav=License -licenses.title=Licence t?etích stran -licenses.header=Licence t?etích stran +licenses.nav=Licence +licenses.title=Licence třetích stran +licenses.header=Licence třetích stran licenses.module=Modul licenses.version=Verze licenses.license=Licence #error -error.sorry=Omlouváme se za potí?e! -error.needHelp=Pot?ebujete pomoc / Na?li jste problém? -error.contactTip=Pokud stále máte potí?e, neváhejte nás kontaktovat o pomoc. M??ete nám odeslat po?adavek na na?í stránce na GitHubu nebo nás kontaktovat p?es Discord: -error.404.head=404 - Stránka nebyla nalezena | Oops, zakopli jsme v kódu! -error.404.1=Neda?í se nám najít stránku, kterou hledáte. -error.404.2=N?co se nepovedlo -error.github=Odeslat po?adavek na GitHubu -error.showStack=Zobrazit stopu zásobníku -error.copyStack=Kopírovat stopu zásobníku -error.githubSubmit=GitHub - Odeslat po?adavek -error.discordSubmit=Discord - Odeslat p?ísp?vek podpory +error.sorry=Omlouváme se za potíže! +error.needHelp=Potřebujete pomoc / Našli jste problém? +error.contactTip=Pokud stále máte potíže, neváhejte nás kontaktovat o pomoc. Můžete nám odeslat požadavek na naší stránce na GitHubu nebo nás kontaktovat přes Discord: +error.404.head=404 - Stránka nebyla nalezena | Oops, zakopli jsme v kódu! +error.404.1=Nedaří se nám najít stránku, kterou hledáte. +error.404.2=Něco se nepovedlo +error.github=Odeslat požadavek na GitHubu +error.showStack=Zobrazit stopu zásobníku +error.copyStack=Kopírovat stopu zásobníku +error.githubSubmit=GitHub - Odeslat požadavek +error.discordSubmit=Discord - Odeslat příspěvek podpory diff --git a/src/main/resources/messages_de_DE.properties b/src/main/resources/messages_de_DE.properties index 26a643fd49..4d43188717 100644 --- a/src/main/resources/messages_de_DE.properties +++ b/src/main/resources/messages_de_DE.properties @@ -452,6 +452,12 @@ login.locked=Ihr Konto wurde gesperrt. login.signinTitle=Bitte melden Sie sich an. login.ssoSignIn=Anmeldung per Single Sign-On login.oauth2AutoCreateDisabled=OAUTH2 Benutzer automatisch erstellen deaktiviert +login.oauth2RequestNotFound=Authorization request not found +login.oauth2AccessDenied=Access Denied +login.oauth2InvalidTokenResponse=Invalid Token Response +login.oauth2RequestNotFound=Authorization Request not found +login.oauth2InvalidUserInfoResponse=Invalid User Info Response +login.oauth2invalidRequest=Invalid Request #auto-redact diff --git a/src/main/resources/messages_el_GR.properties b/src/main/resources/messages_el_GR.properties index 2c4b589dc2..045a9dbe69 100644 --- a/src/main/resources/messages_el_GR.properties +++ b/src/main/resources/messages_el_GR.properties @@ -452,6 +452,11 @@ login.locked=Ο λογαριασμός σας έχει κλειδωθεί. login.signinTitle=Παρακαλώ, συνδεθείτε login.ssoSignIn=Σύνδεση μέσω μοναδικής σύνδεσης login.oauth2AutoCreateDisabled=Απενεργοποιήθηκε ο χρήστης αυτόματης δημιουργίας OAUTH2 +login.oauth2RequestNotFound=Authorization request not found +login.oauth2InvalidUserInfoResponse=Invalid User Info Response +login.oauth2invalidRequest=Invalid Request +login.oauth2AccessDenied=Access Denied +login.oauth2InvalidTokenResponse=Invalid Token Response #auto-redact diff --git a/src/main/resources/messages_en_GB.properties b/src/main/resources/messages_en_GB.properties index 4db7aa9c41..2d4b9043b5 100644 --- a/src/main/resources/messages_en_GB.properties +++ b/src/main/resources/messages_en_GB.properties @@ -452,6 +452,12 @@ login.locked=Your account has been locked. login.signinTitle=Please sign in login.ssoSignIn=Login via Single Sign-on login.oauth2AutoCreateDisabled=OAUTH2 Auto-Create User Disabled +login.oauth2RequestNotFound=Authorization request not found +login.oauth2AccessDenied=Access Denied +login.oauth2InvalidTokenResponse=Invalid Token Response +login.oauth2RequestNotFound=Authorization Request not found +login.oauth2InvalidUserInfoResponse=Invalid User Info Response +login.oauth2invalidRequest=Invalid Request #auto-redact diff --git a/src/main/resources/messages_en_US.properties b/src/main/resources/messages_en_US.properties index fc9ef598c5..f7ec59d73d 100644 --- a/src/main/resources/messages_en_US.properties +++ b/src/main/resources/messages_en_US.properties @@ -452,6 +452,11 @@ login.locked=Your account has been locked. login.signinTitle=Please sign in login.ssoSignIn=Login via Single Sign-on login.oauth2AutoCreateDisabled=OAUTH2 Auto-Create User Disabled +login.oauth2RequestNotFound=Authorization request not found +login.oauth2InvalidUserInfoResponse=Invalid User Info Response +login.oauth2invalidRequest=Invalid Request +login.oauth2AccessDenied=Access Denied +login.oauth2InvalidTokenResponse=Invalid Token Response #auto-redact diff --git a/src/main/resources/messages_es_ES.properties b/src/main/resources/messages_es_ES.properties index c52777748b..468d2c8d7b 100644 --- a/src/main/resources/messages_es_ES.properties +++ b/src/main/resources/messages_es_ES.properties @@ -452,6 +452,11 @@ login.locked=Su cuenta se ha bloqueado. login.signinTitle=Por favor, inicie sesión login.ssoSignIn=Iniciar sesión a través del inicio de sesión único login.oauth2AutoCreateDisabled=Usuario DE creación automática de OAUTH2 DESACTIVADO +login.oauth2RequestNotFound=Authorization request not found +login.oauth2InvalidUserInfoResponse=Invalid User Info Response +login.oauth2invalidRequest=Invalid Request +login.oauth2AccessDenied=Access Denied +login.oauth2InvalidTokenResponse=Invalid Token Response #auto-redact diff --git a/src/main/resources/messages_eu_ES.properties b/src/main/resources/messages_eu_ES.properties index 44a07a11e7..5b875c39ae 100644 --- a/src/main/resources/messages_eu_ES.properties +++ b/src/main/resources/messages_eu_ES.properties @@ -452,6 +452,11 @@ login.locked=Zure kontua blokeatu egin da. login.signinTitle=Mesedez, hasi saioa login.ssoSignIn=Hasi saioa Saioa hasteko modu bakarraren bidez login.oauth2AutoCreateDisabled=OAUTH2 Sortu automatikoki erabiltzailea desgaituta dago +login.oauth2RequestNotFound=Authorization request not found +login.oauth2InvalidUserInfoResponse=Invalid User Info Response +login.oauth2invalidRequest=Invalid Request +login.oauth2AccessDenied=Access Denied +login.oauth2InvalidTokenResponse=Invalid Token Response #auto-redact diff --git a/src/main/resources/messages_fr_FR.properties b/src/main/resources/messages_fr_FR.properties index 26afdb0e2f..0c7e2d0bc2 100644 --- a/src/main/resources/messages_fr_FR.properties +++ b/src/main/resources/messages_fr_FR.properties @@ -452,6 +452,11 @@ login.locked=Votre compte a été verrouillé. login.signinTitle=Veuillez vous connecter login.ssoSignIn=Se connecter via l'authentification unique login.oauth2AutoCreateDisabled=OAUTH2 Création automatique d'utilisateur désactivée +login.oauth2RequestNotFound=Authorization request not found +login.oauth2InvalidUserInfoResponse=Invalid User Info Response +login.oauth2invalidRequest=Invalid Request +login.oauth2AccessDenied=Access Denied +login.oauth2InvalidTokenResponse=Invalid Token Response #auto-redact diff --git a/src/main/resources/messages_hi_IN.properties b/src/main/resources/messages_hi_IN.properties index 8fb9d83010..361d2c1978 100644 --- a/src/main/resources/messages_hi_IN.properties +++ b/src/main/resources/messages_hi_IN.properties @@ -452,6 +452,11 @@ login.locked=आपका खाता लॉक कर दिया गया login.signinTitle=कृपया साइन इन करें login.ssoSignIn=सिंगल साइन - ऑन के ज़रिए लॉग इन करें login.oauth2AutoCreateDisabled=OAUTH2 ऑटो - क्रिएट यूज़र अक्षम किया गया +login.oauth2RequestNotFound=Authorization request not found +login.oauth2InvalidUserInfoResponse=Invalid User Info Response +login.oauth2invalidRequest=Invalid Request +login.oauth2AccessDenied=Access Denied +login.oauth2InvalidTokenResponse=Invalid Token Response #auto-redact diff --git a/src/main/resources/messages_hu_HU.properties b/src/main/resources/messages_hu_HU.properties index 6cb096303c..0f460d69ad 100644 --- a/src/main/resources/messages_hu_HU.properties +++ b/src/main/resources/messages_hu_HU.properties @@ -452,6 +452,11 @@ login.locked=A fiókja zárolva lett! login.signinTitle=Kérjük, jelentkezzen be! login.ssoSignIn=Bejelentkezés egyszeri bejelentkezéssel login.oauth2AutoCreateDisabled=OAUTH2 Felhasználó automatikus létrehozása letiltva +login.oauth2RequestNotFound=Authorization request not found +login.oauth2InvalidUserInfoResponse=Invalid User Info Response +login.oauth2invalidRequest=Invalid Request +login.oauth2AccessDenied=Access Denied +login.oauth2InvalidTokenResponse=Invalid Token Response #auto-redact diff --git a/src/main/resources/messages_id_ID.properties b/src/main/resources/messages_id_ID.properties index 7dee099f47..c978f544d6 100644 --- a/src/main/resources/messages_id_ID.properties +++ b/src/main/resources/messages_id_ID.properties @@ -452,6 +452,11 @@ login.locked=Akun Anda telah dikunci. login.signinTitle=Silakan masuk login.ssoSignIn=Masuk melalui Single Sign - on login.oauth2AutoCreateDisabled=OAUTH2 Buat Otomatis Pengguna Dinonaktifkan +login.oauth2RequestNotFound=Authorization request not found +login.oauth2InvalidUserInfoResponse=Invalid User Info Response +login.oauth2invalidRequest=Invalid Request +login.oauth2AccessDenied=Access Denied +login.oauth2InvalidTokenResponse=Invalid Token Response #auto-redact diff --git a/src/main/resources/messages_it_IT.properties b/src/main/resources/messages_it_IT.properties index 8f023cb308..9c7f131cba 100644 --- a/src/main/resources/messages_it_IT.properties +++ b/src/main/resources/messages_it_IT.properties @@ -452,6 +452,11 @@ login.locked=Il tuo account è stato bloccato. login.signinTitle=Per favore accedi login.ssoSignIn=Accedi tramite Single Sign-on login.oauth2AutoCreateDisabled=Creazione automatica utente OAUTH2 DISABILITATA +login.oauth2RequestNotFound=Authorization request not found +login.oauth2InvalidUserInfoResponse=Invalid User Info Response +login.oauth2invalidRequest=Invalid Request +login.oauth2AccessDenied=Access Denied +login.oauth2InvalidTokenResponse=Invalid Token Response #auto-redact diff --git a/src/main/resources/messages_ja_JP.properties b/src/main/resources/messages_ja_JP.properties index fe06fffc55..a835a71e19 100644 --- a/src/main/resources/messages_ja_JP.properties +++ b/src/main/resources/messages_ja_JP.properties @@ -452,6 +452,11 @@ login.locked=あなたのアカウントはロックされています。 login.signinTitle=サインインしてください login.ssoSignIn=シングルサインオンでログイン login.oauth2AutoCreateDisabled=OAuth 2自動作成ユーザーが無効 +login.oauth2RequestNotFound=Authorization request not found +login.oauth2InvalidUserInfoResponse=Invalid User Info Response +login.oauth2invalidRequest=Invalid Request +login.oauth2AccessDenied=Access Denied +login.oauth2InvalidTokenResponse=Invalid Token Response #auto-redact diff --git a/src/main/resources/messages_ko_KR.properties b/src/main/resources/messages_ko_KR.properties index 02f1993268..a4b09c3c98 100644 --- a/src/main/resources/messages_ko_KR.properties +++ b/src/main/resources/messages_ko_KR.properties @@ -452,6 +452,11 @@ login.locked=계정이 잠겼습니다. login.signinTitle=로그인해 주세요. login.ssoSignIn=싱글사인온을 통한 로그인 login.oauth2AutoCreateDisabled=OAUTH2 사용자 자동 생성 비활성화됨 +login.oauth2RequestNotFound=Authorization request not found +login.oauth2InvalidUserInfoResponse=Invalid User Info Response +login.oauth2invalidRequest=Invalid Request +login.oauth2AccessDenied=Access Denied +login.oauth2InvalidTokenResponse=Invalid Token Response #auto-redact diff --git a/src/main/resources/messages_nl_NL.properties b/src/main/resources/messages_nl_NL.properties index 7352589545..cd1674dede 100644 --- a/src/main/resources/messages_nl_NL.properties +++ b/src/main/resources/messages_nl_NL.properties @@ -452,6 +452,11 @@ login.locked=Je account is geblokkeerd. login.signinTitle=Gelieve in te loggen login.ssoSignIn=Inloggen via Single Sign-on login.oauth2AutoCreateDisabled=OAUTH2 Automatisch aanmaken gebruiker uitgeschakeld +login.oauth2RequestNotFound=Authorization request not found +login.oauth2InvalidUserInfoResponse=Invalid User Info Response +login.oauth2invalidRequest=Invalid Request +login.oauth2AccessDenied=Access Denied +login.oauth2InvalidTokenResponse=Invalid Token Response #auto-redact diff --git a/src/main/resources/messages_pl_PL.properties b/src/main/resources/messages_pl_PL.properties index 6b98571b14..c82910a0d3 100644 --- a/src/main/resources/messages_pl_PL.properties +++ b/src/main/resources/messages_pl_PL.properties @@ -452,6 +452,11 @@ login.locked=Your account has been locked. login.signinTitle=Please sign in login.ssoSignIn=Zaloguj się za pomocą logowania jednokrotnego login.oauth2AutoCreateDisabled=Wyłączono automatyczne tworzenie użytkownika OAUTH2 +login.oauth2RequestNotFound=Authorization request not found +login.oauth2InvalidUserInfoResponse=Invalid User Info Response +login.oauth2invalidRequest=Invalid Request +login.oauth2AccessDenied=Access Denied +login.oauth2InvalidTokenResponse=Invalid Token Response #auto-redact diff --git a/src/main/resources/messages_pt_BR.properties b/src/main/resources/messages_pt_BR.properties index 8f16f1e568..9a859f4ecc 100644 --- a/src/main/resources/messages_pt_BR.properties +++ b/src/main/resources/messages_pt_BR.properties @@ -452,6 +452,11 @@ login.locked=Your account has been locked. login.signinTitle=Please sign in login.ssoSignIn=Iniciar sessão através de início de sessão único login.oauth2AutoCreateDisabled=OAUTH2 Auto-Criar Usuário Desativado +login.oauth2RequestNotFound=Authorization request not found +login.oauth2InvalidUserInfoResponse=Invalid User Info Response +login.oauth2invalidRequest=Invalid Request +login.oauth2AccessDenied=Access Denied +login.oauth2InvalidTokenResponse=Invalid Token Response #auto-redact diff --git a/src/main/resources/messages_pt_PT.properties b/src/main/resources/messages_pt_PT.properties index 94a076f3f1..16b3bf81e2 100644 --- a/src/main/resources/messages_pt_PT.properties +++ b/src/main/resources/messages_pt_PT.properties @@ -452,6 +452,11 @@ login.locked=A sua conta foi bloqueada. login.signinTitle=Introduza os seus dados de acesso login.ssoSignIn=Iniciar sessão através de início de sessão único login.oauth2AutoCreateDisabled=OAUTH2 Criação Automática de Utilizador Desativada +login.oauth2RequestNotFound=Authorization request not found +login.oauth2InvalidUserInfoResponse=Invalid User Info Response +login.oauth2invalidRequest=Invalid Request +login.oauth2AccessDenied=Access Denied +login.oauth2InvalidTokenResponse=Invalid Token Response #auto-redact diff --git a/src/main/resources/messages_ro_RO.properties b/src/main/resources/messages_ro_RO.properties index 7297ddf32a..97a672b516 100644 --- a/src/main/resources/messages_ro_RO.properties +++ b/src/main/resources/messages_ro_RO.properties @@ -452,6 +452,11 @@ login.locked=Your account has been locked. login.signinTitle=Please sign in login.ssoSignIn=Conectare prin conectare unică login.oauth2AutoCreateDisabled=OAUTH2 Creare automată utilizator dezactivată +login.oauth2RequestNotFound=Authorization request not found +login.oauth2InvalidUserInfoResponse=Invalid User Info Response +login.oauth2invalidRequest=Invalid Request +login.oauth2AccessDenied=Access Denied +login.oauth2InvalidTokenResponse=Invalid Token Response #auto-redact diff --git a/src/main/resources/messages_ru_RU.properties b/src/main/resources/messages_ru_RU.properties index 98453a1e05..58a5a21b33 100644 --- a/src/main/resources/messages_ru_RU.properties +++ b/src/main/resources/messages_ru_RU.properties @@ -452,6 +452,11 @@ login.locked=Ваша учетная запись заблокирована. login.signinTitle=Пожалуйста, войдите login.ssoSignIn=Вход через единый вход login.oauth2AutoCreateDisabled=OAUTH2 Автоматическое создание пользователя отключено +login.oauth2RequestNotFound=Authorization request not found +login.oauth2InvalidUserInfoResponse=Invalid User Info Response +login.oauth2invalidRequest=Invalid Request +login.oauth2AccessDenied=Access Denied +login.oauth2InvalidTokenResponse=Invalid Token Response #auto-redact diff --git a/src/main/resources/messages_sk_SK.properties b/src/main/resources/messages_sk_SK.properties index 00970c4a1a..959bf0ef05 100644 --- a/src/main/resources/messages_sk_SK.properties +++ b/src/main/resources/messages_sk_SK.properties @@ -452,6 +452,11 @@ login.locked=Váš účet bol uzamknutý. login.signinTitle=Prosím, prihláste sa login.ssoSignIn=Prihlásiť sa cez Single Sign-on login.oauth2AutoCreateDisabled=Vytváranie používateľa cez OAUTH2 je zakázané +login.oauth2RequestNotFound=Authorization request not found +login.oauth2InvalidUserInfoResponse=Invalid User Info Response +login.oauth2invalidRequest=Invalid Request +login.oauth2AccessDenied=Access Denied +login.oauth2InvalidTokenResponse=Invalid Token Response #auto-redact diff --git a/src/main/resources/messages_sr_LATN_RS.properties b/src/main/resources/messages_sr_LATN_RS.properties index 4ac3d90316..ae4f1386aa 100644 --- a/src/main/resources/messages_sr_LATN_RS.properties +++ b/src/main/resources/messages_sr_LATN_RS.properties @@ -452,6 +452,11 @@ login.locked=Vaš nalog je zaključan. login.signinTitle=Molimo vas da se prijavite login.ssoSignIn=Prijavite se putem jedinstvene prijave login.oauth2AutoCreateDisabled=OAUTH2 automatsko kreiranje korisnika je onemogućeno +login.oauth2RequestNotFound=Authorization request not found +login.oauth2InvalidUserInfoResponse=Invalid User Info Response +login.oauth2invalidRequest=Invalid Request +login.oauth2AccessDenied=Access Denied +login.oauth2InvalidTokenResponse=Invalid Token Response #auto-redact diff --git a/src/main/resources/messages_sv_SE.properties b/src/main/resources/messages_sv_SE.properties index 049325a9b5..e8a9a95524 100644 --- a/src/main/resources/messages_sv_SE.properties +++ b/src/main/resources/messages_sv_SE.properties @@ -452,6 +452,11 @@ login.locked=Your account has been locked. login.signinTitle=Please sign in login.ssoSignIn=Logga in via enkel inloggning login.oauth2AutoCreateDisabled=OAUTH2 Auto-Create User inaktiverad +login.oauth2RequestNotFound=Authorization request not found +login.oauth2InvalidUserInfoResponse=Invalid User Info Response +login.oauth2invalidRequest=Invalid Request +login.oauth2AccessDenied=Access Denied +login.oauth2InvalidTokenResponse=Invalid Token Response #auto-redact diff --git a/src/main/resources/messages_tr_TR.properties b/src/main/resources/messages_tr_TR.properties index fd4660b7ee..f27437bbf9 100644 --- a/src/main/resources/messages_tr_TR.properties +++ b/src/main/resources/messages_tr_TR.properties @@ -452,6 +452,11 @@ login.locked=Hesabınız kilitlendi. login.signinTitle=Lütfen giriş yapınız. login.ssoSignIn=Tek Oturum Açma ile Giriş Yap login.oauth2AutoCreateDisabled=OAUTH2 Otomatik Oluşturma Kullanıcı Devre Dışı Bırakıldı +login.oauth2RequestNotFound=Authorization request not found +login.oauth2InvalidUserInfoResponse=Invalid User Info Response +login.oauth2invalidRequest=Invalid Request +login.oauth2AccessDenied=Access Denied +login.oauth2InvalidTokenResponse=Invalid Token Response #auto-redact diff --git a/src/main/resources/messages_uk_UA.properties b/src/main/resources/messages_uk_UA.properties index c77f63dea1..60b6399add 100644 --- a/src/main/resources/messages_uk_UA.properties +++ b/src/main/resources/messages_uk_UA.properties @@ -452,6 +452,11 @@ login.locked=Ваш обліковий запис заблоковано. login.signinTitle=Будь ласка, увійдіть login.ssoSignIn=Увійти через єдиний вхід login.oauth2AutoCreateDisabled=Автоматичне створення користувача OAUTH2 ВИМКНЕНО +login.oauth2RequestNotFound=Authorization request not found +login.oauth2InvalidUserInfoResponse=Invalid User Info Response +login.oauth2invalidRequest=Invalid Request +login.oauth2AccessDenied=Access Denied +login.oauth2InvalidTokenResponse=Invalid Token Response #auto-redact diff --git a/src/main/resources/messages_zh_CN.properties b/src/main/resources/messages_zh_CN.properties index a94cf9a8c0..9234c06bb5 100644 --- a/src/main/resources/messages_zh_CN.properties +++ b/src/main/resources/messages_zh_CN.properties @@ -452,6 +452,11 @@ login.locked=您的账户已被锁定。 login.signinTitle=请登录 login.ssoSignIn=通过单点登录登录 login.oauth2AutoCreateDisabled=OAUTH2自动创建用户已禁用 +login.oauth2RequestNotFound=Authorization request not found +login.oauth2InvalidUserInfoResponse=Invalid User Info Response +login.oauth2invalidRequest=Invalid Request +login.oauth2AccessDenied=Access Denied +login.oauth2InvalidTokenResponse=Invalid Token Response #auto-redact diff --git a/src/main/resources/messages_zh_TW.properties b/src/main/resources/messages_zh_TW.properties index 0ed9e43a52..51607d5d16 100644 --- a/src/main/resources/messages_zh_TW.properties +++ b/src/main/resources/messages_zh_TW.properties @@ -452,6 +452,11 @@ login.locked=您的帳戶已被鎖定。 login.signinTitle=請登入 login.ssoSignIn=透過織網單一簽入 login.oauth2AutoCreateDisabled=OAUTH2自動建立使用者已停用 +login.oauth2RequestNotFound=Authorization request not found +login.oauth2InvalidUserInfoResponse=Invalid User Info Response +login.oauth2invalidRequest=Invalid Request +login.oauth2AccessDenied=Access Denied +login.oauth2InvalidTokenResponse=Invalid Token Response #auto-redact diff --git a/src/main/resources/settings.yml.template b/src/main/resources/settings.yml.template index c2a201ef7e..f8e9bbbdec 100644 --- a/src/main/resources/settings.yml.template +++ b/src/main/resources/settings.yml.template @@ -19,6 +19,23 @@ security: # 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 system: defaultLocale: 'en-US' # Set the default language (e.g. 'de-DE', 'fr-FR', etc) diff --git a/src/main/resources/templates/login.html b/src/main/resources/templates/login.html index 31bb4531ce..ed67117958 100644 --- a/src/main/resources/templates/login.html +++ b/src/main/resources/templates/login.html @@ -13,8 +13,6 @@ document.addEventListener('modeChanged', function(e) { var mode = e.detail; - setInputMode("username", mode); - setInputMode("password", mode); document.body.classList.remove("light-mode", "dark-mode", "rainbow-mode"); // remove all mode classes first switch (mode) { @@ -117,7 +115,7 @@

Stirling-PDF

- Login Via SSO + Login Via SSO

@@ -126,7 +124,7 @@
-
+
OAuth2: Error Message
@@ -170,5 +168,27 @@
+ \ No newline at end of file From 4dcf2f5870ebee2a49222ae5ce5af4b3ef74b369 Mon Sep 17 00:00:00 2001 From: Ludy87 Date: Sat, 25 May 2024 18:25:13 +0200 Subject: [PATCH 05/13] Update CustomOAuth2LogoutSuccessHandler.java --- .../CustomOAuth2LogoutSuccessHandler.java | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/src/main/java/stirling/software/SPDF/config/security/oauth2/CustomOAuth2LogoutSuccessHandler.java b/src/main/java/stirling/software/SPDF/config/security/oauth2/CustomOAuth2LogoutSuccessHandler.java index 1dca2df9f3..f8b76ab96e 100644 --- a/src/main/java/stirling/software/SPDF/config/security/oauth2/CustomOAuth2LogoutSuccessHandler.java +++ b/src/main/java/stirling/software/SPDF/config/security/oauth2/CustomOAuth2LogoutSuccessHandler.java @@ -37,7 +37,7 @@ public class CustomOAuth2LogoutSuccessHandler extends SimpleUrlLogoutSuccessHand HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException { String param = "logout=true"; - String provider = null; + String registrationId = null; String issuer = null; String clientId = null; @@ -45,21 +45,18 @@ public class CustomOAuth2LogoutSuccessHandler extends SimpleUrlLogoutSuccessHand if (authentication instanceof OAuth2AuthenticationToken) { OAuth2AuthenticationToken oauthToken = (OAuth2AuthenticationToken) authentication; - String registrationId = oauthToken.getAuthorizedClientRegistrationId(); + registrationId = oauthToken.getAuthorizedClientRegistrationId(); - provider = registrationId; - logger.info(registrationId); - Provider pro; try { - pro = oauth.getClient().get(registrationId); - issuer = pro.getIssuer(); - clientId = pro.getClientId(); + Provider provider = oauth.getClient().get(registrationId); + issuer = provider.getIssuer(); + clientId = provider.getClientId(); } catch (Exception e) { e.printStackTrace(); } } else { - provider = oauth.getProvider() != null ? oauth.getProvider() : ""; + registrationId = oauth.getProvider() != null ? oauth.getProvider() : ""; issuer = oauth.getIssuer(); clientId = oauth.getClientId(); } @@ -84,7 +81,7 @@ public class CustomOAuth2LogoutSuccessHandler extends SimpleUrlLogoutSuccessHand logger.info("Session invalidated: " + sessionId); } - switch (provider) { + switch (registrationId) { case "keycloak": // Add Keycloak specific logout URL if needed String logoutUrl = From ce5af5ddde60bb92a2b4e4c1feed4bc5fa867f37 Mon Sep 17 00:00:00 2001 From: Ludy87 Date: Sat, 25 May 2024 20:44:51 +0200 Subject: [PATCH 06/13] Fix: remove dublicate en_GB, missing translation German --- scripts/translation_status.toml | 5 +++ src/main/resources/messages_cs_CZ.properties | 2 +- src/main/resources/messages_de_DE.properties | 45 ++++++++++---------- src/main/resources/messages_en_GB.properties | 5 +-- 4 files changed, 30 insertions(+), 27 deletions(-) diff --git a/scripts/translation_status.toml b/scripts/translation_status.toml index 21fcad822f..633847c9b1 100644 --- a/scripts/translation_status.toml +++ b/scripts/translation_status.toml @@ -13,6 +13,11 @@ ignore = [ 'language.direction', ] +[cs_CZ] +ignore = [ + 'language.direction', +] + [de_DE] ignore = [ 'AddStampRequest.alphabet', diff --git a/src/main/resources/messages_cs_CZ.properties b/src/main/resources/messages_cs_CZ.properties index 7518de8e56..d86d4b84ae 100644 --- a/src/main/resources/messages_cs_CZ.properties +++ b/src/main/resources/messages_cs_CZ.properties @@ -452,7 +452,7 @@ login.locked=Your account has been locked. login.signinTitle=Please sign in login.ssoSignIn=Login via Single Sign-on login.oauth2AutoCreateDisabled=OAUTH2 Auto-Create User Disabled -login.oauth2RequestNotFound=Authorization Request not found +login.oauth2RequestNotFound=Authorization request not found login.oauth2InvalidUserInfoResponse=Invalid User Info Response login.oauth2invalidRequest=Invalid Request login.oauth2AccessDenied=Access Denied diff --git a/src/main/resources/messages_de_DE.properties b/src/main/resources/messages_de_DE.properties index 4d43188717..dea7c393a1 100644 --- a/src/main/resources/messages_de_DE.properties +++ b/src/main/resources/messages_de_DE.properties @@ -59,8 +59,8 @@ deleteCurrentUserMessage=Der aktuell angemeldete Benutzer kann nicht gelöscht w deleteUsernameExistsMessage=Der Benutzername existiert nicht und kann nicht gelöscht werden. downgradeCurrentUserMessage=Die Rolle des aktuellen Benutzers kann nicht herabgestuft werden downgradeCurrentUserLongMessage=Die Rolle des aktuellen Benutzers kann nicht herabgestuft werden. Daher wird der aktuelle Benutzer nicht angezeigt. -userAlreadyExistsOAuthMessage=The user already exists as an OAuth2 user. -userAlreadyExistsWebMessage=The user already exists as an web user. +userAlreadyExistsOAuthMessage=Der Benutzer ist bereits als OAuth2-Benutzer vorhanden. +userAlreadyExistsWebMessage=Der Benutzer ist bereits als Webbenutzer vorhanden. error=Fehler oops=Hoppla! help=Hilfe @@ -71,7 +71,7 @@ visitGithub=GitHub-Repository besuchen donate=Spenden color=Farbe sponsor=Sponsor -info=Info +info=Die Info @@ -105,18 +105,18 @@ pipelineOptions.validateButton=Validieren ############# # NAVBAR # ############# -navbar.favorite=Favorites +navbar.favorite=Favoriten navbar.darkmode=Dunkler Modus -navbar.language=Languages +navbar.language=Sprachen navbar.settings=Einstellungen -navbar.allTools=Tools -navbar.multiTool=Multi Tools -navbar.sections.organize=Organize -navbar.sections.convertTo=Convert to PDF -navbar.sections.convertFrom=Convert from PDF -navbar.sections.security=Sign & Security -navbar.sections.advance=Advanced -navbar.sections.edit=View & Edit +navbar.allTools=Werkzeuge +navbar.multiTool=Multitools +navbar.sections.organize=Organisieren +navbar.sections.convertTo=In PDF konvertieren +navbar.sections.convertFrom=Konvertieren von PDF +navbar.sections.security=Zeichen und Sicherheit +navbar.sections.advance=Fortschrittlich +navbar.sections.edit=Anzeigen und Bearbeiten ############# # SETTINGS # @@ -185,7 +185,7 @@ adminUserSettings.internalApiUser=Interner API-Benutzer adminUserSettings.forceChange=Benutzer dazu zwingen, Benutzernamen/Passwort bei der Anmeldung zu ändern adminUserSettings.submit=Benutzer speichern adminUserSettings.changeUserRole=Benutzerrolle ändern -adminUserSettings.authenticated=Authenticated +adminUserSettings.authenticated=Authentifiziert ############# # HOME-PAGE # @@ -452,12 +452,11 @@ login.locked=Ihr Konto wurde gesperrt. login.signinTitle=Bitte melden Sie sich an. login.ssoSignIn=Anmeldung per Single Sign-On login.oauth2AutoCreateDisabled=OAUTH2 Benutzer automatisch erstellen deaktiviert -login.oauth2RequestNotFound=Authorization request not found -login.oauth2AccessDenied=Access Denied -login.oauth2InvalidTokenResponse=Invalid Token Response -login.oauth2RequestNotFound=Authorization Request not found -login.oauth2InvalidUserInfoResponse=Invalid User Info Response -login.oauth2invalidRequest=Invalid Request +login.oauth2RequestNotFound=Autorisierungsanfrage nicht gefunden +login.oauth2InvalidUserInfoResponse=Ungültige Benutzerinformationsantwort +login.oauth2invalidRequest=ungültige Anfrage +login.oauth2AccessDenied=Zugriff abgelehnt +login.oauth2InvalidTokenResponse=Ungültige Token-Antwort #auto-redact @@ -710,7 +709,7 @@ repair.submit=Reparieren #flatten flatten.title=Abflachen flatten.header=PDFs reduzieren -flatten.flattenOnlyForms=Flatten only forms +flatten.flattenOnlyForms=Nur Formulare abflachen flatten.submit=Abflachen @@ -758,7 +757,7 @@ extractImages.submit=Extrahieren fileToPDF.title=Datei in PDF fileToPDF.header=Beliebige Dateien in PDF konvertieren fileToPDF.credit=Dieser Dienst verwendet LibreOffice und Unoconv für die Dateikonvertierung. -fileToPDF.supportedFileTypesInfo=Supported File types +fileToPDF.supportedFileTypesInfo=Unterstützte Dateitypen fileToPDF.supportedFileTypes=Unterstützte Dateitypen sollten die folgenden enthalten, eine vollständige aktualisierte Liste der unterstützten Formate finden Sie jedoch in der LibreOffice-Dokumentation fileToPDF.submit=In PDF konvertieren @@ -811,7 +810,7 @@ pdfOrganiser.placeholder=(z.B. 1,3,2 oder 4-8,2,10-12 oder 2n-1) #multiTool multiTool.title=PDF-Multitool multiTool.header=PDF-Multitool -multiTool.uploadPrompts=File Name +multiTool.uploadPrompts=Dateiname #view pdf viewPdf.title=PDF anzeigen diff --git a/src/main/resources/messages_en_GB.properties b/src/main/resources/messages_en_GB.properties index 2d4b9043b5..e9f2ad8d83 100644 --- a/src/main/resources/messages_en_GB.properties +++ b/src/main/resources/messages_en_GB.properties @@ -453,11 +453,10 @@ login.signinTitle=Please sign in login.ssoSignIn=Login via Single Sign-on login.oauth2AutoCreateDisabled=OAUTH2 Auto-Create User Disabled login.oauth2RequestNotFound=Authorization request not found -login.oauth2AccessDenied=Access Denied -login.oauth2InvalidTokenResponse=Invalid Token Response -login.oauth2RequestNotFound=Authorization Request not found login.oauth2InvalidUserInfoResponse=Invalid User Info Response login.oauth2invalidRequest=Invalid Request +login.oauth2AccessDenied=Access Denied +login.oauth2InvalidTokenResponse=Invalid Token Response #auto-redact From 41e73e4fd16cc45650451686019c73eb437e85dc Mon Sep 17 00:00:00 2001 From: "GitHub Action action@github.com" Date: Sat, 25 May 2024 19:06:53 +0000 Subject: [PATCH 07/13] :memo: Sync README > Made via sync_files.yml --- README.md | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index a6bf84b15d..fc1b1f37bd 100644 --- a/README.md +++ b/README.md @@ -166,30 +166,30 @@ Stirling PDF currently supports 27! | English (English) (en_GB) | ![100%](https://geps.dev/progress/100) | | English (US) (en_US) | ![100%](https://geps.dev/progress/100) | | Arabic (العربية) (ar_AR) | ![41%](https://geps.dev/progress/41) | -| German (Deutsch) (de_DE) | ![97%](https://geps.dev/progress/97) | +| German (Deutsch) (de_DE) | ![100%](https://geps.dev/progress/100) | | French (Français) (fr_FR) | ![94%](https://geps.dev/progress/94) | -| Spanish (Español) (es_ES) | ![97%](https://geps.dev/progress/97) | -| Simplified Chinese (简体中文) (zh_CN) | ![96%](https://geps.dev/progress/96) | -| Traditional Chinese (繁體中文) (zh_TW) | ![96%](https://geps.dev/progress/96) | -| Catalan (Català) (ca_CA) | ![50%](https://geps.dev/progress/50) | -| Italian (Italiano) (it_IT) | ![99%](https://geps.dev/progress/99) | +| Spanish (Español) (es_ES) | ![96%](https://geps.dev/progress/96) | +| Simplified Chinese (简体中文) (zh_CN) | ![95%](https://geps.dev/progress/95) | +| Traditional Chinese (繁體中文) (zh_TW) | ![95%](https://geps.dev/progress/95) | +| Catalan (Català) (ca_CA) | ![49%](https://geps.dev/progress/49) | +| Italian (Italiano) (it_IT) | ![98%](https://geps.dev/progress/98) | | Swedish (Svenska) (sv_SE) | ![41%](https://geps.dev/progress/41) | | Polish (Polski) (pl_PL) | ![43%](https://geps.dev/progress/43) | | Romanian (Română) (ro_RO) | ![40%](https://geps.dev/progress/40) | -| Korean (한국어) (ko_KR) | ![89%](https://geps.dev/progress/89) | +| Korean (한국어) (ko_KR) | ![88%](https://geps.dev/progress/88) | | Portuguese Brazilian (Português) (pt_BR) | ![62%](https://geps.dev/progress/62) | -| Russian (Русский) (ru_RU) | ![89%](https://geps.dev/progress/89) | -| Basque (Euskara) (eu_ES) | ![65%](https://geps.dev/progress/65) | -| Japanese (日本語) (ja_JP) | ![89%](https://geps.dev/progress/89) | +| Russian (Русский) (ru_RU) | ![88%](https://geps.dev/progress/88) | +| Basque (Euskara) (eu_ES) | ![64%](https://geps.dev/progress/64) | +| Japanese (日本語) (ja_JP) | ![88%](https://geps.dev/progress/88) | | Dutch (Nederlands) (nl_NL) | ![86%](https://geps.dev/progress/86) | -| Greek (Ελληνικά) (el_GR) | ![87%](https://geps.dev/progress/87) | +| Greek (Ελληνικά) (el_GR) | ![86%](https://geps.dev/progress/86) | | Turkish (Türkçe) (tr_TR) | ![99%](https://geps.dev/progress/99) | -| Indonesia (Bahasa Indonesia) (id_ID) | ![80%](https://geps.dev/progress/80) | -| Hindi (हिंदी) (hi_IN) | ![81%](https://geps.dev/progress/81) | +| Indonesia (Bahasa Indonesia) (id_ID) | ![79%](https://geps.dev/progress/79) | +| Hindi (हिंदी) (hi_IN) | ![80%](https://geps.dev/progress/80) | | Hungarian (Magyar) (hu_HU) | ![79%](https://geps.dev/progress/79) | | Bulgarian (Български) (bg_BG) | ![96%](https://geps.dev/progress/96) | -| Sebian Latin alphabet (Srpski) (sr_LATN_RS) | ![82%](https://geps.dev/progress/82) | -| Ukrainian (Українська) (uk_UA) | ![88%](https://geps.dev/progress/88) | +| Sebian Latin alphabet (Srpski) (sr_LATN_RS) | ![81%](https://geps.dev/progress/81) | +| Ukrainian (Українська) (uk_UA) | ![87%](https://geps.dev/progress/87) | | Slovakian (Slovensky) (sk_SK) | ![96%](https://geps.dev/progress/96) | ## Contributing (creating issues, translations, fixing bugs, etc.) From cbb4ccd4b743deaaba5039c35e28327cc7a2a6d9 Mon Sep 17 00:00:00 2001 From: Ludy87 Date: Sat, 25 May 2024 21:10:12 +0200 Subject: [PATCH 08/13] add: multi OAuth2 option README.md, small cosmetic repairs --- CONTRIBUTING.md | 2 +- README.md | 22 ++++++++- .../converters/ConvertImgPDFController.java | 7 ++- .../SPDF/model/ApplicationProperties.java | 3 -- .../resources/static/js/languageSelection.js | 32 ++++++------- src/main/resources/static/js/search.js | 1 - .../templates/convert/pdf-to-pdfa.html | 14 +++--- .../fragments/errorBannerPerPage.html | 18 ++++---- .../resources/templates/fragments/navbar.html | 46 ++++++++----------- .../resources/templates/misc/flatten.html | 2 +- .../resources/templates/misc/print-file.html | 4 +- 11 files changed, 78 insertions(+), 73 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 646bdddbe1..dad8928ded 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -29,7 +29,7 @@ If you would like to add or modify a translation, please see [How to add new lan ## Docs -Documentation for Stirling-PDF is handled in a seperate repository. Please see [Docs repository](https://github.com/Stirling-Tools/Stirling-Tools.github.io) or use "edit this page"-button at the bottom of each page at [https://stirlingtools.com/docs/](https://stirlingtools.com/docs/). +Documentation for Stirling-PDF is handled in a separate repository. Please see [Docs repository](https://github.com/Stirling-Tools/Stirling-Tools.github.io) or use "edit this page"-button at the bottom of each page at [https://stirlingtools.com/docs/](https://stirlingtools.com/docs/). ## Fixing Bugs or Adding a New Feature diff --git a/README.md b/README.md index a6bf84b15d..748bfb1be1 100644 --- a/README.md +++ b/README.md @@ -159,7 +159,7 @@ Please view https://github.com/Stirling-Tools/Stirling-PDF/blob/main/HowToUseOCR ## Supported Languages -Stirling PDF currently supports 27! +Stirling PDF currently supports 28! | Language | Progress | | ------------------------------------------- | -------------------------------------- | @@ -191,6 +191,7 @@ Stirling PDF currently supports 27! | Sebian Latin alphabet (Srpski) (sr_LATN_RS) | ![82%](https://geps.dev/progress/82) | | Ukrainian (Українська) (uk_UA) | ![88%](https://geps.dev/progress/88) | | Slovakian (Slovensky) (sk_SK) | ![96%](https://geps.dev/progress/96) | +| Czech (Česky) (cs_CZ) | ![96%](https://geps.dev/progress/96) | ## Contributing (creating issues, translations, fixing bugs, etc.) @@ -226,7 +227,7 @@ security: 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 (these are defaulted) +# 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) @@ -237,6 +238,23 @@ security: # 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 system: defaultLocale: 'en-US' # Set the default language (e.g. 'de-DE', 'fr-FR', etc) diff --git a/src/main/java/stirling/software/SPDF/controller/api/converters/ConvertImgPDFController.java b/src/main/java/stirling/software/SPDF/controller/api/converters/ConvertImgPDFController.java index 3f880a807f..25c37aadcb 100644 --- a/src/main/java/stirling/software/SPDF/controller/api/converters/ConvertImgPDFController.java +++ b/src/main/java/stirling/software/SPDF/controller/api/converters/ConvertImgPDFController.java @@ -56,7 +56,7 @@ public class ConvertImgPDFController { String filename = Filenames.toSimpleFileName(file.getOriginalFilename()) .replaceFirst("[.][^.]+$", ""); - + result = PdfUtils.convertFromPdf( pdfBytes, @@ -65,10 +65,9 @@ public class ConvertImgPDFController { singleImage, Integer.valueOf(dpi), filename); - - if(result == null || result.length == 0) { - logger.error("resultant bytes for {} is null, error converting ", filename); + if (result == null || result.length == 0) { + logger.error("resultant bytes for {} is null, error converting ", filename); } if (singleImage) { String docName = filename + "." + imageFormat; diff --git a/src/main/java/stirling/software/SPDF/model/ApplicationProperties.java b/src/main/java/stirling/software/SPDF/model/ApplicationProperties.java index c8e74e4064..c2253b2111 100644 --- a/src/main/java/stirling/software/SPDF/model/ApplicationProperties.java +++ b/src/main/java/stirling/software/SPDF/model/ApplicationProperties.java @@ -750,9 +750,6 @@ public class ApplicationProperties { this.googlevisibility = googlevisibility; } - - - @Override public String toString() { return "System [defaultLocale=" diff --git a/src/main/resources/static/js/languageSelection.js b/src/main/resources/static/js/languageSelection.js index 55f0647ebb..788a3420aa 100644 --- a/src/main/resources/static/js/languageSelection.js +++ b/src/main/resources/static/js/languageSelection.js @@ -60,22 +60,22 @@ function handleDropdownItemClick(event) { } document.addEventListener("DOMContentLoaded", function () { - -document.querySelectorAll(".col-lg-2.col-sm-6").forEach((element) => { - const dropdownItems = element.querySelectorAll(".dropdown-item"); - const items = Array.from(dropdownItems).filter(item => !item.querySelector("hr.dropdown-divider")); - - if (items.length <= 2) { - if ( - element.previousElementSibling && - element.previousElementSibling.classList.contains("col-lg-2") && - element.previousElementSibling.classList.contains("nav-item-separator") - ) { - element.previousElementSibling.remove(); - } - element.remove(); - } -}); + + document.querySelectorAll(".col-lg-2.col-sm-6").forEach((element) => { + const dropdownItems = element.querySelectorAll(".dropdown-item"); + const items = Array.from(dropdownItems).filter(item => !item.querySelector("hr.dropdown-divider")); + + if (items.length <= 2) { + if ( + element.previousElementSibling && + element.previousElementSibling.classList.contains("col-lg-2") && + element.previousElementSibling.classList.contains("nav-item-separator") + ) { + element.previousElementSibling.remove(); + } + element.remove(); + } + }); //Sort languages by alphabet const list = Array.from(document.querySelector('.dropdown-menu[aria-labelledby="languageDropdown"]').children).filter( diff --git a/src/main/resources/static/js/search.js b/src/main/resources/static/js/search.js index a5b9d70fb1..aec3e6c18c 100644 --- a/src/main/resources/static/js/search.js +++ b/src/main/resources/static/js/search.js @@ -40,7 +40,6 @@ document.querySelector("#navbarSearchInput").addEventListener("input", function var itemHref = item.getAttribute("href"); var tags = item.getAttribute("data-bs-tags") || ""; // If no tags, default to empty string - if (titleElement && iconElement && itemHref !== "#") { var title = titleElement.innerText; if ( diff --git a/src/main/resources/templates/convert/pdf-to-pdfa.html b/src/main/resources/templates/convert/pdf-to-pdfa.html index 4925751141..654d58febb 100644 --- a/src/main/resources/templates/convert/pdf-to-pdfa.html +++ b/src/main/resources/templates/convert/pdf-to-pdfa.html @@ -20,13 +20,13 @@

-
- - -
+
+ + +

diff --git a/src/main/resources/templates/fragments/errorBannerPerPage.html b/src/main/resources/templates/fragments/errorBannerPerPage.html index eb74361ef1..9121f1b3aa 100644 --- a/src/main/resources/templates/fragments/errorBannerPerPage.html +++ b/src/main/resources/templates/fragments/errorBannerPerPage.html @@ -6,10 +6,10 @@ + + close + +
@@ -23,11 +23,11 @@
diff --git a/src/main/resources/templates/misc/print-file.html b/src/main/resources/templates/misc/print-file.html index 16dc5c3fee..e665139cb8 100644 --- a/src/main/resources/templates/misc/print-file.html +++ b/src/main/resources/templates/misc/print-file.html @@ -19,8 +19,8 @@

Select Printer

- - + +
From befd0974f3b3cdeb97c5bb5e74ffde86cdd9d472 Mon Sep 17 00:00:00 2001 From: wai4y Date: Sun, 26 May 2024 18:05:56 +0900 Subject: [PATCH 09/13] chore: add some Chinese text translation --- src/main/resources/messages_zh_CN.properties | 28 ++++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/main/resources/messages_zh_CN.properties b/src/main/resources/messages_zh_CN.properties index 9234c06bb5..d5535f5e16 100644 --- a/src/main/resources/messages_zh_CN.properties +++ b/src/main/resources/messages_zh_CN.properties @@ -105,18 +105,18 @@ pipelineOptions.validateButton=验证 ############# # NAVBAR # ############# -navbar.favorite=Favorites -navbar.darkmode=暗模式 -navbar.language=Languages +navbar.favorite=收藏 +navbar.darkmode=暗黑模式 +navbar.language=语言 navbar.settings=设置 -navbar.allTools=Tools -navbar.multiTool=Multi Tools -navbar.sections.organize=Organize -navbar.sections.convertTo=Convert to PDF -navbar.sections.convertFrom=Convert from PDF -navbar.sections.security=Sign & Security -navbar.sections.advance=Advanced -navbar.sections.edit=View & Edit +navbar.allTools=工具箱 +navbar.multiTool=多页面工具 +navbar.sections.organize=组织 +navbar.sections.convertTo=转换成PDF +navbar.sections.convertFrom=从PDF转换 +navbar.sections.security=签名和安全 +navbar.sections.advance=高级功能 +navbar.sections.edit=查看和编辑 ############# # SETTINGS # @@ -808,9 +808,9 @@ pdfOrganiser.placeholder=(例如 1,3,2 或 4-8,2,10-12 或 2n-1) #multiTool -multiTool.title=PDF多功能工具 -multiTool.header=PDF多功能工具 -multiTool.uploadPrompts=File Name +multiTool.title=PDF多页面工具 +multiTool.header=PDF多页面工具 +multiTool.uploadPrompts=文件名 #view pdf viewPdf.title=浏览PDF From bbaaaf7ae6271a9b62bf85f12df60bdf2725313c Mon Sep 17 00:00:00 2001 From: albanobattistella <34811668+albanobattistella@users.noreply.github.com> Date: Sun, 26 May 2024 11:58:31 +0200 Subject: [PATCH 10/13] Update messages_it_IT.properties --- src/main/resources/messages_it_IT.properties | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/resources/messages_it_IT.properties b/src/main/resources/messages_it_IT.properties index 9c7f131cba..92c13e6e00 100644 --- a/src/main/resources/messages_it_IT.properties +++ b/src/main/resources/messages_it_IT.properties @@ -452,11 +452,11 @@ login.locked=Il tuo account è stato bloccato. login.signinTitle=Per favore accedi login.ssoSignIn=Accedi tramite Single Sign-on login.oauth2AutoCreateDisabled=Creazione automatica utente OAUTH2 DISABILITATA -login.oauth2RequestNotFound=Authorization request not found -login.oauth2InvalidUserInfoResponse=Invalid User Info Response -login.oauth2invalidRequest=Invalid Request -login.oauth2AccessDenied=Access Denied -login.oauth2InvalidTokenResponse=Invalid Token Response +login.oauth2RequestNotFound=Richiesta di autorizzazione non trovata +login.oauth2InvalidUserInfoResponse=Risposta relativa alle informazioni utente non valida +login.oauth2invalidRequest=Richiesta non valida +login.oauth2AccessDenied=Accesso negato +login.oauth2InvalidTokenResponse=Risposta token non valida #auto-redact From 5e9c780d3142e2a2823cf558af7f966192c87712 Mon Sep 17 00:00:00 2001 From: wai4y Date: Sun, 26 May 2024 21:21:30 +0900 Subject: [PATCH 11/13] chore: revert change for multi tool translation --- src/main/resources/messages_zh_CN.properties | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/resources/messages_zh_CN.properties b/src/main/resources/messages_zh_CN.properties index d5535f5e16..b9c60a4cdb 100644 --- a/src/main/resources/messages_zh_CN.properties +++ b/src/main/resources/messages_zh_CN.properties @@ -110,7 +110,7 @@ navbar.darkmode=暗黑模式 navbar.language=语言 navbar.settings=设置 navbar.allTools=工具箱 -navbar.multiTool=多页面工具 +navbar.multiTool=多功能工具 navbar.sections.organize=组织 navbar.sections.convertTo=转换成PDF navbar.sections.convertFrom=从PDF转换 @@ -808,8 +808,8 @@ pdfOrganiser.placeholder=(例如 1,3,2 或 4-8,2,10-12 或 2n-1) #multiTool -multiTool.title=PDF多页面工具 -multiTool.header=PDF多页面工具 +multiTool.title=PDF多功能工具 +multiTool.header=PDF多功能工具 multiTool.uploadPrompts=文件名 #view pdf From 2dabf8955d159c2ea062e25172204eadb6e947f8 Mon Sep 17 00:00:00 2001 From: "GitHub Action action@github.com" Date: Sun, 26 May 2024 12:47:16 +0000 Subject: [PATCH 12/13] :memo: Sync README > Made via sync_files.yml --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 0b5bfa5709..4f5dbb8dac 100644 --- a/README.md +++ b/README.md @@ -169,10 +169,10 @@ Stirling PDF currently supports 28! | German (Deutsch) (de_DE) | ![100%](https://geps.dev/progress/100) | | French (Français) (fr_FR) | ![94%](https://geps.dev/progress/94) | | Spanish (Español) (es_ES) | ![96%](https://geps.dev/progress/96) | -| Simplified Chinese (简体中文) (zh_CN) | ![95%](https://geps.dev/progress/95) | +| Simplified Chinese (简体中文) (zh_CN) | ![96%](https://geps.dev/progress/96) | | Traditional Chinese (繁體中文) (zh_TW) | ![95%](https://geps.dev/progress/95) | | Catalan (Català) (ca_CA) | ![49%](https://geps.dev/progress/49) | -| Italian (Italiano) (it_IT) | ![98%](https://geps.dev/progress/98) | +| Italian (Italiano) (it_IT) | ![99%](https://geps.dev/progress/99) | | Swedish (Svenska) (sv_SE) | ![41%](https://geps.dev/progress/41) | | Polish (Polski) (pl_PL) | ![43%](https://geps.dev/progress/43) | | Romanian (Română) (ro_RO) | ![40%](https://geps.dev/progress/40) | @@ -191,7 +191,7 @@ Stirling PDF currently supports 28! | Sebian Latin alphabet (Srpski) (sr_LATN_RS) | ![81%](https://geps.dev/progress/81) | | Ukrainian (Українська) (uk_UA) | ![87%](https://geps.dev/progress/87) | | Slovakian (Slovensky) (sk_SK) | ![96%](https://geps.dev/progress/96) | -| Czech (Česky) (cs_CZ) | ![96%](https://geps.dev/progress/96) | +| Czech (Česky) (cs_CZ) | ![94%](https://geps.dev/progress/94) | ## Contributing (creating issues, translations, fixing bugs, etc.) From 37a010369914d8aa15c802a853aa338f09370264 Mon Sep 17 00:00:00 2001 From: Anthony Stirling <77850077+Frooodle@users.noreply.github.com> Date: Sun, 26 May 2024 14:16:29 +0100 Subject: [PATCH 13/13] Update FUNDING.yml --- .github/FUNDING.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index 30a5ce238d..de2e827bee 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -10,4 +10,4 @@ liberapay: # Replace with a single Liberapay username issuehunt: # Replace with a single IssueHunt username otechie: # Replace with a single Otechie username lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry -custom: ['https://paypal.me/froodleplex?country.x=GB&locale.x=en_GB'] # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] +custom: ['https://www.paypal.com/donate/?hosted_button_id=MN7JPG5G6G3JL'] # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']