diff --git a/AMWD.Common.Tests/Extensions/StringExtensionsTests.cs b/AMWD.Common.Tests/Extensions/StringExtensionsTests.cs index 5f8f501..0770ef2 100644 --- a/AMWD.Common.Tests/Extensions/StringExtensionsTests.cs +++ b/AMWD.Common.Tests/Extensions/StringExtensionsTests.cs @@ -1,5 +1,6 @@ using System; using System.Linq; +using System.Net; using System.Text; using Microsoft.VisualStudio.TestTools.UnitTesting; @@ -245,5 +246,60 @@ namespace AMWD.Common.Tests.Extensions Assert.AreEqual(number, numberEn); Assert.AreEqual(number, numberDe); } + + [TestMethod] + public void ShouldValidateEmailAddressWithoutRecordCheck() + { + // arrange + string validEmailWithoutTag = "test@gmail.com"; + string validEmailWithTag = "test+tag@not.exists"; + string invalidEmailWithoutTag = " test@gmail.com"; + string invalidEmailWithTag = " test+tag@not.exists"; + + // act + bool validWithoutTag = validEmailWithoutTag.IsValidEmailAddress(checkRecordExists: false); + bool validWithTag = validEmailWithTag.IsValidEmailAddress(checkRecordExists: false); + bool invalidWithoutTag = !invalidEmailWithoutTag.IsValidEmailAddress(checkRecordExists: false); + bool invalidWithTag = !invalidEmailWithTag.IsValidEmailAddress(checkRecordExists: false); + + // assert + Assert.IsTrue(validWithoutTag); + Assert.IsTrue(validWithTag); + Assert.IsTrue(invalidWithoutTag); + Assert.IsTrue(invalidWithTag); + } + + [TestMethod] + public void ShouldValidateEmailAddressWithRecordCheck() + { + // arrange + string validEmail = "test@gmail.com"; + string invalidEmail = "test@not.exists"; + + // act + bool valid = validEmail.IsValidEmailAddress(checkRecordExists: true); + bool invalid = !invalidEmail.IsValidEmailAddress(checkRecordExists: true); + + // assert + Assert.IsTrue(valid); + Assert.IsTrue(invalid); + } + + [TestMethod] + public void ShouldValidateEmailAddressWithRecordCheckDefinedNameservers() + { + // arrange + string validEmail = "test@gmail.com"; + string invalidEmail = "test@not.exists"; + var nameserver = new IPEndPoint(IPAddress.Parse("1.1.1.1"), 53); + + // act + bool valid = validEmail.IsValidEmailAddress(new[] { nameserver }); + bool invalid = !invalidEmail.IsValidEmailAddress(new[] { nameserver }); + + // assert + Assert.IsTrue(valid); + Assert.IsTrue(invalid); + } } } diff --git a/AMWD.Common/AMWD.Common.csproj b/AMWD.Common/AMWD.Common.csproj index f52927a..91ec70b 100644 --- a/AMWD.Common/AMWD.Common.csproj +++ b/AMWD.Common/AMWD.Common.csproj @@ -36,6 +36,7 @@ + diff --git a/AMWD.Common/Extensions/StringExtensions.cs b/AMWD.Common/Extensions/StringExtensions.cs index 19b72ca..96cb18b 100644 --- a/AMWD.Common/Extensions/StringExtensions.cs +++ b/AMWD.Common/Extensions/StringExtensions.cs @@ -1,8 +1,11 @@ using System.Collections.Generic; using System.Globalization; using System.Linq; +using System.Net; +using System.Net.Mail; using System.Text; using System.Text.RegularExpressions; +using DnsClient; namespace System { @@ -137,5 +140,50 @@ namespace System return decimal.Parse(decString, culture); } + + /// + /// Checks whether the given is a valid . + /// + /// + /// You can enhance the check by requesting the MX record of the domain. + /// + /// The email address as string to validate. + /// A value indicating whether to resolve a MX record. + /// true when the email address is valid, other wise false. + public static bool IsValidEmailAddress(this string email, bool checkRecordExists = false) + => email.IsValidEmailAddress(checkRecordExists ? new LookupClient() : null); + + /// + /// Checks whether the given is a valid . + /// + /// + /// The check is enhanced by a request for MX records on the defined . + /// + /// The email address as string to validate. + /// A list of s of nameservers. + /// true when the email address is valid, other wise false. + public static bool IsValidEmailAddress(this string email, IEnumerable nameservers) + => email.IsValidEmailAddress(new LookupClient(nameservers.ToArray())); + + private static bool IsValidEmailAddress(this string email, LookupClient lookupClient) + { + try + { + var mailAddress = new MailAddress(email); + bool isValid = mailAddress.Address == email; + + if (isValid && lookupClient != null) + { + var result = lookupClient.Query(mailAddress.Host, QueryType.MX); + isValid &= result.Answers.MxRecords().Any(); + } + + return isValid; + } + catch + { + return false; + } + } } } diff --git a/README.md b/README.md index 30e4344..e2c9f7d 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ To save time, they are all packed to NuGet packages. | AMWD.Common | ![https://nuget.am-wd.de/packages/amwd.common/](https://img.shields.io/badge/dynamic/json?color=blue&label=AMWD.Common&query=%24.versions[-1%3A]&url=https%3A%2F%2Fnuget.am-wd.de%2Fv3%2Fpackage%2Famwd.common%2Findex.json&style=flat-square) | | AMWD.Common.AspNetCore | ![https://nuget.am-wd.de/packages/amwd.common.aspnetcore/](https://img.shields.io/badge/dynamic/json?color=blue&label=AMWD.Common.AspNetCore&query=%24.versions[-1%3A]&url=https%3A%2F%2Fnuget.am-wd.de%2Fv3%2Fpackage%2Famwd.common.aspnetcore%2Findex.json&style=flat-square) | | AMWD.Common.EntityFrameworkCore | ![https://nuget.am-wd.de/packages/amwd.common.entityframeworkcore/](https://img.shields.io/badge/dynamic/json?color=blue&label=AMWD.Common.EntityFrameworkCore&query=%24.versions[-1%3A]&url=https%3A%2F%2Fnuget.am-wd.de%2Fv3%2Fpackage%2Famwd.common.entityframeworkcore%2Findex.json&style=flat-square) | -| Build Pipeline | ![https://git.am-wd.de/AM.WD/common/-/commits/master](https://git.am-wd.de/AM.WD/common/badges/master/pipeline.svg?style=flat-square) | +| CI / CD | ![https://git.am-wd.de/AM.WD/common/-/pipelines](https://git.am-wd.de/AM.WD/common/badges/master/pipeline.svg?style=flat-square) ![https://git.am-wd.de/AM.WD/common/-/tree/master](https://git.am-wd.de/AM.WD/common/badges/master/coverage.svg?style=flat-square) | ## Documentation