-
-
Notifications
You must be signed in to change notification settings - Fork 261
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
256 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
# MailChecker | ||
|
||
[![Deps]( https://img.shields.io/david/FGRibreau/mailchecker.svg)](https://david-dm.org/FGRibreau/mailchecker) [![NPM version](https://img.shields.io/npm/v/mailchecker.svg)](http://badge.fury.io/js/mailchecker) [![Gem version](https://img.shields.io/gem/v/ruby-mailchecker.svg)](http://badge.fury.io/js/mailchecker) [![PyPi version](https://img.shields.io/pypi/v/mailchecker.svg)](https://pypi.org/project/mailchecker/#history) [![Packagist version](https://img.shields.io/packagist/v/FGRibreau/mailchecker.svg)](https://packagist.org/packages/fgribreau/mailchecker) [![Cargo version](https://img.shields.io/crates/v/mailchecker.svg)](https://crates.io/crates/mailchecker) [![Downloads](http://img.shields.io/npm/dm/mailchecker.svg)](https://www.npmjs.com/package/mailchecker) | ||
[![Deps]( https://img.shields.io/david/FGRibreau/mailchecker.svg)](https://david-dm.org/FGRibreau/mailchecker) [![NPM version](https://img.shields.io/npm/v/mailchecker.svg)](http://badge.fury.io/js/mailchecker) [![Gem version](https://img.shields.io/gem/v/ruby-mailchecker.svg)](http://badge.fury.io/js/mailchecker) [![PyPi version](https://img.shields.io/pypi/v/mailchecker.svg)](https://pypi.org/project/mailchecker/#history) [![Packagist version](https://img.shields.io/packagist/v/FGRibreau/mailchecker.svg)](https://packagist.org/packages/fgribreau/mailchecker) [![Cargo version](https://img.shields.io/crates/v/mailchecker.svg)](https://crates.io/crates/mailchecker) [![Downloads](http://img.shields.io/npm/dm/mailchecker.svg)](https://www.npmjs.com/package/mailchecker) [![GoDoc](https://godoc.org/github.com/FGRibreau/mailchecker/platform/go?status.svg)](https://godoc.org/github.com/FGRibreau/mailchecker/platform/go) | ||
|
||
[![Get help on Codementor](https://cdn.codementor.io/badges/get_help_github.svg)](https://www.codementor.io/francois-guillaume-ribreau?utm_source=github&utm_medium=button&utm_term=francois-guillaume-ribreau&utm_campaign=github) [![available-for-advisory](https://img.shields.io/badge/available%20for%20advising-yes-ff69b4.svg?)](http://bit.ly/2c7uFJq) ![extra](https://img.shields.io/badge/actively%20maintained-yes-ff69b4.svg?) | ||
|
||
|
@@ -72,6 +72,7 @@ MailChecker currently supports: | |
* [Rust](https://github.com/FGRibreau/mailchecker/tree/master/platform/rust) ([Instructions](#rust)) | ||
* [Elixir](https://github.com/FGRibreau/mailchecker/tree/master/platform/elixir) ([Instructions](#elixir)) | ||
* [Clojure](https://github.com/FGRibreau/mailchecker/tree/master/platform/clojure) ([Instructions](#clojure)) | ||
* [Go](https://github.com/FGRibreau/mailchecker/tree/master/platform/go) ([Instructions](#go)) | ||
* **Easily add support for your own language with MailChecker template system and [send us a pull-request!](https://github.com/FGRibreau/mailchecker/fork_select)** | ||
|
||
------------------------- | ||
|
@@ -185,11 +186,36 @@ end | |
(throw (Throwable. "O RLY!"))) | ||
``` | ||
|
||
### Go | ||
|
||
```go | ||
package main | ||
|
||
import ( | ||
"log" | ||
|
||
"github.com/FGRibreau/mailchecker/platform/go" | ||
) | ||
|
||
if !mail_checker.IsValid('[email protected]') { | ||
log.Fatal('O RLY !'); | ||
} | ||
|
||
if !mail_checker.IsValid('myemail.com') { | ||
log.Fatal("O RLY !") | ||
} | ||
``` | ||
|
||
-------------------- | ||
|
||
|
||
## Installation | ||
|
||
Go | ||
```bash | ||
go get https://github.com/FGRibreau/mailchecker | ||
``` | ||
|
||
NodeJS/JavaScript | ||
```bash | ||
npm install mailchecker | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
module github.com/FGRibreau/mailchecker | ||
|
||
go 1.13 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
package mail_checker | ||
|
||
import ( | ||
"regexp" | ||
"strings" | ||
) | ||
|
||
var ( | ||
// emailRegex from https://github.com/asaskevich/govalidator as the go regex implementation does not fully support Perl | ||
// syntax: (?! | ||
emailRegex = regexp.MustCompile("^(((([a-zA-Z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])+(\\.([a-zA-Z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])+)*)|((\\x22)((((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(([\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f]|\\x21|[\\x23-\\x5b]|[\\x5d-\\x7e]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])|(\\([\\x01-\\x09\\x0b\\x0c\\x0d-\\x7f]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}]))))*(((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(\\x22)))@((([a-zA-Z]|\\d|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])|(([a-zA-Z]|\\d|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])([a-zA-Z]|\\d|-|\\.|_|~|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])*([a-zA-Z]|\\d|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])))\\.)+(([a-zA-Z]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])|(([a-zA-Z]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])([a-zA-Z]|\\d|-|_|~|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])*([a-zA-Z]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])))\\.?$") | ||
blacklist = []string{ | ||
{{&listSTR}}, | ||
} | ||
) | ||
|
||
func allDomainSuffixes(domain string) []string { | ||
|
||
components := strings.Split(domain, ".") | ||
|
||
var result []string | ||
|
||
for i := range components { | ||
result = append(result, strings.Join(components[i:], ".")) | ||
} | ||
|
||
return result | ||
} | ||
|
||
// IsValid checks if the email address is a valid email address and is not blacklisted | ||
func IsValid(email string) bool { | ||
|
||
email = strings.ToLower(email) | ||
|
||
return emailRegex.MatchString(email) && !IsBlacklisted(email) | ||
} | ||
|
||
// IsBlacklisted checks if the email address is blacklisted | ||
func IsBlacklisted(email string) bool { | ||
|
||
parts := strings.Split(email, "@") | ||
|
||
if len(parts) != 2 { | ||
return false | ||
} | ||
|
||
for _, domainSuffix := range allDomainSuffixes(parts[1]) { | ||
for _, blacklistedDomain := range blacklist { | ||
if blacklistedDomain == domainSuffix { | ||
return true | ||
} | ||
} | ||
} | ||
|
||
return false | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
package mail_checker | ||
|
||
import ( | ||
"fmt" | ||
"reflect" | ||
"testing" | ||
) | ||
|
||
func TestReturnTrueIfValidEmail(t *testing.T) { | ||
emails := []string{ | ||
"[email protected]", | ||
"[email protected]", | ||
"[email protected]", | ||
"[email protected]", | ||
"[email protected]", | ||
"[email protected]", | ||
} | ||
|
||
for i, email := range emails { | ||
if !IsValid(email) { | ||
t.Errorf("Valid email %x (test case %d) was considered invalid", email, i) | ||
} | ||
} | ||
} | ||
|
||
func TestReturnFalseIfEmailInvalid(t *testing.T) { | ||
emails := []string{ | ||
"", | ||
" ", | ||
"plopplop.com", | ||
"my+ok@ok=plop.com", | ||
"my,[email protected]", | ||
" [email protected] ", | ||
" [email protected]", | ||
"[email protected] ", | ||
"\n[email protected]\n", | ||
"\n[email protected]", | ||
"[email protected]\n", | ||
} | ||
|
||
for i, email := range emails { | ||
if IsValid(email) { | ||
t.Errorf("Invalid email %x (test case %d) was considered valid", email, i) | ||
} | ||
} | ||
} | ||
|
||
func TestReturnFalseIfThrowableDomain(t *testing.T) { | ||
emails := []string{ | ||
"[email protected]", | ||
"[email protected]", | ||
"[email protected]", | ||
"[email protected]", | ||
} | ||
|
||
for i, email := range emails { | ||
if IsValid(email) { | ||
t.Errorf("Email with blacklisted domain %x (test case %d) was considered valid", email, i) | ||
} | ||
} | ||
} | ||
|
||
func TestExtractAllDomainSuffixes(t *testing.T) { | ||
testCases := []struct { | ||
domain string | ||
expected []string | ||
}{ | ||
{ | ||
domain: "sub.example.org", | ||
expected: []string{"sub.example.org", "example.org", "org"}, | ||
}, | ||
} | ||
|
||
for i, testCase := range testCases { | ||
result := allDomainSuffixes(testCase.domain) | ||
|
||
if !reflect.DeepEqual(result, testCase.expected) { | ||
t.Errorf("Extracted domain suffixes for %s (test case %d) does not match expected result", testCase.domain, i) | ||
} | ||
} | ||
} | ||
|
||
func TestReturnFalseForBlacklistedDomainsAndTheirSubdomains(t *testing.T) { | ||
testCases := []struct { | ||
template string | ||
valid bool | ||
}{ | ||
{ | ||
template: "test@%s", | ||
valid: false, | ||
}, | ||
{ | ||
template: "test@subdomain.%s", | ||
valid: false, | ||
}, | ||
{ | ||
template: "test@%s.gmail.com", | ||
valid: true, | ||
}, | ||
} | ||
|
||
for i, testCase := range testCases { | ||
for _, blacklistedDomain := range blacklist { | ||
|
||
email := fmt.Sprintf(testCase.template, blacklistedDomain) | ||
result := IsValid(email) | ||
|
||
if result != testCase.valid { | ||
t.Errorf("Expected result for email %s (test case %d) is %t, got %t", email, i, testCase.valid, result) | ||
} | ||
} | ||
} | ||
} |