From f26e2ba75a7d9cb1ee53deec720e1e13b627b544 Mon Sep 17 00:00:00 2001
From: ffalqui
Date: Thu, 26 Mar 2026 18:54:10 +0100
Subject: [PATCH 1/5] ESB-1041 Fix HTTPS mixed content in iframe widget config
and fix jpwebdynamicform configui assignment
Replace request.getRequestURL() with UrlUtils.determineFrontendURL() in KeycloakFilter (login/logout redirects) and KcRequestAuthorizator (authorization redirect) so that OAuth redirect URIs respect X-Forwarded-Proto and ENTANDO_APP_USE_TLS behind reverse proxies.
---
.../entando/keycloak/filter/KeycloakFilter.java | 4 ++--
.../services/control/KcRequestAuthorizator.java | 3 ++-
.../keycloak/filter/KeycloakFilterTest.java | 17 +++--------------
.../port/00000000000001_dataPort.xml | 2 +-
4 files changed, 8 insertions(+), 18 deletions(-)
diff --git a/keycloak-plugin/src/main/java/org/entando/entando/keycloak/filter/KeycloakFilter.java b/keycloak-plugin/src/main/java/org/entando/entando/keycloak/filter/KeycloakFilter.java
index 3f67b9ef4..b1696174e 100644
--- a/keycloak-plugin/src/main/java/org/entando/entando/keycloak/filter/KeycloakFilter.java
+++ b/keycloak-plugin/src/main/java/org/entando/entando/keycloak/filter/KeycloakFilter.java
@@ -215,7 +215,7 @@ private void invalidateSession(final HttpServletRequest request) {
private void doLogout(final HttpServletRequest request, final HttpServletResponse response) throws IOException {
final HttpSession session = request.getSession();
final String idToken = (String)session.getAttribute(SESSION_PARAM_ID_TOKEN);
- final String redirectUri = request.getRequestURL().toString().replace("/do/logout.action", "");
+ final String redirectUri = UrlUtils.determineFrontendURL(request).replace("/do/logout.action", "");
session.invalidate();
response.sendRedirect(oidcService.getLogoutUrl(redirectUri, idToken));
}
@@ -224,7 +224,7 @@ private void doLogin(final HttpServletRequest request, final HttpServletResponse
final HttpSession session = request.getSession();
final String authorizationCode = request.getParameter("code");
final String stateParameter = request.getParameter("state");
- final String redirectUri = request.getRequestURL().toString();
+ final String redirectUri = UrlUtils.determineFrontendURL(request);
final String redirectTo = request.getParameter("redirectTo");
final String error = request.getParameter("error");
final String errorDescription = request.getParameter("error_description");
diff --git a/keycloak-plugin/src/main/java/org/entando/entando/keycloak/services/control/KcRequestAuthorizator.java b/keycloak-plugin/src/main/java/org/entando/entando/keycloak/services/control/KcRequestAuthorizator.java
index 1ff0e0b01..d0cf3b55f 100644
--- a/keycloak-plugin/src/main/java/org/entando/entando/keycloak/services/control/KcRequestAuthorizator.java
+++ b/keycloak-plugin/src/main/java/org/entando/entando/keycloak/services/control/KcRequestAuthorizator.java
@@ -24,6 +24,7 @@
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
+import org.entando.entando.aps.util.UrlUtils;
import org.entando.entando.ent.exception.EntException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -58,7 +59,7 @@ public int service(RequestContext reqCtx, int status) {
} else if (!currentUser.getUsername().equalsIgnoreCase(SystemConstants.GUEST_USER_NAME)) {
return this.returnUserNotAuthorized(reqCtx);
} else {
- StringBuilder targetUrl = new StringBuilder(req.getRequestURL());
+ StringBuilder targetUrl = new StringBuilder(UrlUtils.determineFrontendURL(req));
targetUrl.append("?");
String queryString = req.getQueryString();
if (null != queryString && queryString.trim().length() > 0) {
diff --git a/keycloak-plugin/src/test/java/org/entando/entando/keycloak/filter/KeycloakFilterTest.java b/keycloak-plugin/src/test/java/org/entando/entando/keycloak/filter/KeycloakFilterTest.java
index d0702e25f..73679a64f 100644
--- a/keycloak-plugin/src/test/java/org/entando/entando/keycloak/filter/KeycloakFilterTest.java
+++ b/keycloak-plugin/src/test/java/org/entando/entando/keycloak/filter/KeycloakFilterTest.java
@@ -95,6 +95,8 @@ public void setUp() {
Mockito.lenient().when(session.getServletContext()).thenReturn(svCtx);
Mockito.lenient().when(wac.getBean(ITenantManager.class)).thenReturn(tenantManager);
Mockito.lenient().when(request.getServerName()).thenReturn("dev.entando.org");
+ Mockito.lenient().when(request.getScheme()).thenReturn("https");
+ Mockito.lenient().when(request.getServerPort()).thenReturn(443);
Mockito.lenient().when(request.getHeader("X-Forwarded-Proto")).thenReturn("https");
Mockito.lenient().when(request.getHeader("Host")).thenReturn("dev.entando.org");
}
@@ -117,7 +119,7 @@ void testAuthenticationFlow() throws IOException, ServletException, EntException
when(request.getRequestURL()).thenReturn(new StringBuffer(loginEndpoint));
Mockito.lenient().when(request.getParameter(eq("redirectTo"))).thenReturn(requestRedirect);
- final String redirect = "http://dev.entando.org/auth/realms/entando/protocol/openid-connect/auth";
+ final String redirect = "https://dev.entando.org/auth/realms/entando/protocol/openid-connect/auth";
when(oidcService.getRedirectUrl(any(), any(), any())).thenReturn(redirect);
keycloakFilter.doFilter(request, response, filterChain);
@@ -169,7 +171,6 @@ void testAuthenticationFlow() throws IOException, ServletException, EntException
@Test
void testAuthenticationFlowWithError() {
- final String loginEndpoint = "https://dev.entando.org/entando-app/do/login";
final String state = "0ca97afd-f0b0-4860-820a-b7cd1414f69c";
final String authorizationCode = "the-authorization-code-from-keycloak";
@@ -185,7 +186,6 @@ void testAuthenticationFlowWithError() {
when(request.getServletPath()).thenReturn("/do/login");
when(request.getParameter(eq("code"))).thenReturn(authorizationCode);
when(request.getParameter(eq("state"))).thenReturn(state);
- when(request.getRequestURL()).thenReturn(new StringBuffer(loginEndpoint));
Mockito.lenient().when(request.getContextPath()).thenReturn("/entando-app");
@@ -204,7 +204,6 @@ void testAuthenticationFlowWithError() {
@Test
void testAuthenticationWithInvalidAuthCode() throws IOException, ServletException {
- final String loginEndpoint = "https://dev.entando.org/entando-app/do/login";
final String state = "0ca97afd-f0b0-4860-820a-b7cd1414f69c";
final String authorizationCode = "the-authorization-code-from-keycloak";
@@ -216,7 +215,6 @@ void testAuthenticationWithInvalidAuthCode() throws IOException, ServletExceptio
when(request.getServletPath()).thenReturn("/do/login");
when(request.getParameter(eq("code"))).thenReturn(authorizationCode);
when(request.getParameter(eq("state"))).thenReturn(state);
- when(request.getRequestURL()).thenReturn(new StringBuffer(loginEndpoint));
when(request.getContextPath()).thenReturn("/entando-app");
final HttpClientErrorException exception = Mockito.mock(HttpClientErrorException.class);
@@ -235,11 +233,9 @@ void testAuthenticationWithInvalidAuthCode() throws IOException, ServletExceptio
@Test
void shouldLoginWithInvalidRedirectURLHostnameNotThrowError() throws IOException, ServletException {
final String requestRedirect = "https://not.authorized.url";
- final String loginEndpoint = "https://dev.entando.org/entando-app/do/login";
when(configuration.isEnabled()).thenReturn(true);
when(request.getServletPath()).thenReturn("/do/login");
- when(request.getRequestURL()).thenReturn(new StringBuffer(loginEndpoint));
Mockito.lenient().when(request.getParameter(eq("redirectTo"))).thenReturn(requestRedirect);
final String redirect = "http://dev.entando.org/auth/realms/entando/protocol/openid-connect/auth";
@@ -254,11 +250,8 @@ void shouldLoginWithInvalidRedirectURLHostnameNotThrowError() throws IOException
@Test
void testLogout() throws IOException, ServletException {
- final String loginEndpoint = "https://dev.entando.org/entando-app/do/logout.action";
-
when(configuration.isEnabled()).thenReturn(true);
when(request.getServletPath()).thenReturn("/do/logout.action");
- when(request.getRequestURL()).thenReturn(new StringBuffer(loginEndpoint));
final String redirect = "http://dev.entando.org/auth/realms/entando/protocol/openid-connect/logout";
when(oidcService.getLogoutUrl(any(),any())).thenReturn(redirect);
@@ -441,7 +434,6 @@ void testLoginWithAuthorizationCode() throws Exception {
when(configuration.isEnabled()).thenReturn(true);
when(request.getServletPath()).thenReturn(path);
- when(request.getRequestURL()).thenReturn(new StringBuffer(endpoint));
when(request.getParameter("state")).thenReturn("");
when(request.getParameter("code")).thenReturn("");
@@ -593,7 +585,6 @@ void shouldLoginWithRedirectToDifferentDomainNotThrowException() throws Exceptio
String path = "/do/login.action";
when(configuration.isEnabled()).thenReturn(true);
when(request.getServletPath()).thenReturn(path);
- when(request.getRequestURL()).thenReturn(new StringBuffer("http://dev.entando.org/entando-de-app/do/login.action"));
when(request.getParameter("code")).thenReturn(null);
when(request.getParameter("state")).thenReturn(null);
when(request.getParameter("redirectTo")).thenReturn("http://fakedomain.entando.org/entando-de-app/pages/en/homepage/");
@@ -624,7 +615,6 @@ private void testLoginExecuteFine(final String protoAndServerName, final String
final String redirectToUri, final String redirectToPath) throws Exception {
when(configuration.isEnabled()).thenReturn(true);
when(request.getServletPath()).thenReturn(path);
- when(request.getRequestURL()).thenReturn(new StringBuffer(protoAndServerName+contextRoot+path));
when(request.getParameter("code")).thenReturn(null);
when(request.getParameter("state")).thenReturn(null);
when(request.getParameter("redirectTo")).thenReturn(redirectToUri);
@@ -661,7 +651,6 @@ void shouldLoginWithRedirectToSameDomainWithDifferentSchemaExecuteFine() throws
String path = "/do/login.action";
when(configuration.isEnabled()).thenReturn(true);
when(request.getServletPath()).thenReturn(path);
- when(request.getRequestURL()).thenReturn(new StringBuffer("http://dev.entando.org/entando-de-app/do/login.action"));
when(request.getParameter("code")).thenReturn(null);
when(request.getParameter("state")).thenReturn(null);
when(request.getParameter("redirectTo")).thenReturn("https://dev.entando.org/entando-de-app/pages/en/mypage");
diff --git a/webdynamicform-plugin/src/main/resources/liquibase/jpwebdynamicform/port/00000000000001_dataPort.xml b/webdynamicform-plugin/src/main/resources/liquibase/jpwebdynamicform/port/00000000000001_dataPort.xml
index 8bdbdcc86..47b66fec1 100644
--- a/webdynamicform-plugin/src/main/resources/liquibase/jpwebdynamicform/port/00000000000001_dataPort.xml
+++ b/webdynamicform-plugin/src/main/resources/liquibase/jpwebdynamicform/port/00000000000001_dataPort.xml
@@ -46,6 +46,7 @@
+
@@ -56,7 +57,6 @@
-
From dbb61df54c8a853c8f1103e06ca1b6c7b5e384ae Mon Sep 17 00:00:00 2001
From: ffalqui
Date: Fri, 27 Mar 2026 11:27:28 +0100
Subject: [PATCH 2/5] ESB-1041 Fix liquibase.exception.DatabaseException: CLOB
resource not found: clob/production/sysconfig_kc.xml
---
.../port/clob/production/sysconfig_kc.xml | 52 +++++++++++++++++++
1 file changed, 52 insertions(+)
create mode 100644 keycloak-plugin/src/main/resources/liquibase/entando-keycloak-auth/port/clob/production/sysconfig_kc.xml
diff --git a/keycloak-plugin/src/main/resources/liquibase/entando-keycloak-auth/port/clob/production/sysconfig_kc.xml b/keycloak-plugin/src/main/resources/liquibase/entando-keycloak-auth/port/clob/production/sysconfig_kc.xml
new file mode 100644
index 000000000..7eb07cc61
--- /dev/null
+++ b/keycloak-plugin/src/main/resources/liquibase/entando-keycloak-auth/port/clob/production/sysconfig_kc.xml
@@ -0,0 +1,52 @@
+
+
+ false
+ FULL
+
+
+ true
+ groups
+ GROUPCLAIM
+
+
+ true
+ realm_access.roles
+ ROLECLAIM
+
+
+ false
+ realm_access.roles
+ ROLEGROUPCLAIM
+ _SEP_
+
+
+ false
+ AD_ROLE
+ ROLE
+
+
+ false
+ AD_GROUP
+ GROUP
+
+
+ false
+ AD_GROUPROLE
+ ROLEGROUP
+ _r_
+
+
+
+ default-roles-entando-development
+ offline_access
+ uma_authorization
+
+
+ imported_role
+ imported_role2
+
+
+ imported_group
+ imported_group2
+
+
From 7e4fa7b83fd63e444b5eab0c53c4e29a5f2ddb85 Mon Sep 17 00:00:00 2001
From: ffalqui
Date: Tue, 31 Mar 2026 11:12:58 +0200
Subject: [PATCH 3/5] ESB-1041 Fix jpwebdynform fe date type, fix log ESAPI
encoding error in XSSRequestWrapper
---
.../aps/servlet/XSSRequestWrapper.java | 4 +-
.../port/00000000000001_dataPort.xml | 21 ++++++
.../jpwebdynamicform_is_entryMessage.ftl | 3 +-
.../jpwebdynamicform_message_form.ftl | 31 +++++++++
.../jpwebdynform_is_front-DateAttribute.ftl | 68 ++++---------------
...pwebdynform_is_front-DateSubmitHandler.ftl | 19 ++++++
...form_is_front_attributeInfo-help-block.ftl | 1 -
.../apsadmin/messageActionsConfig.xml | 8 ---
8 files changed, 89 insertions(+), 66 deletions(-)
create mode 100644 webdynamicform-plugin/src/main/resources/liquibase/jpwebdynamicform/port/clob/production/guifragment/jpwebdynform_is_front-DateSubmitHandler.ftl
diff --git a/portal-ui/src/main/java/org/entando/entando/aps/servlet/XSSRequestWrapper.java b/portal-ui/src/main/java/org/entando/entando/aps/servlet/XSSRequestWrapper.java
index 65148a384..f281540fc 100644
--- a/portal-ui/src/main/java/org/entando/entando/aps/servlet/XSSRequestWrapper.java
+++ b/portal-ui/src/main/java/org/entando/entando/aps/servlet/XSSRequestWrapper.java
@@ -62,7 +62,7 @@ private String validatedParameter(String name) {
try {
value = ESAPI.validator().getValidInput("HTTP parameter value: " + value, value, "HTTPParameterValue", 2000, true);
} catch (ValidationException e) {
- log.error("Invalid parameter ('{}' - '{}'), encoding as HTML attribute", name, value, e);
+ log.warn("Invalid parameter ('{}' - '{}'), encoding as HTML attribute", name, value);
value = ESAPI.encoder().encodeForHTMLAttribute(value);
} catch (Throwable e) {
log.debug("Invalid parameter ('{}' - '{}') - error message {}", name, value, e.getMessage());
@@ -78,7 +78,7 @@ private String validatedHeader(String name) {
try {
value = ESAPI.validator().getValidInput("HTTP header value: " + value, value, "HTTPHeaderValue", 150, false);
} catch (ValidationException e) {
- log.error("Invalid header ('{}' - '{}'), encoding as HTML attribute", name, value, e);
+ log.warn("Invalid header ('{}' - '{}'), encoding as HTML attribute", name, value);
value = ESAPI.encoder().encodeForHTMLAttribute(value);
} catch (Throwable e) {
log.debug("Invalid header ('{}' - '{}') - error message {}", name, value, e.getMessage());
diff --git a/webdynamicform-plugin/src/main/resources/liquibase/jpwebdynamicform/port/00000000000001_dataPort.xml b/webdynamicform-plugin/src/main/resources/liquibase/jpwebdynamicform/port/00000000000001_dataPort.xml
index 47b66fec1..9ef393bc7 100644
--- a/webdynamicform-plugin/src/main/resources/liquibase/jpwebdynamicform/port/00000000000001_dataPort.xml
+++ b/webdynamicform-plugin/src/main/resources/liquibase/jpwebdynamicform/port/00000000000001_dataPort.xml
@@ -451,4 +451,25 @@
+
+
+
+
+
+ SELECT COUNT(*)
+ FROM GUIFRAGMENT
+ WHERE code = 'jpwebdynform_is_front-DateSubmitHandler'
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/webdynamicform-plugin/src/main/resources/liquibase/jpwebdynamicform/port/clob/production/guifragment/jpwebdynamicform_is_entryMessage.ftl b/webdynamicform-plugin/src/main/resources/liquibase/jpwebdynamicform/port/clob/production/guifragment/jpwebdynamicform_is_entryMessage.ftl
index c6758a783..d4db9cf5c 100644
--- a/webdynamicform-plugin/src/main/resources/liquibase/jpwebdynamicform/port/clob/production/guifragment/jpwebdynamicform_is_entryMessage.ftl
+++ b/webdynamicform-plugin/src/main/resources/liquibase/jpwebdynamicform/port/clob/production/guifragment/jpwebdynamicform_is_entryMessage.ftl
@@ -111,4 +111,5 @@
useTabindexAutoIncrement=true
value="%{#attr.labelSubmit}" />
-
\ No newline at end of file
+
+<@wp.fragment code="jpwebdynform_is_front-DateSubmitHandler" escapeXml=false />
\ No newline at end of file
diff --git a/webdynamicform-plugin/src/main/resources/liquibase/jpwebdynamicform/port/clob/production/guifragment/jpwebdynamicform_message_form.ftl b/webdynamicform-plugin/src/main/resources/liquibase/jpwebdynamicform/port/clob/production/guifragment/jpwebdynamicform_message_form.ftl
index 418358e68..a53051404 100644
--- a/webdynamicform-plugin/src/main/resources/liquibase/jpwebdynamicform/port/clob/production/guifragment/jpwebdynamicform_message_form.ftl
+++ b/webdynamicform-plugin/src/main/resources/liquibase/jpwebdynamicform/port/clob/production/guifragment/jpwebdynamicform_message_form.ftl
@@ -1,2 +1,33 @@
<#assign wp=JspTaglibs["/aps-core"]>
+<#--
+ jpwebdynamicform_message_form - Message Form Widget
+ ====================================================
+ This widget renders a dynamic message form via internalServlet.
+ The Struts action dispatches to GUI fragments (stored in DB, tenant-aware)
+ with JSP fallback.
+
+ Struts action results GUI fragments (see userMessage.xml):
+ - jpwebdynamicform_is_entryMessage : Main form with all attribute fields
+ - jpwebdynamicform_is_messageTypeFinding : Message type selection (if multiple types)
+ - jpwebdynamicform_is_captchaPage : CAPTCHA confirmation step
+ - jpwebdynamicform_is_messageSaveConfirmed : Success confirmation page
+
+ Attribute type fragments (customizable per-tenant via DB):
+ - jpwebdynform_is_front-BooleanAttribute : Boolean (Yes/No radio buttons)
+ - jpwebdynform_is_front-CheckboxAttribute : CheckBox (single checkbox)
+ - jpwebdynform_is_front-DateAttribute : Date (native HTML5 date input)
+ - jpwebdynform_is_front-EnumeratorAttribute : Enumerator (select dropdown)
+ - jpwebdynform_is_front-EnumeratorMapAttribute : EnumeratorMap (select with key/value)
+ - jpwebdynform_is_front-LongtextAttribute : Longtext (textarea)
+ - jpwebdynform_is_front-NumberAttribute : Number (text input)
+ - jpwebdynform_is_front-MonotextAttribute : Monotext/Text (text input, also default fallback)
+ - jpwebdynform_is_front-ThreeStateAttribute : ThreeState (Yes/No/None radio buttons)
+ - jpwebdynform_is_front-CompositeAttribute : Composite (group of sub-attributes)
+
+ Utility fragments:
+ - jpwebdynform_is_front_AttributeInfo : Required field indicator (*)
+ - jpwebdynform_is_front_attributeInfo-help-block : Validation hints (min/max length, OGNL help)
+ - jpwebdynform_is_front-DateSubmitHandler : Date format conversion (yyyy-MM-dd -> dd/MM/yyyy)
+ - jpwebdynamicform_is_captchaInclude : Google reCAPTCHA v2/v3 integration
+-->
<@wp.internalServlet actionPath="/ExtStr2/do/jpwebdynamicform/Message/User/new" />
\ No newline at end of file
diff --git a/webdynamicform-plugin/src/main/resources/liquibase/jpwebdynamicform/port/clob/production/guifragment/jpwebdynform_is_front-DateAttribute.ftl b/webdynamicform-plugin/src/main/resources/liquibase/jpwebdynamicform/port/clob/production/guifragment/jpwebdynform_is_front-DateAttribute.ftl
index 4ef8839c0..9a4af2f59 100644
--- a/webdynamicform-plugin/src/main/resources/liquibase/jpwebdynamicform/port/clob/production/guifragment/jpwebdynform_is_front-DateAttribute.ftl
+++ b/webdynamicform-plugin/src/main/resources/liquibase/jpwebdynamicform/port/clob/production/guifragment/jpwebdynform_is_front-DateAttribute.ftl
@@ -1,55 +1,15 @@
-<#assign c=JspTaglibs["http://java.sun.com/jsp/jstl/core"]>
<#assign s=JspTaglibs["/struts-tags"]>
-<#assign wp=JspTaglibs["/aps-core"]>
-<#assign wpsf=JspTaglibs["/apsadmin-form"]>
-<#assign currentLangVar ><@wp.info key="currentLang" />#assign>
-<@s.if test="#attribute.failedDateString == null">
- <@s.set var="dateAttributeValue" value="#attribute.getFormattedDate('dd/MM/yyyy')" />
-@s.if>
-<@s.else>
- <@s.set var="dateAttributeValue" value="#attribute.failedDateString" />
-@s.else>
-<@wpsf.textfield
-useTabindexAutoIncrement=true id="%{attribute_id}"
-name="%{#attributeTracer.getFormFieldName(#attribute)}"
-value="%{#dateAttributeValue}" maxlength="10" cssClass="text userprofile-date" />
-
-<#assign js_for_datepicker="jQuery(function($){
- $.datepicker.regional['it'] = {
- closeText: 'Chiudi',
- prevText: '<Prec',
- nextText: 'Succ>',
- currentText: 'Oggi',
- monthNames: ['Gennaio','Febbraio','Marzo','Aprile','Maggio','Giugno',
- 'Luglio','Agosto','Settembre','Ottobre','Novembre','Dicembre'],
- monthNamesShort: ['Gen','Feb','Mar','Apr','Mag','Giu',
- 'Lug','Ago','Set','Ott','Nov','Dic'],
- dayNames: ['Domenica','Lunedì','Martedì','Mercoledì','Giovedì','Venerdì','Sabato'],
- dayNamesShort: ['Dom','Lun','Mar','Mer','Gio','Ven','Sab'],
- dayNamesMin: ['Do','Lu','Ma','Me','Gi','Ve','Sa'],
- weekHeader: 'Sm',
- dateFormat: 'dd/mm/yy',
- firstDay: 1,
- isRTL: false,
- showMonthAfterYear: false,
- yearSuffix: ''};
-});
-
-jQuery(function($){
- if (Modernizr.touch && Modernizr.inputtypes.date) {
- $.each( $('input.jpwebdynamicform-date'), function(index, item) {
- item.type = 'date';
- });
- } else {
- $.datepicker.setDefaults( $.datepicker.regional['${currentLangVar}'] );
- $('input.jpwebdynamicform-date').datepicker({
- changeMonth: true,
- changeYear: true,
- dateFormat: 'dd/mm/yy'
- });
- }
-});" >
-<@wp.headInfo type="JS" info="entando-misc-html5-essentials/modernizr-2.5.3-full.js" />
-<@wp.headInfo type="JS_EXT" info="http://code.jquery.com/ui/1.10.0/jquery-ui.min.js" />
-<@wp.headInfo type="CSS_EXT" info="http://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.min.css" />
-<@wp.headInfo type="JS_RAW" info="${js_for_datepicker}" />
\ No newline at end of file
+<@s.if test="#lang.default">
+ <@s.if test="#attribute.failedDateString == null">
+ <@s.set var="dateAttributeValue" value="#attribute.getFormattedDate('yyyy-MM-dd')" />
+ @s.if>
+ <@s.else>
+ <@s.set var="dateAttributeValue" value="#attribute.failedDateString" />
+ @s.else>
+ "
+ data-jpwebdynamicform-date="true"
+ name="<@s.property value="#attributeTracer.getFormFieldName(#attribute)" />"
+ value="<@s.property value="#dateAttributeValue" />"
+ class="jpwebdynamicform-date" />
+@s.if>
\ No newline at end of file
diff --git a/webdynamicform-plugin/src/main/resources/liquibase/jpwebdynamicform/port/clob/production/guifragment/jpwebdynform_is_front-DateSubmitHandler.ftl b/webdynamicform-plugin/src/main/resources/liquibase/jpwebdynamicform/port/clob/production/guifragment/jpwebdynform_is_front-DateSubmitHandler.ftl
new file mode 100644
index 000000000..a74aa37fd
--- /dev/null
+++ b/webdynamicform-plugin/src/main/resources/liquibase/jpwebdynamicform/port/clob/production/guifragment/jpwebdynform_is_front-DateSubmitHandler.ftl
@@ -0,0 +1,19 @@
+<#assign wp=JspTaglibs["/aps-core"]>
+
\ No newline at end of file
diff --git a/webdynamicform-plugin/src/main/resources/liquibase/jpwebdynamicform/port/clob/production/guifragment/jpwebdynform_is_front_attributeInfo-help-block.ftl b/webdynamicform-plugin/src/main/resources/liquibase/jpwebdynamicform/port/clob/production/guifragment/jpwebdynform_is_front_attributeInfo-help-block.ftl
index 417db1f90..a4f85d8ff 100644
--- a/webdynamicform-plugin/src/main/resources/liquibase/jpwebdynamicform/port/clob/production/guifragment/jpwebdynform_is_front_attributeInfo-help-block.ftl
+++ b/webdynamicform-plugin/src/main/resources/liquibase/jpwebdynamicform/port/clob/production/guifragment/jpwebdynform_is_front_attributeInfo-help-block.ftl
@@ -7,7 +7,6 @@
<@s.if test="%{#hasValidationRulesVar || #attribute.type == 'Date' || (#attribute.textAttribute && (#attribute.minLength != -1 || #attribute.maxLength != -1))}">
- <@s.if test="#attribute.type == 'Date'">dd/MM/yyyy @s.if>
<@s.if test="%{#validationRules.helpMessageKey != null}">
<@s.set var="label" scope="page" value="#validationRules.helpMessageKey" /><@wp.i18n key="${label}" />
@s.if>
diff --git a/webdynamicform-plugin/src/main/resources/spring/plugins/jpwebdynamicform/apsadmin/messageActionsConfig.xml b/webdynamicform-plugin/src/main/resources/spring/plugins/jpwebdynamicform/apsadmin/messageActionsConfig.xml
index 31337ee26..9c472ff96 100644
--- a/webdynamicform-plugin/src/main/resources/spring/plugins/jpwebdynamicform/apsadmin/messageActionsConfig.xml
+++ b/webdynamicform-plugin/src/main/resources/spring/plugins/jpwebdynamicform/apsadmin/messageActionsConfig.xml
@@ -12,20 +12,12 @@
/WEB-INF/plugins/jpwebdynamicform/apsadmin/jsp/common/layouts/subMenuAppBuilder.jsp
core.menu.legacyplugins.appbuilder
-
Date: Tue, 31 Mar 2026 16:38:07 +0200
Subject: [PATCH 4/5] ESB-1041 code cleaning
---
.../entando/keycloak/filter/KeycloakFilterTest.java | 13 ++++---------
1 file changed, 4 insertions(+), 9 deletions(-)
diff --git a/keycloak-plugin/src/test/java/org/entando/entando/keycloak/filter/KeycloakFilterTest.java b/keycloak-plugin/src/test/java/org/entando/entando/keycloak/filter/KeycloakFilterTest.java
index 73679a64f..a540620f7 100644
--- a/keycloak-plugin/src/test/java/org/entando/entando/keycloak/filter/KeycloakFilterTest.java
+++ b/keycloak-plugin/src/test/java/org/entando/entando/keycloak/filter/KeycloakFilterTest.java
@@ -196,9 +196,7 @@ void testAuthenticationFlowWithError() {
Mockito.lenient().when(auth.getRefreshToken()).thenReturn("refresh-token-over-here");
try ( MockedStatic wacUtil = Mockito.mockStatic(WebApplicationContextUtils.class)) {
wacUtil.when(() -> WebApplicationContextUtils.getWebApplicationContext(svCtx)).thenReturn(wac);
- Assertions.assertThrows(EntandoTokenException.class, () -> {
- keycloakFilter.doFilter(request, response, filterChain);
- });
+ Assertions.assertThrows(EntandoTokenException.class, () -> keycloakFilter.doFilter(request, response, filterChain));
}
}
@@ -430,7 +428,6 @@ void apiCallShouldNotSaveUserOnSession() throws Exception {
void testLoginWithAuthorizationCode() throws Exception {
final String path = "/do/login";
- final String endpoint = "https://dev.entando.org/entando-app" + path;
when(configuration.isEnabled()).thenReturn(true);
when(request.getServletPath()).thenReturn(path);
@@ -607,11 +604,11 @@ void shouldLoginWithRedirectWithUrlExecuteFine() throws Exception {
final String contextRoot = "/entando-de-app";
final String protoAndServerName = "http://dev.entando.org";
- testLoginExecuteFine(protoAndServerName, contextRoot, path, protoAndServerName+contextRoot+redirectPath, redirectPath);
+ testLoginExecuteFine(contextRoot, path, protoAndServerName+contextRoot+redirectPath, redirectPath);
}
- private void testLoginExecuteFine(final String protoAndServerName, final String contextRoot, final String path,
+ private void testLoginExecuteFine(final String contextRoot, final String path,
final String redirectToUri, final String redirectToPath) throws Exception {
when(configuration.isEnabled()).thenReturn(true);
when(request.getServletPath()).thenReturn(path);
@@ -639,10 +636,8 @@ void shouldLoginWithRedirectToWithPathExecuteFine() throws Exception {
final String path = "/do/login.action";
final String redirectPath = "/pages/en/homepage/";
final String contextRoot = "/entando-de-app";
- final String protoAndServerName = "http://dev.entando.org";
-
- testLoginExecuteFine(protoAndServerName, contextRoot, path, contextRoot+redirectPath, redirectPath);
+ testLoginExecuteFine(contextRoot, path, contextRoot+redirectPath, redirectPath);
}
@Test
From bc1dc5e2d3e50962e1550ece855b5796b3d964d5 Mon Sep 17 00:00:00 2001
From: ffalqui
Date: Tue, 31 Mar 2026 17:55:33 +0200
Subject: [PATCH 5/5] ESB-1041 Disable ESAPI IntrusionDetector to prevent
false-positive blocking
---
portal-ui/src/main/resources/ESAPI.properties | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/portal-ui/src/main/resources/ESAPI.properties b/portal-ui/src/main/resources/ESAPI.properties
index 88b02e157..19e83b08b 100644
--- a/portal-ui/src/main/resources/ESAPI.properties
+++ b/portal-ui/src/main/resources/ESAPI.properties
@@ -381,7 +381,7 @@ Logger.MaxLogFileSize=10000000
# You can also disable intrusion detection completely by changing
# the following parameter to true
#
-IntrusionDetector.Disable=false
+IntrusionDetector.Disable=true
#
IntrusionDetector.event.test.count=2
IntrusionDetector.event.test.interval=10