Reduce misspelled email addresses in your web apps.

Overview

mailcheck.js

TravisCI Build Status

The Javascript library and jQuery plugin that suggests a right domain when your users misspell it in an email address.

mailcheck.js is part of the Mailcheck family, and we're always on the lookout for more ports and adaptions. Get in touch!

What does it do?

When your user types in "[email protected]", Mailcheck will suggest "[email protected]".

Mailcheck will offer up suggestions for second and top level domains too. For example, when a user types in "[email protected]", "hotmail.com" will be suggested. Similarly, if only the second level domain is misspelled, it will be corrected independently of the top level domain.

diagram

See it live in action here.

Installation

For instant use, download the minified library mailcheck.min.js into your javascripts directory. mailcheck.js is also available unminimised if you want to hack on it, or have your own minimizer.

Bower

> bower install --save mailcheck

Node/Browserify

> npm install --save mailcheck

Usage with jQuery

First, include jQuery and Mailcheck into the page.

<script src="jquery.min.js"></script>
<script src="mailcheck.min.js"></script>

Have a text field.

<input id="email" name="email" type="email" />

Now, attach Mailcheck to the text field. You can declare an array of domains, second level domains and top level domains you want to check against.

<script>
var domains = ['gmail.com', 'aol.com'];
var secondLevelDomains = ['hotmail']
var topLevelDomains = ["com", "net", "org"];

var superStringDistance = function(string1, string2) {
  // a string distance algorithm of your choosing
}

$('#email').on('blur', function() {
  $(this).mailcheck({
    domains: domains,                       // optional
    secondLevelDomains: secondLevelDomains, // optional
    topLevelDomains: topLevelDomains,       // optional
    distanceFunction: superStringDistance,  // optional
    suggested: function(element, suggestion) {
      // callback code
    },
    empty: function(element) {
      // callback code
    }
  });
});
</script>

Mailcheck takes in two callbacks, suggested and empty. We recommend you supply both.

suggested is called when there's a suggestion. Mailcheck passes in the target element and the suggestion. The suggestion is an object with the following members:

{
  address: 'test',          // the address; part before the @ sign
  domain: 'gmail.com',    // the suggested domain
  full: '[email protected]'  // the full suggested email
}

Mailcheck does not want to get in the way of how you can show suggestions. Use the suggestion object to display suggestions in your preferred manner.

empty is called when there's no suggestion. Mailcheck just passes in the target element. It is a good idea to use this callback to clear an existing suggestion.

Usage without jQuery

Mailcheck is decoupled from jQuery, so its usage without jQuery is almost identical.

Using the example from above, you would call Mailcheck.run instead.

<script>
Mailcheck.run({
  email: yourTextInput.value,
  domains: domains,                       // optional
  topLevelDomains: topLevelDomains,       // optional
  secondLevelDomains: secondLevelDomains, // optional
  distanceFunction: superStringDistance,  // optional
  suggested: function(suggestion) {
    // callback code
  },
  empty: function() {
    // callback code
  }
});
</script>

The rest works similarly. In fact, the Mailcheck jQuery plugin just wraps Mailcheck.run.

Usage on Node.js

If you're running this on Node.js, you can just require('mailcheck') to get the mailcheck object, and call run on that:

var mailcheck = require('mailcheck');

mailcheck.run({
  // see 'usage without jQuery' above.
});

Domains

Mailcheck has inbuilt defaults if the domains, secondLevelDomains or topLevelDomains options aren't provided. We still recommend supplying your own domains based on the distribution of your users.

Adding your own Domains

You can replace Mailcheck's default domain/TLD suggestions by supplying replacements to mailcheck.run:

Mailcheck.run({
  domains: ['customdomain.com', 'anotherdomain.net'], // replaces existing domains
  secondLevelDomains: ['domain', 'yetanotherdomain'], // replaces existing SLDs
  topLevelDomains: ['com.au', 'ru'] // replaces existing TLDs
});

Alternatively, you can extend Mailcheck's global set of default domains and TLDs by adding items to Mailcheck.defaultDomains and Mailcheck.defaultTopLevelDomains:

