Git Product home page Git Product logo

checkmail's Introduction

checkmail

Golang package for email validation.

GoDoc

Usage

Install the Checkmail package

go get github.com/badoux/checkmail

1. Format

func main() {
    err := checkmail.ValidateFormat("ç$€§/[email protected]")
    if err != nil {
        fmt.Println(err)
    }
}

output: invalid format

2. Domain

func main() {
    err := checkmail.ValidateHost("[email protected]")
    if err != nil {
        fmt.Println(err)
    }
}

output: unresolvable host

3. Host and User

If host is valid, requires valid SMTP serverHostName (see to online validator) and serverMailAddress to reverse validation for prevent SPAN and BOTS.

func main() {
    var (
        serverHostName    = "smtp.myserver.com" // set your SMTP server here
        serverMailAddress = "[email protected]"  // set your valid mail address here
    )
    err := checkmail.ValidateHostAndUser(serverHostName, serverMailAddress, "[email protected]")
    if smtpErr, ok := err.(checkmail.SmtpError); ok && err != nil {
        fmt.Printf("Code: %s, Msg: %s", smtpErr.Code(), smtpErr)
    }
}

output: Code: 550, Msg: 550 5.1.1 The email account that you tried to reach does not exist.

License

Checkmail is licensed under the MIT License.

checkmail's People

Contributors

agau4779 avatar badoux avatar disconnekt avatar doctor-henry avatar dolmen avatar goodnessuc avatar iwex avatar k0st1an avatar moisespsena avatar octopepper avatar sergeyfast avatar shuler avatar skolodyazhnyy avatar thanhpk avatar xescugc avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

checkmail's Issues

no route to host

Hi

when i try your third example (user), i always get the following result:

Code: dia, Msg: dial tcp 74.125.71.26:25: getsockopt: no route to host

Is this a error with smtp? And do you know how to fix this?

Best regards

Double-quoted-user-part of an email address should be valid

A valid email address: "[email protected]"@example2.com cannot pass checkmail.ValidateFormat()

quoted:

space and "(),:;<>@[] characters are allowed with restrictions (they are only allowed inside a quoted string, as described in the paragraph below, and in addition, a backslash or double-quote must be preceded by a backslash);

It seems like current regex in checkmail.emailRegexp is rather simple.
Reference regex:

var emailRegexp = regexp.MustCompile("(?:[a-z0-9!#$%&'+/=?^_{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_{|}~-]+)|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])")@(?:(?:a-z0-9?\.)+a-z0-9?|\[(?:(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9]))\.){3}(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9])|[a-z0-9-][a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])")

Release a version

Please release a version so vendoring can work with a specific version.

A regex?

You link to a document that says don't use a regex, and then use a regex. At work, we send about 1.6 billion emails a day. We agree with the article. Search for @.

Set a MX timeout

Instead of using the default resolver to lookup the MX record. I recommend using a custom resolver with a context timeout to prevent long-lived connections.

https://github.com/badoux/checkmail/blob/master/checkmail.go#L49

    const timeout = 10 * time.Millisecond
    ctx, cancel := context.WithTimeout(context.TODO(), timeout)
    defer cancel() // important to avoid a resource leak
    var r net.Resolver
    names, err := r.LookupMX(ctx, "127.0.0.1")
    if err == nil && len(names) > 0 {
        fmt.Println(names[0]) // "localhost"
    }

https://play.golang.org/p/HTW6-2o0qeT

panic: runtime error: invalid memory address or nil pointer dereference

Hi,
func ValidateHost() of checkmail.go trow "panic: runtime error: invalid memory address or nil pointer dereference" if err is not nil on connection.
You should check the error before call the defer function on line 55.

(https://stackoverflow.com/questions/16280176/go-panic-runtime-error-invalid-memory-address-or-nil-pointer-dereference)

Regards

Update: I just see that you already have a couple of pull requests for this. I close my issue as duplicated.

Will this repo be better than email-verifier?

Hi, I am not very familiar with the principle of email address verification.

We have a new Go backend service that needs to verify the email addresses of newly registered users, and I found two repos: this one and AfterShip/email-verifier.

Compared to email-verifier, I found that this repo only provides verification of format, domain and user But it is simple and efficient enough, and the other one seems to have an outgoing smtp 25 port limit while providing multiple dimensions to check(including disposable and free domain).

My question is, is it possible to use this library to accurately and efficiently verify the validity of user addresses for new user mailboxes?

last two versions released are missing `v` in front

the last two versions 1.2.2 and 1.2.3 are missing the v in front of them that is required for go mod to pick them up

resultL:

go: downloading github.com/badoux/checkmail v1.2.3
go: github.com/badoux/[email protected]: reading github.com/badoux/checkmail/go.mod at revision v1.2.3: unknown revision v1.2.3

always got error althougt email is real

Hi, I always got Error 421 Cannot connect to SMTP server 74.125.68.26 (74.125.68.26:25), connect error 10060 althought it's valid email

Do you have any ideas to fix it

Panic on smtp

panic: runtime error: slice bounds out of range

goroutine 1 [running]:
main.split(0x0, 0x0, 0x0, 0x561540, 0x561500, 0xffffffffffffffff)
E:/GoProject/Project/src/goproject/hello.go:73 +0xa2
main.ValidateHost(0x0, 0x0, 0x0, 0x0)
E:/GoProject/Project/src/goproject/hello.go:45 +0x6c
main.main()
E:/GoProject/Project/src/goproject/hello.go:120 +0x208
exit status 2

invalid memory address or nil pointer dereference

When the host is existed but port not available. Example: g2mail.com:

panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x1187ba2]

