@ -1,395 +0,0 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
using System.Threading.Tasks; | |||||
using Microsoft.AspNetCore.Authorization; | |||||
using Microsoft.AspNetCore.Identity; | |||||
using Microsoft.AspNetCore.Mvc; | |||||
using Microsoft.Extensions.Logging; | |||||
using Microsoft.eShopOnContainers.WebMVC.Models; | |||||
using Microsoft.eShopOnContainers.WebMVC.Models.ManageViewModels; | |||||
using Microsoft.eShopOnContainers.WebMVC.Services; | |||||
namespace Microsoft.eShopOnContainers.WebMVC.Controllers | |||||
{ | |||||
[Authorize] | |||||
public class ManageController : Controller | |||||
{ | |||||
private readonly UserManager<ApplicationUser> _userManager; | |||||
private readonly SignInManager<ApplicationUser> _signInManager; | |||||
private readonly IEmailSender _emailSender; | |||||
private readonly ISmsSender _smsSender; | |||||
private readonly ILogger _logger; | |||||
public ManageController( | |||||
UserManager<ApplicationUser> userManager, | |||||
SignInManager<ApplicationUser> signInManager, | |||||
IEmailSender emailSender, | |||||
ISmsSender smsSender, | |||||
ILoggerFactory loggerFactory) | |||||
{ | |||||
_userManager = userManager; | |||||
_signInManager = signInManager; | |||||
_emailSender = emailSender; | |||||
_smsSender = smsSender; | |||||
_logger = loggerFactory.CreateLogger<ManageController>(); | |||||
} | |||||
// | |||||
// GET: /Manage/Index | |||||
[HttpGet] | |||||
public async Task<IActionResult> Index(ManageMessageId? message = null) | |||||
{ | |||||
ViewData["StatusMessage"] = | |||||
message == ManageMessageId.ChangePasswordSuccess ? "Your password has been changed." | |||||
: message == ManageMessageId.SetPasswordSuccess ? "Your password has been set." | |||||
: message == ManageMessageId.SetTwoFactorSuccess ? "Your two-factor authentication provider has been set." | |||||
: message == ManageMessageId.Error ? "An error has occurred." | |||||
: message == ManageMessageId.AddPhoneSuccess ? "Your phone number was added." | |||||
: message == ManageMessageId.RemovePhoneSuccess ? "Your phone number was removed." | |||||
: ""; | |||||
var user = await GetCurrentUserAsync(); | |||||
if (user == null) | |||||
{ | |||||
return View("Error"); | |||||
} | |||||
var model = new IndexViewModel | |||||
{ | |||||
HasPassword = await _userManager.HasPasswordAsync(user), | |||||
PhoneNumber = await _userManager.GetPhoneNumberAsync(user), | |||||
TwoFactor = await _userManager.GetTwoFactorEnabledAsync(user), | |||||
Logins = await _userManager.GetLoginsAsync(user), | |||||
BrowserRemembered = await _signInManager.IsTwoFactorClientRememberedAsync(user), | |||||
User = user | |||||
}; | |||||
return View(model); | |||||
} | |||||
[HttpPost] | |||||
[ValidateAntiForgeryToken] | |||||
public async Task<IActionResult> Index(IndexViewModel model) | |||||
{ | |||||
if (!ModelState.IsValid) | |||||
{ | |||||
return View(model); | |||||
} | |||||
var user = await _userManager.GetUserAsync(HttpContext.User); | |||||
user.CardHolderName = model.User.CardHolderName; | |||||
user.CardNumber = model.User.CardNumber; | |||||
//user.CardType = model.User.CardType; | |||||
user.City = model.User.City; | |||||
user.Country = model.User.Country; | |||||
user.Expiration = model.User.Expiration; | |||||
user.State = model.User.State; | |||||
user.Street = model.User.Street; | |||||
user.ZipCode = model.User.ZipCode; | |||||
var result = await _userManager.UpdateAsync(user); | |||||
if (result.Succeeded) | |||||
{ | |||||
_logger.LogInformation(99, "User changed his address and payment method information."); | |||||
return RedirectToAction(nameof(Index), new { Message = ManageMessageId.ProfileUpdated }); | |||||
} | |||||
AddErrors(result); | |||||
return View(model); | |||||
} | |||||
// | |||||
// POST: /Manage/RemoveLogin | |||||
[HttpPost] | |||||
[ValidateAntiForgeryToken] | |||||
public async Task<IActionResult> RemoveLogin(RemoveLoginViewModel account) | |||||
{ | |||||
ManageMessageId? message = ManageMessageId.Error; | |||||
var user = await GetCurrentUserAsync(); | |||||
if (user != null) | |||||
{ | |||||
var result = await _userManager.RemoveLoginAsync(user, account.LoginProvider, account.ProviderKey); | |||||
if (result.Succeeded) | |||||
{ | |||||
await _signInManager.SignInAsync(user, isPersistent: false); | |||||
message = ManageMessageId.RemoveLoginSuccess; | |||||
} | |||||
} | |||||
return RedirectToAction(nameof(ManageLogins), new { Message = message }); | |||||
} | |||||
// | |||||
// GET: /Manage/AddPhoneNumber | |||||
public IActionResult AddPhoneNumber() | |||||
{ | |||||
return View(); | |||||
} | |||||
// | |||||
// POST: /Manage/AddPhoneNumber | |||||
[HttpPost] | |||||
[ValidateAntiForgeryToken] | |||||
public async Task<IActionResult> AddPhoneNumber(AddPhoneNumberViewModel model) | |||||
{ | |||||
if (!ModelState.IsValid) | |||||
{ | |||||
return View(model); | |||||
} | |||||
// Generate the token and send it | |||||
var user = await GetCurrentUserAsync(); | |||||
if (user == null) | |||||
{ | |||||
return View("Error"); | |||||
} | |||||
var code = await _userManager.GenerateChangePhoneNumberTokenAsync(user, model.PhoneNumber); | |||||
await _smsSender.SendSmsAsync(model.PhoneNumber, "Your security code is: " + code); | |||||
return RedirectToAction(nameof(VerifyPhoneNumber), new { PhoneNumber = model.PhoneNumber }); | |||||
} | |||||
// | |||||
// POST: /Manage/EnableTwoFactorAuthentication | |||||
[HttpPost] | |||||
[ValidateAntiForgeryToken] | |||||
public async Task<IActionResult> EnableTwoFactorAuthentication() | |||||
{ | |||||
var user = await GetCurrentUserAsync(); | |||||
if (user != null) | |||||
{ | |||||
await _userManager.SetTwoFactorEnabledAsync(user, true); | |||||
await _signInManager.SignInAsync(user, isPersistent: false); | |||||
_logger.LogInformation(1, "User enabled two-factor authentication."); | |||||
} | |||||
return RedirectToAction(nameof(Index), "Manage"); | |||||
} | |||||
// | |||||
// POST: /Manage/DisableTwoFactorAuthentication | |||||
[HttpPost] | |||||
[ValidateAntiForgeryToken] | |||||
public async Task<IActionResult> DisableTwoFactorAuthentication() | |||||
{ | |||||
var user = await GetCurrentUserAsync(); | |||||
if (user != null) | |||||
{ | |||||
await _userManager.SetTwoFactorEnabledAsync(user, false); | |||||
await _signInManager.SignInAsync(user, isPersistent: false); | |||||
_logger.LogInformation(2, "User disabled two-factor authentication."); | |||||
} | |||||
return RedirectToAction(nameof(Index), "Manage"); | |||||
} | |||||
// | |||||
// GET: /Manage/VerifyPhoneNumber | |||||
[HttpGet] | |||||
public async Task<IActionResult> VerifyPhoneNumber(string phoneNumber) | |||||
{ | |||||
var user = await GetCurrentUserAsync(); | |||||
if (user == null) | |||||
{ | |||||
return View("Error"); | |||||
} | |||||
var code = await _userManager.GenerateChangePhoneNumberTokenAsync(user, phoneNumber); | |||||
// Send an SMS to verify the phone number | |||||
return phoneNumber == null ? View("Error") : View(new VerifyPhoneNumberViewModel { PhoneNumber = phoneNumber }); | |||||
} | |||||
// | |||||
// POST: /Manage/VerifyPhoneNumber | |||||
[HttpPost] | |||||
[ValidateAntiForgeryToken] | |||||
public async Task<IActionResult> VerifyPhoneNumber(VerifyPhoneNumberViewModel model) | |||||
{ | |||||
if (!ModelState.IsValid) | |||||
{ | |||||
return View(model); | |||||
} | |||||
var user = await GetCurrentUserAsync(); | |||||
if (user != null) | |||||
{ | |||||
var result = await _userManager.ChangePhoneNumberAsync(user, model.PhoneNumber, model.Code); | |||||
if (result.Succeeded) | |||||
{ | |||||
await _signInManager.SignInAsync(user, isPersistent: false); | |||||
return RedirectToAction(nameof(Index), new { Message = ManageMessageId.AddPhoneSuccess }); | |||||
} | |||||
} | |||||
// If we got this far, something failed, redisplay the form | |||||
ModelState.AddModelError(string.Empty, "Failed to verify phone number"); | |||||
return View(model); | |||||
} | |||||
// | |||||
// POST: /Manage/RemovePhoneNumber | |||||
[HttpPost] | |||||
[ValidateAntiForgeryToken] | |||||
public async Task<IActionResult> RemovePhoneNumber() | |||||
{ | |||||
var user = await GetCurrentUserAsync(); | |||||
if (user != null) | |||||
{ | |||||
var result = await _userManager.SetPhoneNumberAsync(user, null); | |||||
if (result.Succeeded) | |||||
{ | |||||
await _signInManager.SignInAsync(user, isPersistent: false); | |||||
return RedirectToAction(nameof(Index), new { Message = ManageMessageId.RemovePhoneSuccess }); | |||||
} | |||||
} | |||||
return RedirectToAction(nameof(Index), new { Message = ManageMessageId.Error }); | |||||
} | |||||
// | |||||
// GET: /Manage/ChangePassword | |||||
[HttpGet] | |||||
public IActionResult ChangePassword() | |||||
{ | |||||
return View(); | |||||
} | |||||
// | |||||
// POST: /Manage/ChangePassword | |||||
[HttpPost] | |||||
[ValidateAntiForgeryToken] | |||||
public async Task<IActionResult> ChangePassword(ChangePasswordViewModel model) | |||||
{ | |||||
if (!ModelState.IsValid) | |||||
{ | |||||
return View(model); | |||||
} | |||||
var user = await GetCurrentUserAsync(); | |||||
if (user != null) | |||||
{ | |||||
var result = await _userManager.ChangePasswordAsync(user, model.OldPassword, model.NewPassword); | |||||
if (result.Succeeded) | |||||
{ | |||||
await _signInManager.SignInAsync(user, isPersistent: false); | |||||
_logger.LogInformation(3, "User changed their password successfully."); | |||||
return RedirectToAction(nameof(Index), new { Message = ManageMessageId.ChangePasswordSuccess }); | |||||
} | |||||
AddErrors(result); | |||||
return View(model); | |||||
} | |||||
return RedirectToAction(nameof(Index), new { Message = ManageMessageId.Error }); | |||||
} | |||||
// | |||||
// GET: /Manage/SetPassword | |||||
[HttpGet] | |||||
public IActionResult SetPassword() | |||||
{ | |||||
return View(); | |||||
} | |||||
// | |||||
// POST: /Manage/SetPassword | |||||
[HttpPost] | |||||
[ValidateAntiForgeryToken] | |||||
public async Task<IActionResult> SetPassword(SetPasswordViewModel model) | |||||
{ | |||||
if (!ModelState.IsValid) | |||||
{ | |||||
return View(model); | |||||
} | |||||
var user = await GetCurrentUserAsync(); | |||||
if (user != null) | |||||
{ | |||||
var result = await _userManager.AddPasswordAsync(user, model.NewPassword); | |||||
if (result.Succeeded) | |||||
{ | |||||
await _signInManager.SignInAsync(user, isPersistent: false); | |||||
return RedirectToAction(nameof(Index), new { Message = ManageMessageId.SetPasswordSuccess }); | |||||
} | |||||
AddErrors(result); | |||||
return View(model); | |||||
} | |||||
return RedirectToAction(nameof(Index), new { Message = ManageMessageId.Error }); | |||||
} | |||||
//GET: /Manage/ManageLogins | |||||
[HttpGet] | |||||
public async Task<IActionResult> ManageLogins(ManageMessageId? message = null) | |||||
{ | |||||
ViewData["StatusMessage"] = | |||||
message == ManageMessageId.RemoveLoginSuccess ? "The external login was removed." | |||||
: message == ManageMessageId.AddLoginSuccess ? "The external login was added." | |||||
: message == ManageMessageId.Error ? "An error has occurred." | |||||
: ""; | |||||
var user = await GetCurrentUserAsync(); | |||||
if (user == null) | |||||
{ | |||||
return View("Error"); | |||||
} | |||||
var userLogins = await _userManager.GetLoginsAsync(user); | |||||
var otherLogins = _signInManager.GetExternalAuthenticationSchemes().Where(auth => userLogins.All(ul => auth.AuthenticationScheme != ul.LoginProvider)).ToList(); | |||||
ViewData["ShowRemoveButton"] = user.PasswordHash != null || userLogins.Count > 1; | |||||
return View(new ManageLoginsViewModel | |||||
{ | |||||
CurrentLogins = userLogins, | |||||
OtherLogins = otherLogins | |||||
}); | |||||
} | |||||
// | |||||
// POST: /Manage/LinkLogin | |||||
[HttpPost] | |||||
[ValidateAntiForgeryToken] | |||||
public IActionResult LinkLogin(string provider) | |||||
{ | |||||
// Request a redirect to the external login provider to link a login for the current user | |||||
var redirectUrl = Url.Action("LinkLoginCallback", "Manage"); | |||||
var properties = _signInManager.ConfigureExternalAuthenticationProperties(provider, redirectUrl, _userManager.GetUserId(User)); | |||||
return Challenge(properties, provider); | |||||
} | |||||
// | |||||
// GET: /Manage/LinkLoginCallback | |||||
[HttpGet] | |||||
public async Task<ActionResult> LinkLoginCallback() | |||||
{ | |||||
var user = await GetCurrentUserAsync(); | |||||
if (user == null) | |||||
{ | |||||
return View("Error"); | |||||
} | |||||
var info = await _signInManager.GetExternalLoginInfoAsync(await _userManager.GetUserIdAsync(user)); | |||||
if (info == null) | |||||
{ | |||||
return RedirectToAction(nameof(ManageLogins), new { Message = ManageMessageId.Error }); | |||||
} | |||||
var result = await _userManager.AddLoginAsync(user, info); | |||||
var message = result.Succeeded ? ManageMessageId.AddLoginSuccess : ManageMessageId.Error; | |||||
return RedirectToAction(nameof(ManageLogins), new { Message = message }); | |||||
} | |||||
#region Helpers | |||||
private void AddErrors(IdentityResult result) | |||||
{ | |||||
foreach (var error in result.Errors) | |||||
{ | |||||
ModelState.AddModelError(string.Empty, error.Description); | |||||
} | |||||
} | |||||
public enum ManageMessageId | |||||
{ | |||||
AddPhoneSuccess, | |||||
AddLoginSuccess, | |||||
ChangePasswordSuccess, | |||||
SetTwoFactorSuccess, | |||||
SetPasswordSuccess, | |||||
RemoveLoginSuccess, | |||||
RemovePhoneSuccess, | |||||
Error, | |||||
ProfileUpdated | |||||
} | |||||
private Task<ApplicationUser> GetCurrentUserAsync() | |||||
{ | |||||
return _userManager.GetUserAsync(HttpContext.User); | |||||
} | |||||
#endregion | |||||
} | |||||
} |
@ -1,12 +0,0 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
using System.Threading.Tasks; | |||||
namespace Microsoft.eShopOnContainers.WebMVC.Services | |||||
{ | |||||
public interface IEmailSender | |||||
{ | |||||
Task SendEmailAsync(string email, string subject, string message); | |||||
} | |||||
} |
@ -1,12 +0,0 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
using System.Threading.Tasks; | |||||
namespace Microsoft.eShopOnContainers.WebMVC.Services | |||||
{ | |||||
public interface ISmsSender | |||||
{ | |||||
Task SendSmsAsync(string number, string message); | |||||
} | |||||
} |
@ -1,25 +0,0 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
using System.Threading.Tasks; | |||||
namespace Microsoft.eShopOnContainers.WebMVC.Services | |||||
{ | |||||
// This class is used by the application to send Email and SMS | |||||
// when you turn on two-factor authentication in ASP.NET Identity. | |||||
// For more details see this link http://go.microsoft.com/fwlink/?LinkID=532713 | |||||
public class AuthMessageSender : IEmailSender, ISmsSender | |||||
{ | |||||
public Task SendEmailAsync(string email, string subject, string message) | |||||
{ | |||||
// Plug in your email service here to send an email. | |||||
return Task.FromResult(0); | |||||
} | |||||
public Task SendSmsAsync(string number, string message) | |||||
{ | |||||
// Plug in your SMS service here to send a text message. | |||||
return Task.FromResult(0); | |||||
} | |||||
} | |||||
} |
@ -1,10 +0,0 @@ | |||||
@{ | |||||
ViewData["Title"] = "Confirm Email"; | |||||
} | |||||
<h2>@ViewData["Title"].</h2> | |||||
<div> | |||||
<p> | |||||
Thank you for confirming your email. Please <a asp-controller="Account" asp-action="Login">Click here to Log in</a>. | |||||
</p> | |||||
</div> |
@ -1,35 +0,0 @@ | |||||
@model ExternalLoginConfirmationViewModel | |||||
@{ | |||||
ViewData["Title"] = "Register"; | |||||
} | |||||
<h2>@ViewData["Title"].</h2> | |||||
<h3>Associate your @ViewData["LoginProvider"] account.</h3> | |||||
<form asp-controller="Account" asp-action="ExternalLoginConfirmation" asp-route-returnurl="@ViewData["ReturnUrl"]" method="post" class="form-horizontal"> | |||||
<h4>Association Form</h4> | |||||
<hr /> | |||||
<div asp-validation-summary="All" class="text-danger"></div> | |||||
<p class="text-info"> | |||||
You've successfully authenticated with <strong>@ViewData["LoginProvider"]</strong>. | |||||
Please enter an email address for this site below and click the Register button to finish | |||||
logging in. | |||||
</p> | |||||
<div class="form-group"> | |||||
<label asp-for="Email" class="col-md-2 control-label"></label> | |||||
<div class="col-md-10"> | |||||
<input asp-for="Email" class="form-control" /> | |||||
<span asp-validation-for="Email" class="text-danger"></span> | |||||
</div> | |||||
</div> | |||||
<div class="form-group"> | |||||
<div class="col-md-offset-2 col-md-10"> | |||||
<button type="submit" class="btn btn-default">Register</button> | |||||
</div> | |||||
</div> | |||||
</form> | |||||
@section Scripts { | |||||
@{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); } | |||||
} |
@ -1,8 +0,0 @@ | |||||
@{ | |||||
ViewData["Title"] = "Login Failure"; | |||||
} | |||||
<header> | |||||
<h2>@ViewData["Title"].</h2> | |||||
<p class="text-danger">Unsuccessful login with service.</p> | |||||
</header> |
@ -1,31 +0,0 @@ | |||||
@model ForgotPasswordViewModel | |||||
@{ | |||||
ViewData["Title"] = "Forgot your password?"; | |||||
} | |||||
<h2>@ViewData["Title"]</h2> | |||||
<p> | |||||
For more information on how to enable reset password please see this <a href="http://go.microsoft.com/fwlink/?LinkID=532713">article</a>. | |||||
</p> | |||||
@*<form asp-controller="Account" asp-action="ForgotPassword" method="post" class="form-horizontal"> | |||||
<h4>Enter your email.</h4> | |||||
<hr /> | |||||
<div asp-validation-summary="All" class="text-danger"></div> | |||||
<div class="form-group"> | |||||
<label asp-for="Email" class="col-md-2 control-label"></label> | |||||
<div class="col-md-10"> | |||||
<input asp-for="Email" class="form-control" /> | |||||
<span asp-validation-for="Email" class="text-danger"></span> | |||||
</div> | |||||
</div> | |||||
<div class="form-group"> | |||||
<div class="col-md-offset-2 col-md-10"> | |||||
<button type="submit" class="btn btn-default">Submit</button> | |||||
</div> | |||||
</div> | |||||
</form>*@ | |||||
@section Scripts { | |||||
@{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); } | |||||
} |
@ -1,8 +0,0 @@ | |||||
@{ | |||||
ViewData["Title"] = "Forgot Password Confirmation"; | |||||
} | |||||
<h2>@ViewData["Title"].</h2> | |||||
<p> | |||||
Please check your email to reset your password. | |||||
</p> |
@ -1,8 +0,0 @@ | |||||
@{ | |||||
ViewData["Title"] = "Locked out"; | |||||
} | |||||
<header> | |||||
<h1 class="text-danger">Locked out.</h1> | |||||
<p class="text-danger">This account has been locked out, please try again later.</p> | |||||
</header> |
@ -1,43 +0,0 @@ | |||||
@model ResetPasswordViewModel | |||||
@{ | |||||
ViewData["Title"] = "Reset password"; | |||||
} | |||||
<h2>@ViewData["Title"].</h2> | |||||
<form asp-controller="Account" asp-action="ResetPassword" method="post" class="form-horizontal"> | |||||
<h4>Reset your password.</h4> | |||||
<hr /> | |||||
<div asp-validation-summary="All" class="text-danger"></div> | |||||
<input asp-for="Code" type="hidden" /> | |||||
<div class="form-group"> | |||||
<label asp-for="Email" class="col-md-2 control-label"></label> | |||||
<div class="col-md-10"> | |||||
<input asp-for="Email" class="form-control" /> | |||||
<span asp-validation-for="Email" class="text-danger"></span> | |||||
</div> | |||||
</div> | |||||
<div class="form-group"> | |||||
<label asp-for="Password" class="col-md-2 control-label"></label> | |||||
<div class="col-md-10"> | |||||
<input asp-for="Password" class="form-control" /> | |||||
<span asp-validation-for="Password" class="text-danger"></span> | |||||
</div> | |||||
</div> | |||||
<div class="form-group"> | |||||
<label asp-for="ConfirmPassword" class="col-md-2 control-label"></label> | |||||
<div class="col-md-10"> | |||||
<input asp-for="ConfirmPassword" class="form-control" /> | |||||
<span asp-validation-for="ConfirmPassword" class="text-danger"></span> | |||||
</div> | |||||
</div> | |||||
<div class="form-group"> | |||||
<div class="col-md-offset-2 col-md-10"> | |||||
<button type="submit" class="btn btn-default">Reset</button> | |||||
</div> | |||||
</div> | |||||
</form> | |||||
@section Scripts { | |||||
@{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); } | |||||
} |
@ -1,8 +0,0 @@ | |||||
@{ | |||||
ViewData["Title"] = "Reset password confirmation"; | |||||
} | |||||
<h1>@ViewData["Title"].</h1> | |||||
<p> | |||||
Your password has been reset. Please <a asp-controller="Account" asp-action="Login">Click here to log in</a>. | |||||
</p> |
@ -1,21 +0,0 @@ | |||||
@model SendCodeViewModel | |||||
@{ | |||||
ViewData["Title"] = "Send Verification Code"; | |||||
} | |||||
<h2>@ViewData["Title"].</h2> | |||||
<form asp-controller="Account" asp-action="SendCode" asp-route-returnurl="@Model.ReturnUrl" method="post" class="form-horizontal"> | |||||
<input asp-for="RememberMe" type="hidden" /> | |||||
<div class="row"> | |||||
<div class="col-md-8"> | |||||
Select Two-Factor Authentication Provider: | |||||
<select asp-for="SelectedProvider" asp-items="Model.Providers"></select> | |||||
<button type="submit" class="btn btn-default">Submit</button> | |||||
</div> | |||||
</div> | |||||
</form> | |||||
@section Scripts { | |||||
@{await Html.RenderPartialAsync("_ValidationScriptsPartial"); } | |||||
} |
@ -1,38 +0,0 @@ | |||||
@model VerifyCodeViewModel | |||||
@{ | |||||
ViewData["Title"] = "Verify"; | |||||
} | |||||
<h2>@ViewData["Title"].</h2> | |||||
<form asp-controller="Account" asp-action="VerifyCode" asp-route-returnurl="@ViewData["ReturnUrl"]" method="post" class="form-horizontal"> | |||||
<div asp-validation-summary="All" class="text-danger"></div> | |||||
<input asp-for="Provider" type="hidden" /> | |||||
<input asp-for="RememberMe" type="hidden" /> | |||||
<h4>@ViewData["Status"]</h4> | |||||
<hr /> | |||||
<div class="form-group"> | |||||
<label asp-for="Code" class="col-md-2 control-label"></label> | |||||
<div class="col-md-10"> | |||||
<input asp-for="Code" class="form-control" /> | |||||
<span asp-validation-for="Code" class="text-danger"></span> | |||||
</div> | |||||
</div> | |||||
<div class="form-group"> | |||||
<div class="col-md-offset-2 col-md-10"> | |||||
<div class="checkbox"> | |||||
<input asp-for="RememberBrowser" /> | |||||
<label asp-for="RememberBrowser"></label> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
<div class="form-group"> | |||||
<div class="col-md-offset-2 col-md-10"> | |||||
<button type="submit" class="btn btn-default">Submit</button> | |||||
</div> | |||||
</div> | |||||
</form> | |||||
@section Scripts { | |||||
@{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); } | |||||
} |
@ -1,50 +0,0 @@ | |||||
@{ | |||||
ViewData["Title"] = "Orders"; | |||||
@model IEnumerable<Order> | |||||
} | |||||
<h2>@ViewData["Title"].</h2> | |||||
<h3>@ViewData["Message"]</h3> | |||||
@foreach (var order in Model) | |||||
{ | |||||
<div class="panel panel-default"> | |||||
<div class="panel-heading"> | |||||
<h3 class="panel-title"> | |||||
<strong>Order Number:</strong> @order.OrderNumber | |||||
</h3> | |||||
</div> | |||||
<div class="panel-body"> | |||||
<strong>BuyerId: </strong> @order.BuyerId <br /> | |||||
<strong>OrderDate: </strong> @order.OrderDate <br /> | |||||
<strong>SequenceNumber: </strong> @order.SequenceNumber <br /> | |||||
</div> | |||||
<div class="panel-body"> | |||||
<address> | |||||
<strong>Street: </strong> @order.ShippingAddress.Street <br /> | |||||
<strong>City: </strong> @order.ShippingAddress.City <br /> | |||||
<strong>State: </strong> @order.ShippingAddress.State <br /> | |||||
<strong>StateCode: </strong> @order.ShippingAddress.StateCode <br /> | |||||
<strong>Country: </strong> @order.ShippingAddress.Country <br /> | |||||
<strong>CountryCode: </strong> @order.ShippingAddress.CountryCode <br /> | |||||
<strong>ZipCode: </strong> @order.ShippingAddress.ZipCode <br /> | |||||
<strong>Latitude: </strong> @order.ShippingAddress.Latitude <br /> | |||||
<strong>Longitude: </strong> @order.ShippingAddress.Longitude <br /> | |||||
</address> | |||||
</div> | |||||
<div class="panel-body"> | |||||
@foreach (var orderItem in order.OrderItems) | |||||
{ | |||||
<address> | |||||
<strong>ProductId: </strong> @orderItem.ProductId <br /> | |||||
<strong>ProductName: </strong> @orderItem.ProductName <br /> | |||||
<strong>Price: </strong> @orderItem.UnitPrice <br /> | |||||
<strong>Quantity: </strong> @orderItem.Quantity <br /> | |||||
<strong>Discount: </strong> @orderItem.Discount <br /> | |||||
</address> | |||||
} | |||||
</div> | |||||
</div> | |||||
} | |||||
@ -1,27 +0,0 @@ | |||||
@model AddPhoneNumberViewModel | |||||
@{ | |||||
ViewData["Title"] = "Add Phone Number"; | |||||
} | |||||
<h2>@ViewData["Title"].</h2> | |||||
<form asp-controller="Manage" asp-action="AddPhoneNumber" method="post" class="form-horizontal"> | |||||
<h4>Add a phone number.</h4> | |||||
<hr /> | |||||
<div asp-validation-summary="All" class="text-danger"></div> | |||||
<div class="form-group"> | |||||
<label asp-for="PhoneNumber" class="col-md-2 control-label"></label> | |||||
<div class="col-md-10"> | |||||
<input asp-for="PhoneNumber" class="form-control" /> | |||||
<span asp-validation-for="PhoneNumber" class="text-danger"></span> | |||||
</div> | |||||
</div> | |||||
<div class="form-group"> | |||||
<div class="col-md-offset-2 col-md-10"> | |||||
<button type="submit" class="btn btn-default">Send verification code</button> | |||||
</div> | |||||
</div> | |||||
</form> | |||||
@section Scripts { | |||||
@{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); } | |||||
} |
@ -1,42 +0,0 @@ | |||||
@model ChangePasswordViewModel | |||||
@{ | |||||
ViewData["Title"] = "Change Password"; | |||||
} | |||||
<form asp-controller="Manage" asp-action="ChangePassword" method="post" class="form-horizontal"> | |||||
<h4>Change Password Form</h4> | |||||
<hr /> | |||||
<div asp-validation-summary="All" class="text-danger"></div> | |||||
<div class="form-group"> | |||||
<label asp-for="OldPassword" class="col-md-2 control-label"></label> | |||||
<div class="col-md-10"> | |||||
<input asp-for="OldPassword" class="form-control" /> | |||||
<span asp-validation-for="OldPassword" class="text-danger"></span> | |||||
</div> | |||||
</div> | |||||
<div class="form-group"> | |||||
<label asp-for="NewPassword" class="col-md-2 control-label"></label> | |||||
<div class="col-md-10"> | |||||
<input asp-for="NewPassword" class="form-control" /> | |||||
<span asp-validation-for="NewPassword" class="text-danger"></span> | |||||
</div> | |||||
</div> | |||||
<div class="form-group"> | |||||
<label asp-for="ConfirmPassword" class="col-md-2 control-label"></label> | |||||
<div class="col-md-10"> | |||||
<input asp-for="ConfirmPassword" class="form-control" /> | |||||
<span asp-validation-for="ConfirmPassword" class="text-danger"></span> | |||||
</div> | |||||
</div> | |||||
<div class="form-group"> | |||||
<div class="col-md-offset-2 col-md-10"> | |||||
<button type="submit" class="btn btn-default">Change password</button> | |||||
</div> | |||||
</div> | |||||
</form> | |||||
@section Scripts { | |||||
@{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); } | |||||
} |
@ -1,100 +0,0 @@ | |||||
@model IndexViewModel | |||||
@{ | |||||
ViewData["Title"] = "Manage your account"; | |||||
} | |||||
@*<h2>@ViewData["Title"].</h2>*@ | |||||
<p class="text-success">@ViewData["StatusMessage"]</p> | |||||
<div class="brand-header-block"> | |||||
<ul class="container"> | |||||
<li class="brand-header-back"><a asp-area="" asp-controller="Home" asp-action="Index">Back to list</a></li> | |||||
</ul> | |||||
</div> | |||||
<div class="container cart-index-container"> | |||||
<form asp-controller="Manage" asp-action="Index" method="post" class="form-horizontal"> | |||||
<div class="form-group"> | |||||
<div class="col-md-offset-8 col-md-4"> | |||||
<button type="submit" class="btn btn-default btn-brand">[ Save ]</button> | |||||
</div> | |||||
</div> | |||||
<h4 class="order-create-section-title">SHIPPING ADDRESS</h4> | |||||
<div class="form-horizontal row"> | |||||
<div class="form-group col-sm-6"> | |||||
<label asp-for="User.Street" class="control-label form-label">ADDRESS</label> | |||||
<input asp-for="User.Street" class="form-control form-input" /> | |||||
<span asp-validation-for="User.Street" class="text-danger" /> | |||||
</div> | |||||
<div class="form-group col-sm-6"> | |||||
<label asp-for="User.City" class="control-label form-label"></label> | |||||
<input asp-for="User.City" class="form-control form-input" /> | |||||
<span asp-validation-for="User.City" class="text-danger" /> | |||||
</div> | |||||
<div class="form-group col-sm-6"> | |||||
<label asp-for="User.State" class="control-label form-label"></label> | |||||
<input asp-for="User.State" class="form-control form-input" /> | |||||
<span asp-validation-for="User.State" class="text-danger" /> | |||||
</div> | |||||
<div class="form-group col-sm-6"> | |||||
<label asp-for="User.Country" class="control-label form-label"></label> | |||||
<input asp-for="User.Country" class="form-control form-input" /> | |||||
<span asp-validation-for="User.Country" class="text-danger" /> | |||||
</div> | |||||
<div class="form-group col-sm-6"> | |||||
<label asp-for="User.ZipCode" class="control-label form-label"></label> | |||||
<input asp-for="User.ZipCode" class="form-control form-input form-input-small" /> | |||||
<span asp-validation-for="User.ZipCode" class="text-danger" /> | |||||
</div> | |||||
</div> | |||||
<br /><br /> | |||||
<div class="order-create-section-payment"> | |||||
<h4 class="order-create-section-title">PAYMENT METHOD</h4> | |||||
<div class="form-horizontal row"> | |||||
<div class="form-group col-sm-6"> | |||||
<label asp-for="User.CardNumber" class="control-label form-label">Card Number</label> | |||||
<input asp-for="User.CardNumber" class="form-control form-input" /> | |||||
<span asp-validation-for="User.CardNumber" class="text-danger" /> | |||||
</div> | |||||
<div class="form-group col-sm-6"> | |||||
<label asp-for="User.CardHolderName" class="control-label form-label">Cardholder Name</label> | |||||
<input asp-for="User.CardHolderName" class="form-control form-input" /> | |||||
<span asp-validation-for="User.CardHolderName" class="text-danger" /> | |||||
</div> | |||||
<div class="form-group col-sm-3"> | |||||
<label asp-for="User.Expiration" class="control-label form-label">Expiration Date</label> | |||||
<input asp-for="User.Expiration" placeholder="MM/YY" class="form-control form-input form-input-small" /> | |||||
<span asp-validation-for="User.Expiration" class="text-danger" /> | |||||
</div> | |||||
<div class="form-group col-sm-3"> | |||||
<label asp-for="User.SecurityNumber" class="control-label form-label">Security Code</label> | |||||
<input asp-for="User.SecurityNumber" class="form-control form-input form-input-small" /> | |||||
<span asp-validation-for="User.SecurityNumber" class="text-danger" /> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
<br /><br /> | |||||
<h4 class="order-create-section-title">Change your account settings</h4> | |||||
<div class="form-horizontal row"> | |||||
<div class="form-group col-sm-6"> | |||||
<label asp-for="User.Street" class="control-label form-label">PASSWORD</label> | |||||
<br /> | |||||
@if (Model.HasPassword) | |||||
{ | |||||
<a asp-controller="Manage" asp-action="ChangePassword" class="text">Change</a> | |||||
} | |||||
else | |||||
{ | |||||
<a asp-controller="Manage" asp-action="SetPassword" class="text">Create</a> | |||||
} | |||||
</div> | |||||
</div> | |||||
<br /><br /> | |||||
<div class="form-group"> | |||||
<div class="col-md-offset-8 col-md-4"> | |||||
<button type="submit" class="btn btn-default btn-brand">[ Save ]</button> | |||||
</div> | |||||
</div> | |||||
<br /><br /> | |||||
</form> | |||||
</div> | |||||
@ -1,54 +0,0 @@ | |||||
@model ManageLoginsViewModel | |||||
@using Microsoft.AspNetCore.Http.Authentication | |||||
@{ | |||||
ViewData["Title"] = "Manage your external logins"; | |||||
} | |||||
<h2>@ViewData["Title"].</h2> | |||||
<p class="text-success">@ViewData["StatusMessage"]</p> | |||||
@if (Model.CurrentLogins.Count > 0) | |||||
{ | |||||
<h4>Registered Logins</h4> | |||||
<table class="table"> | |||||
<tbody> | |||||
@for (var index = 0; index < Model.CurrentLogins.Count; index++) | |||||
{ | |||||
<tr> | |||||
<td>@Model.CurrentLogins[index].LoginProvider</td> | |||||
<td> | |||||
@if ((bool)ViewData["ShowRemoveButton"]) | |||||
{ | |||||
<form asp-controller="Manage" asp-action="RemoveLogin" method="post" class="form-horizontal"> | |||||
<div> | |||||
<input asp-for="@Model.CurrentLogins[index].LoginProvider" name="LoginProvider" type="hidden" /> | |||||
<input asp-for="@Model.CurrentLogins[index].ProviderKey" name="ProviderKey" type="hidden" /> | |||||
<input type="submit" class="btn btn-default" value="Remove" title="Remove this @Model.CurrentLogins[index].LoginProvider login from your account" /> | |||||
</div> | |||||
</form> | |||||
} | |||||
else | |||||
{ | |||||
@: | |||||
} | |||||
</td> | |||||
</tr> | |||||
} | |||||
</tbody> | |||||
</table> | |||||
} | |||||
@if (Model.OtherLogins.Count > 0) | |||||
{ | |||||
<h4>Add another service to log in.</h4> | |||||
<hr /> | |||||
<form asp-controller="Manage" asp-action="LinkLogin" method="post" class="form-horizontal"> | |||||
<div id="socialLoginList"> | |||||
<p> | |||||
@foreach (var provider in Model.OtherLogins) | |||||
{ | |||||
<button type="submit" class="btn btn-default" name="provider" value="@provider.AuthenticationScheme" title="Log in using your @provider.DisplayName account">@provider.AuthenticationScheme</button> | |||||
} | |||||
</p> | |||||
</div> | |||||
</form> | |||||
} |
@ -1,38 +0,0 @@ | |||||
@model SetPasswordViewModel | |||||
@{ | |||||
ViewData["Title"] = "Set Password"; | |||||
} | |||||
<p class="text-info"> | |||||
You do not have a local username/password for this site. Add a local | |||||
account so you can log in without an external login. | |||||
</p> | |||||
<form asp-controller="Manage" asp-action="SetPassword" asp-route-returnurl="@ViewData["ReturnUrl"]" method="post" class="form-horizontal"> | |||||
<h4>Set your password</h4> | |||||
<hr /> | |||||
<div asp-validation-summary="All" class="text-danger"></div> | |||||
<div class="form-group"> | |||||
<label asp-for="NewPassword" class="col-md-2 control-label"></label> | |||||
<div class="col-md-10"> | |||||
<input asp-for="NewPassword" class="form-control" /> | |||||
<span asp-validation-for="NewPassword" class="text-danger"></span> | |||||
</div> | |||||
</div> | |||||
<div class="form-group"> | |||||
<label asp-for="ConfirmPassword" class="col-md-2 control-label"></label> | |||||
<div class="col-md-10"> | |||||
<input asp-for="ConfirmPassword" class="form-control" /> | |||||
<span asp-validation-for="ConfirmPassword" class="text-danger"></span> | |||||
</div> | |||||
</div> | |||||
<div class="form-group"> | |||||
<div class="col-md-offset-2 col-md-10"> | |||||
<button type="submit" class="btn btn-default">Set password</button> | |||||
</div> | |||||
</div> | |||||
</form> | |||||
@section Scripts { | |||||
@{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); } | |||||
} |
@ -1,30 +0,0 @@ | |||||
@model VerifyPhoneNumberViewModel | |||||
@{ | |||||
ViewData["Title"] = "Verify Phone Number"; | |||||
} | |||||
<h2>@ViewData["Title"].</h2> | |||||
<form asp-controller="Manage" asp-action="VerifyPhoneNumber" asp-route-returnurl="@ViewData["ReturnUrl"]" method="post" class="form-horizontal"> | |||||
<input asp-for="PhoneNumber" type="hidden" /> | |||||
<h4>Add a phone number.</h4> | |||||
<h5>@ViewData["Status"]</h5> | |||||
<hr /> | |||||
<div asp-validation-summary="All" class="text-danger"></div> | |||||
<div class="form-group"> | |||||
<label asp-for="Code" class="col-md-2 control-label"></label> | |||||
<div class="col-md-10"> | |||||
<input asp-for="Code" class="form-control" /> | |||||
<span asp-validation-for="Code" class="text-danger"></span> | |||||
</div> | |||||
</div> | |||||
<div class="form-group"> | |||||
<div class="col-md-offset-2 col-md-10"> | |||||
<button type="submit" class="btn btn-default">Submit</button> | |||||
</div> | |||||
</div> | |||||
</form> | |||||
@section Scripts { | |||||
@{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); } | |||||
} |
@ -0,0 +1,84 @@ | |||||
@model Microsoft.eShopOnContainers.WebMVC.Models.Order | |||||
@inject UserManager<ApplicationUser> UserManager | |||||
@{ | |||||
ViewData["Title"] = "Order Detail"; | |||||
} | |||||
<div class="brand-header-block"> | |||||
<ul class="container"> | |||||
<li class="brand-header-back"><a asp-area="" asp-controller="Catalog" asp-action="Index">Back to list</a></li> | |||||
</ul> | |||||
</div> | |||||
<div class="container order-detail-container"> | |||||
<div class="row"> | |||||
<div class="col-sm-3"> | |||||
<span>ORDER NUMBER</span><br /> | |||||
<span>@Model.OrderNumber</span> | |||||
</div> | |||||
<div class="col-sm-3"> | |||||
<span>DATE</span><br /> | |||||
<span>@Model.OrderDate</span> | |||||
</div> | |||||
<div class="col-sm-3"> | |||||
<span>TOTAL</span><br /> | |||||
<span>$ @Model.Total()</span> | |||||
</div> | |||||
<div class="col-sm-3"> | |||||
<span>STATUS</span><br /> | |||||
<span>@Model.State</span> | |||||
</div> | |||||
</div> | |||||
<div class="row order-detail-section"> | |||||
<div class="col-sm-3"> | |||||
<span>SHIPING ADDRESS</span><br /> | |||||
<span>@Model.ShippingAddress.Street</span><br /> | |||||
<span>@Model.ShippingAddress.City</span><br /> | |||||
@*<span>@Model.ShippingAddress.ZipCode</span><br />*@ | |||||
<span>@Model.ShippingAddress.Country</span><br /> | |||||
</div> | |||||
</div> | |||||
<div> | |||||
<div class="row order-detail-section"><div class="col-sm-3">ORDER DETAILS</div></div> | |||||
<section> | |||||
<table class="table"> | |||||
<tbody> | |||||
@for (int i = 0; i < Model.OrderItems.Count; i++) | |||||
{ | |||||
var item = Model.OrderItems[i]; | |||||
<tr> | |||||
<td class="cart-product-column"><img class="cart-product-image" src="@item.PictureUrl" /></td> | |||||
<td class="cart-product-column">@item.ProductName</td> | |||||
<td class="cart-product-column">ROSLYN</td> | |||||
<td class="cart-product-column">$ @item.UnitPrice</td> | |||||
<td class="cart-product-column">@item.Quantity</td> | |||||
<td class="cart-product-column cart-total-value">$ @(item.Quantity * item.UnitPrice)</td> | |||||
</tr> | |||||
} | |||||
</tbody> | |||||
</table> | |||||
<div class="row"> | |||||
<div class="col-sm-6"> | |||||
</div> | |||||
</div> | |||||
</section> | |||||
</div> | |||||
<div class="col-md-offset-9 col-md-3"> | |||||
@*<input type="submit" | |||||
class="btn btn-default cart-refresh-button" | |||||
value="" | |||||
name="action" />*@ | |||||
<div class="order-section-total"> | |||||
@*<div class="cart-subtotal-label"><span>SUBTOTAL</span></div> | |||||
<div class="cart-subtotal-value"><span>$ @Model.Total()</span></div> | |||||
<div class="cart-subtotal-label"><span>TAX</span></div> | |||||
<div class="cart-subtotal-value"><span>$ 4.20</span></div>*@ | |||||
<div class="cart-total-label"><span>TOTAL</span></div> | |||||
<div class="cart-total-value"><span>$ @Model.Total()</span></div> | |||||
</div> | |||||
</div> | |||||
</div> |
@ -0,0 +1,44 @@ | |||||
<?xml version="1.0" encoding="iso-8859-1"?> | |||||
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) --> | |||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" | |||||
viewBox="0 0 259.244 259.244" style="enable-background:new 0 0 259.244 259.244;" xml:space="preserve"> | |||||
<g> | |||||
<path style="fill:#3DB39E;" d="M248.348,129.3h-15.849C232.41,65.277,180.831,13.394,117.202,13.394 | |||||
c-31.841,0-60.661,12.998-81.534,33.996C14.017,68.549,0.25,97.092,0.036,129.3H0l0.018,0.331L0,130.033h0.036 | |||||
c0.393,63.853,51.758,115.816,115.19,115.816c31.841,0,60.661-13.007,81.534-34.049l-25.852-24.931 | |||||
c-14.178,14.303-34.058,23.027-55.682,23.135c-44.401,0.206-79.201-36.49-79.201-80.122c-0.107-22.893,10.092-42.908,25.486-57.595 | |||||
c14.186-14.285,34.058-23.001,55.691-23.108c44.41-0.206,79.201,36.445,79.201,79.997v0.125h-15.661 | |||||
c-9.708,0-13.668,6.499-8.814,14.41l33.799,33.433c7.732,7.732,9.967,7.661,17.646,0l33.799-33.433 | |||||
C262.025,135.781,258.056,129.3,248.348,129.3z"/> | |||||
</g> | |||||
<g> | |||||
</g> | |||||
<g> | |||||
</g> | |||||
<g> | |||||
</g> | |||||
<g> | |||||
</g> | |||||
<g> | |||||
</g> | |||||
<g> | |||||
</g> | |||||
<g> | |||||
</g> | |||||
<g> | |||||
</g> | |||||
<g> | |||||
</g> | |||||
<g> | |||||
</g> | |||||
<g> | |||||
</g> | |||||
<g> | |||||
</g> | |||||
<g> | |||||
</g> | |||||
<g> | |||||
</g> | |||||
<g> | |||||
</g> | |||||
</svg> |
@ -1,14 +1 @@ | |||||
// Write your Javascript code. | |||||
$('#item_Quantity').change(function () { | |||||
$('.cart-refresh-button').removeClass('is-disabled'); | |||||
}); | |||||
function checkoutCart(){ | |||||
$('#cartForm').attr('action', '/Cart?option=checkout'); | |||||
$('#cartForm').submit(); | |||||
} | |||||
function refreshCart() { | |||||
$('#cartForm').attr('action','/Cart?option=refresh'); | |||||
$('#cartForm').submit(); | |||||
} | |||||
// Write your Javascript code. |