Mailcheck.defaultDomains.push('customdomain.com', 'anotherdomain.net') // extend existing domains
Mailcheck.defaultSecondLevelDomains.push('domain', 'yetanotherdomain') // extend existing SLDs
Mailcheck.defaultTopLevelDomains.push('com.au', 'ru') // extend existing TLDs

Customization

The Mailcheck jQuery plugin wraps Mailcheck. The prime candidates for customization are the methods Mailcheck.findClosestDomain and Mailcheck.stringDistance.

Mailcheck currently uses the sift3 string similarity algorithm by Siderite. You can modify the inbuilt string distance function, or pass in your own when calling Mailcheck.

Since Mailcheck runs client side, keep in mind file size, memory usage and performance.

Tests

Mailcheck is tested with Jasmine. Run npm test from the command line to run the test suite. Alternatively, you can Load spec/spec_runner.html in your browser.

Contributing

Let's make Mailcheck awesome. We're on the lookout for maintainers and contributors.

And do send in those pull requests! To get them accepted, please:

  • Test your code. Add test cases to spec/mailcheckSpec.js, and run it across browsers (yes, including IE).
  • Minify the plugin by running grunt in the Mailcheck directory (npm install should have installed a git pre-commit hook that takes care of this for you).

Upcoming features, bugs and feature requests are managed in Issues.

Who uses Mailcheck?

Do you use Mailcheck? Tweet me your link.

Related Links

Core Team

License

Released under the MIT License.

