@ -0,0 +1,23 @@ | |||
using System.ComponentModel; | |||
using System.ComponentModel.DataAnnotations; | |||
namespace Sevomin.Models | |||
{ | |||
public class ChangePasswordViewModel | |||
{ | |||
[DisplayName("رمز عبور فعلی")] | |||
[Required(ErrorMessage = "ورود {0} الزامی است.")] | |||
[DataType(DataType.Password)] | |||
public string Password { get; set; } | |||
[DisplayName("رمز عبور جدید")] | |||
[Required(ErrorMessage = "ورود {0} الزامی است.")] | |||
[DataType(DataType.Password)] | |||
public string NewPassword { get; set; } | |||
[DisplayName("تایید رمز عبور")] | |||
[Required(ErrorMessage = "ورود {0} الزامی است.")] | |||
[DataType(DataType.Password)] | |||
[Compare("NewPassword", ErrorMessage = "تایید رمز عبور با رمز عبور جدید مطابقت ندارد.")] | |||
public string ConfirmPassword { get; set; } | |||
} | |||
} |
@ -0,0 +1,11 @@ | |||
using System.ComponentModel; | |||
using System.ComponentModel.DataAnnotations; | |||
namespace Sevomin.Models | |||
{ | |||
public class ForgotPasswordViewModel | |||
{ | |||
[DisplayName("ایمیل")] | |||
[Required(ErrorMessage = "ورود {0} الزامی است.")] | |||
public string Email { get; set; } | |||
} | |||
} |
@ -1,5 +1,6 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.IO; | |||
using System.Linq; | |||
using System.Net.Mail; | |||
using System.Text; | |||
@ -7,18 +8,67 @@ using System.Threading.Tasks; | |||
namespace Sevomin.Models.Helpers | |||
{ | |||
public enum EmailType | |||
{ | |||
EmailConfirmation, | |||
PasswordReset, | |||
NewPassword | |||
} | |||
public class SevominEmailer | |||
{ | |||
public Dictionary<string, string> Parameters { get; set; } | |||
public EmailType EmailType { get; set; } | |||
private string EmailFolderPath; | |||
private string EmailConfirmationFilePath; | |||
private string NewPasswordFilePath; | |||
private string PasswordResetFilePath; | |||
public SevominEmailer() | |||
{ | |||
EmailFolderPath = Path.Combine(System.Web.HttpContext.Current.Server.MapPath("~/app_data"), "emails"); | |||
if (!Directory.Exists(EmailFolderPath)) | |||
throw new ApplicationException("Emails folder does not exist in the right address."); | |||
EmailConfirmationFilePath = Path.Combine(EmailFolderPath, "email-confirmation.html"); | |||
NewPasswordFilePath = Path.Combine(EmailFolderPath, "new-password.html"); | |||
PasswordResetFilePath = Path.Combine(EmailFolderPath, "password-reset.html"); | |||
if(!File.Exists(EmailConfirmationFilePath)) | |||
throw new ApplicationException("Email confirmation template does not exist in the right address."); | |||
if (!File.Exists(NewPasswordFilePath)) | |||
throw new ApplicationException("New password template does not exist in the right address."); | |||
if (!File.Exists(PasswordResetFilePath)) | |||
throw new ApplicationException("Password reset template does not exist in the right address."); | |||
Parameters = new Dictionary<string, string>(); | |||
} | |||
public SevominEmailer(Dictionary<string, string> parameters, EmailType emailType) : this() | |||
{ | |||
Parameters = parameters; | |||
EmailType = emailType; | |||
} | |||
public async void Send(string to, string subject, string template, bool isHtml) | |||
public async Task SendAsync(string to, string subject, bool isHtml) | |||
{ | |||
SmtpClient client = new SmtpClient(); | |||
MailMessage msg = new MailMessage(); | |||
string template; | |||
switch (EmailType) | |||
{ | |||
case EmailType.EmailConfirmation: | |||
template = | |||
File.ReadAllText(EmailConfirmationFilePath, Encoding.UTF8); | |||
break; | |||
case EmailType.PasswordReset: | |||
template = | |||
File.ReadAllText(PasswordResetFilePath, Encoding.UTF8); | |||
break; | |||
case EmailType.NewPassword: | |||
template = | |||
File.ReadAllText(NewPasswordFilePath, Encoding.UTF8); | |||
break; | |||
default: | |||
template = string.Empty; | |||
break; | |||
} | |||
foreach (var address in to.Split(',')) | |||
msg.To.Add(address); | |||
msg.From = new MailAddress("[email protected]", "سومین - مرکز کاریابی کنترل پروژه"); | |||
@ -28,14 +78,16 @@ namespace Sevomin.Models.Helpers | |||
msg.IsBodyHtml = isHtml; | |||
Func<string> getBody = () => | |||
{ | |||
foreach (var param in Parameters) | |||
template = template.Replace(param.Key, param.Value); | |||
foreach (var param in Parameters) | |||
template = template.Replace(string.Format("[{0}]", param.Key), param.Value); | |||
return template; | |||
}; | |||
msg.Body = getBody(); | |||
client.SendAsync(msg, null); | |||
msg.Body = getBody(); | |||
await Task.Run(() => | |||
{ | |||
client.Send(msg); | |||
}); | |||
} | |||
} | |||
} | |||
} |
@ -0,0 +1,18 @@ | |||
using System.ComponentModel; | |||
using System.ComponentModel.DataAnnotations; | |||
namespace Sevomin.Models | |||
{ | |||
public class ResetPasswordViewModel | |||
{ | |||
[DisplayName("رمز عبور")] | |||
[Required(ErrorMessage = "ورود {0} الزامی است.")] | |||
[DataType(DataType.Password)] | |||
public string Password { get; set; } | |||
[DisplayName("تایید رمز عبور")] | |||
[Required(ErrorMessage = "ورود {0} الزامی است.")] | |||
[DataType(DataType.Password)] | |||
[Compare("Password", ErrorMessage = "تایید رمز عبور با رمز عبور اصلی مطابقت ندارد.")] | |||
public string ConfirmPassword { get; set; } | |||
} | |||
} |
@ -0,0 +1,51 @@ | |||
@model Sevomin.Models.ChangePasswordViewModel | |||
@{ | |||
ViewBag.Title = "تغییر کلمه عبور"; | |||
} | |||
@Html.Partial("PostResult", ViewBag.Result as Sevomin.Models.PostResultViewModel) | |||
<div class="page-header rtl"> | |||
<h1>تغییر کلمه عبور</h1> | |||
</div> | |||
<div class="row rtl"> | |||
<div class="col-md-12"> | |||
@using (Html.BeginForm("ChangePassword", "Account", FormMethod.Post, new { role = "form" })) | |||
{ | |||
@Html.AntiForgeryToken() | |||
<div class="form-horizontal"> | |||
<div class="form-group"> | |||
<div class="col-md-3 pull-right"> | |||
@Html.LabelFor(model => model.Password, new { @class = "control-label" }) | |||
</div> | |||
<div class="col-md-9"> | |||
@Html.PasswordFor(model => model.Password, new { @class = "form-control ltr" }) | |||
@Html.ValidationMessageFor(model => model.Password) | |||
</div> | |||
</div> | |||
<div class="form-group"> | |||
<div class="col-md-3 pull-right"> | |||
@Html.LabelFor(model => model.NewPassword, new { @class = "control-label" }) | |||
</div> | |||
<div class="col-md-9"> | |||
@Html.PasswordFor(model => model.NewPassword, new { @class = "form-control ltr" }) | |||
@Html.ValidationMessageFor(model => model.NewPassword) | |||
</div> | |||
</div> | |||
<div class="form-group"> | |||
<div class="col-md-3 pull-right"> | |||
@Html.LabelFor(model => model.ConfirmPassword, new { @class = "control-label" }) | |||
</div> | |||
<div class="col-md-9"> | |||
@Html.PasswordFor(model => model.ConfirmPassword, new { @class = "form-control ltr" }) | |||
@Html.ValidationMessageFor(model => model.ConfirmPassword) | |||
</div> | |||
</div> | |||
<div class="form-group"> | |||
<div class="col-md-12"> | |||
<button type="submit" class="btn btn-default">ارسال رمز عبور</button> | |||
</div> | |||
</div> | |||
</div> | |||
} | |||
</div> | |||
</div> |
@ -0,0 +1,34 @@ | |||
@model Sevomin.Models.ForgotPasswordViewModel | |||
@{ | |||
ViewBag.Title = "بازنشانی رمز عبور"; | |||
} | |||
@Html.Partial("PostResult", ViewBag.Result as Sevomin.Models.PostResultViewModel) | |||
<div class="page-header rtl"> | |||
<h1>بازنشانی رمز عبور <small>برای بازنشانی رمز عبور خود، ایمیل خود را وارد کنید.</small></h1> | |||
</div> | |||
<div class="row rtl"> | |||
<div class="col-md-12"> | |||
@using (Html.BeginForm("Forgot", "Account", FormMethod.Post, new { role = "form" })) | |||
{ | |||
@Html.AntiForgeryToken() | |||
<div class="form-horizontal"> | |||
<div class="form-group"> | |||
<div class="col-md-3 pull-right"> | |||
@Html.LabelFor(model => model.Email, new { @class = "control-label" }) | |||
</div> | |||
<div class="col-md-9"> | |||
@Html.TextBoxFor(model => model.Email, new { @class = "form-control ltr" }) | |||
@Html.ValidationMessageFor(model => model.Email) | |||
</div> | |||
</div> | |||
<div class="form-group"> | |||
<div class="col-md-12"> | |||
<button type="submit" class="btn btn-default">ارسال رمز عبور</button> | |||
</div> | |||
</div> | |||
</div> | |||
} | |||
</div> | |||
</div> |
@ -0,0 +1,42 @@ | |||
@model Sevomin.Models.ResetPasswordViewModel | |||
@{ | |||
ViewBag.Title = "بازنشانی رمز عبور"; | |||
} | |||
@Html.Partial("PostResult", ViewBag.Result as Sevomin.Models.PostResultViewModel) | |||
<div class="page-header rtl"> | |||
<h1>بازنشانی رمز عبور <small>رمز عبور جدید خود را وارد نمایید.</small></h1> | |||
</div> | |||
<div class="row rtl"> | |||
<div class="col-md-12"> | |||
@using (Html.BeginForm("ResetPassword", "Account", FormMethod.Post, new { role = "form" })) | |||
{ | |||
@Html.AntiForgeryToken() | |||
<div class="form-horizontal"> | |||
<div class="form-group"> | |||
<div class="col-md-3 pull-right"> | |||
@Html.LabelFor(model => model.Password, new { @class = "control-label" }) | |||
</div> | |||
<div class="col-md-9"> | |||
@Html.PasswordFor(model => model.Password, new { @class = "form-control ltr" }) | |||
@Html.ValidationMessageFor(model => model.Password) | |||
</div> | |||
</div> | |||
<div class="form-group"> | |||
<div class="col-md-3 pull-right"> | |||
@Html.LabelFor(model => model.ConfirmPassword, new { @class = "control-label" }) | |||
</div> | |||
<div class="col-md-9"> | |||
@Html.PasswordFor(model => model.ConfirmPassword, new { @class = "form-control ltr" }) | |||
@Html.ValidationMessageFor(model => model.ConfirmPassword) | |||
</div> | |||
</div> | |||
<div class="form-group"> | |||
<div class="col-md-12"> | |||
<button type="submit" class="btn btn-default">ارسال رمز عبور</button> | |||
</div> | |||
</div> | |||
</div> | |||
} | |||
</div> | |||
</div> |
@ -1,3 +1,3 @@ | |||
@if (Model != null && Model is Sevomin.Models.PostResultViewModel) { | |||
<div class="alert @(Model.Success ? "alert-success" : "alert-danger") rtl">@Model.Message</div> | |||
<div class="alert @(Model.Success ? "alert-success" : "alert-danger") rtl">@MvcHtmlString.Create(Model.Message)</div> | |||
} |