diff options
Diffstat (limited to 'connector/src')
12 files changed, 345 insertions, 214 deletions
diff --git a/connector/src/main/java/at/asitplus/eidas/specific/connector/config/StaticResourceConfiguration.java b/connector/src/main/java/at/asitplus/eidas/specific/connector/config/StaticResourceConfiguration.java index 9367c69f..34b9d2fa 100644 --- a/connector/src/main/java/at/asitplus/eidas/specific/connector/config/StaticResourceConfiguration.java +++ b/connector/src/main/java/at/asitplus/eidas/specific/connector/config/StaticResourceConfiguration.java @@ -1,25 +1,25 @@ -/* - * Copyright 2014 Federal Chancellery Austria - * MOA-ID has been developed in a cooperation between BRZ, the Federal - * Chancellery Austria - ICT staff unit, and Graz University of Technology. +/******************************************************************************* + * Copyright 2019 A-SIT Plus GmbH + * AT-specific eIDAS Connector has been developed in a cooperation between EGIZ, + * A-SIT Plus GmbH, A-SIT, and Graz University of Technology. * - * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: - * http://www.osor.eu/eupl/ + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "License"); + * You may not use this work except in compliance with the License. + * You may obtain a copy of the License at: + * https://joinup.ec.europa.eu/news/understanding-eupl-v12 * * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, + * distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. + * See the License for the specific language governing permissions and + * limitations under the License. * * This product combines work with different licenses. See the "NOTICE" text * file for details on the various modules and licenses. * The "NOTICE" text file is part of the distribution. Any derivative works * that you distribute must include a readable copy of the "NOTICE" text file. - */ + *******************************************************************************/ package at.asitplus.eidas.specific.connector.config; import java.net.MalformedURLException; @@ -28,10 +28,14 @@ import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.context.support.ReloadableResourceBundleMessageSource; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; +import org.springframework.web.servlet.i18n.CookieLocaleResolver; +import org.thymeleaf.templateresolver.FileTemplateResolver; import at.asitplus.eidas.specific.connector.MSeIDASNodeConstants; import at.gv.egiz.eaaf.core.api.idp.IConfiguration; @@ -49,6 +53,8 @@ public class StaticResourceConfiguration extends WebMvcConfigurerAdapter { "/" }; + private static final String DEFAULT_MESSAGE_SOURCE = "classpath:properties/status_messages"; + @Autowired private IConfiguration basicConfig; @@ -73,7 +79,83 @@ public class StaticResourceConfiguration extends WebMvcConfigurerAdapter { } registry.addResourceHandler("/**").addResourceLocations(CLASSPATH_RESOURCE_LOCATIONS); + + } + + @Bean + public ReloadableResourceBundleMessageSource internalMessageSource(){ + final ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource(); + + //add default message source + messageSource.setBasename(DEFAULT_MESSAGE_SOURCE); + messageSource.setDefaultEncoding("UTF-8"); + return messageSource; + + } + + @Bean + public ReloadableResourceBundleMessageSource messageSource(){ + final ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource(); + messageSource.setDefaultEncoding("UTF-8"); + messageSource.setParentMessageSource(internalMessageSource()); + + final String staticResources = basicConfig.getBasicConfiguration(MSeIDASNodeConstants.PROP_CONFIG_WEBCONTENT_PROPERTIES_PATH); + try { + if (StringUtils.isNotEmpty(staticResources)) { + final String absPath = FileUtils.makeAbsoluteURL(staticResources , basicConfig.getConfigurationRootDirectory()); + messageSource.setBasename(absPath); + + } else + log.debug("No Ressourcefolder for dynamic Web content templates"); + + } catch (final MalformedURLException e) { + log.warn("Can NOT initialize ressourcefolder for dynamic Web content templates", e); + + } + + return messageSource; + + } + + @Bean + public CookieLocaleResolver localeResolver(){ + final CookieLocaleResolver localeResolver = new CookieLocaleResolver(); + localeResolver.setCookieName("currentLanguage"); + localeResolver.setCookieMaxAge(3600); + return localeResolver; + } - + @Bean(name="templateResolver") + public FileTemplateResolver templateResolver() { + final String staticResources = basicConfig.getBasicConfiguration(MSeIDASNodeConstants.PROP_CONFIG_WEBCONTENT_TEMPLATES_PATH); + try { + if (StringUtils.isNotEmpty(staticResources)) { + String absPath = FileUtils.makeAbsoluteURL(staticResources , basicConfig.getConfigurationRootDirectory()); + if (!absPath.endsWith("/")) + absPath += "/"; + + if (absPath.startsWith("file:")) + absPath = absPath.substring("file:".length()); + + final FileTemplateResolver viewResolver = new FileTemplateResolver(); + viewResolver.setPrefix(absPath); + viewResolver.setSuffix(".html"); + viewResolver.setTemplateMode("HTML5"); + viewResolver.setCacheable(false); + + log.info("Add Ressourcefolder: " + absPath + " for dynamic Web content templates"); + return viewResolver ; + + } else + log.debug("No Ressourcefolder for dynamic Web content templates"); + + } catch (final MalformedURLException e) { + log.warn("Can NOT initialize ressourcefolder for dynamic Web content templates", e); + + } + + //TODO: implement some backup solution + return null; + } } diff --git a/connector/src/main/java/at/asitplus/eidas/specific/connector/processes/tasks/EvaluateCountrySelectionTask.java b/connector/src/main/java/at/asitplus/eidas/specific/connector/processes/tasks/EvaluateCountrySelectionTask.java index 8e32f00e..91cf6515 100644 --- a/connector/src/main/java/at/asitplus/eidas/specific/connector/processes/tasks/EvaluateCountrySelectionTask.java +++ b/connector/src/main/java/at/asitplus/eidas/specific/connector/processes/tasks/EvaluateCountrySelectionTask.java @@ -33,51 +33,42 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; -import at.asitplus.eidas.specific.connector.MSConnectorEventCodes; import at.asitplus.eidas.specific.connector.MSeIDASNodeConstants; import at.gv.egiz.eaaf.core.api.data.EAAFConstants; import at.gv.egiz.eaaf.core.api.idp.process.ExecutionContext; import at.gv.egiz.eaaf.core.exceptions.TaskExecutionException; -import at.gv.egiz.eaaf.core.impl.idp.auth.modules.AbstractAuthServletTask; +import at.gv.egiz.eaaf.core.impl.idp.controller.tasks.AbstractLocaleAuthServletTask; /** * @author tlenz * */ @Component("EvaluateCountrySelectionTask") -public class EvaluateCountrySelectionTask extends AbstractAuthServletTask { +public class EvaluateCountrySelectionTask extends AbstractLocaleAuthServletTask { private static final Logger log = LoggerFactory.getLogger(EvaluateCountrySelectionTask.class); @Override - public void execute(ExecutionContext executionContext, HttpServletRequest request, HttpServletResponse response) + public void executeWithLocale(ExecutionContext executionContext, HttpServletRequest request, HttpServletResponse response) throws TaskExecutionException { try { - - String stopAuthFlag = request.getParameter(MSeIDASNodeConstants.REQ_PARAM_STOP_PROCESS); - if (StringUtils.isNotEmpty(stopAuthFlag) && Boolean.parseBoolean(stopAuthFlag)) { - log.info("Authentication process WAS stopped by entity. Stopping auth. process ... "); - revisionsLogger.logEvent(pendingReq, MSConnectorEventCodes.PROCESS_STOPPED_BY_USER); - pendingReq.setAbortedByUser(true); - pendingReq.setAuthenticated(false); - - } else { - // set parameter execution context - Enumeration<String> reqParamNames = request.getParameterNames(); - while(reqParamNames.hasMoreElements()) { - String paramName = reqParamNames.nextElement(); - if (StringUtils.isNotEmpty(paramName) && - !EAAFConstants.PROCESS_ENGINE_PENDINGREQUESTID.equalsIgnoreCase(paramName)) { - for (String el : MSeIDASNodeConstants.COUNTRY_SELECTION_PARAM_WHITELIST) { - if (el.equalsIgnoreCase(paramName)) - executionContext.put(paramName, - StringEscapeUtils.escapeHtml(request.getParameter(paramName))); - } + + // set parameter execution context + Enumeration<String> reqParamNames = request.getParameterNames(); + while(reqParamNames.hasMoreElements()) { + String paramName = reqParamNames.nextElement(); + if (StringUtils.isNotEmpty(paramName) && + !EAAFConstants.PROCESS_ENGINE_PENDINGREQUESTID.equalsIgnoreCase(paramName)) { + for (String el : MSeIDASNodeConstants.COUNTRY_SELECTION_PARAM_WHITELIST) { + if (el.equalsIgnoreCase(paramName)) + executionContext.put(paramName, + StringEscapeUtils.escapeHtml(request.getParameter(paramName))); } - } - log.info("Country selection finished. Starting auth. process for country ... "); - - } + } + } + + log.info("Country selection finished. Starting auth. process for country ... "); + } catch (Exception e) { log.warn("EvaluateBKUSelectionTask has an internal error", e); diff --git a/connector/src/main/java/at/asitplus/eidas/specific/connector/processes/tasks/GenerateCountrySelectionFrameTask.java b/connector/src/main/java/at/asitplus/eidas/specific/connector/processes/tasks/GenerateCountrySelectionFrameTask.java index a707c827..49dd6b02 100644 --- a/connector/src/main/java/at/asitplus/eidas/specific/connector/processes/tasks/GenerateCountrySelectionFrameTask.java +++ b/connector/src/main/java/at/asitplus/eidas/specific/connector/processes/tasks/GenerateCountrySelectionFrameTask.java @@ -34,7 +34,7 @@ import at.asitplus.eidas.specific.connector.MSConnectorEventCodes; import at.asitplus.eidas.specific.connector.MSeIDASNodeConstants; import at.asitplus.eidas.specific.connector.gui.StaticGuiBuilderConfiguration; import at.gv.egiz.eaaf.core.api.gui.IGUIBuilderConfiguration; -import at.gv.egiz.eaaf.core.api.gui.IGUIFormBuilder; +import at.gv.egiz.eaaf.core.api.gui.ISpringMVCGUIFormBuilder; import at.gv.egiz.eaaf.core.api.idp.IConfiguration; import at.gv.egiz.eaaf.core.api.idp.process.ExecutionContext; import at.gv.egiz.eaaf.core.exceptions.EAAFException; @@ -50,7 +50,7 @@ import at.gv.egiz.eaaf.core.impl.idp.auth.modules.AbstractAuthServletTask; public class GenerateCountrySelectionFrameTask extends AbstractAuthServletTask { private static final Logger log = LoggerFactory.getLogger(GenerateCountrySelectionFrameTask.class); - @Autowired IGUIFormBuilder guiBuilder; + @Autowired ISpringMVCGUIFormBuilder guiBuilder; @Autowired IConfiguration basicConfig; @Override diff --git a/connector/src/main/java/at/asitplus/eidas/specific/connector/storage/CacheWitheIDASBackend.java b/connector/src/main/java/at/asitplus/eidas/specific/connector/storage/CacheWitheIDASBackend.java index 560ae592..4bcced82 100644 --- a/connector/src/main/java/at/asitplus/eidas/specific/connector/storage/CacheWitheIDASBackend.java +++ b/connector/src/main/java/at/asitplus/eidas/specific/connector/storage/CacheWitheIDASBackend.java @@ -22,34 +22,29 @@ *******************************************************************************/ package at.asitplus.eidas.specific.connector.storage; -import java.util.ArrayList; -import java.util.Date; -import java.util.Iterator; -import java.util.List; +import eu.eidas.auth.commons.cache.ConcurrentCacheService; +import eu.eidas.auth.commons.tx.AbstractCache; -import eu.eidas.auth.commons.cache.ConcurrentMapService; -import eu.eidas.auth.commons.tx.AbstractCorrelationMap; +public class CacheWitheIDASBackend extends AbstractCache<String, TransactionStoreElement> { -public class CacheWitheIDASBackend extends AbstractCorrelationMap<TransactionStoreElement> { - - protected CacheWitheIDASBackend(ConcurrentMapService concurrentMapService) { + protected CacheWitheIDASBackend(ConcurrentCacheService concurrentMapService) { super(concurrentMapService); } - public List<String> clean(Date now, long dataTimeOut) { - List<String> result = new ArrayList<String>(); - Iterator<String> iterator = map.keySet().iterator(); - while (iterator.hasNext()) { - String key = iterator.next(); - if (map.containsKey(key)) { - TransactionStoreElement element = map.get(key); - if (now.getTime() - element.getCreated().getTime() > dataTimeOut) - result.add(key); - } - } - - return result; - - } +// public List<String> clean(Date now, long dataTimeOut) { +// List<String> result = new ArrayList<String>(); +// Iterator<String> iterator = map.keySet().iterator(); +// while (iterator.hasNext()) { +// String key = iterator.next(); +// if (map.containsKey(key)) { +// TransactionStoreElement element = map.get(key); +// if (now.getTime() - element.getCreated().getTime() > dataTimeOut) +// result.add(key); +// } +// } +// +// return result; +// +// } } diff --git a/connector/src/main/java/at/asitplus/eidas/specific/connector/storage/eIDASCacheTransactionStoreDecorator.java b/connector/src/main/java/at/asitplus/eidas/specific/connector/storage/eIDASCacheTransactionStoreDecorator.java index 04a8f6fd..270d0e31 100644 --- a/connector/src/main/java/at/asitplus/eidas/specific/connector/storage/eIDASCacheTransactionStoreDecorator.java +++ b/connector/src/main/java/at/asitplus/eidas/specific/connector/storage/eIDASCacheTransactionStoreDecorator.java @@ -22,6 +22,7 @@ *******************************************************************************/ package at.asitplus.eidas.specific.connector.storage; +import java.util.Arrays; import java.util.Date; import java.util.List; @@ -43,6 +44,7 @@ public class eIDASCacheTransactionStoreDecorator implements ITransactionStorage{ if (containsKey(oldKey)) { TransactionStoreElement el = storage.get(oldKey); el.setKey(newKey); + el.setData(value); storage.put(newKey, el); storage.remove(oldKey); @@ -53,19 +55,14 @@ public class eIDASCacheTransactionStoreDecorator implements ITransactionStorage{ @Override public List<String> clean(Date now, long dataTimeOut) { - return storage.clean(now, dataTimeOut); + log.info("Clean is NOT implemented, because its not needed"); + return Arrays.asList(); } @Override - public boolean containsKey(String key) { - if (key != null) { - if (storage.get(key) != null) - return true; - - } - - return false; + public boolean containsKey(String key) { + return storage.containsKey(key); } diff --git a/connector/src/main/resources/applicationContext.xml b/connector/src/main/resources/applicationContext.xml index 709b699f..9105bb56 100644 --- a/connector/src/main/resources/applicationContext.xml +++ b/connector/src/main/resources/applicationContext.xml @@ -22,6 +22,9 @@ <mvc:interceptors> <bean class="at.asitplus.eidas.specific.connector.interceptor.WebFrontEndSecurityInterceptor" /> + <bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor"> + <property name="paramName" value="lang" /> + </bean> </mvc:interceptors> <context:property-placeholder location="${eidas.ms.configuration}"/> diff --git a/connector/src/main/resources/processes/CountrySelection.process.xml b/connector/src/main/resources/processes/CountrySelection.process.xml index e4e23e64..575bbf0d 100644 --- a/connector/src/main/resources/processes/CountrySelection.process.xml +++ b/connector/src/main/resources/processes/CountrySelection.process.xml @@ -8,6 +8,8 @@ <pd:StartEvent id="start" /> <pd:Transition from="start" to="initializeCountrySelection" /> <pd:Transition from="initializeCountrySelection" to="parseCountrySelection" /> + + <pd:Transition from="parseCountrySelection" to="initializeCountrySelection" conditionExpression="ctx['changeLanguage']"/> <pd:Transition from="parseCountrySelection" to="restartAuthProzessManagement" /> <pd:Transition from="restartAuthProzessManagement" to="end" /> <pd:EndEvent id="end" /> diff --git a/connector/src/main/resources/specific_eIDAS_connector.beans.xml b/connector/src/main/resources/specific_eIDAS_connector.beans.xml index a1abca76..32b1685d 100644 --- a/connector/src/main/resources/specific_eIDAS_connector.beans.xml +++ b/connector/src/main/resources/specific_eIDAS_connector.beans.xml @@ -72,11 +72,11 @@ <bean id="eaafProtocolAuthenticationService" class="at.gv.egiz.eaaf.core.impl.idp.auth.services.ProtocolAuthenticationService"> - <property name="guiBuilder" ref="DefaultGUIBuilderImpl"/> + <property name="guiBuilder" ref="mvcGUIBuilderImpl"/> </bean> - <bean id="simplePendingReqIdGenerationStrategy" - class="at.gv.egiz.eaaf.core.impl.utils.SimplePendingRequestIdGenerationStrategy"/> + <bean id="securePendingRequestIdGeneration" + class="at.gv.egiz.eaaf.core.impl.utils.SecurePendingRequestIdGenerationStrategy"/> <bean id="PVPMetadataProvider" class="at.asitplus.eidas.specific.connector.provider.PVPMetadataProvider" /> @@ -89,10 +89,24 @@ <bean id="GUIBuilderConfigurationFactory" class="at.asitplus.eidas.specific.connector.gui.GUIBuilderConfigurationFactory" /> + + <bean id="velocityGUIBuilderImpl" + class="at.asitplus.eidas.specific.connector.gui.DefaultVelocityGUIBuilderImpl"/> - <bean id="DefaultGUIBuilderImpl" - class="at.asitplus.eidas.specific.connector.gui.DefaultGUIBuilderImpl"/> - + <bean id="mvcGUIBuilderImpl" + class="at.asitplus.eidas.specific.connector.gui.SpringMVCGUIFormBuilderImpl"/> + + <bean id="templateEngine" + class="org.thymeleaf.spring5.SpringTemplateEngine"> + <property name="templateResolver" ref="templateResolver" /> + </bean> + + <bean class="org.thymeleaf.spring5.view.ThymeleafViewResolver"> + <property name="order" value="2"/> + <property name="templateEngine" ref="templateEngine" /> + <property name="characterEncoding" value="UTF-8"/> + </bean> + <bean id="StatusMessageProvider" class="at.asitplus.eidas.specific.connector.provider.StatusMessageProvider" /> diff --git a/connector/src/main/resources/specific_eIDAS_connector.storage.beans.xml b/connector/src/main/resources/specific_eIDAS_connector.storage.beans.xml index fa05dc9b..a460dea6 100644 --- a/connector/src/main/resources/specific_eIDAS_connector.storage.beans.xml +++ b/connector/src/main/resources/specific_eIDAS_connector.storage.beans.xml @@ -12,17 +12,7 @@ http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd"> <import resource="classpath:specificCommunicationDefinitionApplicationContext.xml"/> - - <bean id="useDistributedMapsSpecificConnector" class="java.lang.String"> - <constructor-arg value="${eidas.ms.context.use.clustermode}"/> - </bean> - - <!-- suffix for some of the beans having two possible implementations - one for development and one for production --> - <bean id="distributedEnvSuffixSpecificConnector" class="java.lang.String"> - <constructor-arg value="#{useDistributedMapsSpecificConnector.toString()=='false'?'Dev':'Prod'}"/> - </bean> - - + <!-- <bean id="SimpleInMemoryTransactionStorage" class="at.asitplus.eidas.specific.connector.storage.SimpleInMemoryTransactionStorage" /> --> @@ -30,10 +20,16 @@ class="at.asitplus.eidas.specific.connector.storage.eIDASCacheTransactionStoreDecorator"/> <bean id="CacheWitheIDASBackend" class="at.asitplus.eidas.specific.connector.storage.CacheWitheIDASBackend"> - <constructor-arg ref="springServiceCMapspecificMSSpCorProvider#{distributedEnvSuffixSpecificConnector.toString()}"/> + <constructor-arg ref="msNodeCacheImpl"/> </bean> - <bean id="defaultHazelcastInstance" class="java.lang.String"> + <bean id="msNodeCacheImpl" class="eu.eidas.auth.cache.ConcurrentCacheServiceIgniteSpecificCommunicationImpl"> + <property name="igniteInstanceInitializerSpecificCommunication" ref="eidasIgniteInstanceInitializerSpecificCommunication"/> + <property name="cacheName" value="msConnectorCache"/> + </bean> + + + <!-- bean id="defaultHazelcastInstance" class="java.lang.String"> <constructor-arg value="eidasHazelcastInstance"/> </bean> @@ -50,6 +46,6 @@ <bean id="springServiceCMapspecificMSSpCorProviderDev" class="eu.eidas.auth.commons.cache.ConcurrentMapServiceDefaultImpl"> <property name="expireAfterAccess" value="1800"/> <property name="maximumSize" value="1000"/> - </bean> + </bean --> </beans>
\ No newline at end of file diff --git a/connector/src/main/resources/templates/countrySelection.html b/connector/src/main/resources/templates/countrySelection.html index 9ea9c08e..3937b464 100644 --- a/connector/src/main/resources/templates/countrySelection.html +++ b/connector/src/main/resources/templates/countrySelection.html @@ -1,219 +1,255 @@ <!DOCTYPE html> -<html> +<html xmlns:th="http://www.thymeleaf.org" + xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" + layout:decorator="fragments/base" + th:with="lang=${#locale.language}" th:lang="${lang}"> + <head> <meta content="text/html; charset=utf-8" http-equiv="Content-Type"> <meta name="viewport" content="width=device-width, initial-scale=1"> - <link rel="stylesheet" href="$contextPath/css/css_country.css"/> - - -<title>eIDAS-Login</title> + <link rel="stylesheet" href="$contextPath/static/css/css_country.css" th:href="@{/static/css/css_country.css}"/> + <script type="text/javascript" src="$contextPath/static/js/js_country.js" th:attr="src=@{/static/static/js/js_country.js}"></script> + <title th:text="#{gui.countryselection.title}">eIDAS-Login Länderauswahl</title> </head> + <body> <div id="page"> - <h2> Select your country </h2> + <div class="languageselection" th:include="language_selection :: selectlanguage"> + LanguageSelectionBlock + </div> + + <h2 th:text="#{gui.countryselection.header.selection}"> Select your country </h2> <div id="country"> <form class="block" method="post" action="$contextPath$submitEndpoint"> - <img class="countryimage" src="$contextPath/img/countries/Belgium-EU_.png" alt="Belgium-eID"/> - <input type="submit" value="Belgium"> + <a><img class="countryimage" src="$contextPath/img/countries/Belgium-EU.png" alt="Belgium-eID" + th:attr="src=@{img/countries/Belgium-EU.png},alt=#{gui.countryselection.country.be.logo.alt}"/></a> + <input type="submit" value="Belgium" th:attr="value=#{gui.countryselection.country.be}"> <input type="hidden" name="selectedCountry" value="BE"> - <input type="hidden" name="pendingid" value="$pendingReqID"> + <input type="hidden" name="pendingid" value="$pendingid" th:attr="value=${pendingid}" /> </form> <form class="block" method="post" action="$contextPath$submitEndpoint"> - <img class="countryimage" src="$contextPath/img/countries/Bulgaria-EU_.png" alt="Bulgaria-eID"/> - <input type="submit" value="Bulgaria"> + <a><img class="countryimage" src="$contextPath/img/countries/Bulgaria-EU.png" alt="Bulgaria-eID" + th:attr="src=@{img/countries/Bulgaria-EU.png},alt=#{gui.countryselection.country.bg.logo.alt}"/></a> + <input type="submit" value="Bulgaria" th:attr="value=#{gui.countryselection.country.bg}" > <input type="hidden" name="selectedCountry" value="BG"> - <input type="hidden" name="pendingid" value="$pendingReqID"> + <input type="hidden" name="pendingid" value="$pendingid" th:attr="value=${pendingid}" /> </form> <form class="block" method="post" action="$contextPath$submitEndpoint"> - <img class="countryimage" src="$contextPath/img/countries/Croatia-EU_.png" alt="Croatia-eID"/> - <input type="submit" value="Croatia"> + <a><img class="countryimage" src="$contextPath/img/countries/Croatia-EU.png" alt="Croatia-eID" + th:attr="src=@{img/countries/Croatia-EU.png},alt=#{gui.countryselection.country.hr.logo.alt}"/></a> + <input type="submit" value="Croatia" th:attr="value=#{gui.countryselection.country.hr}"> <input type="hidden" name="selectedCountry" value="HR"> - <input type="hidden" name="pendingid" value="$pendingReqID"> + <input type="hidden" name="pendingid" value="$pendingid" th:attr="value=${pendingid}" /> </form> <form class="block" method="post" action="$contextPath$submitEndpoint"> - <img class="countryimage" src="$contextPath/img/countries/Cyprus-EU_.png" alt="Cyprus-eID"/> - <input type="submit" value="Cyprus"> + <a><img class="countryimage" src="$contextPath/img/countries/Cyprus-EU.png" alt="Cyprus-eID" + th:attr="src=@{img/countries/Cyprus-EU.png},alt=#{gui.countryselection.country.cy.logo.alt}"/></a> + <input type="submit" value="Cyprus" th:attr="value=#{gui.countryselection.country.cy}"> <input type="hidden" name="selectedCountry" value="CY"> - <input type="hidden" name="pendingid" value="$pendingReqID"> + <input type="hidden" name="pendingid" value="$pendingid" th:attr="value=${pendingid}" /> </form> <form class="block" method="post" action="$contextPath$submitEndpoint"> - <img class="countryimage" src="$contextPath/img/countries/CzechRepublic-EU_.png" alt="CzechRepublic-eID"/> - <input type="submit" value="Czech Republic"> + <a><img class="countryimage" src="$contextPath/img/countries/CzechRepublic-EU.png" alt="CzechRepublic-eID" + th:attr="src=@{img/countries/CzechRepublic-EU.png},alt=#{gui.countryselection.country.cz.logo.alt}"/></a> + <input type="submit" value="CzechRepublic" th:attr="value=#{gui.countryselection.country.cz}"> <input type="hidden" name="selectedCountry" value="CZ"> - <input type="hidden" name="pendingid" value="$pendingReqID"> + <input type="hidden" name="pendingid" value="$pendingid" th:attr="value=${pendingid}" /> </form> <form class="block" method="post" action="$contextPath$submitEndpoint"> - <img class="countryimage" src="$contextPath/img/countries/Denmark-EU_.png" alt="Denmark-eID"/> - <input type="submit" value="Denmark"> + <a><img class="countryimage" src="$contextPath/img/countries/Denmark-EU.png" alt="Denmark-eID" + th:attr="src=@{img/countries/Denmark-EU.png},alt=#{gui.countryselection.country.dk.logo.alt}"/></a> + <input type="submit" value="Denmark" th:attr="value=#{gui.countryselection.country.dk}"> <input type="hidden" name="selectedCountry" value="DK"> - <input type="hidden" name="pendingid" value="$pendingReqID"> + <input type="hidden" name="pendingid" value="$pendingid" th:attr="value=${pendingid}" /> </form> <form class="block" method="post" action="$contextPath$submitEndpoint"> - <img class="countryimage" src="$contextPath/img/countries/germany-eu_.png" alt="Germany-eID"/> - <input type="submit" value="Germany" role="button" id="button"> + <a><img class="countryimage" src="$contextPath/img/countries/germany-eu_.png" alt="Germany-eID" + th:attr="src=@{img/countries/germany-eu_.png},alt=#{gui.countryselection.country.de.logo.alt}"/></a> + <input type="submit" role="button" value="Deutschland / Germany" th:attr="value=#{gui.countryselection.country.de}" /> <input type="hidden" name="selectedCountry" value="DE"> - <input type="hidden" name="pendingid" value="$pendingReqID"> + <input type="hidden" name="pendingid" value="$pendingid" th:attr="value=${pendingid}" /> </form> <form class="block" method="post" action="$contextPath$submitEndpoint"> - <img class="countryimage" src="$contextPath/img/countries/Estonia-EU_.png" alt="Estonia-eID"/> - <input type="submit" value="Estonia"> + <a><img class="countryimage" src="$contextPath/img/countries/Estonia-EU.png" alt="Estonia-eID" + th:attr="src=@{img/countries/Estonia-EU.png},alt=#{gui.countryselection.country.ee.logo.alt}"/></a> + <input type="submit" value="Estonia" th:attr="value=#{gui.countryselection.country.ee}"> <input type="hidden" name="selectedCountry" value="EE"> - <input type="hidden" name="pendingid" value="$pendingReqID"> + <input type="hidden" name="pendingid" value="$pendingid" th:attr="value=${pendingid}" /> </form> <form class="block" method="post" action="$contextPath$submitEndpoint"> - <img class="countryimage" src="$contextPath/img/countries/Finland-EU_.png" alt="Finland-eID"/> - <input type="submit" value="Finland"> + <a><img class="countryimage" src="$contextPath/img/countries/Finland-EU.png" alt="Finland-eID" + th:attr="src=@{img/countries/Finland-EU.png},alt=#{gui.countryselection.country.fi.logo.alt}"/></a> + <input type="submit" value="Finland" th:attr="value=#{gui.countryselection.country.fi}"> <input type="hidden" name="selectedCountry" value="FI"> - <input type="hidden" name="pendingid" value="$pendingReqID"> + <input type="hidden" name="pendingid" value="$pendingid" th:attr="value=${pendingid}" /> </form> <form class="block" method="post" action="$contextPath$submitEndpoint"> - <img class="countryimage" src="$contextPath/img/countries/France-EU_.png" alt="France-eID"/> - <input type="submit" value="France"> + <a><img class="countryimage" src="$contextPath/img/countries/France-EU.png" alt="France-eID" + th:attr="src=@{img/countries/France-EU.png},alt=#{gui.countryselection.country.fr.logo.alt}"/></a> + <input type="submit" value="France" th:attr="value=#{gui.countryselection.country.fr}"> <input type="hidden" name="selectedCountry" value="FR"> - <input type="hidden" name="pendingid" value="$pendingReqID"> + <input type="hidden" name="pendingid" value="$pendingid" th:attr="value=${pendingid}" /> </form> <form class="block" method="post" action="$contextPath$submitEndpoint"> - <img class="countryimage" src="$contextPath/img/countries/Greece-EU_.png" alt="Greece-eID"/> - <input type="submit" value="Greece"> + <a><img class="countryimage" src="$contextPath/img/countries/Greece-EU.png" alt="Greece-eID" + th:attr="src=@{img/countries/Greece-EU.png},alt=#{gui.countryselection.country.gr.logo.alt}"/></a> + <input type="submit" value="Greece" th:attr="value=#{gui.countryselection.country.gr}"> <input type="hidden" name="selectedCountry" value="GR"> - <input type="hidden" name="pendingid" value="$pendingReqID"> + <input type="hidden" name="pendingid" value="$pendingid" th:attr="value=${pendingid}" /> </form> <form class="block" method="post" action="$contextPath$submitEndpoint"> - <img class="countryimage" src="$contextPath/img/countries/Hungary-EU_.png" alt="Hungary-eID"/> - <input type="submit" value="Hungary"> + <a><img class="countryimage" src="$contextPath/img/countries/Hungary-EU.png" alt="Hungary-eID" + th:attr="src=@{img/countries/Hungary-EU.png},alt=#{gui.countryselection.country.hu.logo.alt}"/></a> + <input type="submit" value="Hungary" th:attr="value=#{gui.countryselection.country.hu}"> <input type="hidden" name="selectedCountry" value="HU"> - <input type="hidden" name="pendingid" value="$pendingReqID"> + <input type="hidden" name="pendingid" value="$pendingid" th:attr="value=${pendingid}" /> </form> <form class="block" method="post" action="$contextPath$submitEndpoint"> - <img class="countryimage" src="$contextPath/img/countries/Iceland.png" alt="Italy-eID"/> - <input type="submit" value="Iceland"> + <a><img class="countryimage" src="$contextPath/img/countries/Ireland-EU.png" alt="Ireland-eID" + th:attr="src=@{img/countries/Iceland.png},alt=#{gui.countryselection.country.is.logo.alt}"/></a> + <input type="submit" value="Ireland" th:attr="value=#{gui.countryselection.country.is}"/> <input type="hidden" name="selectedCountry" value="IS"> - <input type="hidden" name="pendingid" value="$pendingReqID"> + <input type="hidden" name="pendingid" value="$pendingid" th:attr="value=${pendingid}" /> </form> <form class="block" method="post" action="$contextPath$submitEndpoint"> - <img class="countryimage" src="$contextPath/img/countries/Ireland-EU_.png" alt="Ireland-eID"/> - <input type="submit" value="Ireland"> + <a><img class="countryimage" src="$contextPath/img/countries/Ireland-EU.png" alt="Ireland-eID" + th:attr="src=@{img/countries/Ireland-EU.png},alt=#{gui.countryselection.country.ir.logo.alt}"/></a> + <input type="submit" value="Ireland" th:attr="value=#{gui.countryselection.country.ir}"> <input type="hidden" name="selectedCountry" value="IE"> - <input type="hidden" name="pendingid" value="$pendingReqID"> + <input type="hidden" name="pendingid" value="$pendingid" th:attr="value=${pendingid}" /> </form> <form class="block" method="post" action="$contextPath$submitEndpoint"> - <img class="countryimage" src="$contextPath/img/countries/Italy-EU_.png" alt="Italy-eID"/> - <input type="submit" value="Italy"> + <a><img class="countryimage" src="$contextPath/img/countries/Italy-EU.png" alt="Italy-eID" + th:attr="src=@{img/countries/Italy-EU.png},alt=#{gui.countryselection.country.it.logo.alt}"/></a> + <input type="submit" value="Italy" th:attr="value=#{gui.countryselection.country.it}"> <input type="hidden" name="selectedCountry" value="IT"> - <input type="hidden" name="pendingid" value="$pendingReqID"> + <input type="hidden" name="pendingid" value="$pendingid" th:attr="value=${pendingid}" /> </form> <form class="block" method="post" action="$contextPath$submitEndpoint"> - <img class="countryimage" src="$contextPath/img/countries/Latvia-EU_.png" alt="Latvia-eID"/> - <input type="submit" value="Latvia"> + <a><img class="countryimage" src="$contextPath/img/countries/Latvia-EU.png" alt="Latvia-eID" + th:attr="src=@{img/countries/Latvia-EU.png},alt=#{gui.countryselection.country.lv.logo.alt}"/></a> + <input type="submit" value="Latvia" th:attr="value=#{gui.countryselection.country.lv}"> <input type="hidden" name="selectedCountry" value="LV"> - <input type="hidden" name="pendingid" value="$pendingReqID"> + <input type="hidden" name="pendingid" value="$pendingid" th:attr="value=${pendingid}" /> </form> <form class="block" method="post" action="$contextPath$submitEndpoint"> - <img class="countryimage" src="$contextPath/img/countries/Lithuania-EU_.png" alt="Latvia-eID"/> - <input type="submit" value="Lithuania"> + <a><img class="countryimage" src="$contextPath/img/countries/Luxembourg-EU.png" alt="Luxembourg-eID" + th:attr="src=@{img/countries/Luxembourg-EU.png},alt=#{gui.countryselection.country.lu.logo.alt}"/></a> + <input type="submit" value="Luxembourg" th:attr="value=#{gui.countryselection.country.lu}"> <input type="hidden" name="selectedCountry" value="LT"> - <input type="hidden" name="pendingid" value="$pendingReqID"> + <input type="hidden" name="pendingid" value="$pendingid" th:attr="value=${pendingid}" /> </form> <form class="block" method="post" action="$contextPath$submitEndpoint"> - <img class="countryimage" src="$contextPath/img/countries/Luxembourg-EU_.png" alt="Luxembourg-eID"/> - <input type="submit" value="Luxembourg"> + <a><img class="countryimage" src="$contextPath/img/countries/Luxembourg-EU.png" alt="Luxembourg-eID" + th:attr="src=@{img/countries/Luxembourg-EU.png},alt=#{gui.countryselection.country.lu.logo.alt}"/></a> + <input type="submit" value="Luxembourg" th:attr="value=#{gui.countryselection.country.lu}"> <input type="hidden" name="selectedCountry" value="LU"> - <input type="hidden" name="pendingid" value="$pendingReqID"> + <input type="hidden" name="pendingid" value="$pendingid" th:attr="value=${pendingid}" /> </form> <form class="block" method="post" action="$contextPath$submitEndpoint"> - <img class="countryimage" src="$contextPath/img/countries/Malta-EU_.png" alt="Malta-eID"/> - <input type="submit" value="Malta"> + <a><img class="countryimage" src="$contextPath/img/countries/Malta-EU.png" alt="Malta-eID" + th:attr="src=@{img/countries/Malta-EU.png},alt=#{gui.countryselection.country.mt.logo.alt}"/></a> + <input type="submit" value="Malta" th:attr="value=#{gui.countryselection.country.mt}"> <input type="hidden" name="selectedCountry" value="MT"> - <input type="hidden" name="pendingid" value="$pendingReqID"> + <input type="hidden" name="pendingid" value="$pendingid" th:attr="value=${pendingid}" /> </form> <form class="block" method="post" action="$contextPath$submitEndpoint"> - <img class="countryimage" src="$contextPath/img/countries/TheNetherlands-EU_.png" alt="Netherlands-eID"/> - <input type="submit" value="Netherlands"> + <a><img class="countryimage" src="$contextPath/img/countries/TheNetherlands-EU_.png" alt="Netherlands-eID" + th:attr="src=@{img/countries/TheNetherlands-EU_.png},alt=#{gui.countryselection.country.nl.logo.alt}"/></a> + <input type="submit" value="Netherlands" th:attr="value=#{gui.countryselection.country.nl}"> <input type="hidden" name="selectedCountry" value="NL"> - <input type="hidden" name="pendingid" value="$pendingReqID"> + <input type="hidden" name="pendingid" value="$pendingid" th:attr="value=${pendingid}" /> </form> <form class="block" method="post" action="$contextPath$submitEndpoint"> - <img class="countryimage" src="$contextPath/img/countries/Poland-EU_.png" alt="Poland-eID"/> - <input type="submit" value="Poland"> - <input type="hidden" name="selectedCountry" value="PL"> - <input type="hidden" name="pendingid" value="$pendingReqID"> + <a><img class="countryimage" src="$contextPath/img/countries/Poland-EU.png" alt="Poland-eID" + th:attr="src=@{img/countries/Poland-EU.png},alt=#{gui.countryselection.country.pl.logo.alt}"/></a> + <input type="submit" value="Poland" th:attr="value=#{gui.countryselection.country.pl}"> + <input type="hidden" name="selectedCountry" value="PL"> + <input type="hidden" name="pendingid" value="$pendingid" th:attr="value=${pendingid}" /> </form> <form class="block" method="post" action="$contextPath$submitEndpoint"> - <img class="countryimage" src="$contextPath/img/countries/Portugal-EU_.png" alt="Portugal-eID"/> - <input type="submit" value="Portugal"> + <a><img class="countryimage" src="$contextPath/img/countries/Portugal-EU.png" alt="Portugal-eID" + th:attr="src=@{img/countries/Portugal-EU.png},alt=#{gui.countryselection.country.pt.logo.alt}"/></a> + <input type="submit" value="Portugal" th:attr="value=#{gui.countryselection.country.pt}"> <input type="hidden" name="selectedCountry" value="PT"> - <input type="hidden" name="pendingid" value="$pendingReqID"> + <input type="hidden" name="pendingid" value="$pendingid" th:attr="value=${pendingid}" /> </form> <form class="block" method="post" action="$contextPath$submitEndpoint"> - <img class="countryimage" src="$contextPath/img/countries/Romania-EU_.png" alt="Romania-eID"/> - <input type="submit" value="Romania"> + <a><img class="countryimage" src="$contextPath/img/countries/Romania-EU.png" alt="Romania-eID" + th:attr="src=@{img/countries/Romania-EU.png},alt=#{gui.countryselection.country.ro.logo.alt}"/></a> + <input type="submit" value="Romania" th:attr="value=#{gui.countryselection.country.ro}"> <input type="hidden" name="selectedCountry" value="RO"> - <input type="hidden" name="pendingid" value="$pendingReqID"> + <input type="hidden" name="pendingid" value="$pendingid" th:attr="value=${pendingid}" /> </form> <form class="block" method="post" action="$contextPath$submitEndpoint"> - <img class="countryimage" src="$contextPath/img/countries/Slovakia-EU_.png" alt="Slovakia-eID"/> - <input type="submit" value="Slovakia"> + <a><img class="countryimage" src="$contextPath/img/countries/Slovakia-EU.png" alt="Slovakia-eID" + th:attr="src=@{img/countries/Slovakia-EU.png},alt=#{gui.countryselection.country.sk.logo.alt}"/></a> + <input type="submit" value="Slovakia" th:attr="value=#{gui.countryselection.country.sk}"> <input type="hidden" name="selectedCountry" value="SK"> - <input type="hidden" name="pendingid" value="$pendingReqID"> + <input type="hidden" name="pendingid" value="$pendingid" th:attr="value=${pendingid}" /> </form> <form class="block" method="post" action="$contextPath$submitEndpoint"> - <img class="countryimage" src="$contextPath/img/countries/Slovenia-EU_.png" alt="Slovenia-eID"/> - <input type="submit" value="Slovenia"> + <a><img class="countryimage" src="$contextPath/img/countries/Slovenia-EU.png" alt="Slovenia-eID" + th:attr="src=@{img/countries/Slovenia-EU.png},alt=#{gui.countryselection.country.si.logo.alt}"/></a> + <input type="submit" value="Slovenia" th:attr="value=#{gui.countryselection.country.si}"> <input type="hidden" name="selectedCountry" value="SI"> - <input type="hidden" name="pendingid" value="$pendingReqID"> + <input type="hidden" name="pendingid" value="$pendingid" th:attr="value=${pendingid}" /> </form> <form class="block" method="post" action="$contextPath$submitEndpoint"> - <img class="countryimage" src="$contextPath/img/countries/Spain-EU_.png" alt="Spain-eID"/> - <input type="submit" value="Spain"> + <a><img class="countryimage" src="$contextPath/img/countries/Spain-EU.png" alt="Spain-eID" + th:attr="src=@{img/countries/Spain-EU.png},alt=#{gui.countryselection.country.es.logo.alt}"/></a> + <input type="submit" value="Spain" th:attr="value=#{gui.countryselection.country.es}"> <input type="hidden" name="selectedCountry" value="ES"> - <input type="hidden" name="pendingid" value="$pendingReqID"> + <input type="hidden" name="pendingid" value="$pendingid" th:attr="value=${pendingid}" /> </form> <form class="block" method="post" action="$contextPath$submitEndpoint"> - <img class="countryimage" src="$contextPath/img/countries/Sweden-EU_.png" alt="Sweden-eID"/> - <input type="submit" value="Sweden"> + <a><img class="countryimage" src="$contextPath/img/countries/Sweden-EU.png" alt="Sweden-eID" + th:attr="src=@{img/countries/Sweden-EU.png},alt=#{gui.countryselection.country.se.logo.alt}"/></a> + <input type="submit" value="Sweden" th:attr="value=#{gui.countryselection.country.se}"> <input type="hidden" name="selectedCountry" value="SE"> - <input type="hidden" name="pendingid" value="$pendingReqID"> + <input type="hidden" name="pendingid" value="$pendingid" th:attr="value=${pendingid}" /> </form> <form class="block" method="post" action="$contextPath$submitEndpoint"> - <img class="countryimage" src="$contextPath/img/countries/UnitedKingdom-EU_.png" alt="UnitedKingdom-eID"/> - <input type="submit" value="United Kingdom"> + <a><img class="countryimage" src="$contextPath/img/countries/UnitedKingdom-EU.png" alt="UnitedKingdom-eID" + th:attr="src=@{img/countries/UnitedKingdom-EU.png},alt=#{gui.countryselection.country.uk.logo.alt}"/></a> + <input type="submit" value="United Kingdom" th:attr="value=#{gui.countryselection.country.uk}"> <input type="hidden" name="selectedCountry" value="UK"> - <input type="hidden" name="pendingid" value="$pendingReqID"> + <input type="hidden" name="pendingid" value="$pendingid" th:attr="value=${pendingid}" /> </form> - <form class="block" method="post" action="$contextPath$submitEndpoint"> - <input type="submit" value="Abbrechen/Cancel"> - <input type="hidden" name="stopAuthProcess" value="true"> - <input type="hidden" name="pendingid" value="$pendingReqID"> - </form> + <form class="block" method="post" action="$contextPath$submitEndpoint" th:attr="action=@{${submitEndpoint}}"> + <input type="submit" class="btn btn-outline-primary btn-block" value="Abbrechen/Cancel" th:attr="value=#{gui.countryselection.cancle}"> + <input type="hidden" name="stopAuthProcess" value="true" > + <input type="hidden" name="pendingid" value="$pendingid" th:attr="value=${pendingid}"> + </form> </div> </div> </body> diff --git a/connector/src/main/resources/templates/error_message.html b/connector/src/main/resources/templates/error_message.html index fc9b75a1..86f9d29d 100644 --- a/connector/src/main/resources/templates/error_message.html +++ b/connector/src/main/resources/templates/error_message.html @@ -1,36 +1,36 @@ -<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"> -<head> +<!DOCTYPE HTML> +<html xmlns:th="http://www.thymeleaf.org" + xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" + layout:decorator="fragments/base" + th:with="lang=${#locale.language}" th:lang="${lang}"> + <meta content="text/html; charset=utf-8" http-equiv="Content-Type"> - <link rel="stylesheet" href="$contextPath/css/css_error.css" /> + <link rel="stylesheet" href="$contextPath/css/css_error.css" th:href="@{/css/css_error.css}" /> - <title>An error arise ... </title> + <title th:text="#{gui.errorpage.msg.title}">An error arise ... </title> </head> <body> <div id="page"> <div id="page1" class="case selected-case" role="main"> <h2 class="OA_header" role="heading">Authentication error arise</h2> - <!--div id="main"--> - <!--div id="leftcontent" class="hell" role="application"--> - - - + <div class="hell" role="application" > - <p>The authentication stops on account of a process error:</p> - <br/> - <p><b>Error Code:</b> $errorCode</p> - <p><b>Error Message:</b >$errorMsg</p> + <h2 class="OA_header" role="heading" th:text="#{gui.errorpage.msg.title}">Error Header</h2> + + <div id="alert_area" class="hell" role="application" > + <p th:text="#{gui.errorpage.msg.information}">Error Information</p> + <br/> + <p><b th:text="#{gui.errorpage.msg.errorcode}">Code :</b> <span th:text="${errorCode}"></span></p> + <p><b th:text="#{gui.errorpage.msg.errormsg}">Msg :</b > <span th:text="${#messages.msgWithParams('__${errorCode}__', '__${errorParams}__')}"></span></p> + </div> + <!-- errorMsg --> </div> + <div th:if="${stacktrace}"> + <p><b th:text="#{gui.errorpage.msg.stacktrace}">fullError</b> <span th:text="${stacktrace}"></span></p> + </div> - #if($stacktrace) - <div> - <p><b>Stacktrace:</b> $stacktrace</p> - </div> - #end - - <!--/div---> - <!--/div--> </div> </div> </body> diff --git a/connector/src/main/resources/templates/language_selection.html b/connector/src/main/resources/templates/language_selection.html new file mode 100644 index 00000000..a268eb17 --- /dev/null +++ b/connector/src/main/resources/templates/language_selection.html @@ -0,0 +1,15 @@ +<!DOCTYPE html SYSTEM "http://www.thymeleaf.org/dtd/xhtml1-strict-thymeleaf-4.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" + xmlns:th="http://www.thymeleaf.org"> + + <body> + + <div th:fragment="selectlanguage"> + <a th:href="@{|${submitEndpoint}?pendingid=${pendingid}|(lang='de')}" th:text="#{gui.general.language.selection.de}">Spache1</a> + <span> </span> + <a th:href="@{|${submitEndpoint}?pendingid=${pendingid}|(lang='en')}" th:text="#{gui.general.language.selection.en}">Spache2</a> + </div> + + </body> + +</html>
\ No newline at end of file |