From e9f9d8186608be37aac1a098ec71196428a7149b Mon Sep 17 00:00:00 2001 From: Maurus Decimus <11444311+mdecimus@users.noreply.github.com> Date: Wed, 20 May 2026 06:51:34 +0200 Subject: [PATCH] Allow internal TLDs and special characters in e-mail addresses --- CHANGELOG.md | 2 +- crates/utils/src/lib.rs | 16 ++++++++++++---- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b461ae14..c15779b9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,7 +27,7 @@ If you are upgrading from v0.16.x, replace the binary (or run `docker pull`). If - ACME: - Update `defaultCertificateId` when renewing a certificate that is currently set as default. - Perform `DNS-01` authorizations sequentially to avoid race conditions in some DNS providers. -- Allow internal TLDs in e-mail addresses. +- Allow internal TLDs and special characters in e-mail addresses. - Websocket: Perform case insensitive matching during upgrade. - LDAP: Synchronize accounts when expanding mailing list recipients. - Sieve: `replace` action adds an extra `From` header. diff --git a/crates/utils/src/lib.rs b/crates/utils/src/lib.rs index 82b627d2..bac3fdbc 100644 --- a/crates/utils/src/lib.rs +++ b/crates/utils/src/lib.rs @@ -213,10 +213,14 @@ pub fn sanitize_email(email: &str) -> Option { for ch in chars.by_ref() { match ch { - '.' | '+' | '-' | '_' => { - if !last_ch.is_alphanumeric() { + '.' => { + if last_ch == NIL_CHAR || last_ch == '.' { return None; } + result.push('.'); + } + '!' | '#' | '$' | '%' | '&' | '\'' | '*' | '+' | '-' | '/' | '=' | '?' | '^' | '_' + | '`' | '{' | '|' | '}' | '~' => { result.push(ch); } ' ' | '\x09'..='\x0d' => continue, @@ -288,10 +292,14 @@ pub fn sanitize_email_local(local: &str) -> Option { for ch in local.chars() { match ch { - '.' | '+' | '-' | '_' => { - if !last_ch.is_alphanumeric() { + '.' => { + if last_ch == NIL_CHAR || last_ch == '.' { return None; } + result.push('.'); + } + '!' | '#' | '$' | '%' | '&' | '\'' | '*' | '+' | '-' | '/' | '=' | '?' | '^' | '_' + | '`' | '{' | '|' | '}' | '~' => { result.push(ch); } ' ' | '\x09'..='\x0d' => continue,