Recaptcha for contact and registration page implemented
This commit is contained in:
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
|
||||
@@ -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>
|
||||
@@ -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
@@ -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 <noreply@leafweb.org>" />
|
||||
<add key="AdminEmailAddresses" value="kolpacksoftware@gmail.com" />
|
||||
<add key="ProcessQueueInterval" value="*/1 * * * *" />
|
||||
|
||||
@@ -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" />
|
||||
|
||||
@@ -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" />
|
||||
|
||||
Reference in New Issue
Block a user