case 4670 initial changes
This commit is contained in:
@@ -1,13 +1,14 @@
|
|||||||
using System.Collections.Generic;
|
using System;
|
||||||
using Microsoft.AspNetCore.Mvc.RazorPages;
|
|
||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using MailKit.Net.Smtp;
|
||||||
|
using MailKit.Security;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using System.Net.Mail;
|
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||||
using System.Net;
|
|
||||||
//for captcha:
|
|
||||||
using System.Net.Http;
|
|
||||||
using Newtonsoft.Json.Linq;
|
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using MimeKit;
|
||||||
|
|
||||||
namespace contact.Pages
|
namespace contact.Pages
|
||||||
{
|
{
|
||||||
@@ -28,137 +29,31 @@ namespace contact.Pages
|
|||||||
public string Email { get; set; }
|
public string Email { get; set; }
|
||||||
[Required]
|
[Required]
|
||||||
public string Message { get; set; }
|
public string Message { get; set; }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ContactModel : PageModel
|
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
|
||||||
|
private static readonly string[] SpamBlocks = { "google", "jumboleadmagnet", "boostleadgeneration" };
|
||||||
|
|
||||||
public string Message { get; set; }
|
public string Message { get; set; }
|
||||||
|
|
||||||
[BindProperty(SupportsGet = true)]
|
[BindProperty(SupportsGet = true)]
|
||||||
public ContactFormModel Contact { get; set; }
|
public ContactFormModel Contact { get; set; }
|
||||||
|
|
||||||
|
//Set when the send fails, so Contact.cshtml can tell the visitor instead of claiming success
|
||||||
|
public bool SendFailed { get; set; }
|
||||||
|
|
||||||
private readonly IConfiguration _configuration;
|
private readonly IConfiguration _configuration;
|
||||||
public ContactModel(IConfiguration configuration)
|
private readonly ILogger<ContactModel> _logger;
|
||||||
|
|
||||||
|
public ContactModel(IConfiguration configuration, ILogger<ContactModel> logger)
|
||||||
{
|
{
|
||||||
_configuration = configuration;
|
_configuration = configuration;
|
||||||
}
|
_logger = logger;
|
||||||
|
|
||||||
public ActionResult OnPost()
|
|
||||||
{
|
|
||||||
if (!ModelState.IsValid)
|
|
||||||
{
|
|
||||||
return Page();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//2025-11-01 Google dropping support for captcha, just nuking it for now, see how much spam I get
|
|
||||||
// if (!ReCaptchaPassed(
|
|
||||||
// Request.Form["g-recaptcha-response"], // that's how you get it from the Request object
|
|
||||||
// _configuration.GetSection("GoogleReCaptcha:secret").Value
|
|
||||||
// ))
|
|
||||||
// {
|
|
||||||
// //Return a fail code that will hopefully take us off the spammers list
|
|
||||||
// return StatusCode(500);
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//go away spammers
|
|
||||||
//2022-05-06 changes to get rid of jumbo lead magnet spammer but still force him to pay someone to manually enter the stuff
|
|
||||||
//ideally it should read from a text file here but this is a quickie fix while Joyce is on important viha phone call
|
|
||||||
var blocks = new List<string>();
|
|
||||||
blocks.Add("google");
|
|
||||||
blocks.Add("jumboleadmagnet");//<--go away this guy in particular, keeps spamming
|
|
||||||
blocks.Add("boostleadgeneration");
|
|
||||||
//ericjonesmyemail@gmail.com
|
|
||||||
var companyname = Contact.Company.ToLowerInvariant();
|
|
||||||
foreach (string s in blocks)
|
|
||||||
{
|
|
||||||
if (companyname.Contains(s))
|
|
||||||
{
|
|
||||||
goto skipspam;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SendMail();
|
|
||||||
|
|
||||||
skipspam:
|
|
||||||
//TODO: go to a successful submit page on the ayanova site
|
|
||||||
//return Redirect("/confirm.html");//sample quickie page I made up
|
|
||||||
return Redirect("https://ayanova.com/confirmed.htm");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private void SendMail()
|
|
||||||
{
|
|
||||||
var MessageBody = $"Name:\r\n{Contact.Name}\r\n\r\nCompany:\r\n{Contact.Company}\r\n\r\nDatabase Id:\r\n{Contact.DbId}\r\n\r\nMessage:\r\n{Contact.Message}";
|
|
||||||
|
|
||||||
//SEND TO US
|
|
||||||
using (var message = new MailMessage())
|
|
||||||
{
|
|
||||||
message.To.Add(new MailAddress("support@ayanova.com"));
|
|
||||||
message.From = new MailAddress(Contact.Email);
|
|
||||||
message.Subject = $"Question about AyaNova from {Contact.Company}";
|
|
||||||
message.Body = MessageBody;
|
|
||||||
using (var smtpClient = new SmtpClient("smtp.fastmail.com"))
|
|
||||||
{
|
|
||||||
|
|
||||||
smtpClient.Host = "smtp.fastmail.com";
|
|
||||||
smtpClient.Port = 587;
|
|
||||||
smtpClient.UseDefaultCredentials = false;
|
|
||||||
//testing
|
|
||||||
smtpClient.EnableSsl = true;
|
|
||||||
|
|
||||||
// smtpClient.Port=465;
|
|
||||||
// smtpClient.DeliveryMethod= SmtpDeliveryMethod.Network;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//NOTE: Do not use the noreply email address to send mail, it crashes the server somehow
|
|
||||||
|
|
||||||
//******************************************************************************************************************
|
|
||||||
//******************************************************************************************************************
|
|
||||||
//TEST CRASH
|
|
||||||
// smtpClient.Credentials = new System.Net.NetworkCredential("noreply@ayanova.com", "91768700489f8edd28aa71e3e0f4073eba54ce83c4c1a6a910700fa94094ddfd");
|
|
||||||
|
|
||||||
|
|
||||||
//FASTMAIL CHANGES
|
|
||||||
//Fastmail server names and ports help page: https://www.fastmail.help/hc/en-us/articles/1500000278342
|
|
||||||
//APP Password created in fastmail for smtp use only labelled 'contact-form': cnea8agl6nlx5j7l
|
|
||||||
|
|
||||||
//try using from as support@onayanova.com
|
|
||||||
//try domain version if this still won't work
|
|
||||||
smtpClient.Credentials = new System.Net.NetworkCredential("support@onayanova.com", "cnea8agl6nlx5j7l");
|
|
||||||
//******************************************************************************************************************
|
|
||||||
//******************************************************************************************************************
|
|
||||||
|
|
||||||
smtpClient.Send(message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//Removed 2022-10-06 causing backscatter and also not helpful
|
|
||||||
// //SEND COPY TO CLIENT
|
|
||||||
// using (var message = new MailMessage())
|
|
||||||
// {
|
|
||||||
// message.To.Add(new MailAddress(Contact.Email));
|
|
||||||
// message.From = new MailAddress("support@ayanova.com");
|
|
||||||
// message.Subject = $"Confirmation that your question about AyaNova has been received from {Contact.Company}";
|
|
||||||
// message.Body = MessageBody;
|
|
||||||
|
|
||||||
// using (var smtpClient = new SmtpClient("smtp.fastmail.com"))
|
|
||||||
// {
|
|
||||||
|
|
||||||
// smtpClient.Host = "smtp.fastmail.com";
|
|
||||||
// smtpClient.Port = 587;
|
|
||||||
// smtpClient.UseDefaultCredentials = false;
|
|
||||||
// smtpClient.EnableSsl=true;
|
|
||||||
// //NOTE: Do not use the noreply email address to send mail, it crashes the server somehow
|
|
||||||
// smtpClient.Credentials = new System.Net.NetworkCredential("support@onayanova.com", "cnea8agl6nlx5j7l");
|
|
||||||
// smtpClient.Send(message);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnGet()
|
public void OnGet()
|
||||||
@@ -166,28 +61,64 @@ namespace contact.Pages
|
|||||||
Message = "Your contact page.";
|
Message = "Your contact page.";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<IActionResult> OnPostAsync()
|
||||||
|
{
|
||||||
|
if (!ModelState.IsValid)
|
||||||
|
{
|
||||||
|
return Page();
|
||||||
|
}
|
||||||
|
|
||||||
//2025-11-01 Google dropping support for captcha, just nuking it for now, see how much spam I get
|
//2025-11-01 reCAPTCHA removed (Google service change). Replacement deferred, see runbook Phase 6.
|
||||||
// public static bool ReCaptchaPassed(string gRecaptchaResponse, string secret)
|
|
||||||
// {
|
|
||||||
// HttpClient httpClient = new HttpClient();
|
|
||||||
// var res = httpClient.GetAsync($"https://www.google.com/recaptcha/api/siteverify?secret={secret}&response={gRecaptchaResponse}").Result;
|
|
||||||
// if (res.StatusCode != HttpStatusCode.OK)
|
|
||||||
// {
|
|
||||||
// // logger.LogError("Error while sending request to ReCaptcha");
|
|
||||||
// return false;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// string JSONres = res.Content.ReadAsStringAsync().Result;
|
var company = Contact.Company.ToLowerInvariant();
|
||||||
// dynamic JSONdata = JObject.Parse(JSONres);
|
if (SpamBlocks.Any(s => company.Contains(s)))
|
||||||
// if (JSONdata.success != "true")
|
{
|
||||||
// {
|
return Redirect(ConfirmedUrl);
|
||||||
// return false;
|
}
|
||||||
// }
|
|
||||||
|
|
||||||
// return true;
|
try
|
||||||
// }
|
{
|
||||||
|
await SendMailAsync();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
//Log the whole submission so it can be recovered from the journal, not lost
|
||||||
|
_logger.LogError(ex,
|
||||||
|
"Contact form send failed. Name: {Name} | Company: {Company} | Email: {Email} | DbId: {DbId} | Message: {Message}",
|
||||||
|
Contact.Name, Contact.Company, Contact.Email, Contact.DbId, Contact.Message);
|
||||||
|
SendFailed = true;
|
||||||
|
return Page();
|
||||||
|
}
|
||||||
|
|
||||||
|
return Redirect(ConfirmedUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task SendMailAsync()
|
||||||
|
{
|
||||||
|
var smtp = _configuration.GetSection("Smtp");
|
||||||
|
|
||||||
|
//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}";
|
||||||
|
|
||||||
|
var message = new MimeMessage();
|
||||||
|
//From is always the authenticated account; the visitor goes in Reply-To (no sender spoofing)
|
||||||
|
message.From.Add(new MailboxAddress("AyaNova contact form", smtp["User"]));
|
||||||
|
message.To.Add(MailboxAddress.Parse("support@ayanova.com"));
|
||||||
|
if (MailboxAddress.TryParse(Contact.Email, out var replyTo))
|
||||||
|
{
|
||||||
|
replyTo.Name = Contact.Name;
|
||||||
|
message.ReplyTo.Add(replyTo);
|
||||||
|
}
|
||||||
|
message.Subject = $"Question about AyaNova from {OneLine(Contact.Company)}";
|
||||||
|
message.Body = new TextPart("plain") { Text = body };
|
||||||
|
|
||||||
|
using var client = new SmtpClient();
|
||||||
|
await client.ConnectAsync(smtp["Host"], smtp.GetValue<int>("Port"), SecureSocketOptions.StartTls);
|
||||||
|
await client.AuthenticateAsync(smtp["User"], smtp["Password"]);
|
||||||
|
await client.SendAsync(message);
|
||||||
|
await client.DisconnectAsync(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string OneLine(string s) => s.Replace("\r", " ").Replace("\n", " ");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
19
Program.cs
19
Program.cs
@@ -1,19 +1,14 @@
|
|||||||
using Microsoft.AspNetCore;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.Extensions.Hosting;
|
||||||
|
|
||||||
namespace contact
|
namespace contact
|
||||||
{
|
{
|
||||||
public class Program
|
public class Program
|
||||||
{
|
{
|
||||||
public static void Main(string[] args)
|
public static void Main(string[] args) =>
|
||||||
{
|
Host.CreateDefaultBuilder(args)
|
||||||
CreateWebHostBuilder(args).Build().Run();
|
.ConfigureWebHostDefaults(web => web.UseStartup<Startup>())
|
||||||
}
|
.Build()
|
||||||
|
.Run();
|
||||||
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
|
|
||||||
WebHost.CreateDefaultBuilder(args)
|
|
||||||
.UseUrls("http://*:3002")//only this port works with nginx proxy
|
|
||||||
//.UseUrls("http://localhost:3002")//this doesn't work with nginx proxy
|
|
||||||
.UseStartup<Startup>();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,5 +5,6 @@
|
|||||||
"System": "Information",
|
"System": "Information",
|
||||||
"Microsoft": "Information"
|
"Microsoft": "Information"
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
"AllowedHosts": "localhost"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,20 +1,9 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net6.0</TargetFramework>
|
<TargetFramework>net10.0</TargetFramework>
|
||||||
|
<UserSecretsId>efc95c93-c628-4ad5-a697-cd1613181a44</UserSecretsId>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="5.0.0" />
|
<PackageReference Include="MailKit" Version="4.18.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<!-- <ItemGroup>
|
|
||||||
<PackageReference Include="AWSSDK.S3" Version="3.3.111.9" />
|
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="3.1.4" />
|
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="3.1.4" />
|
|
||||||
<PackageReference Include="jose-jwt" Version="2.5.0" />
|
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="3.1.4" />
|
|
||||||
<PackageReference Include="mailkit" Version="2.7.0" />
|
|
||||||
|
|
||||||
</ItemGroup> -->
|
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
Reference in New Issue
Block a user