Releases: RohanNagar/jmail
v2.1.0
- Fix bug where addresses containing unquoted Unicode punctuation or symbol characters in the local-part would be incorrectly considered valid (Thanks @acmcmurray for reporting and @houssam966 for contributing! 🎉).
- While RFC 6531 allows for UTF-8 characters for the purposes of internationalized domain names, not all Unicode symbols are permitted.
Specifically, this excludes Punctuation (Pc, Pd, Ps, Pe, Pi, Pf, Po) and Symbols (Sm, Sc, Sk, So).
- While RFC 6531 allows for UTF-8 characters for the purposes of internationalized domain names, not all Unicode symbols are permitted.
- Fix bug where the validation rules
requireOnlyTopLevelDomains()anddisallowReservedDomains()did not correctly ignore case in the domains (Thanks @mtillberg for contributing! 🎉). - Fix bug where the order of validation rules added to an
EmailValidatorwas not properly maintained. This resulted in rules being applied in an arbitrary order during
validation instead of the intended order (Thanks @Gedankendreher for reporting!). - Add new
ValidationRuledisallowDisposableDomains(DisposableDomainSource)to consider email addresses that have a disposable domain (such asusername@10-minute-mail.com) as invalid.- The
DisposableDomainSource.file(String)implementation ofDisposableDomainSourceuses a given file as the source of truth for disposable domains (Thanks @mtillberg for contributing! 🎉). - The
DisposableDomainSource.inputStream(InputStream)implementation ofDisposableDomainSourceuses a givenInputStreamas the source of truth for disposable domains (Thanks @liias for contributing! 🎉) - The
IsTempMailAPISourceuses the IsTempMail API as the source of truth for disposable domains. Usage of this source requires an API Key provided by IsTempMail.
- The
v2.0.2
- Fix bug where addresses containing a display name that starts with a dot
.character would be incorrectly invalidated. (Thanks @utalmighty for reporting!)
v2.0.1
- Fix bug where using the rule
requireTopLevelDomain()would incorrectly invalidate addresses that use IP domains (since those inherently have a TLD). (Thanks @ahegyes for reporting!) - Fix bug where addresses starting with an at (
@) character and ending with either a dot.or a colon:character threw aStringIndexOutOfBoundsExceptioninstead of correctly invalidating the address. (Thanks @alexc-scopely for reporting!) - Add new
ValidationRuledisallowSingleCharacterTopLevelDomains()to consider email addresses with TLDs that are only a single character (such astest.c) as invalid. (Thanks @alexc-scopely for suggesting!)
v2.0.0
Breaking Changes
-
By default,
Email#normalizednow lowercases the email address and removes any extraneous quotes in
the local-part of the address. To revert this behavior so that it behaves the same as v1, use the following:myEmailObject.normalized( NormalizationOptions.builder() .keepQuotes() .adjustCase(CaseOption.NO_CHANGE) .build()); -
The
jmail.normalize.strip.quotesJVM system property no longer does anything. Quotes are stripped by default now.
If you need to disable quote stripping, useNormalizationOptionsBuilder#keepQuotes(). -
Removed
Email#normalized(boolean)method which allowed for a normalized email with stripped quotes.
Quotes are stripped by default now. If you need to disable quote stripping, useNormalizationOptionsBuilder#keepQuotes(). -
FailureReasonwas switched from an enum to a class in order to support custom failure reasons, so it is no longer
possible to use it in aswitchstatement. -
Email addresses that fail validation due to additional rules added to the
EmailValidator(such as
disallowIpDomain()orrequireValidMXRecord()) no longer return a genericFailureReason.FAILED_CUSTOM_VALIDATION
in theEmailValidationResult. Instead, it returns a more specificFailureReasondepending on the rule. -
FailureReason.MISSING_TOP_LEVEL_DOMAINwas changed toFailureReason.MISSING_FINAL_DOMAIN_PART.
MISSING_TOP_LEVEL_DOMAINwas previously used for email addresses that failed validation because
they ended the email address with a comment. ThisFailureReasonwas potentially misleading, for example if you
enabledrequireTopLevelDomain()on yourEmailValidator. Note that theMISSING_TOP_LEVEL_DOMAINfailure reason
is now used properly: if you use the rulerequireTopLevelDomain(), any address that is missing the TLD will give
that failure reason.
FailureReason Improvements
Changes to the FailureReason supplied for additional rules
The FailureReason returned in the EmailValidationResult is useful to understand why a specific
email address failed validation. In v2.0.0, the FailureReason returned for email addresses that failed
one of the additional validation rules added to your EmailValidator (such as disallowIpDomain() or
requireValidMXRecord()) now return more specific and useful reasons (such as CONTAINS_IP_DOMAIN or
INVALID_MX_RECORD).
EmailValidator validator = JMail.strictValidator()
.requireOnlyTopLevelDomains(TopLevelDomain.DOT_COM);
EmailValidationResult result = validator.validate("test@test.org");
assertEquals(FailureReason.INVALID_TOP_LEVEL_DOMAIN, result.getFailureReason());
Option to provide FailureReason for custom rules
Additionally, you can specify your own FailureReason for any custom validation rules that you add
to your EmailValidator. Use the new withRule(Predicate<Email>, FailureReason) or
withRules(Map<Predicate<Email>, FailureReason>) methods to specify the failure reason for each
of your custom rules. If no failure reason is supplied, then the rule will default to the
FailureReason.FAILED_CUSTOM_VALIDATION reason.
FailureReason nonGmailFailure = new FailureReason("NON_GMAIL_ADDRESS");
EmailValidator validator = JMail.strictValidator()
.withRule(e -> e.domain.startsWith("gmail"), nonGmailFailure);
EmailValidationResult result = validator.validate("test@yahoo.com");
assertEquals(nonGmailFailure, result.getFailureReason());
Email Address Normalization Improvements
New Normalization Methods
This version introduces a new NormalizationOptions class that is used to provide
configuration of the behavior of the Email#normalized() method. See the table below to see
all the new and existing options.
In v2.0.0, you can use either Email#normalized() (with no parameters) or Email#normalized(NormalizationOptions options).
The first method without parameters will return a normalized email address based on the default
normalization options. The second method allows you to provide your own NormalizationOptions at runtime
depending on your needs. The custom normalization options can be created using the NormalizationOptions#builder()
method.
Normalization Options
Thanks, @Sprokof, for contributing (introducing removeDots and adjustCase options)! 🎉
| Option | Description | NormalizationOptionsBuilder Method |
|---|---|---|
| stripQuotes | Remove all unnecessary quotes in the local-part of the address | stripQuotes() |
| adjustCase | Adjust the case of the email address. Possible options are: NO_CHANGE, LOWERCASE, LOWERCASE_LOCAL_PART_ONLY, LOWERCASE_DOMAIN_ONLY, UPPERCASE, UPPERCASE_LOCAL_PART_ONLY, UPPERCASE_DOMAIN_ONLY |
adjustCase(CaseOption) |
| removeDots | Remove all dots from the local-part of the address | removeDots() |
| removeSubAddress | Remove any sub-addressing (or tagged-addressing) from the local-part of the address. For example, first.last+test@gmail.com will become first.last@gmail.com |
removeSubAddress() or removeSubAddress(String) |
| performUnicodeNormalization | Perform unicode normalization on the local-part of the email address | performUnicodeNormalization() or performUnicodeNormalization(Normalizer.Form) |
Additional Address Formats
Version 2.0.0 introduces new additional email address formats that can be obtained from
the Email object (similar to the normalized() method).
-
Email#reference()returns an MD5 hash of the normalized email address."test@gmail.com" => "1aedb8d9dc4751e229a335e371db8058" -
Email#redacted()returns a version of the normalized email address where the local-part
is replaced with the SHA-1 hash of the local-part."test@gmail.com" => "{a94a8fe5ccb19ba61c4c0873d391e987982fbbd3}@gmail.com" -
Email#munged()returns a version of the normalized email address where the local-part
and domain are obfuscated with five asterisk characters."test@gmail.com" => "te*****@gm*****"
Support for Leading and Trailing Dots in the Local-Part
While technically disallowed under published RFCs, some email providers (ex: GMail)
consider email addresses that have local-parts that start with or end with a dot . character
as valid. For example, GMail considers .my.email.@gmail.com valid, even though it is not
actually valid according to RFC.
JMail now gives you the option to consider these addresses valid as well. You must use an
EmailValidator with the allowNonstandardDots rule added to it to allow these addresses to pass validation.
EmailValidator validator = JMail.strictValidator()
.allowNonstandardDots();
validator.isValid(".my.email.@gmail.com"); // returns truev1.6.3
- Fix bug where email addresses containing control characters in the local-part were incorrectly considered valid. (Thanks @PascalSchumacher for reporting!)
- Add new methods
ifValid(Consumer<Email> action)andifValidOrElse(Consumer<Email> action, Consumer<FailureReason> failureAction)to theEmailValidationResultobject.
v1.6.2
- Fix bug where IPv4 addresses with non-arabic numerals would incorrectly be considered valid. (Thanks @harrel56 for reporting!)
- Fix bug where IPv4 addresses with extraneous leading zeros would incorrectly be considered valid. (Thanks @harrel56 for reporting!)
- The
requireValidMXRecord()validation rule now correctly fails validation for domains that use a "Null MX" record. (Thanks @elmolm for contributing! 🎉)
v1.6.1
- Fix bug so that email addresses that end in a dash
-character now correctly fail validation with the reasonFailureReason.DOMAIN_PART_ENDS_WITH_DASHinstead of incorrectly returningFailureReason.ENDS_WITH_DOT. (Thanks @tbatchlear for reporting!)
v1.6.0
- Add a new rule
requireAscii()that considers an email address containing non-ASCII characters to be invalid. (Thanks @frodeto for suggesting!) - Add new property
isAscii()onEmailobjects that returns if the email address only contains ASCII characters or not. - Add option to strip quotes within the local-part of an email address when normalizing the address with the
normalize()method. (Thanks @tdelaney-leadiro for suggesting!)- This new option will remove quotes if the email address would still be valid and semantically the same without them.
- To enable the option, either:
- Call the normalize method that takes a boolean as the parameter, and use
true. Example:email.normalize(true) - Set the
-Djmail.normalize.strip.quotes=trueJVM property at runtime, and continue to use thenormalize()method without parameters.
- Call the normalize method that takes a boolean as the parameter, and use
v1.5.1
- Add a new rule
requireValidMXRecord(int initialTimeout, int numRetries)that allows for customization of the timeout for DNS lookups. (Thanks @dotneutron for suggesting!) - Reduce the default timeout for DNS lookups when adding the
requireValidMXRecord()rule to anEmailValidatorfrom potentially taking a maximum of 25 seconds to a maximum of 600 milliseconds.
v1.5.0
- Add new method
validate(String email)that returns anEmailValidationResultobject, containing the reason for validation failure upon failure. (Thanks @bobharner for suggesting!) - Add new
ValidationRulerequireValidMXRecord()to consider email addresses that have a domain with no MX record in DNS as invalid. (Thanks @lpellegr for suggesting!) - Fix bug where an email address that ends with a comment that is missing the closing parentheses were incorrectly considered as valid. For example:
test@test.com(comment