webdav portal password reset added

This commit is contained in:
vfedosevich 2015-04-14 00:40:11 -07:00
parent 4bae47e17f
commit 599e9a8865
48 changed files with 1163 additions and 117 deletions

View file

@ -18,6 +18,30 @@ namespace WebsitePanel.WebDavPortal
defaults: new { controller = "Account", action = "UserProfile" }
);
routes.MapRoute(
name: AccountRouteNames.PasswordResetEmail,
url: "account/password-reset/step-1",
defaults: new { controller = "Account", action = "PasswordResetEmail" }
);
routes.MapRoute(
name: AccountRouteNames.PasswordResetSms,
url: "account/password-reset/step-2/{token}",
defaults: new { controller = "Account", action = "PasswordResetSms" }
);
routes.MapRoute(
name: AccountRouteNames.PasswordResetSendSms,
url: "account/password-reset/step-final/{token}",
defaults: new { controller = "Account", action = "PasswordResetSendSms" }
);
routes.MapRoute(
name: AccountRouteNames.PasswordResetFinalStep,
url: "account/password-reset/send-new-sms/{token}",
defaults: new { controller = "Account", action = "PasswordResetFinalStep" }
);
routes.MapRoute(
name: AccountRouteNames.PasswordChange,
url: "account/profile/password-change",

View file

@ -12,5 +12,9 @@ namespace WebsitePanel.WebDavPortal.UI.Routes
public const string UserProfile = "UserProfileRoute";
public const string PasswordChange = "PasswordChangeRoute";
public const string PasswordResetEmail = "PasswordResetEmailRoute";
public const string PasswordResetSms = "PasswordResetSmsRoute";
public const string PasswordResetSendSms = "PasswordResetSendSmsRoute";
public const string PasswordResetFinalStep = "PasswordResetFinalStepRoute";
}
}

View file

@ -230,6 +230,9 @@ tr.selected-file {
color: white;
}
.forgot-your-password-link {
margin-left: 10px;
}
.navbar-fixed-top #user-profile {
font-size: 18px;

View file

