Skip to content

Commit

Permalink
Add changelog file
Browse files Browse the repository at this point in the history
  • Loading branch information
RohanNagar committed Sep 30, 2023
1 parent 6567fb6 commit 97be15c
Show file tree
Hide file tree
Showing 5 changed files with 160 additions and 28 deletions.
123 changes: 123 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
# JMail Changelog

## i1.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()` on `Email` objects 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=true` JVM property at runtime, and continue to use the `normalize()` method without parameters.

---
## 1.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 an `EmailValidator` from potentially taking a maximum of 25 seconds to a maximum of 600 milliseconds.

---
## 1.5.0

- Add new method `validate(String email)` that returns an `EmailValidationResult` object, containing the reason for validation failure upon failure. (Thanks @bobharner for suggesting!)
- Add new `ValidationRule` `requireValidMXRecord()` 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`

---
## 1.4.1

- Add new `ValidationRule` `disallowObsoleteWhitespace()` to consider email addresses with obsolete whitespace as invalid. (Thanks @PascalSchumacher for suggesting!)

---
## 1.4.0

- Add new `normalized()` method on the `Email` class to provide a way to get a "normalized" version of an email address (the address without any comments or optional parts).

---
## 1.3.3

- Fix bug where invalid characters in the domain could result in an `IllegalArgumentException` instead of returning false. (Thanks @PascalSchumacher for reporting!)

---
## 1.3.2

- Fix bug where domain names that contained an emoji would be incorrectly invalid. (Thanks @Autom8edChaos for reporting!)

---
## 1.3.1

- Improve `equals()` and `hashCode()` methods for `Email` and `TopLevelDomain`
- Fix inconsistencies in some Javadocs

---
## 1.3.0

- `InternetProtocolAddress.validate(String ip)` now validates IPv6 addresses without requiring the `IPv6:` prefix.
- Add new `JMail.isInvalid(String email)` and `EmailValidator#isInvalid(String email)` methods as a convenience for testing if an email address is invalid.

---
## 1.2.3

- Add `toString()` method on `EmailValidator`
- Add `withRules(Collection<Predicate<Email>> rules)` method on `EmailValidator` to create a new `EmailValidator` from the collection of rules provided

---
## 1.2.2

- Fix bug where an exception would be thrown on invalid email addresses with whitespace or comments after a trailing `.` character. For example, `abc.def@ghi. (comment)` is invalid, and before this version JMail would throw an exception instead of return invalid.
(Thanks @ea234 for reporting!)

---
## 1.2.1

- `EmailValidator` is now immutable

---
## 1.2.0

- Switch `TopLevelDomain` from an enum to a class, allowing for creation of any valid top level domain (Thanks @bowbahdoe!)
- Add `module-info.java` so projects on JDK 9+ can use this library as a Java module
- Bugfix: Addresses with empty quoted strings (`""@test.org`) are now correctly considered valid
- Bugfix: Addresses with explicit source routing (`@1st.relay,@2nd.relay:user@final.domain`) are now considered valid. However, explicit source routing is deprecated since RFC 5321. `JMail.strictValidator()` disallows explicit source routing by default
- Bugfix: Addresses with quoted identifiers (`John Smith <John@smith.com>`) are now correctly considered valid
- New properties on the `Email` object:
- `identifier()`
- `hasIdentifier()`
- `explicitSourceRoutes()`

---
## 1.1.0

- Disallow construction of utility classes and prevent classes from being subclassed (Thanks @bowbahdoe!)
- Fix bug where email addresses that have a dotless domain or top level domain starting with the `-` character would be incorrectly classified as valid.
For example, `test@-foo` and `test@my.-domain` should both be invalid.

---
## 1.0.4

