using System; using System.ComponentModel.DataAnnotations; using System.Linq; using System.Threading.Tasks; using contact.Services; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.RazorPages; using Microsoft.Extensions.Logging; namespace contact.Pages { [BindProperties(SupportsGet = true)] public class ContactFormModel { public ContactFormModel() { DbId = "n/a v7"; } [Required] public string Name { get; set; } [Required] public string Company { get; set; } //Optional; AyaNova clients deep-link to this page with their database ID. //Binding attributes left exactly as they were so that link keeps working. [BindProperty(SupportsGet = true)] public string DbId { get; set; } [Required, EmailAddress] public string Email { get; set; } [Required] public string Message { get; set; } } public class ContactModel : PageModel { private const string ConfirmedUrl = "https://ayanova.com/confirmed.htm"; //2022-05-06 Company names containing any of these are dropped silently but still get the //success redirect, so the spammer gets no signal and has to pay someone to enter them by hand public static readonly string[] SpamBlocks = { "google", "jumboleadmagnet", "boostleadgeneration" }; [BindProperty(SupportsGet = true)] public ContactFormModel Contact { get; set; } //Set when the send fails, so the page can tell the visitor instead of claiming success public bool SendFailed { get; set; } private readonly MailSender _mail; private readonly ILogger _logger; public ContactModel(MailSender mail, ILogger logger) { _mail = mail; _logger = logger; } public void OnGet() { } public async Task OnPostAsync() { if (!ModelState.IsValid) { return Page(); } //2025-11-01 reCAPTCHA removed (Google service change). Replacement deferred, see runbook Phase 6. if (IsBlocked(Contact.Company)) { return Redirect(ConfirmedUrl); } //Email is in the body as well as Reply-To, so it survives even if Reply-To can't be set var body = $"Name:\r\n{Contact.Name}\r\n\r\nCompany:\r\n{Contact.Company}\r\n\r\nEmail:\r\n{Contact.Email}\r\n\r\nDatabase Id:\r\n{Contact.DbId}\r\n\r\nMessage:\r\n{Contact.Message}"; try { await _mail.SendToSupportAsync($"Question about AyaNova from {Contact.Company}", body, Contact.Name, Contact.Email); } catch (Exception ex) { //Log the whole submission so it can be recovered from the journal, not lost _logger.LogError(ex, "Contact form send failed. Submission:\r\n{Body}", body); SendFailed = true; return Page(); } return Redirect(ConfirmedUrl); } public static bool IsBlocked(string company) { var c = company.ToLowerInvariant(); return SpamBlocks.Any(s => c.Contains(s)); } } }