@ -1,4 +1,5 @@
using System.Linq;
using System;
using System.Linq;
using System.Net;
using System.Web.Mvc;
using System.Web.Routing;
@ -7,6 +8,7 @@ using WebsitePanel.Providers.HostedSolution;
using WebsitePanel.WebDav.Core.Config;
using WebsitePanel.WebDav.Core.Security.Authentication;
using WebsitePanel.WebDav.Core.Security.Cryptography;
using WebsitePanel.WebDav.Core.Wsp.Framework;
using WebsitePanel.WebDavPortal.CustomAttributes;
using WebsitePanel.WebDavPortal.Models;
using WebsitePanel.WebDavPortal.Models.Account;
@ -24,16 +26,17 @@ namespace WebsitePanel.WebDavPortal.Controllers
{
private readonly ICryptography _cryptography;
private readonly IAuthenticationService _authenticationService;
private readonly ISmsAuthenticationService _smsAuthService;
public AccountController(ICryptography cryptography, IAuthenticationService authenticationService)
public AccountController(ICryptography cryptography, IAuthenticationService authenticationService, ISmsAuthenticationService smsAuthService)
{
_cryptography = cryptography;
_authenticationService = authenticationService;
_smsAuthService = smsAuthService;
}
[HttpGet]
[AllowAnonymous]
public ActionResult Login()
{
if (WspContext.User != null && WspContext.User.Identity.IsAuthenticated)
@ -127,6 +130,157 @@ namespace WebsitePanel.WebDavPortal.Controllers
return RedirectToRoute(AccountRouteNames.UserProfile);
}
[HttpGet]
[AllowAnonymous]
public ActionResult PasswordResetEmail()
{
var model = new PasswordResetEmailModel();
return View(model);
}
[HttpPost]
[AllowAnonymous]
public ActionResult PasswordResetEmail(PasswordResetEmailModel model)
{
if (!ModelState.IsValid)
{
return View(model);
}
var exchangeAccount = WspContext.Services.ExchangeServer.GetAccountByAccountNameWithoutItemId(model.Email);
if (exchangeAccount == null)
{
model.AddMessage(MessageType.Error, Resources.Messages.AccountNotFound);
return View(model);
}
WspContext.Services.Organizations.SendResetUserPasswordEmail(exchangeAccount.ItemId, exchangeAccount.AccountId, Resources.Messages.PasswordResetUserReason, exchangeAccount.PrimaryEmailAddress);
return View("PasswordResetEmailSent");
}
[HttpGet]
[AllowAnonymous]
public ActionResult PasswordResetSms(Guid token)
{
var model = new PasswordResetSmsModel();
var accessToken = WspContext.Services.Organizations.GetPasswordresetAccessToken(token);
model.IsTokenExist = accessToken != null;
if (model.IsTokenExist == false)
{
model.AddMessage(MessageType.Error, Resources.Messages.IncorrectPasswordResetUrl);
return View(model);
}
if (accessToken.IsSmsSent == false)
{
var user = WspContext.Services.Organizations.GetUserGeneralSettings(accessToken.ItemId, accessToken.AccountId);
var response = _smsAuthService.SendRequestMessage(user.MobilePhone);
WspContext.Services.Organizations.SetAccessTokenResponse(accessToken.AccessTokenGuid, response);
}
return View(model);
}
[HttpPost]
[AllowAnonymous]
public ActionResult PasswordResetSms(Guid token, PasswordResetSmsModel model)
{
if (!ModelState.IsValid)
{
return View(model);
}
if (_smsAuthService.VerifyResponse(token, model.Sms))
{
var tokenEntity = WspContext.Services.Organizations.GetPasswordresetAccessToken(token);
Session[WebDavAppConfigManager.Instance.SessionKeys.PasswordResetSmsKey] = model.Sms;
Session[WebDavAppConfigManager.Instance.SessionKeys.ItemId] = tokenEntity.ItemId;
return RedirectToRoute(AccountRouteNames.PasswordResetFinalStep);
}
model.AddMessage(MessageType.Error, Resources.Messages.IncorrectSmsResponse);
return View(model);
}
[HttpGet]
[AllowAnonymous]
public ActionResult PasswordResetFinalStep(Guid token)
{
var smsResponse = Session[WebDavAppConfigManager.Instance.SessionKeys.PasswordResetSmsKey] as string;
if (_smsAuthService.VerifyResponse(token, smsResponse) == false)
{
return RedirectToRoute(AccountRouteNames.PasswordResetSms);
}
var model = new PasswordEditor();
return View(model);
}
[HttpPost]
[AllowAnonymous]
public ActionResult PasswordResetFinalStep(Guid token, PasswordEditor model)
{
if (!ModelState.IsValid)
{
return View(model);
}
var smsResponse = Session[WebDavAppConfigManager.Instance.SessionKeys.PasswordResetSmsKey] as string;
if (_smsAuthService.VerifyResponse(token, smsResponse) == false)
{
model.AddMessage(MessageType.Error, Resources.Messages.IncorrectSmsResponse);
return RedirectToRoute(AccountRouteNames.PasswordResetSms);
}
var tokenEntity = WspContext.Services.Organizations.GetPasswordresetAccessToken(token);
WspContext.Services.Organizations.SetUserPassword(
tokenEntity.ItemId, tokenEntity.AccountId,
model.NewPassword);
WspContext.Services.Organizations.DeletePasswordresetAccessToken(token);
return RedirectToRoute(AccountRouteNames.Login);
}
[HttpGet]
[AllowAnonymous]
public ActionResult PasswordResetSendSms(Guid token)
{
var accessToken = WspContext.Services.Organizations.GetPasswordresetAccessToken(token);
if (accessToken == null)
{
return RedirectToRoute(AccountRouteNames.PasswordResetSms);
}
var user = WspContext.Services.Organizations.GetUserGeneralSettings(accessToken.ItemId,
accessToken.AccountId);
var response = _smsAuthService.SendRequestMessage(user.MobilePhone);
WspContext.Services.Organizations.SetAccessTokenResponse(accessToken.AccessTokenGuid, response);
return RedirectToRoute(AccountRouteNames.PasswordResetSms);
}
#region Helpers
private UserProfile GetUserProfileModel(int itemId, int accountId)

View file

@ -2,9 +2,11 @@
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using WebsitePanel.Providers.HostedSolution;
using WebsitePanel.WebDav.Core;
using WebsitePanel.WebDav.Core.Config;
namespace WebsitePanel.WebDavPortal.CustomAttributes
{
@ -15,14 +17,25 @@ namespace WebsitePanel.WebDavPortal.CustomAttributes
public OrganizationPasswordPolicyAttribute()
{
Settings = WspContext.Services.Organizations.GetOrganizationPasswordSettings(WspContext.User.ItemId);
int itemId = -1;
if (WspContext.User != null)
{
itemId = WspContext.User.ItemId;
}
else if (HttpContext.Current != null && HttpContext.Current.Session[WebDavAppConfigManager.Instance.SessionKeys.ItemId] != null)
{
itemId = (int) HttpContext.Current.Session[WebDavAppConfigManager.Instance.SessionKeys.ItemId];
}
Settings = WspContext.Services.Organizations.GetOrganizationPasswordSettings(itemId);
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
if (value != null && WspContext.User != null)
if (value != null)
{
var resultMessages = new List<string>();
if (Settings != null)

View file

@ -4,6 +4,7 @@ using WebsitePanel.WebDav.Core.Interfaces.Managers;
using WebsitePanel.WebDav.Core.Interfaces.Managers.Users;
using WebsitePanel.WebDav.Core.Interfaces.Owa;
using WebsitePanel.WebDav.Core.Interfaces.Security;
using WebsitePanel.WebDav.Core.Interfaces.Services;
using WebsitePanel.WebDav.Core.Interfaces.Storages;
using WebsitePanel.WebDav.Core.Managers;
using WebsitePanel.WebDav.Core.Managers.Users;
@ -11,6 +12,7 @@ using WebsitePanel.WebDav.Core.Owa;
using WebsitePanel.WebDav.Core.Security.Authentication;
using WebsitePanel.WebDav.Core.Security.Authorization;
using WebsitePanel.WebDav.Core.Security.Cryptography;
using WebsitePanel.WebDav.Core.Services;
using WebsitePanel.WebDav.Core.Storages;
using WebsitePanel.WebDavPortal.DependencyInjection.Providers;
@ -31,6 +33,8 @@ namespace WebsitePanel.WebDavPortal.DependencyInjection
kernel.Bind<ICobaltManager>().To<CobaltManager>();
kernel.Bind<ITtlStorage>().To<CacheTtlStorage>();
kernel.Bind<IUserSettingsManager>().To<UserSettingsManager>();
kernel.Bind<ISmsDistributionService>().To<TwillioSmsDistributionService>();
kernel.Bind<ISmsAuthenticationService>().To<SmsAuthenticationService>();
}
}
}

View file

@ -0,0 +1,14 @@
using System.ComponentModel.DataAnnotations;
using WebsitePanel.WebDavPortal.Models.Common;
using WebsitePanel.WebDavPortal.Resources;
namespace WebsitePanel.WebDavPortal.Models.Account
{
public class PasswordResetEmailModel : BaseModel
{
[Required]
[Display(ResourceType = typeof(Resources.UI), Name = "Email")]
[EmailAddress(ErrorMessageResourceType = typeof(Messages), ErrorMessageResourceName = "EmailInvalid",ErrorMessage = null)]
public string Email { get; set; }
}
}

View file

@ -0,0 +1,12 @@
using System.ComponentModel.DataAnnotations;
using WebsitePanel.WebDavPortal.Models.Common;
namespace WebsitePanel.WebDavPortal.Models.Account
{
public class PasswordResetSmsModel : BaseModel
{
[Required]
public string Sms { get; set; }
public bool IsTokenExist { get; set; }
}
}

View file

@ -4,7 +4,7 @@ using WebsitePanel.WebDavPortal.CustomAttributes;
namespace WebsitePanel.WebDavPortal.Models.Common.EditorTemplates
{
public class PasswordEditor
public class PasswordEditor : BaseModel
{
[Display(ResourceType = typeof(Resources.UI), Name = "NewPassword")]

View file

@ -60,6 +60,15 @@ namespace WebsitePanel.WebDavPortal.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to Account was not found.
/// </summary>
public static string AccountNotFound {
get {
return ResourceManager.GetString("AccountNotFound", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Email is invalid.
/// </summary>
@ -69,6 +78,24 @@ namespace WebsitePanel.WebDavPortal.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to Your password could not be reset. The url you followed is either incorrect, has been used or has expired..
/// </summary>
public static string IncorrectPasswordResetUrl {
get {
return ResourceManager.GetString("IncorrectPasswordResetUrl", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Incorrect text message (SMS) response..
/// </summary>
public static string IncorrectSmsResponse {
get {
return ResourceManager.GetString("IncorrectSmsResponse", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Old password is not correct.
/// </summary>
@ -114,6 +141,33 @@ namespace WebsitePanel.WebDavPortal.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to A message was sent to your email address. Please check your email for further instructions..
/// </summary>
public static string PasswordResetEmailSent {
get {
return ResourceManager.GetString("PasswordResetEmailSent", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Text message (SMS) was sent to the phone number associated to your account. If you didn&apos;t recieve text message (SMS) click {0} for new text message (SMS)..
/// </summary>
public static string PasswordResetSmsHintFormat {
get {
return ResourceManager.GetString("PasswordResetSmsHintFormat", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Webdav portal user request..
/// </summary>
public static string PasswordResetUserReason {
get {
return ResourceManager.GetString("PasswordResetUserReason", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Password should contain at least {0} non-alphanumeric symbols.
/// </summary>

View file

@ -117,9 +117,18 @@
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="AccountNotFound" xml:space="preserve">
<value>Account was not found</value>
</data>
<data name="EmailInvalid" xml:space="preserve">
<value>Email is invalid</value>
</data>
<data name="IncorrectPasswordResetUrl" xml:space="preserve">
<value>Your password could not be reset. The url you followed is either incorrect, has been used or has expired.</value>
</data>
<data name="IncorrectSmsResponse" xml:space="preserve">
<value>Incorrect text message (SMS) response.</value>
</data>
<data name="OldPasswordIsNotCorrect" xml:space="preserve">
<value>Old password is not correct</value>
</data>
@ -135,6 +144,15 @@
<data name="PasswordNumbersCountFormat" xml:space="preserve">
<value>Password should contain at least {0} numbers</value>
</data>
<data name="PasswordResetEmailSent" xml:space="preserve">
<value>A message was sent to your email address. Please check your email for further instructions.</value>
</data>
<data name="PasswordResetSmsHintFormat" xml:space="preserve">
<value>Text message (SMS) was sent to the phone number associated to your account. If you didn't recieve text message (SMS) click {0} for new text message (SMS).</value>
</data>
<data name="PasswordResetUserReason" xml:space="preserve">
<value>Webdav portal user request.</value>
</data>
<data name="PasswordSymbolsCountFormat" xml:space="preserve">
<value>Password should contain at least {0} non-alphanumeric symbols</value>
</data>

View file

@ -357,6 +357,15 @@ namespace WebsitePanel.WebDavPortal.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to Forgot your password?.
/// </summary>
public static string ForgotYourPassword {
get {
return ResourceManager.GetString("ForgotYourPassword", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to General Information.
/// </summary>
@ -528,6 +537,15 @@ namespace WebsitePanel.WebDavPortal.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to Next.
/// </summary>
public static string Next {
get {
return ResourceManager.GetString("Next", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to No files are selected..
/// </summary>
@ -600,6 +618,15 @@ namespace WebsitePanel.WebDavPortal.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to Password reset.
/// </summary>
public static string PasswordReset {
get {
return ResourceManager.GetString("PasswordReset", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to PB.
/// </summary>
@ -717,6 +744,15 @@ namespace WebsitePanel.WebDavPortal.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to Send email.
/// </summary>
public static string SendEmail {
get {
return ResourceManager.GetString("SendEmail", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Size.
/// </summary>
@ -726,6 +762,15 @@ namespace WebsitePanel.WebDavPortal.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to Sms.
/// </summary>
public static string Sms {
get {
return ResourceManager.GetString("Sms", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to State/Province.
/// </summary>

View file

@ -216,6 +216,9 @@
<data name="FirstName" xml:space="preserve">
<value>First Name</value>
</data>
<data name="ForgotYourPassword" xml:space="preserve">
<value>Forgot your password?</value>
</data>
<data name="GeneralInformation" xml:space="preserve">
<value>General Information</value>
</data>
@ -273,6 +276,9 @@
<data name="NewPasswordConfirmation" xml:space="preserve">
<value>Confirm password</value>
</data>
<data name="Next" xml:space="preserve">
<value>Next</value>
</data>
<data name="NoFilesAreSelected" xml:space="preserve">
<value>No files are selected.</value>
</data>
@ -297,6 +303,9 @@
<data name="PasswordExpirationFormat" xml:space="preserve">
<value>Will expire on {0}. If you want to change password then please click {1}.</value>
</data>
<data name="PasswordReset" xml:space="preserve">
<value>Password reset</value>
</data>
<data name="PetabyteShort" xml:space="preserve">
<value>PB</value>
</data>
@ -336,9 +345,15 @@
<data name="SelectFilesToUpload" xml:space="preserve">
<value>Select files to upload</value>
</data>
<data name="SendEmail" xml:space="preserve">
<value>Send email</value>
</data>
<data name="Size" xml:space="preserve">
<value>Size</value>
</data>
<data name="Sms" xml:space="preserve">
<value>Sms</value>
</data>
<data name="State" xml:space="preserve">
<value>State/Province</value>
</data>

View file

@ -1,8 +1,9 @@
/// <reference path="jquery-ui-1.9.0.js" />
/// <autosync enabled="true" />
/// <autosync enabled="true" />
/// <reference path="bootstrap.js" />
/// <reference path="jquery-2.1.1.js" />
/// <reference path="jquery-ui-1.9.0.js" />
/// <reference path="jquery.cookie.js" />
/// <reference path="jquery.ui.widget.js" />
/// <reference path="jquery.validate.js" />
/// <reference path="jquery.validate.unobtrusive.js" />
/// <reference path="modernizr-2.8.3.js" />
@ -10,5 +11,36 @@
/// <reference path="respond.js" />
/// <reference path="respond.matchmedia.addlistener.js" />
/// <reference path="appscripts/authentication.js" />
/// <reference path="appscripts/dialogs.js" />
/// <reference path="appscripts/filebrowsing.js" />
/// <reference path="appscripts/messages.js" />
/// <reference path="appscripts/recalculateresourseheight.js" />
/// <reference path="appscripts/uploadingdata2.js" />
/// <reference path="appscripts/wsp-webdav.js" />
/// <reference path="appscripts/wsp.js" />
/// <reference path="datatables-1.10.4/datatables.autofill.js" />
/// <reference path="datatables-1.10.4/datatables.bootstrap.js" />
/// <reference path="datatables-1.10.4/datatables.colreorder.js" />
/// <reference path="datatables-1.10.4/datatables.colvis.js" />
/// <reference path="datatables-1.10.4/datatables.fixedcolumns.js" />
/// <reference path="datatables-1.10.4/datatables.fixedheader.js" />
/// <reference path="datatables-1.10.4/datatables.foundation.js" />
/// <reference path="datatables-1.10.4/datatables.jqueryui.js" />
/// <reference path="datatables-1.10.4/datatables.keytable.js" />
/// <reference path="datatables-1.10.4/datatables.responsive.js" />
/// <reference path="datatables-1.10.4/datatables.scroller.js" />
/// <reference path="datatables-1.10.4/datatables.tabletools.js" />
/// <reference path="datatables-1.10.4/jquery.datatables.js" />
/// <reference path="jquery.fileupload/jquery.fileupload-angular.js" />
/// <reference path="jquery.fileupload/jquery.fileupload-audio.js" />
/// <reference path="jquery.fileupload/jquery.fileupload-image.js" />
/// <reference path="jquery.fileupload/jquery.fileupload-jquery-ui.js" />
/// <reference path="jquery.fileupload/jquery.fileupload-process.js" />
/// <reference path="jquery.fileupload/jquery.fileupload-ui.js" />
/// <reference path="jquery.fileupload/jquery.fileupload-validate.js" />
/// <reference path="jquery.fileupload/jquery.fileupload-video.js" />
/// <reference path="jquery.fileupload/jquery.fileupload.js" />
/// <reference path="jquery.fileupload/jquery.iframe-transport.js" />
/// <reference path="jquery.fileupload/tmpl.min.js" />
/// <reference path="jquery.fileupload/cors/jquery.postmessage-transport.js" />
/// <reference path="jquery.fileupload/cors/jquery.xdr-transport.js" />

View file

@ -1,4 +1,6 @@
@model WebsitePanel.WebDavPortal.Models.AccountModel
@using WebsitePanel.WebDavPortal.Resources
@using WebsitePanel.WebDavPortal.UI.Routes
@model WebsitePanel.WebDavPortal.Models.AccountModel
@{
ViewBag.Title = "Login";
}
@ -30,6 +32,7 @@
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-default">Sign in</button>
<a href="@Url.RouteUrl(AccountRouteNames.PasswordResetEmail)" class="forgot-your-password-link">@UI.ForgotYourPassword</a>
</div>
</div>
</form>

View file

@ -0,0 +1,31 @@
@using WebsitePanel.WebDavPortal.Resources
@using WebsitePanel.WebDavPortal.UI.Routes
@model WebsitePanel.WebDavPortal.Models.Account.PasswordResetEmailModel
@{
Layout = "~/Views/Shared/_Layout.cshtml";
}
<div class="container row">
@using (Html.BeginRouteForm(AccountRouteNames.PasswordResetEmail, FormMethod.Post, new { @class = "form-horizontal user-password-reset-email bs-val-styles col-lg-10 col-lg-offset-3", id = "user-password-reset" }))
{
<div class="form-group">
<h3>@UI.PasswordReset</h3>
</div>
<div class="form-group">
<label for="@Html.IdFor(x => x.Email)" class="col-sm-2 control-label">@UI.Email</label>
<div class="col-sm-10">
@Html.TextBoxFor(x => x.Email, new { @class = "form-control", placeholder = UI.Email })
@Html.ValidationMessageFor(x => x.Email)
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-default">@UI.SendEmail</button>
</div>
</div>
}
</div>

View file

@ -0,0 +1,14 @@
@using WebsitePanel.WebDavPortal.Resources
@{
Layout = "~/Views/Shared/_Layout.cshtml";
}
<div class="container row">
<div class="form-group">
<h3>@UI.PasswordReset</h3>
<h4>@Messages.PasswordResetEmailSent</h4>
</div>
</div>

View file

@ -0,0 +1,27 @@
@{
Layout = "~/Views/Shared/_Layout.cshtml";
}
@using WebsitePanel.WebDavPortal.Resources
@using WebsitePanel.WebDavPortal.UI.Routes
@model WebsitePanel.WebDavPortal.Models.Common.EditorTemplates.PasswordEditor
<div class="container row">
@using (Html.BeginRouteForm(AccountRouteNames.PasswordResetFinalStep, FormMethod.Post, new { @class = "form-horizontal user-password-reset-final-step bs-val-styles col-lg-9 col-lg-offset-3", id = "user-password-reset" }))
{
<div class="form-group">
<h3>@UI.PasswordReset</h3>
</div>
@Html.EditorFor(x=>x)
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-default">@UI.ChangePassword</button>
</div>
</div>
}
</div>

View file

@ -0,0 +1,38 @@
@using WebsitePanel.WebDavPortal.Resources
@using WebsitePanel.WebDavPortal.UI.Routes
@model WebsitePanel.WebDavPortal.Models.Account.PasswordResetSmsModel
@{
Layout = "~/Views/Shared/_Layout.cshtml";
}
@if (Model.IsTokenExist)
{
<div class="container row">
@using (Html.BeginRouteForm(AccountRouteNames.PasswordResetSms, FormMethod.Post, new {@class = "form-horizontal user-password-reset-sms bs-val-styles col-lg-9 col-lg-offset-3", id = "user-password-reset"}))
{
@Html.HiddenFor(x=>x.IsTokenExist)
<div class="form-group">
<h3>@UI.PasswordReset</h3>
</div>
<div class="form-group">
<span>@Html.Raw(string.Format(Messages.PasswordResetSmsHintFormat, Html.RouteLink(UI.Here.ToLowerInvariant(), AccountRouteNames.PasswordResetSendSms)))</span>
</div>
<div class="form-group">
<label for="@Html.IdFor(x => x.Sms)" class="col-sm-2 control-label">@UI.Sms</label>
<div class="col-sm-10">
@Html.TextBoxFor(x => x.Sms, new {@class = "form-control", placeholder = UI.Sms})
@Html.ValidationMessageFor(x => x.Sms)
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-default">@UI.Next</button>
</div>
</div>
}
</div>
}

View file

@ -43,7 +43,8 @@
</div>
</div>
<div class="container body-content">
<div id="message-area" class="container prevent-deselect"> </div>
<div id="message-area" class="container row prevent-deselect"> </div>
@RenderBody()
</div>

View file

@ -52,7 +52,8 @@
<add key="ResourseRenderCountSessionKey" value="ResourseRenderCount" />
<add key="ItemIdSessionKey" value="ItemId" />
<add key="UserGroupsKey" value="UserGroups" />
<add key="OwaEditFoldersSession" value="OwaEditFolders"/>
<add key="OwaEditFoldersSession" value="OwaEditFolders" />
<add key="PassswordResetSmsKey" value="PassswordResetSms" />
</sessionKeys>
<fileIcons defaultPath="~/Content/Images/other-icon.png" folderPath="~/Content/Images/folder_100x100.png">
<add extension=".txt" path="~/Content/Images/txt-icon.png" />
@ -86,12 +87,12 @@
<add browser="Safari" version="4" />
</owaSupportedBrowsers>
<officeOnline isEnabled="True" url="https://vir-owa.virtuworks.net" cobaltFileTtl="1" cobaltNewFilePath="~/Content/OwaFiles/New">
<add extension=".doc" OwaView="wv/wordviewerframe.aspx?" OwaEditor="wv/wordviewerframe.aspx?" OwaMobileView="wv/mWord.aspx?wdMobileHost=3&amp;" OwaNewFileView="we/wordeditorframe.aspx?new=1&amp;"/>
<add extension=".docx" OwaView="wv/wordviewerframe.aspx?" OwaEditor="we/wordeditorframe.aspx?" OwaMobileView="wv/mWord.aspx?wdMobileHost=3&amp;" OwaNewFileView="we/wordeditorframe.aspx?new=1&amp;"/>
<add extension=".xls" OwaView="x/_layouts/xlviewerinternal.aspx?" OwaEditor="x/_layouts/xlviewerinternal.aspx?edit=1&amp;" OwaMobileView="x/_layouts/mobile/mXL.aspx?wdMobileHost=3&amp;" OwaNewFileView="x/_layouts/xlviewerinternal.aspx?new=1&amp;"/>
<add extension=".xlsx" OwaView="x/_layouts/xlviewerinternal.aspx?" OwaEditor="x/_layouts/xlviewerinternal.aspx?edit=1&amp;" OwaMobileView="x/_layouts/mobile/mXL.aspx?wdMobileHost=3&amp;" OwaNewFileView="x/_layouts/xlviewerinternal.aspx?edit=1&amp;"/>
<add extension=".ppt" OwaView="p/PowerPointFrame.aspx?" OwaEditor="p/PowerPointFrame.aspx?" OwaMobileView="p/mPPT.aspx?wdMobileHost=3&amp;" OwaNewFileView="p/PowerPointFrame.aspx?PowerPointView=EditView&amp;New=1&amp;"/>
<add extension=".pptx" OwaView="p/PowerPointFrame.aspx?" OwaEditor="p/PowerPointFrame.aspx?PowerPointView=EditView&amp;" OwaMobileView="p/mPPT.aspx?wdMobileHost=3&amp;" OwaNewFileView="p/PowerPointFrame.aspx?PowerPointView=EditView&amp;New=1&amp;"/>
<add extension=".doc" OwaView="wv/wordviewerframe.aspx?" OwaEditor="wv/wordviewerframe.aspx?" OwaMobileView="wv/mWord.aspx?wdMobileHost=3&amp;" OwaNewFileView="we/wordeditorframe.aspx?new=1&amp;" />
<add extension=".docx" OwaView="wv/wordviewerframe.aspx?" OwaEditor="we/wordeditorframe.aspx?" OwaMobileView="wv/mWord.aspx?wdMobileHost=3&amp;" OwaNewFileView="we/wordeditorframe.aspx?new=1&amp;" />
<add extension=".xls" OwaView="x/_layouts/xlviewerinternal.aspx?" OwaEditor="x/_layouts/xlviewerinternal.aspx?edit=1&amp;" OwaMobileView="x/_layouts/mobile/mXL.aspx?wdMobileHost=3&amp;" OwaNewFileView="x/_layouts/xlviewerinternal.aspx?new=1&amp;" />
<add extension=".xlsx" OwaView="x/_layouts/xlviewerinternal.aspx?" OwaEditor="x/_layouts/xlviewerinternal.aspx?edit=1&amp;" OwaMobileView="x/_layouts/mobile/mXL.aspx?wdMobileHost=3&amp;" OwaNewFileView="x/_layouts/xlviewerinternal.aspx?edit=1&amp;" />
<add extension=".ppt" OwaView="p/PowerPointFrame.aspx?" OwaEditor="p/PowerPointFrame.aspx?" OwaMobileView="p/mPPT.aspx?wdMobileHost=3&amp;" OwaNewFileView="p/PowerPointFrame.aspx?PowerPointView=EditView&amp;New=1&amp;" />
<add extension=".pptx" OwaView="p/PowerPointFrame.aspx?" OwaEditor="p/PowerPointFrame.aspx?PowerPointView=EditView&amp;" OwaMobileView="p/mPPT.aspx?wdMobileHost=3&amp;" OwaNewFileView="p/PowerPointFrame.aspx?PowerPointView=EditView&amp;New=1&amp;" />
</officeOnline>
<typeOpener>
<add extension=".jpg" mimeType="image/jpeg" isTargetBlank="true" />
@ -100,6 +101,7 @@
<add extension=".txt" mimeType="text/plain" isTargetBlank="true" />
<add extension=".pdf" mimeType="application/pdf" isTargetBlank="true" />
</typeOpener>
<twilio accountSid="s" authorizationToken="s" phoneFrom="s"/>
</webDavExplorerConfigurationSettings>
<!--
For a description of web.config changes see http://go.microsoft.com/fwlink/?LinkId=235367.

View file

@ -195,6 +195,8 @@
<Compile Include="ModelBinders\DataTables\JqueryDataTableModelBinder.cs" />
<Compile Include="Models\AccountModel.cs" />
<Compile Include="Models\Account\PasswordChangeModel.cs" />
<Compile Include="Models\Account\PasswordResetEmailModel.cs" />
<Compile Include="Models\Account\PasswordResetSmsModel.cs" />
<Compile Include="Models\Account\UserProfile.cs" />
<Compile Include="Models\Common\BaseModel.cs" />
<Compile Include="Models\Common\DataTable\JqueryDataTableBaseEntity.cs" />
@ -481,6 +483,10 @@
<Content Include="Views\Shared\EditorTemplates\CountrySelector.cshtml" />
<Content Include="Views\Account\PasswordChange.cshtml" />
<Content Include="Views\Shared\EditorTemplates\PasswordEditor.cshtml" />
<Content Include="Views\Account\PasswordResetEmail.cshtml" />
<Content Include="Views\Account\PasswordResetEmailSent.cshtml" />
<Content Include="Views\Account\PasswordResetSms.cshtml" />
<Content Include="Views\Account\PasswordResetFinalStep.cshtml" />
</ItemGroup>
<ItemGroup>
<Folder Include="Models\FileSystem\Enums\" />