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,