- You can now disallow email addresses with reserved domains listed in [RFC 2606](https://datatracker.ietf.org/doc/html/rfc2606), such as `example.com` or `.invalid`.

```
JMail.validator().disallowReservedDomains().isValid("test@example.com");
```

---
## 1.0.3

- Fix bug where JMail did not consider single quoted symbols (ex. `\@`) as valid.

---
## 1.0.2

- Better javadocs
- Internal performance improvements

---
## 1.0.1

- Add `JMail.strictValidator()` that has pre-configured common rules enabled (stricter than the RFCs allow)

---
## 1.0.0

- Initial release of JMail with email validation, IP address validation, and custom rules.
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ class ComparisonTest {
.asList(jmailImpl, apacheImpl, javaMailImpl, rfc2822Impl);

@BeforeAll
@SuppressWarnings({"unused", "BeforeOrAfterWithIncorrectSignature"})
@SuppressWarnings({"unused"})
void setupFile() throws Exception {
Files.write(htmlFile, "".getBytes(StandardCharsets.UTF_8),
StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);
Expand All @@ -87,7 +87,7 @@ void setupFile() throws Exception {
}

@AfterAll
@SuppressWarnings({"unused", "BeforeOrAfterWithIncorrectSignature"})
@SuppressWarnings({"unused"})
void addTotals() throws Exception {
StringBuilder totals = new StringBuilder().append(" <tr>\n"
+ " <th scope=\"row\">Totals</th>\n");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,24 +37,33 @@ public static Stream<String> provideInvalidWhitespaceEmails() {
// Valid emails with quotes
public static Stream<Arguments> provideValidEmails() {
return Stream.of(
Arguments.of("\" \"@example.org", "\" \"", "example.org", ""),
Arguments.of("\"john..doe\"@example.org", "\"john..doe\"", "example.org", ""),
Arguments.of("\"email\"@example.com", "\"email\"", "example.com", ""),
Arguments.of("\"first@last\"@test.org", "\"first@last\"", "test.org", ""),
Arguments.of("\" \"@example.org", "\" \"", "example.org",
"Quoted whitespace is allowed"),
Arguments.of("\"john..doe\"@example.org", "\"john..doe\"", "example.org",
"Multiple dots in a row are allowed within quotes"),
Arguments.of("\"email\"@example.com", "\"email\"", "example.com",
"Simple quotes are allowed"),
Arguments.of("\"first@last\"@test.org", "\"first@last\"", "test.org",
"The @ symbol can be quoted"),
Arguments.of("very.unusual.\"@\".unusual.com@example.com",
"very.unusual.\"@\".unusual.com", "example.com", ""),
Arguments.of("\"first\\\"last\"@test.org", "\"first\\\"last\"", "test.org", ""),
"very.unusual.\"@\".unusual.com", "example.com",
"Quotes are allowed within the local-part when dot separated"),
Arguments.of("\"first\\\"last\"@test.org", "\"first\\\"last\"", "test.org",
"Quote characters can be backslash-escaped"),
Arguments.of("much.\"more\\ unusual\"@example.com",
"much.\"more\\ unusual\"", "example.com", ""),
"much.\"more\\ unusual\"", "example.com",
"Whitespace within quotes is allowed when backslash-escaped"),
// Arguments.of("very.\"(),:;<>[]\".VERY.\"very@\\\\ \"very\".unusual@strange.example.com",
// "very.\"(),:;<>[]\".VERY.\"very@\\\\ \"very\".unusual", "strange.example.com"),
Arguments.of("\"first\\\\last\"@test.org", "\"first\\\\last\"", "test.org", ""),
Arguments.of("\"first\\\\last\"@test.org", "\"first\\\\last\"", "test.org",
"Escaped backslashes are allowed"),
Arguments.of("\"Abc\\@def\"@test.org", "\"Abc\\@def\"", "test.org", ""),
Arguments.of("\"Fred\\ Bloggs\"@test.org", "\"Fred\\ Bloggs\"", "test.org", ""),
Arguments.of("\"Joe.\\\\Blow\"@test.org", "\"Joe.\\\\Blow\"", "test.org", ""),
Arguments.of("\"Abc@def\"@test.org", "\"Abc@def\"", "test.org", ""),
Arguments.of("\"Fred Bloggs\"@test.org", "\"Fred Bloggs\"", "test.org", ""),
Arguments.of("\"first\\last\"@test.org", "\"first\\last\"", "test.org", ""),
Arguments.of("\"first\\last\"@test.org", "\"first\\last\"", "test.org",
"Backslash is allowed without an escape within quotes"),
Arguments.of("\"Doug \\\"Ace\\\" L.\"@test.org", "\"Doug \\\"Ace\\\" L.\"", "test.org", ""),
Arguments.of("\"[[ test ]]\"@test.org", "\"[[ test ]]\"", "test.org", ""),
Arguments.of("\"test.test\"@test.org", "\"test.test\"", "test.org", ""),
Expand Down
20 changes: 10 additions & 10 deletions src/test/resources/invalid-addresses.csv
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,14 @@ x@x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x2345678
"\"@iana.org ; A single backslash is invalid
first\\@last@iana.org ; The extra @ must be quote-escaped
first.last@ ; The domain cannot be missing
test@example.com&#10; ; Invalid characters in the domain are not allowed
first.last@[IPv6:1111:2222:3333:4444:5555:6666:7777] ; IPv6 address does not have enough segments)
first.last@[IPv6:1111:2222:3333:4444:5555:6666:7777:8888:9999] ; IPv6 address has too many segments)
first.last@[IPv6:1111:2222::3333::4444:5555:6666] ; The IPv6 format is invalid (Only one set of :: is allowed)
first.last@[IPv6:1111:2222:333x::4444:5555] ; The IPv6 format is invalid (x is not a valid hexadecimal character)
first.last@[IPv6:1111:2222:33333::4444:5555] ; The IPv6 format is invalid (33333 is not a valid segment)
first.last@[IPv6::] ; The IPv6 format is invalid (: is invalid)
first.last@[IPv6::::] ; The IPv6 format is invalid (::: is invalid)
test@example.com&#10; ; The line feed character is not allowed in the domain
first.last@[IPv6:1111:2222:3333:4444:5555:6666:7777] ; IPv6 address does not have enough segments
first.last@[IPv6:1111:2222:3333:4444:5555:6666:7777:8888:9999] ; IPv6 address has too many segments
first.last@[IPv6:1111:2222::3333::4444:5555:6666] ; IPv6 domain literal must be valid (Only one set of :: is allowed)
first.last@[IPv6:1111:2222:333x::4444:5555] ; IPv6 domain literal must be valid (x is not a valid hexadecimal character)
first.last@[IPv6:1111:2222:33333::4444:5555] ; IPv6 domain literal must be valid (33333 is not a valid segment)
first.last@[IPv6::] ; IPv6 domain literal must be valid (: is invalid)
first.last@[IPv6::::] ; IPv6 domain literal must be valid (::: is invalid)
first.last@[IPv6::b4] ; The IPv6 format is invalid
first.last@[IPv6::::b4] ; The IPv6 format is invalid
first.last@[IPv6::b3:b4] ; The IPv6 format is invalid
Expand Down Expand Up @@ -124,8 +124,8 @@ foo@[\1.2.3.4] ;
first\last@test.org ; The \ character is not escaping anything
first(abc("def".ghi).mno)middle(abc("def".ghi).mno).last@(abc("def".ghi).mno)example(abc("def".ghi).mno).(abc("def".ghi).mno)com(abc("def".ghi).mno) ; The first comment is not dot separated
first(middle)last@test.org ; Comments in the middle of the local-part must be dot separated
"Unicode NULL ␀"@char.com ; The unicode null character must be escaped within quotes
Unicode NULL \␀@char.com ; The escaped unicode null character is only allowed within quotes
"Unicode NULL ␀"@char.com ; The unicode null character must be escaped within quotes
Unicode NULL \␀@char.com ; The escaped unicode null character is only allowed within quotes
"test"test@test.com ; Quotes must be dot separated
()@test.com ; Empty comment is not allowed
test@really.long.topleveldomainisnotallowedunfortunatelyforpeoplewholikereallylongtopleveldomainnames ; The top level domain can only be 63 characters long
Expand Down
14 changes: 7 additions & 7 deletions src/test/resources/valid-addresses.csv
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Format: email-to-test,expected-local-part,expected-domain,Description
File format: email-to-test,expected-local-part,expected-domain,description
simple@example.com,simple,example.com,A simple valid email address
very.common@example.com,very.common,example.com,A simple address with a dot separator
very.common@example.org,very.common,example.org,A simple address ending in .org
Expand Down Expand Up @@ -110,13 +110,13 @@ first(abc.def).last@test.org,first(abc.def).last,test.org,
first(a"bc.def).last@test.org,first(a"bc.def).last,test.org,
first.(")middle.last(")@test.org,first.(")middle.last("),test.org,
first.last@x(1234567890123456789012345678901234567890123456789012345678901234567890).com,first.last,x(1234567890123456789012345678901234567890123456789012345678901234567890).com,
user%uucp!path@berkeley.edu,user%uucp!path,berkeley.edu,
first().last@test.org,first().last,test.org,
mymail\@hello@hotmail.com,mymail\@hello,hotmail.com,
Abc\@def@test.org,Abc\@def,test.org,
Fred\ Bloggs@test.org,Fred\ Bloggs,test.org,
user%uucp!path@berkeley.edu,user%uucp!path,berkeley.edu,The % and ! symbols are valid in the local-part
first().last@test.org,first().last,test.org,Empty comments are valid
mymail\@hello@hotmail.com,mymail\@hello,hotmail.com,Escaped @ symbols are allowed
Abc\@def@test.org,Abc\@def,test.org,Escaped @ symbols are allowed
Fred\ Bloggs@test.org,Fred\ Bloggs,test.org,Whitespace is allowed when quoted or between parts
Joe.\\Blow@test.org,Joe.\\Blow,test.org,
test\<angled@mytest.edu,test\<angled,mytest.edu,
test\<angled@mytest.edu,test\<angled,mytest.edu,Angled bracket is allowed when quoted
{^c\@**Dog^}@cartoon.com,{^c\@**Dog^},cartoon.com,
phil.h\@\@ck@haacked.com,phil.h\@\@ck,haacked.com,Escaped @ symbols are allowed
abc\\@test.org,abc\\,test.org,Escaped backslash is allowed
Expand Down

0 comments on commit 97be15c

Please sign in to comment.