Recaptcha for contact and registration page implemented

This commit is contained in:
2022-10-21 14:43:33 -04:00
parent 0160c1d7b5
commit 8fd0796019
10 changed files with 155 additions and 42 deletions
+13 -4
View File
@@ -11,21 +11,30 @@ namespace LeafWeb.WebCms.Controllers
public ActionResult Index()
{
var viewModel = new ContactForm();
return PartialView(viewModel);
// if user is logged in, pre fill the name and email
var member = Members.GetCurrentMember();
if (member != null)
{
viewModel.Name = member.Name;
viewModel.Email= (string)member.GetProperty("Email").Value;
}
return PartialView(viewModel);
}
[HttpPost]
[ValidateRecaptcha]
public ActionResult Submit(ContactForm viewModel)
{
if (ModelState.IsValid) // HttpParamMatch indicates it's backing out from Confirm
if (ModelState.IsValid)
{
BackgroundJob.Enqueue<EmailNotificationService>(
BackgroundJob.Enqueue<EmailNotificationService>(
e => e.SendContactEmail(viewModel));
var logger = LogManager.GetLogger(GetType());
logger.Info($"Contact: Name:{viewModel.Name} Added, Email:{viewModel.Email}, Message:{viewModel.Message}");
SetStatusMessage("Your message has been sent!", StatusType.Success);
SetStatusMessage($"Thank you, {viewModel.Name}. Your message has been sent" , StatusType.Success);
return RedirectToCurrentUmbracoPage();
}
+59
View File
@@ -0,0 +1,59 @@
using System;
using System.Web.Mvc;
using System.Web.Security;
using Umbraco.Core;
using Umbraco.Web.Models;
using Umbraco.Web.Mvc;
namespace LeafWeb.WebCms.Controllers
{
public class RegisterController : BaseController
{
[HttpPost]
//[ValidateAntiForgeryToken]
[ValidateRecaptcha]
[ValidateUmbracoFormRouteString]
public ActionResult HandleRegisterMember([Bind(Prefix = "registerModel")] RegisterModel model)
{
if (!this.ModelState.IsValid)
return (ActionResult)this.CurrentUmbracoPage();
if (string.IsNullOrEmpty(model.Name) && !string.IsNullOrEmpty(model.Email))
model.Name = model.Email;
MembershipCreateStatus status;
this.Members.RegisterMember(model, out status, model.LoginOnSuccess);
switch (status)
{
case MembershipCreateStatus.Success:
this.TempData["FormSuccess"] = (object)true;
return !model.RedirectUrl.IsNullOrWhiteSpace() ? (ActionResult)this.Redirect(model.RedirectUrl) : (ActionResult)this.RedirectToCurrentUmbracoPage();
case MembershipCreateStatus.InvalidUserName:
this.ModelState.AddModelError(model.UsernameIsEmail || model.Username == null ? "registerModel.Email" : "registerModel.Username", "Username is not valid");
break;
case MembershipCreateStatus.InvalidPassword:
this.ModelState.AddModelError("registerModel.Password", "The password is not strong enough");
break;
case MembershipCreateStatus.InvalidQuestion:
case MembershipCreateStatus.InvalidAnswer:
throw new NotImplementedException(status.ToString());
case MembershipCreateStatus.InvalidEmail:
this.ModelState.AddModelError("registerModel.Email", "Email is invalid");
break;
case MembershipCreateStatus.DuplicateUserName:
this.ModelState.AddModelError(model.UsernameIsEmail || model.Username == null ? "registerModel.Email" : "registerModel.Username", "A member with this username already exists.");
break;
case MembershipCreateStatus.DuplicateEmail:
this.ModelState.AddModelError("registerModel.Email", "A member with this e-mail address already exists");
break;
case MembershipCreateStatus.UserRejected:
case MembershipCreateStatus.InvalidProviderUserKey:
case MembershipCreateStatus.DuplicateProviderUserKey:
case MembershipCreateStatus.ProviderError:
this.ModelState.AddModelError("registerModel", "An error occurred creating the member: " + (object)status);
break;
default:
throw new ArgumentOutOfRangeException();
}
return (ActionResult)this.CurrentUmbracoPage();
}
}
}
@@ -0,0 +1,30 @@
using System.Linq;
using System.Web;
using System.Web.Http.Results;
using System.Web.Mvc;
using hbehr.recaptcha;
using log4net;
using Umbraco.Web.Mvc;
namespace LeafWeb.WebCms.Controllers
{
public class ValidateRecaptchaAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext context)
{
if (context != null)
{
//https://github.com/henriqb/ReCaptcha-Asp-Net
//https://stackoverflow.com/questions/58328542/trying-the-samesite-attribute-fix-for-the-google-recaptcha-v2-warning-on-chrome
var userResponse = context.RequestContext.HttpContext.Request.Params["g-recaptcha-response"];
var validCaptcha = userResponse != null && ReCaptcha.ValidateCaptcha(userResponse);
if (!validCaptcha)
{
context.Result = new System.Web.Mvc.RedirectResult("/error");
}
}
base.OnActionExecuting(context);
}
}
}
+4 -2
View File
@@ -1,4 +1,5 @@
using Hangfire;
using System.Linq;
using Hangfire;
using LeafWeb.WebCms.Controllers;
using LeafWeb.WebCms.Services;
using MlkPwgen;
@@ -18,7 +19,8 @@ namespace LeafWeb.WebCms.EventHandlers
MemberService.Created += MemberService_Created;
MemberService.Saving += MemberService_OnSaving;
}
// https://our.umbraco.com/Documentation/Tutorials/Members-Registration-And-Logins/index-v9
private void MemberService_OnSaving(IMemberService sender, SaveEventArgs<IMember> e)
{
foreach (var member in e.SavedEntities)
+5 -2
View File
@@ -1,4 +1,5 @@
@using ClientDependency.Core.Mvc
@using hbehr.recaptcha
@using LeafWeb.WebCms.Controllers
@model ContactForm
@{
@@ -7,6 +8,7 @@
Html.RequiresJs("~/scripts/jquery.validate.unobtrusive.bootstrap.js", 2);
Html.RequiresJs("~/scripts/jquery.validate.custom.js", 2);
}
<script type="text/javascript">function submit() { $('form').submit(); }</script>
<div class="container mt-4">
<div class="row justify-content-center">
@@ -18,8 +20,9 @@
@Html.EditorFor(m => m.Name)
@Html.EditorFor(m => m.Email)
@Html.EditorFor(m => m.Message)
<input type="submit" id="submit-form" class="d-none"/>}
<label for="submit-form" class="btn btn-primary pull-right">Send</label>
@ReCaptcha.GetInvisibleCaptcha("submit", "Send")
@* Restyling this button does not appear to allow it to continue operating *@
}
</div>
</div>
</div>
@@ -1,6 +1,7 @@
@inherits Umbraco.Web.Macros.PartialViewMacroPage
@using ClientDependency.Core.Mvc
@using Umbraco.Web.Controllers
@using LeafWeb.WebCms.Controllers
@using hbehr.recaptcha
@{
// https://24days.in/umbraco-cms/2015/membership-apis-investigation/
// https://our.umbraco.com/forum/templates-partial-views-and-macros/93133-membership-provider-registration-form
@@ -19,44 +20,45 @@
var user = Membership.GetUser();
}
<script type="text/javascript">function submit() { $('form').submit(); }</script>
<div class="container mt-5">
<div class="row justify-content-center">
<div class="col-lg-6 card card-body bg-light">
@* ReSharper disable once UnknownCssClass *@
@if (success || (!user?.IsApproved ?? false))
{
<h2 class="text-center"><span class="fa fa-check text-primary"></span> </h2>
<p>Registration succeeded. Please check your email to verify your account.</p>
}
else if (user != null)
{
<p>No need to register - you are already logged with email @user.Email</p>
}
else
{
using (Html.BeginUmbracoForm<UmbRegisterController>(
"HandleRegisterMember",
null,
new {id="register-member"}))
{
@Html.ValidationSummary(false)
@if (success || (!user?.IsApproved ?? false))
{
<h2 class="text-center"><span class="fa fa-check text-primary"></span> </h2>
<p>Registration succeeded. Please check your email (@user.Email) to verify your account.</p>
}
else if (user != null)
{
<p>No need to register - you are already logged in with email @user.Email</p>
}
else
{
using (Html.BeginUmbracoForm<RegisterController>(
"HandleRegisterMember",
null,
new { id = "register-member" }))
{
@Html.ValidationSummary(false)
@Html.EditorFor(m => registerModel.Name, new {labelText = "Name"})
@Html.EditorFor(m => registerModel.Email, new { type = "email", labelText = "Email"})
@Html.EditorFor(m => registerModel.Password, "Password")
<div class="form-group verifyPassword">
@Html.Label("Verify Password")
@Html.Password("VerifyPassword", null, new { @class = "form-control" })
@Html.ValidationMessage("VerifyPassword", "", new { @class = "text-danger" })
</div>
@Html.HiddenFor(m => registerModel.MemberTypeAlias)
@Html.HiddenFor(m => registerModel.RedirectUrl)
@*@Html.HiddenFor(m => registerModel.UsernameIsEmail)*@
@Html.EditorFor(m => registerModel.Name, new { labelText = "Name" })
@Html.EditorFor(m => registerModel.Email, new { type = "email", labelText = "Email" })
@Html.EditorFor(m => registerModel.Password, "Password")
<div class="form-group verifyPassword">
@Html.Label("Verify Password")
@Html.Password("VerifyPassword", null, new { @class = "form-control" })
@Html.ValidationMessage("VerifyPassword", "", new { @class = "text-danger" })
</div>
@Html.HiddenFor(m => registerModel.MemberTypeAlias)
@Html.HiddenFor(m => registerModel.RedirectUrl)
@*@Html.HiddenFor(m => registerModel.UsernameIsEmail)*@
<button type="submit" class="btn btn-primary pull-right">Register</button>
}
}
@ReCaptcha.GetInvisibleCaptcha("submit", "Register")
}
}
</div>
</div>
</div>
+1 -1
View File
@@ -7,4 +7,4 @@
</h1>
<p>Permission denied for requested resource. If you believe this to be in error please contact administrator, referencing the following url:</p>
<code>@Html.Raw(Request.Url)</code>
<code>@Html.Raw(Request.UrlReferrer.AbsoluteUri)</code>
+3 -1
View File
@@ -65,7 +65,9 @@
<add key="owin:appStartup" value="LeafWeb.WebCms.App_Start.LeafwebOwinStartup" />
<add key="Umbraco.ModelsBuilder.Enable" value="true" />
<add key="Umbraco.ModelsBuilder.ModelsMode" value="PureLive" />
<add key="recaptcha-secret-key" value="6LeIxAcTAAAAAGG-vFI1TnRWxMZNFuojJ4WifJWe" />
<add key="recaptcha-public-key" value="6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI" />
<add key="EmailFromAddress" value="LeafWeb &lt;noreply@leafweb.org&gt;" />
<add key="AdminEmailAddresses" value="kolpacksoftware@gmail.com" />
<add key="ProcessQueueInterval" value="*/1 * * * *" />
+5
View File
@@ -99,6 +99,9 @@
<Reference Include="Hangfire.SqlServer, Version=1.7.7.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Hangfire.SqlServer.1.7.7\lib\net45\Hangfire.SqlServer.dll</HintPath>
</Reference>
<Reference Include="hbehr.recaptcha, Version=1.9.0.36338, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\ReCaptcha-AspNet.1.9.0\lib\net452\hbehr.recaptcha.dll</HintPath>
</Reference>
<Reference Include="HtmlAgilityPack, Version=1.11.17.0, Culture=neutral, PublicKeyToken=bd319b19eaf3b43a, processorArchitecture=MSIL">
<HintPath>..\packages\HtmlAgilityPack.1.11.17\lib\Net45\HtmlAgilityPack.dll</HintPath>
</Reference>
@@ -1116,7 +1119,9 @@
<Compile Include="Controllers\LeafWebPageIds.cs" />
<Compile Include="Controllers\MembershipController.cs" />
<Compile Include="Controllers\QueueController.cs" />
<Compile Include="Controllers\RegisterController.cs" />
<Compile Include="Controllers\ResultsController.cs" />
<Compile Include="Controllers\ValidateRecaptchaAttribute.cs" />
<Compile Include="EventHandlers\MemberEvents.cs" />
<Compile Include="Models\ChartViewModel.cs" />
<Compile Include="Models\LeafDataQuery.cs" />
+1
View File
@@ -60,6 +60,7 @@
<package id="Owin" version="1.0" targetFramework="net452" />
<package id="Polly" version="7.2.0" targetFramework="net452" />
<package id="popper.js" version="1.16.0" targetFramework="net452" />
<package id="ReCaptcha-AspNet" version="1.9.0" targetFramework="net452" />
<package id="semver" version="1.1.2" targetFramework="net452" />
<package id="SharpZipLib" version="1.2.0" targetFramework="net452" />
<package id="System.Collections" version="4.3.0" targetFramework="net452" />