Comments
  • valid secondLevelDomain + topLevelDomain combination still gets corrected to

    valid secondLevelDomain + topLevelDomain combination still gets corrected to "likely" choice from domains list.

    Taking the example straight from the README.md:

    var domains = ['gmail.com', 'aol.com'];
    var secondLevelDomains = ['hotmail']
    var topLevelDomains = ["com", "net", "org"];
    

    then a user entering "[email protected]" will have "[email protected]" suggested to them.

    Surely that can't be the desired behaviour?

    http://jsfiddle.net/8habg633/

    opened by hjwp 11
  • Bower points to a fork

    Bower points to a fork

    Consider the following command and output.

    $ bower search mailcheck
    Search results:
    
        mailcheck git://github.com/niftylettuce/mailcheck.git
    

    The bower package mailcheck points to a fork by @niftylettuce. That fork is way behind master and it misses tag 1.1.0.

    I suggest to create a new mailcheck package and point it to this repository. And also to update the docs.

    opened by Nyholm 9
  • mailw.com is not mail.com or gmail.com

    mailw.com is not mail.com or gmail.com

    I own the domain mailw.com and when I enter the domain it asks if I am sure it is not mail.com.

    This is not useful when you start questioning real domains. It makes the user think they are using a mail service which is not popular enough. If this is going to happen. You are doing FREE advertising for other mail services.

    The w is on the opposite side of the keyboard so the user is not likely to misspell the domain anyway. I would look for typos of possibly maill.com or mail,com or maik.com maybe but even then how can you check spelling of domains when domains are misspelled anyway. All you can check is for incorrectly formatted emails.

    opened by ghost 9
  • sift3 string distance in IE7 is invalid.

    sift3 string distance in IE7 is invalid.

    This got caught by our QA team:

    https://github.com/DimitarChristoff/mailcheck/issues/1

    compare: String.distance('gmails.com', 'aol.co.uk')

    Expected / seen: 8.5 in major browsers, actual: 0.5 in IE7 As a result, in IE7:

    Expect [email protected]' to suggest[email protected], actual:[email protected]in our DB Expect[email protected]' to suggest [email protected], actual: [email protected] in your kicksend DB

    As a workaround, I have now added levenstein to calculate the distance instead, seems far more reliable. https://github.com/DimitarChristoff/mailcheck/blob/master/src/String.distance.js#L71-93 or google for other implementations.

    This is now covered by my test coverage and buster.js reports the following tests in Ie7 (they pass in all other browsers):

    Internet Explorer 7.0 Windows: .FFF..........FFFFFF............
    Failure: Internet Explorer 7.0 Windows String.distance tests Expect distance between two strings with 1 typo to be 1
        [assert.equals] 0 expected to be equal to 1
    
    Failure: Internet Explorer 7.0 Windows String.distance tests Expect distance between two strings with 1 typo and 1 char difference to be 1.5
        [assert.equals] 0.5 expected to be equal to 1.5
    
    Failure: Internet Explorer 7.0 Windows String.distance tests Expect distance between two unrelated strings to be length of base string
        [assert.equals] 0 expected to be equal to 5
    
    Failure: Internet Explorer 7.0 Windows mailcheck.mootools distance tests Working with emails > Expect a typo in domain to produce a suggestion (gnail.com -> gmail.com)
        [assert.equals] undefined expected to be equal to gmail.com
    
    Failure: Internet Explorer 7.0 Windows mailcheck.mootools distance tests Working with emails > Expect a typo in domain to produce a suggestion with custom threshold of 3 (gmail.org -> gmail.com)
        [assert.equals] undefined expected to be equal to gmail.com
    
    Failure: Internet Explorer 7.0 Windows mailcheck.mootools distance tests Working with emails > Expect uppercase user input not to matter to suggestions
        [assert.equals] fsmail.net expected to be equal to hotmail.com
    
    Failure: Internet Explorer 7.0 Windows mailcheck.mootools distance tests Working with emails > Expect obscure RFC compatible emails like "foo@bar"@gnail.com to produce a valid suggestion
        [assert.equals] undefined expected to be equal to gmail.com
    
    Failure: Internet Explorer 7.0 Windows mailcheck.mootools distance tests Working with emails > Expect cache to store look-up for faster future reference
        [assert.equals] false expected to be equal to gmail.com
    
    Failure: Internet Explorer 7.0 Windows mailcheck.mootools distance tests Working with emails > Expect cache to store look-up failures for faster future reference
        [assert.isFalse] Expected aol.co.uk to be false
    
    4 test cases, 32 tests, 32 assertions, 9 failures, 0 errors, 0 timeouts
    
    Bug Under Review 
    opened by DimitarChristoff 9
  • Case of illogical domain suggestion

    Case of illogical domain suggestion

    Hi there,

    i found case of illogical domain suggestion:

    domains = ["ua.com", "ui.com"], input val is [email protected], suggestion: [email protected], but if you look at keyboard image - it's obvious that i've mispelled for domain ui.com

    kb

    I clearly understand that built-in algorithm doesn't solve all cases, but i suggest to think about how to solve similar cases.

    opened by demark 7
  • invalid check?

    invalid check?

    https://github.com/Kicksend/mailcheck/blob/master/src/jquery.mailcheck.js#L21-22

    var parts = email.split('@');
    if (parts < 2) {
    

    what exactly are you testing for here? parts is going to be an array, should test parts.length - this will only fail on a falsy array... or if the email string is '1' or something.

    opened by DimitarChristoff 6
  • fix v1.1.0

    fix v1.1.0

    No code changes, just "version": "1.1.0" in 3 JSON, & /src header comments https://github.com/mailcheck/mailcheck/pull/76#issuecomment-45434593

    opened by tomByrer 5
  • Node.js support!

    Node.js support!

    Implements issue #54.

    Good news: I was able to use the existing Jasmine tests and run them on Node too, via jasmine-node. (Skipping the jQuery tests, of course.)

    $ npm test
    
    > [email protected] test /Users/aseemk/Projects/Node/mailcheck
    > jasmine-node spec/
    
    .............
    
    Finished in 0.025 seconds
    13 tests, 50 assertions, 0 failures, 0 skipped
    

    Hope you like. =)

    (Don't forget to publish to npm if you do. I didn't think I should be the one to do that.)

    opened by aseemk 5
  • Swap out sift3 for swift4 common

    Swap out sift3 for swift4 common

    Fix #113

    From Siderite's blog:

    After implementing Sift4, I can now tell you that the simple version is slightly better than Sift3 for small maxOffset values like 5, but it gets better as the value increases. The common version is a bit more complex, but the error decreases with 33% and maintains a low error for large maxOffset values.

    I pretty much just copied over the source. I took out the maxDistance for simplicity, and set a default maxOffset of 5 for consistency.

    opened by thatguyintech 4
  • Doesn't work in IE8

    Doesn't work in IE8

    I think mailcheck crashes in IE8 because of a single call to String.trim. I know IE8 is annoying, but we're so close!

    I have a long bus ride coming up this weekend, so I'll probably take a shot at it.

    opened by jdpopkin 4
  • Use diff thresholds for domain, top-level domain

    Use diff thresholds for domain, top-level domain

    Use a higher threshold when checking for an exact match with an entire domain. This is useful because otherwise we have a problem where corrections can "chain" - [email protected] leads to a suggestion of [email protected], which leads to a suggestion of yahoo.com.

    If the user was already corrected once, they shouldn't have to be corrected again - especially since they're using the answer we just gave them.

    opened by jdpopkin 4
  • Remove minified version of script

    Remove minified version of script

    Do not include minified version of script as part of source code and remove pre-commit hook. Because minified code can be easily generated from the unminified code, committing two codes of the script is an anti-pattern.

    opened by martey 1
  • List of Popular Domains

    List of Popular Domains

    Heads up, here's a larger and more comprehensive list of popular domains released by Hubspot for the wiki.

    See attached, sourced from https://knowledge.hubspot.com/forms/what-domains-are-blocked-when-using-the-forms-email-domains-to-block-feature

    free-domains.csv.zip

    opened by justerhan 1
  • Regular Expression DoS vulnerabilities in mailcheck/spec/lib/jquery.js

    Regular Expression DoS vulnerabilities in mailcheck/spec/lib/jquery.js

    We are working on the ReDoS problem and detected two vulnerable regexes from your code.

    /:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/ in link takes forever to match the string ":\\\b(\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b" We suggest you change the structure (?:\([^\)]+\)|[^\(\)]*)+, to [^\(\)]*(?:\([^\)]+\)[^\(\)]*)+.

    /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g in link takes forever to match the string "[\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b" We suggest you change the structure (?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+, to [^\[\]'"]*(?:(\[[^\[\]]*\]|['"][^'"]*['"])[^\[\]'"]*)+.

    Please try the following:

    var pattern = /:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/; 
    var input = ":\\\b(\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b";
    var re = new RegExp(pattern);
    var matched = input.match(re);
    
    var pattern = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g; 
    var input = "[\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b";
    var re = new RegExp(pattern);
    var matched = input.match(re);
    

    We didn’t create a pull request because we're not sure if these cases are possible to take place in your program, we also do not understand the functionality of these regexes as you do. Thank you for your understanding.

    opened by linci8210 1
  • The example in the readme doesn't use mailcheck anymore

    The example in the readme doesn't use mailcheck anymore

    The url to kickstarter in the readme under https://github.com/mailcheck/mailcheck#what-does-it-do doesn't use mailcheck anymore i didn't get email suggest

    opened by JohJohan 2
Releases(1.1.2)
  • v1.1.0(Aug 7, 2014)

    • Simplification of Mailcheck's namespace; Kicksend.mailcheck is now just Mailcheck.
    • Additional fixes from pull requests.

    This release potentially breaks backward compatibility if your app calls Mailcheck via Kicksend.mailcheck. Just replace all instances of Kicksend.mailcheck with Mailcheck.

    Source code(tar.gz)
    Source code(zip)
Owner
mailcheck
mailchecks for all platforms.
mailcheck
why make apps to increase focus -- when you can make apps to reduce focus

impossifocus ?? What is this? ImpossiFocus will measure focus by reading your brainwaves -- and if you're in the zone, it'll ensure that changes with

Aleem Rehmtulla 10 Nov 30, 2022
Proxy but misspelled -- closed proxy for the internet

pyrox Proxy that runs on Cloudflare Workers. Setup Install wrangler2. npm install wrangler. Generate a public Ed25519 key, exported under SPKI mode wi

bots.gg 10 Sep 9, 2022
Email Genie Allows autocomplete on email field by providing a list of domain suggestions (gmail.com, outlook.com, etc.).

Allows users to easily and quickly complete an email field by providing a list of domain suggestions (gmail.com, outlook.com, etc.). This package stands out for its flexibility, its compatibility with libraries / frameworks, but especially its use of basic HTML and Javascript functionalities that maximize the native behavior of desktop AND mobile browsers.

Simon Arnold 3 Oct 4, 2022
Jonathan Parker 6 Nov 23, 2022
Eth-explorers-extension - Chrome extension to open Ethereum addresses & transaction hash from any page on popular explorers + dashboards

eth-explorers-extension(s) This repository contains two folders with two extensions that work for address and transactions respectively. 1. eth-addres

Apoorv Lathey 71 Jan 6, 2023
Script to fetch all NFT owners using moralis API. This script output is a data.txt file containing all owner addresses of a given NFT and their balances.

?? Moralis NFT Snapshot Moralis NFT API will only return 500 itens at a time when its is called. For that reason, a simple logic is needed to fetch al

Phill Menezes 6 Jun 23, 2022
📃 A public dataset of crypto addresses labeled

EVM Labels A public dataset of crypto addresses labeled (Ethereum and more) Ethereum Label CSV JSON Updated exchange (Centralized Exchanges) View CSV

earnifi 69 Jan 7, 2023
Minimal versions of popular analytics libraries. Reduce the impact of third-party scripts on your application.

minimal-analytics This project aims to provide minimal implementations of popular analytics libraries. It's aimed at users who want to reduce the impa

James Hill 32 Dec 25, 2022
JavaScript library to resize, reduce, or change ranges of DOM elements.

Range.js JavaScript library to resize, reduce, or change ranges of DOM elements using the HTML5 <input type="range"> element. Usage: Include range.js

Kyle Belanger 4 Jun 3, 2021
Reduce image size of 1000s of photos as a batch.

downsizer A tiny tool to reduce size of images in bulk. Helps you to bulk reduce size of images in a folder or individual images. Install Install Node

Vajahath Ahmed 2 Sep 15, 2022
Demodal is a browser extension that automatically removes content blocking modals including paywalls, discount offers, promts to sign up or enter your email address and more.

Demodal Demodal is a browser extension that automatically removes content blocking modals including paywalls, discount offers, promts to sign up or en

Elbert Alias 225 Jan 4, 2023
💌 A simple contact form that helps people send you a message. 📩 to your email. - built with JavaScript/Nodemailer 📃

Implementation using async/await: app.js const contactForm = document.querySelector(".contact-form"); let name = document.getElementById("name"); let

Tobi Adesokan 8 Aug 17, 2022
Open apps directly in GNOME Software by clicking Install from Flathub and apps.gnome.

Flatline Open apps directly in GNOME Software by clicking Install from Flathub and apps.gnome. Load the extension in Firefox Clone the repository Open

Cleo Menezes Jr. 43 Nov 7, 2022
Sample apps showing how to build music and video apps for Xbox using a WebView.

description languages name page_type products urlFragment Sample showing how to build music and video apps using primarily web technologies for Xbox.

Microsoft 11 Dec 14, 2022
A plugin for Strapi Headless CMS that provides ability to sign-in/sign-up to an application by link had sent to email.

Strapi PasswordLess Plugin A plugin for Strapi Headless CMS that provides ability to sign-in/sign-up to an application by link had sent to email. A pl

Andrey Kucherenko 51 Dec 12, 2022
📧 Layanan pengirim pesan elektronik (email) dengan API.

?? Fimail Fimail, layanan pengirim pesan elektronik dengan API. Dibuat dengan ❤ dan NodeJs oleh Feri Irawan pada 31/12/2021 06.27 ⚡ Memulai Cepat Beri

Feri Irawan 4 Dec 22, 2022
A free simple responsive HTML email template

Free Responsive HTML Email Template Sometimes all you want is a really simple responsive HTML email template with a clear call-to-action button. Here

Lee Munroe 11.8k Dec 30, 2022
This is an unofficial front end for Hacker News, reminiscent of the Windows XP era Outlook email client on a Windows XP default desktop

Hacker XP Hacker News styled as the Windows XP Outlook email client. Try out Hacker XP here! Description This is an unofficial front end for Hacker Ne

null 19 Jul 12, 2022
LucaMail - an Open Source,Cross Platform Email Client

LucaMail v0.0.1-beta An Awesome Cross Platform Email Client! Note : This Project Is Still in Beta Version Website . Report Bug . Request Feature . Dis

Yuva raghav 210 Dec 28, 2022