From 78ee5fb270505a07be586f7e6f9aef9405bc672f Mon Sep 17 00:00:00 2001 From: Alen Alex <71920951+AlenGeoAlex@users.noreply.github.com> Date: Tue, 18 Apr 2023 20:24:46 +0530 Subject: [PATCH] Added MailChecker.java --- .../java/io/github/fgribreau/MailChecker.java | 104 ++++++++++++++++++ 1 file changed, 104 insertions(+) create mode 100644 platform/java/src/main/java/io/github/fgribreau/MailChecker.java diff --git a/platform/java/src/main/java/io/github/fgribreau/MailChecker.java b/platform/java/src/main/java/io/github/fgribreau/MailChecker.java new file mode 100644 index 00000000..f0f814bf --- /dev/null +++ b/platform/java/src/main/java/io/github/fgribreau/MailChecker.java @@ -0,0 +1,104 @@ +package io.github.fgribreau; + +import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Cross-language temporary (disposable/throwaway) email detection library. Covers 55 734+ fake email providers. + * Written in Java 8 + */ +public final class MailChecker { + + /** + * A class to hold of constants which will be parsed through the generator.js + */ + private static final class MailCheckerConstants { + /** + * Contains all the blacklisted domains present in the database at https://github.com/FGRibreau/mailchecker/blob/master/list.txt + */ + static final HashSet BLACKLISTED = new HashSet<>(Arrays.asList({{& listSTR }})); + //static final HashSet BLACKLISTED_SET = new HashSet<>(Arrays.asList("test.com", "test2.com")); + + /** + * Provides a regex-pattern for matching whether the provided email is a valid email. + * For more: See https://fightingforalostcause.net/content/misc/2006/compare-email-regex.php + */ + static final String VALIDATION_REGEX = "/^{{& unanchoredRegexpString }}$/"; + //static final String VALIDATION_REGEX = "/^(?!(?:(?:\\x22?\\x5C[\\x00-\\x7E]\\x22?)|(?:\\x22?[^\\x5C\\x22]\\x22?)){255,})(?!(?:(?:\\x22?\\x5C[\\x00-\\x7E]\\x22?)|(?:\\x22?[^\\x5C\\x22]\\x22?)){65,}@)(?:(?:[\\x21\\x23-\\x27\\x2A\\x2B\\x2D\\x2F-\\x39\\x3D\\x3F\\x5E-\\x7E]+)|(?:\\x22(?:[\\x01-\\x08\\x0B\\x0C\\x0E-\\x1F\\x21\\x23-\\x5B\\x5D-\\x7F]|(?:\\x5C[\\x00-\\x7F]))*\\x22))(?:\\.(?:(?:[\\x21\\x23-\\x27\\x2A\\x2B\\x2D\\x2F-\\x39\\x3D\\x3F\\x5E-\\x7E]+)|(?:\\x22(?:[\\x01-\\x08\\x0B\\x0C\\x0E-\\x1F\\x21\\x23-\\x5B\\x5D-\\x7F]|(?:\\x5C[\\x00-\\x7F]))*\\x22)))*@(?:(?:(?!.*[^.]{64,})(?:(?:(?:xn--)?[a-z0-9]+(?:-[a-z0-9]+)*\\.){1,126}){1,}(?:(?:[a-z][a-z0-9]*)|(?:(?:xn--)[a-z0-9]+))(?:-[a-z0-9]+)*)|(?:\\[(?:(?:IPv6:(?:(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){7})|(?:(?!(?:.*[a-f0-9][:\\]]){7,})(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,5})?::(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,5})?)))|(?:(?:IPv6:(?:(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){5}:)|(?:(?!(?:.*[a-f0-9]:){5,})(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,3})?::(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,3}:)?)))?(?:(?:25[0-5])|(?:2[0-4][0-9])|(?:1[0-9]{2})|(?:[1-9]?[0-9]))(?:\\.(?:(?:25[0-5])|(?:2[0-4][0-9])|(?:1[0-9]{2})|(?:[1-9]?[0-9]))){3}))\\]))$/"; + } + + /** + * Regex Pattern Matcher + */ + private static final Pattern VALIDATOR_PATTERN; + + /** + * Static initializer to initialize {@link MailChecker#VALIDATOR_PATTERN} + */ + static { + VALIDATOR_PATTERN = Pattern.compile(MailCheckerConstants.VALIDATION_REGEX); + } + + /** + * Checks whether a provided email is valid or not? + * This will also return false, if the passed string is null or empty + * @param emailAddress An email address + * @return true is the specified email is valid, false otherwise + */ + public static boolean isValidEmail(final String emailAddress){ + if(emailAddress == null || emailAddress.isEmpty()) + return false; + + final String emailAddressLowerCase = emailAddress.toLowerCase(); + + final Matcher matcher = VALIDATOR_PATTERN.matcher(emailAddress); + if(!matcher.matches()) + return false; + + for (String eachSuffix : getAllDomainSuffix(emailAddress)) { + if(MailCheckerConstants.BLACKLISTED_SET.contains(eachSuffix)) + return true; + } + + return false; + } + + /** + * Get all the blacklisted domain providers. + * This will only provide domains which are present at the moment, if new domains are added via {@link MailChecker#addCustomDomains(String...)} or {@link MailChecker#addCustomDomains(Collection)} + * one should get a new copy by calling it over again. + * @return A copy of all the blacklisted domains + */ + public static Collection blacklist(){ + return new HashSet<>(MailCheckerConstants.BLACKLISTED_SET); + } + + /** + * Add a domain to the blacklisted list temporarily + * @param domains Domains to be added + */ + public static void addCustomDomains(String... domains){ + addCustomDomains(Arrays.asList(domains)); + } + + /** + * Add a domain to the blacklisted list temporarily + * @param domains Domains to be added + */ + public static void addCustomDomains(Collection domains){ + MailCheckerConstants.BLACKLISTED_SET.addAll(domains); + } + + private static List getAllDomainSuffix(String emailAddress) { + String[] components = emailAddress.split("@")[1].split("\\."); + List domainSuffixes = new ArrayList<>(); + for (int n = 0; n < components.length; n++) { + String domainSuffix = String.join(".", Arrays.copyOfRange(components, n, components.length)); + domainSuffixes.add(domainSuffix); + } + return domainSuffixes; + } + + +}