diff --git a/ChangeLog.md b/ChangeLog.md
index e5483bad3c..5af2bd4096 100644
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -16,9 +16,24 @@ KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->
+
+**2025-11-13 Alex O'Ree (alexoree AT apache DOT org)**
+
+* _3.0.0-git-06_
+
+* Dependency Updates
+ * commons-validator (added) at 1.10.0
+
+* [JSPWIKI-1239](https://issues.apache.org/jira/browse/JSPWIKI-1239) New user signup says the email is optional, but does not accept blank since it's already in use by the admin account
+* [JSPWIKI-1243](https://issues.apache.org/jira/browse/JSPWIKI-1243 Email validation rouine is incorrect (unicode symbols and more)
+* NOJIRA disables and removes the ClearSiteData Servlet Filter which broke CSRF token checks
+
+
+
**2025-11-13 Alex O'Ree (alexoree AT apache DOT org)**
* _3.0.0-git-05_
+
* Dependency Updates
* Tomcat updated to 10.1.49
diff --git a/jspwiki-api/src/main/java/org/apache/wiki/api/Release.java b/jspwiki-api/src/main/java/org/apache/wiki/api/Release.java
index 93502d19f0..e919bc5fc6 100644
--- a/jspwiki-api/src/main/java/org/apache/wiki/api/Release.java
+++ b/jspwiki-api/src/main/java/org/apache/wiki/api/Release.java
@@ -69,7 +69,7 @@ public final class Release {
*
* If the build identifier is empty, it is not added.
*/
- public static final String BUILD = "05";
+ public static final String BUILD = "06";
/**
* This is the generic version string you should use when printing out the version. It is of
diff --git a/jspwiki-http/src/main/java/org/apache/wiki/http/filter/ClearSiteDataFilter.java b/jspwiki-http/src/main/java/org/apache/wiki/http/filter/ClearSiteDataFilter.java
deleted file mode 100644
index 6477f408cd..0000000000
--- a/jspwiki-http/src/main/java/org/apache/wiki/http/filter/ClearSiteDataFilter.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright 2025 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.wiki.http.filter;
-
-import jakarta.servlet.Filter;
-import jakarta.servlet.FilterChain;
-import jakarta.servlet.FilterConfig;
-import jakarta.servlet.ServletException;
-import jakarta.servlet.ServletRequest;
-import jakarta.servlet.ServletResponse;
-import jakarta.servlet.http.HttpServletResponse;
-import java.io.IOException;
-
-/**
- *
- * Clear-Site-Data: Allows websites to request that browsers clear specific
- * browsing data (e.g., cookies, storage, cache) associated with the site. *
- */
-public class ClearSiteDataFilter implements Filter {
-
- private String mode = "\"cookies\", \"storage\"";
-
- public void init(FilterConfig filterConfig) {
- String configMode = filterConfig.getInitParameter("CSDValue");
- if (configMode != null) {
- mode = configMode;
- }
- }
-
- @Override
- public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
- HttpServletResponse res = (HttpServletResponse) response;
- res.addHeader("Clear-Site-Data", mode);
- chain.doFilter(request, response);
- }
-
-}
diff --git a/jspwiki-main/pom.xml b/jspwiki-main/pom.xml
index 223f9860fa..d7e8fd6261 100644
--- a/jspwiki-main/pom.xml
+++ b/jspwiki-main/pom.xml
@@ -106,6 +106,11 @@
org.apache.commons
commons-collections4
+
+
+ commons-validator
+ commons-validator
+
org.apache.commons
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/auth/DefaultUserManager.java b/jspwiki-main/src/main/java/org/apache/wiki/auth/DefaultUserManager.java
index ceb9f50f3e..5688c78e99 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/auth/DefaultUserManager.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/auth/DefaultUserManager.java
@@ -382,15 +382,17 @@ public void validateProfile( final Context context, final UserProfile profile )
} catch( final NoSuchPrincipalException e ) { /* It's clean */ }
// It's illegal to use multiple accounts with the same email
- try {
- otherProfile = getUserDatabase().findByEmail( email );
- if( otherProfile != null && !profile.getUid().equals( otherProfile.getUid() ) // Issue JSPWIKI-1042
- && !profile.equals( otherProfile ) && StringUtils.lowerCase( email )
- .equals( StringUtils.lowerCase( otherProfile.getEmail() ) ) ) {
- final Object[] args = { email };
- session.addMessage( SESSION_MESSAGES, MessageFormat.format( rb.getString( "security.error.email.taken" ), args ) );
- }
- } catch( final NoSuchPrincipalException e ) { /* It's clean */ }
+ if (email != null && email.trim().length() > 0) {
+ try {
+ otherProfile = getUserDatabase().findByEmail( email );
+ if( otherProfile != null && !profile.getUid().equals( otherProfile.getUid() ) // Issue JSPWIKI-1042
+ && !profile.equals( otherProfile ) && StringUtils.lowerCase( email )
+ .equals( StringUtils.lowerCase( otherProfile.getEmail() ) ) ) {
+ final Object[] args = { email };
+ session.addMessage( SESSION_MESSAGES, MessageFormat.format( rb.getString( "security.error.email.taken" ), args ) );
+ }
+ } catch( final NoSuchPrincipalException e ) { /* It's clean */ }
+ }
}
/** {@inheritDoc} */
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/tasks/auth/SaveUserProfileTask.java b/jspwiki-main/src/main/java/org/apache/wiki/tasks/auth/SaveUserProfileTask.java
index fd81abaccc..6bf94833fe 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/tasks/auth/SaveUserProfileTask.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/tasks/auth/SaveUserProfileTask.java
@@ -70,7 +70,7 @@ public Outcome execute( final Context context ) throws WikiException {
context.getEngine().getManager( UserManager.class ).getUserDatabase().save( profile );
// Send e-mail if user supplied an e-mail address
- if ( profile != null && profile.getEmail() != null ) {
+ if ( profile != null && profile.getEmail() != null && profile.getEmail().length() > 0 ) {
try {
final InternationalizationManager i18n = context.getEngine().getManager( InternationalizationManager.class );
final String app = context.getEngine().getApplicationName();
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/ui/InputValidator.java b/jspwiki-main/src/main/java/org/apache/wiki/ui/InputValidator.java
index 91300e9c86..c644d551ac 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/ui/InputValidator.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/ui/InputValidator.java
@@ -27,6 +27,7 @@ Licensed to the Apache Software Foundation (ASF) under one
import java.util.ResourceBundle;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import org.apache.commons.validator.routines.EmailValidator;
/**
* Provides basic validation services for HTTP parameters. Three standard validators are provided: email address, identifier and
@@ -49,7 +50,6 @@ public final class InputValidator {
* @since 2.4.82
*/
static final Pattern ID_PATTERN = Pattern.compile( "[\\x00\\r\\n\\x0f\"'<>;&\\xff{}]" );
- static final Pattern EMAIL_PATTERN = Pattern.compile( "^[0-9a-zA-Z-_.+]+@([0-9a-zA-Z-_]+\\.)+[a-zA-Z]+$" );
static final Pattern UNSAFE_PATTERN = Pattern.compile( "[\\x00\\r\\n\\x0f\"':<>\\[\\];#&@\\xff{}$%\\\\]" );
private final String m_form;
@@ -130,8 +130,7 @@ public boolean validate( final String input, final String label, final int type
}
return valid;
case EMAIL:
- matcher = EMAIL_PATTERN.matcher( input );
- valid = matcher.matches();
+ valid = EmailValidator.getInstance().isValid(input);
if ( !valid ) {
final Object[] args = { label };
m_session.addMessage( m_form, MessageFormat.format( rb.getString( "validate.invalidemail" ), args ) );
diff --git a/jspwiki-war/src/main/webapp/Login.jsp b/jspwiki-war/src/main/webapp/Login.jsp
index 3574c0b0b2..660d9b4f69 100644
--- a/jspwiki-war/src/main/webapp/Login.jsp
+++ b/jspwiki-war/src/main/webapp/Login.jsp
@@ -56,7 +56,7 @@
// Are we saving the profile?
if( "saveProfile".equals( request.getParameter( "action" ) ) ) {
if( !CsrfProtectionFilter.isCsrfProtectedPost( request ) ) {
- response.sendRedirect( "/error/Forbidden.html" );
+ response.sendRedirect( "error/Forbidden.html" );
return;
}
diff --git a/jspwiki-war/src/main/webapp/WEB-INF/web.xml b/jspwiki-war/src/main/webapp/WEB-INF/web.xml
index 36c98961a9..9a462efed1 100644
--- a/jspwiki-war/src/main/webapp/WEB-INF/web.xml
+++ b/jspwiki-war/src/main/webapp/WEB-INF/web.xml
@@ -106,14 +106,7 @@
CORPFilter
/*
-
- ClearSiteDataFilter
- org.apache.wiki.http.filter.ClearSiteDataFilter
-
-
- ClearSiteDataFilter
- /*
-
+
ContentTypeOptionsFilter
org.apache.wiki.http.filter.ContentTypeOptionsFilter
diff --git a/pom.xml b/pom.xml
index 57cfc6fee4..8569bf65cf 100644
--- a/pom.xml
+++ b/pom.xml
@@ -53,6 +53,7 @@
3.19.0
3.12.0
1.14.0
+ 1.10.0
2.10.9.2
0.64.8
0.60
@@ -172,6 +173,12 @@
commons-net
${commons-net.version}
+
+
+ commons-validator
+ commons-validator
+ ${commons-validator.version}
+
com.sun.mail