goroutine 1 [running]:
net/smtp.(*Client).Close(0x0, 0x122d620, 0xc4200a0370)
	/usr/local/go/src/net/smtp/smtp.go:76 +0x22
github.com/k0st1an/tests/emailcheck/vendor/github.com/badoux/checkmail.ValidateHost(0x7ffeefbff97c, 0x13, 0x122dc20, 0xc42005aee0)
	/Users/k0st1an/develop/golang/src/github.com/k0st1an/tests/emailcheck/vendor/github.com/badoux/checkmail/checkmail.go:57 +0x441
main.emailIsValid(0x7ffeefbff97c, 0x13, 0x0)
	/Users/k0st1an/develop/golang/src/github.com/k0st1an/tests/emailcheck/emailcheck.go:26 +0x57
main.main()
	/Users/k0st1an/develop/golang/src/github.com/k0st1an/tests/emailcheck/emailcheck.go:15 +0x42

Supposedly invalid addresses are passing validation

I've found a list of supposedly invalid email addresses.

Apparently they violate rfc2822.

Some of them are passing validation in checkmail.

invalidEmails := []string {
    "[email protected]",
    "[email protected]",
    "[email protected]",
    "email@example",
    "[email protected]",
    "[email protected]",
    "[email protected]",
    "[email protected]",
}

// ^ These are all considered valid by checkmail,

I think it has something to do with leading/trailing/double period characters.

Are these meant to be passing validation or not?

Please tag a new release and start using Semantic Versioning

I found that this project already supports Go modules. But sadly, the tags doesn't follow Semantic Versioning, which means that all tags of this project will be ignored by Go modules and replaced by pseudo-versions, go get acts weirdly when tags are not in that form. It would be great to have the tagged release be named in the format vX.X.X format so that go mod can read it.

	github.com/badoux/checkmail v0.0.0-20200623144435-f9f80cb795fa

Else the mod file shows something like github.com/badoux/checkmail v0.0.0-20200623144435-f9f80cb795fa which is not very readable and difficult to upgrade. It’s hard to verify which version is in use. This is not conducive to version control

So, I propose this project to follow Semantic Versioning in future versions. For example, v1.0.1, v2.0.0, v3.1.0-alpha, v3.1.0-beta.2etc.

runtime error: slice bounds out of range [:-1]

split() fails if the email address passed through is blank and returns runtime error: slice bounds out of range [:-1]

For example using ValidateHost() and passing an empty string or does not contain @ symbol

var formData struct {
    EmailAddress string
    ...
}
// get form data from post and populate formData variable

// assume formData.EmailAddress = "" or does not contain @ symbol
err := checkmail.ValidateHost(formData.EmailAddress)
if err != nil {
	fmt.Println(err)
}

This would happen where ever split() is used

func split(email string) (account, host string, err error) {
        // This is where the code currently fails as email = "" or does not contain the @ symbol
	i := strings.LastIndexByte(email, '@')
	account = email[:i]
	host = email[i+1:]
	return
}

Below is an updated split() function I have tested which could be a solution?

It reuses the regex used by ValidateFormat() before trying to generate the slice and passes the error back and allows for it to be caught by the error returned by checkmail.ValidateHost(...)

func split(email string) (account, host string, err error) {
	if !emailRegexp.MatchString(strings.ToLower(email)) {
		err = ErrBadFormat
		return
	}
	i := strings.LastIndexByte(email, '@')
	account = email[:i]
	host = email[i+1:]
	return
}

This feels a bit more robust compared to checking the format and then checking if the user/host is valid? Correct me if I'm wrong

Another potential solution could be the below if you don't want to use the regex again? and just checks that the email being passed in is not an empty string and contains the @ symbol

func split(email string) (account, host string, err error) {
	if email == "" || !strings.Contains(email, "@") {
		err = ErrBadFormat
		return
	}
	fmt.Println("Getting LastIndexByte")
	i := strings.LastIndexByte(email, '@')
	account = email[:i]
	fmt.Println(account)
	host = email[i+1:]
	fmt.Println(host)
	return
}

EOF

getting EOF error for some email, how to handle this

Error with same provider

Hi i have an error to check same provider host like:
gmx.de, net or com
freenet.de, web.de, ecc

error:

gmx.net (mxgmx002) Nemesis ESMTP Service not available
No SMTP service
Bad DNS PTR resource record.

or

freenet.de 550 inconsistent or no DNS PTR record for 95.110.198.3

double verification

Hello,
I do not see any sense in mixing domain mx validation with actual verifying of email user. verification should be on one function and email verifying should be on another function. That makes much sense and reduce double load on the verifying ip

Think about it bro

Change regex to match all the email addresses according to RFC 3696

According to RFC 3696, Application Techniques for Checking and Transformation of Names, the example email address used in the first example of README.md is apparently a valid email address.

Similarly, these are all valid email addresses:

For more, check this I Knew How To Validate An Email Address Until I Read The RFC

Doesn't work with Yahoo! Any other ideas?

I know Yahoo! always sends 250 even if the mailbox does not exist. Are there any work arounds or ideas I could use? I have seen some commercial services verify Yahoo! email addresses properly. I was wondering how they do that.

BTW, thank for your awesome work!

Panic when MX record is empty

client, err := DialTimeout(fmt.Sprintf("%s:%d", mx[0].Host, 25), forceDisconnectAfter)

I just tested with random host name, for example like invalidmail.com. The LookupMX function does not return an error, but the MX record is empty. So, it will panic on line 64 when accessing the first index of empty MX record. I think it's better to check the length of MX record first.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.