From c2179ccd63bd476aeeb2b5e265a28ac3147b5455 Mon Sep 17 00:00:00 2001 From: Ludy87 Date: Sat, 25 May 2024 18:19:03 +0200 Subject: [PATCH 1/2] 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 e8433588..d258ea51 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 3b3cdaf3..ce6ce799 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 244efed3..c4748ff9 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 6b6a72c1..c3827bf3 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 ea1b05b2..1dca2df9 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 69900b4a..00000000 --- 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 3a2074a7..b0490fb5 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 ae96d07b..c8e74e40 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 00000000..a8dce446 --- /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 00000000..d0d54827 --- /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 21324a9c..e0c4a51e 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 00000000..991713de --- /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 ec327fcd..c38d74bb 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 69c63c60..3bf590bc 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 938de9b4..1b1da164 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 70ace06f..7518de8e 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?ethn?te) v?echny po?adovan PDF soubory -imgPrompt=Vyberte obrzek(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=Varovn: Tento proces m??e trvat a? minutu, v zvislosti na velikosti souboru -pageOrderPrompt=Vlastn po?ad strnek (Zadejte seznam ?sel strnek odd?lench ?rkou nebo funkci jako nap?. 2n+1): -pageSelectionPrompt=Vlastn po?ad strnek (Zadejte seznam ?sel strnek odd?lench ?rkou jako 1,5,6 nebo funkci jako nap?. 2n+1): -goToPage=Jt +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=Neznm -save=Ulo?it -saveToBrowser=Ulo?it do prohl?e?e -close=Zav?t -filesSelected=vybran soubory -noFavourites=?dn oblben polo?ky -downloadComplete=Stahovn dokon?eno -bored=Nudte se p?i ?ekn? +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=Sthnout PDF +downloadPdf=Stáhnout PDF text=Text font=Font selectFillter=-- Vyberte -- -pageNum=?slo strnky -sizes.small=Mal -sizes.medium=St?edn -sizes.large=Velk -sizes.x-large=Extra velk -error.pdfPassword=PDF dokument je chrn?n heslem a bu? heslo nebylo zadn, nebo bylo nesprvn. +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 jmno +username=Uživatelské jméno password=Heslo -welcome=Vtejte +welcome=Vítejte property=Vlastnost -black=?ern -white=Bl -red=?erven -green=Zelen -blue=Modr -custom=Vlastn... -WorkInProgess=Nedokon?en, nemus fungovat nebo m??e d?lat chyby, prosm, hla?te jakkoliv problmy! -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 sprvn. -usernameExistsMessage=Nov u?ivatelsk jmno ji? existuje. -invalidUsernameMessage=Nesprvn u?ivatelsk jmno, sm obsahovat pouze psmena, ?slice a nsledujc speciln znaky @._+- nebo mus bt validn emailov adresa. -deleteCurrentUserMessage=Nelze smazat aktuln p?ihl?enho u?ivatele. -deleteUsernameExistsMessage=U?ivatelsk jmno neexistuje a nelze ho smazat. -downgradeCurrentUserMessage=Nelze sn?it roli aktulnho u?ivatele. -downgradeCurrentUserLongMessage=Nelze sn?it roli aktulnho u?ivatele. Proto nebude aktuln 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=Jt na domovskou strnku -joinDiscord=P?ipojte se k na?emu Discordu -seeDockerHub=Podvejte 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=Nahrt 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 skenovnm adres?e +pipeline.scanHelp=Pomoc se skenováním adresáře ###################### # Pipeline Options # ###################### -pipelineOptions.header=Nastaven pipeline -pipelineOptions.pipelineNameLabel=Nzev pipeline -pipelineOptions.saveSettings=Ulo?it nastaven operace -pipelineOptions.pipelineNamePrompt=Zadejte zde nzev 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=Sthnout -pipelineOptions.validateButton=Ov??it +pipelineOptions.saveButton=Stáhnout +pipelineOptions.validateButton=Ověřit @@ -105,335 +105,335 @@ pipelineOptions.validateButton=Ov??it ############# # NAVBAR # ############# -navbar.favorite=Oblben -navbar.darkmode=Tmav re?im +navbar.favorite=Oblíbené +navbar.darkmode=Tmavý režim navbar.language=Jazyky -navbar.settings=Nastaven -navbar.allTools=Nstroje -navbar.multiTool=Multifunk?n nstroje +navbar.settings=Nastavení +navbar.allTools=Nástroje +navbar.multiTool=Multifunkční nástroje navbar.sections.organize=Organizovat -navbar.sections.convertTo=P?evst do PDF -navbar.sections.convertFrom=P?evst z PDF -navbar.sections.security=Podpis a Bezpe?nost -navbar.sections.advance=Pokro?il -navbar.sections.edit=Prohldnout 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 aktuln? 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 stahovn (Pro stahovn jednoho souboru bez zipu): -settings.downloadOption.1=Otev?t ve stejnm okn? -settings.downloadOption.2=Otev?t v novm okn? -settings.downloadOption.3=Sthnout soubor -settings.zipThreshold=Zazipuj soubory, kdy? p?ekro? po?et sta?ench soubor? -settings.signOut=Odhlsit -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?vte vchoz p?ihla?ovac daje. Prosm zadejte nov heslo -changeCreds.newUsername=Nov U?ivatelsk Jmno -changeCreds.oldPassword=Aktuln 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 Ovldn -account.changeUsername=Zm?nit U?ivatelsk Jmno -account.newUsername=Nov U?ivatelsk Jmno -account.password=Potvrzovac Heslo -account.oldPassword=Star Heslo -account.newPassword=Nov Heslo -account.changePassword=Zm?nit Heslo -account.confirmNewPassword=Potvrdit Nov Heslo -account.signOut=Odhlsit -account.yourApiKey=V? API Kl? -account.syncTitle=Synchronizovat nastaven prohl?e?e s ?tem -account.settingsCompare=Porovnn 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 Webovho 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?ivatelskho 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 Novho U?ivatele -adminUserSettings.usernameInfo=U?ivatelsk Jmno m??e obsahovat pouze psmena, ?sla a nsledujc speciln znaky @._+- nebo mus bt sprvn 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 lokln? hostovan jednotn kontaktn msto pro v?echny va?e pot?eby ve formtu 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 obrzky -viewPdf.tags=zobrazit,p?e?st,opat?it vysv?tlivkami,text,obrzek +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 nstroj -home.multiTool.desc=Slou?it, Rotovat, P?eskupit, a Odstranit strnky -multiTool.tags=Multifunk?n nstroj,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 vce PDF do jednoho -merge.tags=Seskupit,Operace strnky,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 vce dokument? -split.tags=Operace strnky,rozd?lit,Multi strnka,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=Obrzek do PDF -home.imageToPdf.desc=Konvertovat obrzek (PNG, JPEG, GIF) do PDF. -imageToPdf.tags=konverze,img,jpg,obrzek,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 obrzek -home.pdfToImage.desc=Konvertovat PDF na obrzek. (PNG, JPEG, GIF) -pdfToImage.tags=konverze,img,jpg,obrzek,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 strnky v jakmkoli 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 obrzek -home.addImage.desc=P?id obrzek na dan msto v PDF -addImage.tags=img,jpg,obrzek,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,opakovn,ozna?en,vlastn,autorsk prva,obchodn znmka,img,jpg,obrzek,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 oprvn?n va?eho PDF dokumentu -permissions.tags=p?e?st,pst,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 strnky z Va?eho PDF dokumentu -removePages.tags=Odebrat strnky,Odstranit strnky +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==Nzev,autor,datum,tvorba,?as,vydavatel,vrobce,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?evst soubor do PDF -home.fileToPDF.desc=P?evst tm?? jakkoli soubor do PDF (DOCX, PNG, XLS, PPT, TXT a vce) -fileToPDF.tags=prom?na,formt,dokument,obrzek,snmek,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 obrzk? v rmci PDF a znovu je p?id jako text -ocr.tags=uznn,text,obrzek,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 obrzky -home.extractImages.desc=Extrahuje v?echny obrzky z PDF a ulo? je jako zip -extractImages.tags=obrzek,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?,zachovn +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 formt? Wordu (DOC, DOCX a ODT) -PDFToWord.tags=doc,docx,odt,word,transformace,formt,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 formt? prezentace (PPT, PPTX a ODP) -PDFToPresentation.tags=snmky,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 formtu 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 formtu 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 formtu 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 skenovanch fotografi -home.ScannerImageSplit.desc=Rozd?luje vce fotografi ze skenovan fotografie/PDF -ScannerImageSplit.tags=odd?len,automatick detekce,skeny,vce 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 kreslenm, textem nebo obrzkem -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 przdn strnky -home.removeBlanks.desc=Detekuje a odstran przdn strnky 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 poznmky -home.removeAnnotations.desc=Odstran ve?ker koment?e/poznmky z PDF -removeAnnotations.tags=koment?e,zvrazn?n,poznmky,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 rozdly mezi 2 PDF dokumenty -compare.tags=odli?en,kontrast,zm?ny,analza +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 certifiktem -home.certSign.desc=Podpis PDF s certifiktem/kl?em (PEM/P12) -certSign.tags=autentizace,PEM,P12,oficiln,?ifrovn +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=Vcestrnkov rozlo?en -home.pageLayout.desc=Slou?en vce strnek dokumentu PDF do jedn strnky -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/?klu strnky -home.scalePages.desc=Zm?nit velikost/?klu strnky 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 vce akc na PDF s definic skript? potrub -pipeline.tags=automatizovat,sekvence,skriptovan,dvkov zpracovn +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 strnek -home.add-page-numbers.desc=P?idat ?sla strnek do dokumentu na ur?enm mst? -add-page-numbers.tags=strnkovat,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 zklad? detekovan hlavi?ky -auto-rename.tags=automatick rozpoznn,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 (zachovv 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 strnek -home.autoSplitPDF.desc=Automaticky rozd?lit naskenovan PDF s fyzickm skenerem strnky pomoc QR kdu -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 strnka na PDF -home.URLToPDF.desc=P?evd libovolnou http(s) URL adresu na PDF -URLToPDF.tags=chvat-webu,ulo?it-strnku,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?evd 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?evd 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=Zskat V?ECHNY informace o PDF -home.getPdfInfo.desc=Zskn v?ech mo?nch 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 strnky -home.extractPage.desc=Extrahuje vybran strnky 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 Strnku -home.PdfToSinglePage.desc=Slou? v?echny strnky PDF do jedn velk jedin strnky -PdfToSinglePage.tags=jedna strnka +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 jakkoli 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 zakrv text v PDF na zklad? vstupnho textu -autoRedact.tags=Odstranit,Skryt,?ern?,zakrt,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 formtu 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 strnek 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?ekrt PDF -home.overlay-pdfs.desc=P?ekrv PDF na jinm PDF -overlay-pdfs.tags=P?ekrt +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 strnku PDF na men? horizontln a vertikln 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 raztko do PDF -home.AddStampRequest.desc=P?id textov nebo obrazov raztka na ur?en msta -AddStampRequest.tags=Raztko,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?evd PDF do formt? 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?evd formty 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 strnku -pdfToSinglePage.header=PDF na jednu strnku -pdfToSinglePage.submit=P?evst na jednu strnku +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 strnky -pageExtracter.header=Extrahovat strnky +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=Zskat informace o PDF -getPdfInfo.header=Zskat informace o PDF -getPdfInfo.submit=Zskat informace -getPdfInfo.downloadJson=Sthnout 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?evst -MarkdownToPDF.help=Prce 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?evst -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?ijm soubory HTML a ZIPy obsahujc html/css/obrzky atd. -HTMLToPDF.submit=P?evst -HTMLToPDF.credit=Vyu?v WeasyPrint -HTMLToPDF.zoom=rove? zv?t?en pro zobrazen webov strnky. -HTMLToPDF.pageWidth=??ka strnky v centimetrech. (Przdn pro vchoz) -HTMLToPDF.pageHeight=V?ka strnky v centimetrech. (Przdn pro vchoz) -HTMLToPDF.marginTop=Horn okraj strnky v milimetrech. (Przdn pro vchoz) -HTMLToPDF.marginBottom=Doln okraj strnky v milimetrech. (Przdn pro vchoz) -HTMLToPDF.marginLeft=Lev okraj strnky v milimetrech. (Przdn pro vchoz) -HTMLToPDF.marginRight=Prav okraj strnky v milimetrech. (Przdn pro vchoz) -HTMLToPDF.printBackground=Zobrazit pozad webovch strnek. -HTMLToPDF.defaultHeader=Povolit vchoz zhlav (nzev a ?slo strnky) -HTMLToPDF.cssMediaType=Zm?nit typ mdi CSS strnky. -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=Raztko PDF -AddStampRequest.title=Raztko PDF -AddStampRequest.stampType=Typ raztka -AddStampRequest.stampText=Text raztka -AddStampRequest.stampImage=Obrzek raztka +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 psma/obrzku -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 psma +sanitizePDF.selectText.5=Odstranit písma sanitizePDF.submit=Sanitizovat PDF #addPageNumbers -addPageNumbers.title=P?idat ?sla strnek -addPageNumbers.header=P?idat ?sla strnek +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=Strnky k ?slovn -addPageNumbers.selectText.6=Vlastn text -addPageNumbers.customTextDesc=Vlastn text -addPageNumbers.numberPagesDesc=Kter strnky ?slovat, vchoz je 'v?e', p?ijm tak 1-5 nebo 2,5,9 atd. -addPageNumbers.customNumberDesc=Vchoz je {n}, p?ijm tak 'Strnka {n} z {celkem}', 'Text-{n}', '{n} - {n} -addPageNumbers.submit=P?idat ?sla strnek +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?ejmenovn -auto-rename.header=Automatick p?ejmenovn 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=Sthnout +adjustContrast.download=Stáhnout #crop -crop.title=O?znout -crop.header=O?znout obrzek +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 ns automaticky odd?lit va?e dokumenty. Nevy?aduje manuln 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?itm odd?lovac strnky 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 strnky jsou automaticky detekovny a odstran?ny, co? zaru?uje hledn finln dokument. -autoSplitPDF.formPrompt=Vyberte PDF soubor obsahujc odd?lova?e: -autoSplitPDF.duplexMode=Oboustrann re?im (Skenovn z obou stran) -autoSplitPDF.dividerDownload1=Sthnout 'Automatick odd?lova? minimln.pdf' -autoSplitPDF.dividerDownload2=Sthnout '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=Vcestrnkov rozvr?en -pageLayout.header=Vcestrnkov rozvr?en -pageLayout.pagesPerSheet=Strnek na list: -pageLayout.addBorder=P?idat rme?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 strnky -scalePages.header=Upravit m??tko strnky -scalePages.pageSize=Velikost strnky dokumentu. -scalePages.scaleFactor=rove? p?ibl?en (o?znut) strnky. +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=Podepisovn certifiktem -certSign.header=Podepsat PDF soubor s certifiktem (Probh vvoj) +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=Poznmka: Pokud typ va?eho certifiktu nen na seznamu n?e, prosm, p?eve?te ho na typ Java Keystore (.jks) pou?itm keytool command line tool. Pot vyberte .jks jako typ certifiktu. -certSign.selectKey=Vyberte v? soubor s privtnm kl?em (formt PKCS#8, m??e bt .pem nebo .der): -certSign.selectCert=Vyberte v? soubor s certifiktem (X.509 formt, m??e bt .pem or .der): -certSign.selectP12=Vyberte v? soubor s PKCS#12 Keystore (.p12 nebo .pfx) (Voliteln, m?l by obsahovat v? privtn kl? a certifikt): -certSign.selectJKS=Vyberte v? Java Keystore soubor (.jks nebo .keystore): -certSign.certType=Typ certifiktu -certSign.password=Zadejte heslo k va?emu privtnmu kl?i (pokud je zaheslovan): -certSign.showSig=Ukzat podpis -certSign.reason=D?vod -certSign.location=Umst?n -certSign.name=Nzev +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 przdn strnky -removeBlanks.header=Odebrat przdn strnky -removeBlanks.threshold=Prh b?losti pixel?: -removeBlanks.thresholdDesc=Prh pro zji?t?n jak bl mus bt bl pixel aby byl klasifikovn jako 'bl'. 0 = ?ern, 255 = ?ist? bl. -removeBlanks.whitePercent=Procenta b?losti (%): -removeBlanks.whitePercentDesc=Procenta, kolik pixel? na strnce mus bt blch 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?evst +BookToPDF.credit=Využívá Calibre +BookToPDF.submit=Převést #PDFToBook PDFToBook.title=PDF na knihu PDFToBook.header=PDF na knihu -PDFToBook.selectText.1=Formt -PDFToBook.credit=Vyu?v Calibre -PDFToBook.submit=P?evst +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=Nahrt obrzek +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=Prh hlu: -ScannerImageSplit.selectText.2=Nastav minimln absolutn hel, kter je vy?adovn k oto?en obrzku (vchoz: 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 (vchoz: 30). -ScannerImageSplit.selectText.5=Minimln plocha: -ScannerImageSplit.selectText.6=Nastav minimln plo?n prah pro fotografii (vchoz: 10000). -ScannerImageSplit.selectText.7=Minimln plocha kontury: -ScannerImageSplit.selectText.8=Nastav minimln 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?idanho a odebranho k zabrn?n blch ohrani?en ve vstupu (vchoz: 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 rozpoznvn znak?) -ocr.selectText.1=Vyberte jazyky, kter maj bt detekovny ve formtu PDF (Aktuln? detekovan): -ocr.selectText.2=Vytvo?it textov soubor obsahujc text OCR spolu s PDF s OCR -ocr.selectText.3=Opraveny jsou strnky naskenovny pod ?ikmm hlem tm, ?e jsou zp?tn? oto?eny na msto -ocr.selectText.4=O?istit strnku, aby bylo mn? pravd?podobn, ?e OCR najde text ve zvukovm ?umu. (?dn zm?na vstupu) -ocr.selectText.5=O?istit strnku, aby bylo mn? pravd?podobn, ?e OCR najde text ve zvukovm ?umu, udr?uje ?istotu vstupu. -ocr.selectText.6=Ignorovat strnky, kter obsahuj interaktivn text, provd pouze OCR na strnkch, kter jsou obrzky -ocr.selectText.7=Vynutit OCR, provede OCR na ka?d strnce a odeber ve?ker p?vodn textov prvky -ocr.selectText.8=Normln (Chyba, pokud PDF obsahuje text) -ocr.selectText.9=Dal? nastaven -ocr.selectText.10=Re?im OCR -ocr.selectText.11=Odstranit obrzky po OCR (Odstran V?ECHNY obrzky, u?ite?n pouze jako sou?st kroku konverze) -ocr.selectText.12=Typ vykreslen (Pokro?il) -ocr.help=Prosm, 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 obrzky -extractImages.header=Extrahovat obrzky -extractImages.selectText=Vyberte formt obrzku pro extrahovan obrzky +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?evst jakkoli 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 podporovanch formt? se obra?te na dokumentaci LibreOffice. -fileToPDF.submit=P?evst 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 obrzky) -compress.selectText.4=Automatick re?im - Automaticky upravuje kvalitu pro dosa?en p?esn velikosti PDF -compress.selectText.5=O?ekvan 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 obrzek -addImage.header=P?idat obrzek do PDF -addImage.everyPage=Ka?d strnka? -addImage.upload=P?idat obrzek -addImage.submit=P?idat obrzek +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 vce PDF (2+) -merge.sortByName=Se?adit podle nzvu -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=Organizr strnek -pdfOrganiser.header=Organizr strnek PDF -pdfOrganiser.submit=P?euspo?dat strnky -pdfOrganiser.mode=Md -pdfOrganiser.mode.1=Vlastn po?ad strnek -pdfOrganiser.mode.2=Obrcen 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=Vcefunk?n nstroj pro PDF -multiTool.header=Vcefunk?n nstroj pro PDF -multiTool.uploadPrompts=Nzev 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 strnek -pageRemover.header=Odstran?n strnek z PDF -pageRemover.pagesToDelete=Strnky k odstran?n (Zadejte ?rkami odd?len seznam ?sel strnek) : -pageRemover.submit=Odstranit strnky -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 nsobcch 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 strnky, na kter chcete provst rozd?len -split.desc.2=Jako takov vb?r 1,3,7-9 by rozd?lil 10strnkov dokument na 6 samostatnch PDF soubor? s: -split.desc.3=Dokument ?. 1: Strnka 1 -split.desc.4=Dokument ?. 2: Strnky 2 a 3 -split.desc.5=Dokument ?. 3: Strnky 4, 5, 6 a 7 -split.desc.6=Dokument ?. 4: Strnka 8 -split.desc.7=Dokument ?. 5: Strnka 9 -split.desc.8=Dokument ?. 6: Strnka 10 -split.splitPages=Zadejte strnky, 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=Obrzek na PDF -imageToPDF.header=Obrzek na PDF -imageToPDF.submit=P?evst -imageToPDF.selectLabel=Mo?nosti p?izp?soben obrzku -imageToPDF.fillPage=Vyplnit strnku -imageToPDF.fitDocumentToImage=P?izp?sobit strnku obrzku -imageToPDF.maintainAspectRatio=Zachovat pom?r stran -imageToPDF.selectText.2=Automaticky oto?it PDF -imageToPDF.selectText.3=Vce soubor? (Pouze pokud je vlo?eno vce obrzk?) -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 obrzek -pdfToImage.header=PDF na obrzek -pdfToImage.selectText=Formt obrzku -pdfToImage.singleOrMultiple=Typ vsledku strnky na obrzek -pdfToImage.single=Jeden velk obrzek spojujc v?echny strnky -pdfToImage.multi=Vce obrzk?, jeden obrzek na strnku +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=?ernobl (M??e dojt k ztrt? dat!) -pdfToImage.submit=P?evst +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 ?ifrovn -addPassword.selectText.2=U?ivatelsk heslo -addPassword.selectText.3=Dlka ?ifrovacho kl?e -addPassword.selectText.4=Vy?? hodnoty jsou siln?j?, ale ni?? hodnoty maj lep? kompatibilitu. -addPassword.selectText.5=Povolen oprvn?n (Doporu?uje se pou?vat spole?n? s heslem vlastnka) -addPassword.selectText.6=Zabra?te sestaven dokumentu -addPassword.selectText.7=Zabrnit extrakci obsahu -addPassword.selectText.8=Zabra?te extrakci pro p?stupnost -addPassword.selectText.9=Zabrnit vypl?ovn formul?e -addPassword.selectText.10=Zabra?te pravm -addPassword.selectText.11=Zabrnit prav? poznmek -addPassword.selectText.12=Zabrnit tisku -addPassword.selectText.13=Zabrnit tisku r?znch formt? -addPassword.selectText.14=Heslo vlastnka -addPassword.selectText.15=Omez, co lze s dokumentem provd?t po jeho otev?en (Nen podporovno 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 ktermu 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 psma: +watermark.selectText.3=Velikost písma: watermark.selectText.4=Rotace (0-360): -watermark.selectText.5=??ka mezery (Mezera mezi ka?dm vodoznakem vodorovn?): -watermark.selectText.6=V?ka mezery (Mezera mezi ka?dm 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=Obrzek vodoznaku: -watermark.submit=P?idat vodoznak +watermark.selectText.9=Obrázek vodoznaku: +watermark.submit=Přidat vodoznak watermark.type.1=Text -watermark.type.2=Obrzek +watermark.type.2=Obrázek #Change permissions -permissions.title=Zm?nit oprvn?n -permissions.header=Zm?nit oprvn?n -permissions.warning=Upozorn?n: Chcete-li mt tato oprvn?n nezm?niteln, doporu?uje se je nastavit heslem prost?ednictvm strnky P?idat heslo. -permissions.selectText.1=Vyberte PDF ke zm?n? oprvn?n -permissions.selectText.2=Oprvn?n k nastaven -permissions.selectText.3=Zabrnit sestaven dokumentu -permissions.selectText.4=Zabrnit extrakci obsahu -permissions.selectText.5=Zabrnit extrakci pro p?stupnost -permissions.selectText.6=Zabrnit vypl?ovn formul?e -permissions.selectText.7=Zabrnit pravm -permissions.selectText.8=Zabrnit prav? poznmek -permissions.selectText.9=Zabrnit tisku -permissions.selectText.10=Zabrnit tisku r?znch formt? -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?ifrovn +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 formtu PDF/A -pdfToPDFA.submit=P?evst -pdfToPDFA.tip=V sou?asn dob? nepracuje pro vce vstup? najednou -pdfToPDFA.outputFormat=Vstupn formt +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=Formt vstupnho souboru -PDFToWord.credit=Tato slu?ba pou?v LibreOffice pro konverzi soubor?. -PDFToWord.submit=P?evst +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=Formt vstupnho souboru -PDFToPresentation.credit=Tato slu?ba pou?v LibreOffice pro konverzi soubor?. -PDFToPresentation.submit=P?evst +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=Formt vstupnho souboru -PDFToText.credit=Tato slu?ba pou?v LibreOffice pro konverzi soubor?. -PDFToText.submit=P?evst +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?evst +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?evst +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 strnku 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 strnek -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?ekrt soubory PDF -overlay-pdfs.baseFile.label=Vyberte zkladn 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 opakovn p?ekryt -overlay-pdfs.counts.label=P?ekryt po?et (pro re?im pevnho opakovn) -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 pln -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=Horizontln d?len -split-by-sections.vertical.label=Vertikln d?len -split-by-sections.horizontal.placeholder=Zadejte po?et horizontlnch d?len -split-by-sections.vertical.placeholder=Zadejte po?et vertiklnch 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 tiskrnu +printFile.header=Tisknout soubor na tiskárnu printFile.selectText.1=Vyberte soubor k tisku -printFile.selectText.2=Zadejte nzev tiskrny +printFile.selectText.2=Zadejte název tiskárny printFile.submit=Tisknout #licenses -licenses.nav=License -licenses.title=Licence t?etch stran -licenses.header=Licence t?etch 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=Omlouvme se za pot?e! -error.needHelp=Pot?ebujete pomoc / Na?li jste problm? -error.contactTip=Pokud stle mte pot?e, nevhejte ns kontaktovat o pomoc. M??ete nm odeslat po?adavek na na? strnce na GitHubu nebo ns kontaktovat p?es Discord: -error.404.head=404 - Strnka nebyla nalezena | Oops, zakopli jsme v kdu! -error.404.1=Neda? se nm najt strnku, kterou hledte. -error.404.2=N?co se nepovedlo -error.github=Odeslat po?adavek na GitHubu -error.showStack=Zobrazit stopu zsobnku -error.copyStack=Koprovat stopu zsobnku -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 26a643fd..4d431887 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 2c4b589d..045a9dbe 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 4db7aa9c..2d4b9043 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 fc9ef598..f7ec59d7 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 c5277774..468d2c8d 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 44a07a11..5b875c39 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 26afdb0e..0c7e2d0b 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 8fb9d830..361d2c19 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 6cb09630..0f460d69 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 7dee099f..c978f544 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 8f023cb3..9c7f131c 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 fe06fffc..a835a71e 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 02f19932..a4b09c3c 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 73525895..cd1674de 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 6b98571b..c82910a0 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 8f16f1e5..9a859f4e 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 94a076f3..16b3bf81 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 7297ddf3..97a672b5 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 98453a1e..58a5a21b 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 00970c4a..959bf0ef 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 4ac3d903..ae4f1386 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 049325a9..e8a9a955 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 fd4660b7..f27437bb 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 c77f63de..60b6399a 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 a94cf9a8..9234c06b 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 0ed9e43a..51607d5d 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 c2a201ef..f8e9bbbd 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 31bb4531..ed671179 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 2/2] 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 1dca2df9..f8b76ab9 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 =