diff --git a/Streetwriters.Identity/Controllers/SignupController.cs b/Streetwriters.Identity/Controllers/SignupController.cs index a54ee5b..85f0aeb 100644 --- a/Streetwriters.Identity/Controllers/SignupController.cs +++ b/Streetwriters.Identity/Controllers/SignupController.cs @@ -54,7 +54,7 @@ namespace Streetwriters.Identity.Controllers public async Task Signup([FromForm] SignupForm form) { var client = Clients.FindClientById(form.ClientId); - if (client == null) return BadRequest("Invalid client_id."); + if (client == null) return BadRequest(new string[] { "Invalid client id." }); await AddClientRoleAsync(client.Id); @@ -62,6 +62,8 @@ namespace Streetwriters.Identity.Controllers form.Email = form.Email.ToLowerInvariant(); form.Username = form.Username?.ToLowerInvariant(); + if (!await EmailAddressValidator.IsEmailAddressValidAsync(form.Email)) return BadRequest(new string[] { "Invalid email address." }); + var result = await UserManager.CreateAsync(new User { Email = form.Email, @@ -85,7 +87,7 @@ namespace Streetwriters.Identity.Controllers } else { - return BadRequest(new string[] { "Email is invalid or already taken." }); + return BadRequest(new string[] { "Invalid email address." }); } return Ok(new diff --git a/Streetwriters.Identity/Services/EmailAddressValidator.cs b/Streetwriters.Identity/Services/EmailAddressValidator.cs new file mode 100644 index 0000000..8710fa1 --- /dev/null +++ b/Streetwriters.Identity/Services/EmailAddressValidator.cs @@ -0,0 +1,36 @@ +using System; +using System.Collections.Generic; +using System.Net.Http; +using System.Threading.Tasks; +using Streetwriters.Common; + +namespace Streetwriters.Identity.Services +{ + public class EmailAddressValidator + { + private static DateTimeOffset LAST_FETCH_TIME = DateTimeOffset.MinValue; + private static HashSet BLACKLISTED_DOMAINS = new HashSet(); + + public static async Task IsEmailAddressValidAsync(string email) + { + var domain = email.ToLowerInvariant().Split("@")[1]; + try + { + if (LAST_FETCH_TIME.AddDays(1) < DateTimeOffset.UtcNow) + { + var httpClient = new HttpClient(); + var domainsList = await httpClient.GetStringAsync("https://disposable.github.io/disposable-email-domains/domains.txt"); + BLACKLISTED_DOMAINS = new HashSet(domainsList.Split('\n')); + LAST_FETCH_TIME = DateTimeOffset.UtcNow; + } + + return !BLACKLISTED_DOMAINS.Contains(domain); + } + catch (Exception ex) + { + await Slogger.Error("IsEmailAddressValidAsync", ex.ToString()); + return BLACKLISTED_DOMAINS.Count > 0 ? !BLACKLISTED_DOMAINS.Contains(domain) : true; + } + } + } +} \ No newline at end of file