Password reset

This commit is contained in:
2020-01-26 09:05:54 -05:00
parent 4c51a72544
commit 8ca5105fca
19 changed files with 398 additions and 38 deletions
+4 -3
View File
@@ -1,4 +1,5 @@
using System.Web.Mvc; using System.Web.Mvc;
using Hangfire;
using log4net; using log4net;
using LeafWeb.WebCms.Models; using LeafWeb.WebCms.Models;
using LeafWeb.WebCms.Services; using LeafWeb.WebCms.Services;
@@ -18,10 +19,10 @@ namespace LeafWeb.WebCms.Controllers
{ {
if (ModelState.IsValid) // HttpParamMatch indicates it's backing out from Confirm if (ModelState.IsValid) // HttpParamMatch indicates it's backing out from Confirm
{ {
// convert viewModel into Model BackgroundJob.Enqueue<EmailNotificationService>(
new EmailNotificationService().SendContactEmail(viewModel); e => e.SendContactEmail(viewModel));
var logger = LogManager.GetLogger(GetType()); var logger = LogManager.GetLogger(GetType());
logger.Info($"Contact: Name:{viewModel.Name} Added, Email:{viewModel.Email}, Message:{viewModel.Message}"); logger.Info($"Contact: Name:{viewModel.Name} Added, Email:{viewModel.Email}, Message:{viewModel.Message}");
SetStatusMessage("Your message has been sent!", StatusType.Success); SetStatusMessage("Your message has been sent!", StatusType.Success);
+8 -1
View File
@@ -6,5 +6,12 @@ namespace LeafWeb.WebCms.Controllers
public const int ManageQueue = 1107; public const int ManageQueue = 1107;
public const int Chart = 1100; public const int Chart = 1100;
public const int Details = 1111; public const int Details = 1111;
} public const int PasswordResetRequest = 1164;
}
public static class LeafWebMemberProperties
{
public const string VerificationToken = "VerificationToken";
public const string PasswordResetToken = "PasswordResetToken";
}
} }
+138 -2
View File
@@ -1,4 +1,8 @@
using System.Web.Mvc; using System.Web.Mvc;
using Hangfire;
using LeafWeb.WebCms.Models;
using LeafWeb.WebCms.Services;
using MlkPwgen;
using Umbraco.Core; using Umbraco.Core;
namespace LeafWeb.WebCms.Controllers namespace LeafWeb.WebCms.Controllers
@@ -23,7 +27,7 @@ namespace LeafWeb.WebCms.Controllers
} }
else else
{ {
var storedToken = member.GetValue("VerificationToken") as string; var storedToken = member.GetValue<string>(LeafWebMemberProperties.VerificationToken);
if (string.IsNullOrEmpty(storedToken)) if (string.IsNullOrEmpty(storedToken))
{ {
@@ -41,7 +45,7 @@ namespace LeafWeb.WebCms.Controllers
member.IsApproved = true; member.IsApproved = true;
// remove the verification // remove the verification
member.SetValue("VerificationToken", string.Empty); member.SetValue(LeafWebMemberProperties.VerificationToken, string.Empty);
memberService.Save(member); memberService.Save(member);
TempData["StatusMessage"] = "Thank you! Your email is now verified at " + member.Email; TempData["StatusMessage"] = "Thank you! Your email is now verified at " + member.Email;
@@ -53,5 +57,137 @@ namespace LeafWeb.WebCms.Controllers
return Redirect(redirectUrl); return Redirect(redirectUrl);
} }
public ActionResult PasswordResetRequest()
{
var viewModel = new PasswordResetRequestForm();
return PartialView("PasswordResetRequest", viewModel);
}
[HttpPost]
public ActionResult PasswordResetRequest(PasswordResetRequestForm requestForm)
{
if (!ModelState.IsValid)
return CurrentUmbracoPage();
var memberService = ApplicationContext.Current.Services.MemberService;
var member = memberService.GetByEmail(requestForm.Email);
if (member == null)
{
// Send notification of attempt to change
BackgroundJob.Enqueue<EmailNotificationService>(
e => e.SendPasswordResetNotMemberEmail(requestForm.Email));
}
else
{
var token = PasswordGenerator.Generate(12, allowed: "0123456789");
member.SetValue(LeafWebMemberProperties.PasswordResetToken, token);
memberService.Save(member);
// Send Email
BackgroundJob.Enqueue<EmailNotificationService>(
e => e.SendPasswordResetEmail(member.Email));
}
// don't acknowledge their email address
TempData["StatusMessage"] =
$"An email has been sent to {requestForm.Email} with instructions on how to reset your password.";
TempData["StatusMessage-Type"] = "alert-success";
return Redirect("/");
}
public ActionResult PasswordReset(string email, string token)
{
var errorMsg = $"Sorry, a valid password reset was not found for user {email}. " +
$"Please try resetting again, " +
$"or use Contact Us if the issue persists.";
if (!string.IsNullOrEmpty(email) && !string.IsNullOrEmpty(token))
{
var memberService = ApplicationContext.Current.Services.MemberService;
var member = memberService.GetByEmail(email);
if (member == null)
{
// don't acknowledge their email address
TempData["StatusMessage"] = errorMsg;
TempData["StatusMessage-Type"] = "alert-danger";
}
else
{
var storedToken = member.GetValue<string>(LeafWebMemberProperties.PasswordResetToken);
if (string.IsNullOrEmpty(storedToken))
{
TempData["StatusMessage"] = errorMsg;
TempData["StatusMessage-Type"] = "alert-danger";
}
else if (storedToken != token)
{
TempData["StatusMessage"] = errorMsg;
TempData["StatusMessage-Type"] = "alert-danger";
}
else
{
var viewModel = new PasswordResetForm {Email = email, PasswordResetToken = token};
return PartialView(viewModel);
}
}
}
return PasswordResetRequest();
}
[HttpPost]
public ActionResult PasswordReset(PasswordResetForm form)
{
var redirectUrl = "/";
var errorMsg = $"Sorry, a valid password reset was not found for user {form.Email}. " +
$"Please try resetting again, " +
$"or use Contact Us if the issue persists.";
if (ModelState.IsValid)
{
var memberService = ApplicationContext.Current.Services.MemberService;
var member = memberService.GetByEmail(form.Email);
if (member == null)
{
// don't acknowledge their email address
TempData["StatusMessage"] = errorMsg;
TempData["StatusMessage-Type"] = "alert-danger";
}
else
{
var storedToken = member.GetValue<string>(LeafWebMemberProperties.PasswordResetToken);
if (string.IsNullOrEmpty(storedToken))
{
TempData["StatusMessage"] = errorMsg;
TempData["StatusMessage-Type"] = "alert-danger";
}
else if (storedToken != form.PasswordResetToken)
{
TempData["StatusMessage"] = errorMsg;
TempData["StatusMessage-Type"] = "alert-danger";
}
else
{
memberService.SavePassword(member, form.Password);
// remove the token
member.SetValue(LeafWebMemberProperties.PasswordResetToken, string.Empty);
memberService.Save(member);
TempData["StatusMessage"] = "Password updated for " + member.Email + ", use your new password to login.";
TempData["StatusMessage-Type"] = "alert-success";
redirectUrl = "membership/login";
}
}
}
return Redirect(redirectUrl);
}
} }
} }
+2 -1
View File
@@ -1,4 +1,5 @@
using Hangfire; using Hangfire;
using LeafWeb.WebCms.Controllers;
using LeafWeb.WebCms.Services; using LeafWeb.WebCms.Services;
using MlkPwgen; using MlkPwgen;
using Umbraco.Core; using Umbraco.Core;
@@ -41,7 +42,7 @@ namespace LeafWeb.WebCms.EventHandlers
{ {
e.Entity.IsApproved = false; e.Entity.IsApproved = false;
var token = PasswordGenerator.Generate(12, allowed: "0123456789"); var token = PasswordGenerator.Generate(12, allowed: "0123456789");
e.Entity.SetValue("VerificationToken", token); e.Entity.SetValue(LeafWebMemberProperties.VerificationToken, token);
sender.Save(e.Entity); sender.Save(e.Entity);
// Send Email // Send Email
+1 -1
View File
@@ -21,7 +21,7 @@ namespace LeafWeb.WebCms.Models
[Display(Name = "Confirm email address")] [Display(Name = "Confirm email address")]
[Required(ErrorMessage = "Enter email exactly as above")] [Required(ErrorMessage = "Enter email exactly as above")]
[System.ComponentModel.DataAnnotations.Compare("Email")] [Compare("Email")]
public string EmailConfirm { get; set; } public string EmailConfirm { get; set; }
[Display(Name = "A unique identifier for this data")] [Display(Name = "A unique identifier for this data")]
+25
View File
@@ -0,0 +1,25 @@
using System.ComponentModel.DataAnnotations;
namespace LeafWeb.WebCms.Models
{
public class PasswordResetForm
{
[Display(Name = "Email address")]
[Required(ErrorMessage = "An email address is required")]
[DataType(DataType.EmailAddress)]
[RegularExpression(@"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}", ErrorMessage = "Must be an email address")]
public string Email { get; set; }
[Required(ErrorMessage = "A token is required to reset")]
public string PasswordResetToken { get; set; }
[Required(ErrorMessage = "A new password is required")]
[DataType(DataType.Password)]
public string Password { get; set; }
[Required(ErrorMessage = "Password must match verify exactly")]
[DataType(DataType.Password)]
[Compare("Password")]
public string PasswordVerify { get; set; }
}
}
+13
View File
@@ -0,0 +1,13 @@
using System.ComponentModel.DataAnnotations;
namespace LeafWeb.WebCms.Models
{
public class PasswordResetRequestForm
{
[Display(Name = "Email address")]
[Required(ErrorMessage = "An email address is required")]
[DataType(DataType.EmailAddress)]
[RegularExpression(@"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}", ErrorMessage = "Must be an email address")]
public string Email { get; set; }
}
}
+84 -19
View File
@@ -94,14 +94,24 @@ namespace LeafWeb.WebCms.Services
var body = $"Your leaf analysis job, {leafInput.Identifier}, has been cancelled. " + var body = $"Your leaf analysis job, {leafInput.Identifier}, has been cancelled. " +
"Contact the administrator with any questions."; "Contact the administrator with any questions.";
var message = new MailMessage(_emailFromAddress, leafInput.Email, FormatSubject(CancelledSubject, leafInput), body); using (var message =
SendMessage(message); new MailMessage(
_emailFromAddress,
leafInput.Email,
FormatSubject(CancelledSubject, leafInput),
body))
SendMessage(message);
} }
public void SendAdministratorMessage(string subject, string body) public void SendAdministratorMessage(string subject, string body)
{ {
var message = new MailMessage(_emailFromAddress, _adminEmailAddresses, subject, body); using (var message =
SendMessage(message); new MailMessage(
_emailFromAddress,
_adminEmailAddresses,
subject, body
))
SendMessage(message);
} }
private void SendLeafWebSuccess(LeafInput leafInput) private void SendLeafWebSuccess(LeafInput leafInput)
@@ -129,8 +139,13 @@ namespace LeafWeb.WebCms.Services
+ Environment.NewLine + Environment.NewLine + Environment.NewLine + Environment.NewLine
+ chartUrl; + chartUrl;
var message = new MailMessage(_emailFromAddress, leafInput.Email, FormatSubject(SuccessSubject, leafInput), body); using (var message =
SendMessage(message); new MailMessage(
_emailFromAddress,
leafInput.Email,
FormatSubject(SuccessSubject, leafInput),
body))
SendMessage(message);
} }
//else //else
//{ //{
@@ -173,8 +188,13 @@ namespace LeafWeb.WebCms.Services
body += FormatWarningMessage(leafInput); body += FormatWarningMessage(leafInput);
var message = new MailMessage(_emailFromAddress, leafInput.Email, FormatSubject(ErrorSubject, leafInput), body); using (var message =
SendMessage(message); new MailMessage(
_emailFromAddress,
leafInput.Email,
FormatSubject(ErrorSubject, leafInput),
body))
SendMessage(message);
} }
public void SendLeafWebSystemException(string leafInputIdentifier, string leafInputEmail) public void SendLeafWebSystemException(string leafInputIdentifier, string leafInputEmail)
@@ -183,8 +203,13 @@ namespace LeafWeb.WebCms.Services
+ "System administrators have been notified. You will be notified again when the system error " + "System administrators have been notified. You will be notified again when the system error "
+ "has been resolved and your data has been processed."; + "has been resolved and your data has been processed.";
var message = new MailMessage(_emailFromAddress, leafInputEmail, SystemErrorSubject, body); using (var message =
SendMessage(message); new MailMessage(
_emailFromAddress,
leafInputEmail,
SystemErrorSubject,
body))
SendMessage(message);
} }
public void SendContactEmail(ContactForm contact) public void SendContactEmail(ContactForm contact)
@@ -198,24 +223,65 @@ namespace LeafWeb.WebCms.Services
Environment.NewLine + Environment.NewLine + Environment.NewLine + Environment.NewLine +
contact.Message; contact.Message;
var message = new MailMessage(_emailFromAddress, _adminEmailAddresses, ContactSubject, body) using (var message =
{ new MailMessage(
From = new MailAddress(contact.Email, contact.Name) _emailFromAddress,
}; _adminEmailAddresses,
SendMessage(message); ContactSubject, body)
{
From = new MailAddress(contact.Email, contact.Name)
})
SendMessage(message);
} }
public void SendVerifyMemberEmail(string memberEmail) public void SendVerifyMemberEmail(string memberEmail)
{ {
var member = ApplicationContext.Current.Services.MemberService.GetByEmail(memberEmail); var member = ApplicationContext.Current.Services.MemberService.GetByEmail(memberEmail);
var verifyEmailURl = _urlService.GetVerifyEmailURl(member); var verifyEmailURl = _urlService.GetVerifyEmailUrl(member);
var body = var body =
"Welcome to LeafWeb!" + Environment.NewLine + Environment.NewLine + "Welcome to LeafWeb!" + Environment.NewLine + Environment.NewLine +
"Please verify your email address with this link " + verifyEmailURl + Environment.NewLine + "Please verify your email address with this link " + verifyEmailURl + Environment.NewLine +
"Read more information about LeafWeb on the site here: https://leafweb.org/information/about/"; "Read more information about LeafWeb on the site here: https://leafweb.org/information/about/";
var message = new MailMessage(_emailFromAddress, member.Email, "Welcome to LeafWeb, please verify your email address", body); using (var message =
SendMessage(message); new MailMessage(
_emailFromAddress,
member.Email,
"Welcome to LeafWeb, please verify your email address",
body))
SendMessage(message);
}
public void SendPasswordResetNotMemberEmail(string memberEmail)
{
var body =
"A password reset has been requested for leafweb.org" + Environment.NewLine + Environment.NewLine +
"We do not have an account attached to this email address, " +
"if you'd like to create one click here " + _urlService.GetRegisterUrl();
using (var message =
new MailMessage(
_emailFromAddress,
memberEmail,
"Reset LeafWeb Password",
body))
SendMessage(message);
}
public void SendPasswordResetEmail(string memberEmail)
{
var member = ApplicationContext.Current.Services.MemberService.GetByEmail(memberEmail);
var passwordResetURl = _urlService.GetPasswordResetUrl(member);
var body =
"A password reset has been requested for leafweb.org" + Environment.NewLine + Environment.NewLine +
"Please click here to enter a new password " + passwordResetURl;
using (var message =
new MailMessage(
_emailFromAddress,
member.Email,
"Reset LeafWeb Password",
body))
SendMessage(message);
} }
private string FormatWarningMessage(LeafInput leafInput) private string FormatWarningMessage(LeafInput leafInput)
@@ -246,6 +312,5 @@ namespace LeafWeb.WebCms.Services
{ {
_dataService.Dispose(); _dataService.Dispose();
} }
} }
} }
+23 -3
View File
@@ -1,6 +1,7 @@
using System.Configuration; using System.Configuration;
using System.Web; using System.Web;
using LeafWeb.Core.Entities; using LeafWeb.Core.Entities;
using LeafWeb.WebCms.Controllers;
using Umbraco.Core.Models; using Umbraco.Core.Models;
namespace LeafWeb.WebCms.Services namespace LeafWeb.WebCms.Services
@@ -10,6 +11,8 @@ namespace LeafWeb.WebCms.Services
private readonly string _downloadUrl; private readonly string _downloadUrl;
private readonly string _chartUrl; private readonly string _chartUrl;
private readonly string _verifyEmailUrl; private readonly string _verifyEmailUrl;
private readonly string _passwordResetUrl;
private readonly string _registerUrl;
public UrlService() public UrlService()
{ {
@@ -24,9 +27,17 @@ namespace LeafWeb.WebCms.Services
_verifyEmailUrl = _verifyEmailUrl =
ConfigurationManager.AppSettings["LeafWebUrl"] ConfigurationManager.AppSettings["LeafWebUrl"]
+ ConfigurationManager.AppSettings["MemberVerifyPath"]; + ConfigurationManager.AppSettings["MemberVerifyPath"];
_passwordResetUrl =
ConfigurationManager.AppSettings["LeafWebUrl"]
+ ConfigurationManager.AppSettings["PasswordResetPath"];
_registerUrl =
ConfigurationManager.AppSettings["LeafWebUrl"]
+ ConfigurationManager.AppSettings["RegisterPath"];
} }
public string GetDownloadUrl(LeafInput leafInput) public string GetDownloadUrl(LeafInput leafInput)
{ {
return string.Format(_downloadUrl, leafInput.UniqueToken); return string.Format(_downloadUrl, leafInput.UniqueToken);
} }
@@ -36,11 +47,20 @@ namespace LeafWeb.WebCms.Services
return string.Format(_chartUrl, leafInput.UniqueToken); return string.Format(_chartUrl, leafInput.UniqueToken);
} }
public string GetVerifyEmailURl(IMember member) public string GetVerifyEmailUrl(IMember member)
{ {
var memberEmail = member.Email; var memberEmail = member.Email;
var token = member.GetValue("VerificationToken") as string; var token = member.GetValue<string>(LeafWebMemberProperties.VerificationToken);
return string.Format(_verifyEmailUrl, HttpUtility.UrlEncode(memberEmail), token); return string.Format(_verifyEmailUrl, HttpUtility.UrlEncode(memberEmail), token);
} }
public string GetPasswordResetUrl(IMember member)
{
var memberEmail = member.Email;
var token = member.GetValue<string>(LeafWebMemberProperties.PasswordResetToken);
return string.Format(_passwordResetUrl, HttpUtility.UrlEncode(memberEmail), token);
}
public string GetRegisterUrl() => _registerUrl;
} }
} }
+1 -1
View File
@@ -18,7 +18,7 @@
@Html.EditorFor(m => m.Name) @Html.EditorFor(m => m.Name)
@Html.EditorFor(m => m.Email) @Html.EditorFor(m => m.Email)
@Html.EditorFor(m => m.Message) @Html.EditorFor(m => m.Message)
<input type="submit" id="submit-form" class="hidden"/>} <input type="submit" id="submit-form" class="d-none"/>}
<label for="submit-form" class="btn btn-primary pull-right">Send</label> <label for="submit-form" class="btn btn-primary pull-right">Send</label>
</div> </div>
</div> </div>
@@ -13,8 +13,7 @@
@using (Html.BeginUmbracoForm<UmbLoginController>("HandleLogin")) @using (Html.BeginUmbracoForm<UmbLoginController>("HandleLogin"))
{ {
@Html.EditorFor(m => loginModel.Username) @Html.EditorFor(m => loginModel.Username)
@Html.EditorFor(m => loginModel.Password, "Password") @Html.EditorFor(m => loginModel.Password, "PasswordWithForgotLink")
@Html.ValidationSummary("loginModel", true) @Html.ValidationSummary("loginModel", true)
<button class="btn btn-primary pull-right">Login</button> <button class="btn btn-primary pull-right">Login</button>
@@ -0,0 +1,4 @@
@inherits Umbraco.Web.Macros.PartialViewMacroPage
@{
Html.RenderAction("PasswordReset", "Membership");
}
@@ -0,0 +1,4 @@
@inherits Umbraco.Web.Macros.PartialViewMacroPage
@{
Html.RenderAction("PasswordResetRequest", "Membership");
}
@@ -1,9 +1,10 @@
@inherits Umbraco.Web.Macros.PartialViewMacroPage @inherits Umbraco.Web.Macros.PartialViewMacroPage
@using ClientDependency.Core.Mvc @using ClientDependency.Core.Mvc
@using Umbraco.Web.Controllers @using Umbraco.Web.Controllers
<!-- https://24days.in/umbraco-cms/2015/membership-apis-investigation/ -->
<!-- https://our.umbraco.com/forum/templates-partial-views-and-macros/93133-membership-provider-registration-form -->
@{ @{
// https://24days.in/umbraco-cms/2015/membership-apis-investigation/
// https://our.umbraco.com/forum/templates-partial-views-and-macros/93133-membership-provider-registration-form
var membershipHelper = new Umbraco.Web.Security.MembershipHelper(UmbracoContext.Current); var membershipHelper = new Umbraco.Web.Security.MembershipHelper(UmbracoContext.Current);
var registerModel = membershipHelper.CreateRegistrationModel(); var registerModel = membershipHelper.CreateRegistrationModel();
@@ -28,7 +29,7 @@
} }
else if (user != null) else if (user != null)
{ {
<p>No need to register - you are already logged withe email @user.Email</p> <p>No need to register - you are already logged with email @user.Email</p>
} }
else else
{ {
@@ -0,0 +1,28 @@
@using ClientDependency.Core.Mvc
@using LeafWeb.WebCms.Controllers
@model PasswordResetForm
@{
Html.RequiresJs("~/scripts/jquery.validate.min.js", 2);
Html.RequiresJs("~/scripts/jquery.validate.unobtrusive.min.js", 2);
Html.RequiresJs("~/scripts/jquery.validate.unobtrusive.bootstrap.js", 2);
Html.RequiresJs("~/scripts/jquery.validate.custom.js", 2);
}
<div class="container mt-4">
<div class="row justify-content-center">
<div class="col-md-6 ">
<p>Resetting password for @Model.Email</p>
@Html.Partial("_ValidationSummary")
@using (Html.BeginUmbracoForm<MembershipController>("PasswordReset"))
{
@Html.HiddenFor(m => m.Email)
@Html.HiddenFor(m => m.PasswordResetToken)
@Html.EditorFor(m => m.Password)
@Html.EditorFor(m => m.PasswordVerify)
<input type="submit" id="submit-form" class="d-none"/>
}
<label for="submit-form" class="btn btn-primary pull-right">Reset</label>
</div>
</div>
</div>
@@ -0,0 +1,24 @@
@using ClientDependency.Core.Mvc
@using LeafWeb.WebCms.Controllers
@model PasswordResetRequestForm
@{
Html.RequiresJs("~/scripts/jquery.validate.min.js", 2);
Html.RequiresJs("~/scripts/jquery.validate.unobtrusive.min.js", 2);
Html.RequiresJs("~/scripts/jquery.validate.unobtrusive.bootstrap.js", 2);
Html.RequiresJs("~/scripts/jquery.validate.custom.js", 2);
}
<div class="container mt-4">
<div class="row justify-content-center">
<div class="col-md-6 ">
@Html.Partial("_ValidationSummary")
@using (Html.BeginUmbracoForm<MembershipController>("PasswordResetRequest"))
{
@Html.EditorFor(m => m.Email)
<input type="submit" id="submit-form" class="d-none"/>
}
<label for="submit-form" class="btn btn-primary pull-right">Send</label>
</div>
</div>
</div>
@@ -0,0 +1,24 @@
@model object
@{
Layout = "_FieldLayout.cshtml";
}
@{
var htmlAttributes = new RouteValueDictionary();
var controlClass = "form-control mb-0";
if (ViewBag.@class != null)
{
controlClass = string.Concat(controlClass, " ", ViewBag.@class);
}
if (ViewData.ModelState.ContainsKey(ViewData.TemplateInfo.HtmlFieldPrefix) &&
ViewData.ModelState[ViewData.TemplateInfo.HtmlFieldPrefix].Errors.Any())
{
controlClass = string.Concat(controlClass, " ", "is-invalid");
}
htmlAttributes.Add("class", controlClass);
}
@Html.Password("", ViewData.TemplateInfo.FormattedModelValue, htmlAttributes)
<p class="text-right pt-0 small">Forgot password? <a href="/membership/password-reset-request" class="small">Reset here</a></p>
+3 -1
View File
@@ -76,8 +76,10 @@
<add key="LeafWebUrl" value="http://localhost:61755/" /> <add key="LeafWebUrl" value="http://localhost:61755/" />
<add key="PiscalNotifyCompleteUrlPath" value="notifycomplete" /> <add key="PiscalNotifyCompleteUrlPath" value="notifycomplete" />
<add key="ResultsDownloadPath" value="Results/Download?token={0}" /> <add key="ResultsDownloadPath" value="Results/Download?token={0}" />
<add key="PasswordResetPath" value="membership/password-reset?email={0}&amp;token={1}" />
<add key="ChartPath" value="leaf-data/chart?token={0}" /> <add key="ChartPath" value="leaf-data/chart?token={0}" />
<add key="MemberVerifyPath" value="verify?email={0}&amp;token={1}" /> <add key="MemberVerifyPath" value="verify?email={0}&amp;token={1}" />
<add key="RegisterPath" value="membership/register" />
<add key="PiscalUnresponsiveHourCount" value="24" /> <add key="PiscalUnresponsiveHourCount" value="24" />
</appSettings> </appSettings>
<connectionStrings> <connectionStrings>
@@ -262,7 +264,7 @@
<membership defaultProvider="UmbracoMembershipProvider" userIsOnlineTimeWindow="15"> <membership defaultProvider="UmbracoMembershipProvider" userIsOnlineTimeWindow="15">
<providers> <providers>
<clear /> <clear />
<add name="UmbracoMembershipProvider" type="Umbraco.Web.Security.Providers.MembersMembershipProvider, Umbraco" minRequiredNonalphanumericCharacters="0" minRequiredPasswordLength="8" useLegacyEncoding="true" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" defaultMemberTypeAlias="Member" passwordFormat="Hashed" /> <add name="UmbracoMembershipProvider" type="Umbraco.Web.Security.Providers.MembersMembershipProvider, Umbraco" allowManuallyChangingPassword="true" minRequiredNonalphanumericCharacters="0" minRequiredPasswordLength="8" useLegacyEncoding="true" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" defaultMemberTypeAlias="Member" passwordFormat="Hashed" />
<add name="UsersMembershipProvider" type="Umbraco.Web.Security.Providers.UsersMembershipProvider, Umbraco" minRequiredNonalphanumericCharacters="0" minRequiredPasswordLength="8" useLegacyEncoding="true" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" passwordFormat="Hashed" /> <add name="UsersMembershipProvider" type="Umbraco.Web.Security.Providers.UsersMembershipProvider, Umbraco" minRequiredNonalphanumericCharacters="0" minRequiredPasswordLength="8" useLegacyEncoding="true" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" passwordFormat="Hashed" />
</providers> </providers>
</membership> </membership>
+7 -1
View File
@@ -1063,6 +1063,11 @@
<Content Include="scripts\popper-utils.js.map" /> <Content Include="scripts\popper-utils.js.map" />
<Content Include="Views\MacroPartials\Membership\Register.cshtml" /> <Content Include="Views\MacroPartials\Membership\Register.cshtml" />
<Content Include="Views\Shared\EditorTemplates\EmailAddress.cshtml" /> <Content Include="Views\Shared\EditorTemplates\EmailAddress.cshtml" />
<Content Include="Views\Shared\EditorTemplates\PasswordWithForgotLink.cshtml" />
<Content Include="Views\MacroPartials\Membership\PasswordReset.cshtml" />
<Content Include="Views\Membership\PasswordReset.cshtml" />
<Content Include="Views\MacroPartials\Membership\PasswordResetRequest.cshtml" />
<Content Include="Views\Membership\PasswordResetRequest.cshtml" />
<None Include="Web.Debug.config"> <None Include="Web.Debug.config">
<DependentUpon>Web.config</DependentUpon> <DependentUpon>Web.config</DependentUpon>
</None> </None>
@@ -1101,6 +1106,8 @@
<Compile Include="Controllers\ResultsController.cs" /> <Compile Include="Controllers\ResultsController.cs" />
<Compile Include="EventHandlers\MemberEvents.cs" /> <Compile Include="EventHandlers\MemberEvents.cs" />
<Compile Include="Models\ChartViewModel.cs" /> <Compile Include="Models\ChartViewModel.cs" />
<Compile Include="Models\PasswordResetForm.cs" />
<Compile Include="Models\PasswordResetRequestForm.cs" />
<Compile Include="Models\ContactForm.cs" /> <Compile Include="Models\ContactForm.cs" />
<Compile Include="Models\LeafInputDetails.cs" /> <Compile Include="Models\LeafInputDetails.cs" />
<Compile Include="Models\LeafInputCreate.cs" /> <Compile Include="Models\LeafInputCreate.cs" />
@@ -1128,7 +1135,6 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Folder Include="Media\1051\" /> <Folder Include="Media\1051\" />
<Folder Include="Views\Register\" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Service Include="{4A0DDDB5-7A95-4FBF-97CC-616D07737A77}" /> <Service Include="{4A0DDDB5-7A95-4FBF-97CC-616D07737A77}" />