forked from nwrxi/SignalRChatTest
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added user panel for account management
*Changed the page opening from clicking the username from "/Index" to "/Email"
- Loading branch information
Showing
20 changed files
with
962 additions
and
1 deletion.
There are no files selected for viewing
36 changes: 36 additions & 0 deletions
36
SginalRChatTest/Areas/Identity/Pages/Account/Manage/ChangePassword.cshtml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
@page | ||
@model ChangePasswordModel | ||
@{ | ||
ViewData["Title"] = "Change password"; | ||
ViewData["ActivePage"] = ManageNavPages.ChangePassword; | ||
} | ||
|
||
<h4>@ViewData["Title"]</h4> | ||
<partial name="_StatusMessage" for="StatusMessage" /> | ||
<div class="row"> | ||
<div class="col-md-6"> | ||
<form id="change-password-form" method="post"> | ||
<div asp-validation-summary="All" class="text-danger"></div> | ||
<div class="form-group"> | ||
<label asp-for="Input.OldPassword"></label> | ||
<input asp-for="Input.OldPassword" class="form-control" /> | ||
<span asp-validation-for="Input.OldPassword" class="text-danger"></span> | ||
</div> | ||
<div class="form-group"> | ||
<label asp-for="Input.NewPassword"></label> | ||
<input asp-for="Input.NewPassword" class="form-control" /> | ||
<span asp-validation-for="Input.NewPassword" class="text-danger"></span> | ||
</div> | ||
<div class="form-group"> | ||
<label asp-for="Input.ConfirmPassword"></label> | ||
<input asp-for="Input.ConfirmPassword" class="form-control" /> | ||
<span asp-validation-for="Input.ConfirmPassword" class="text-danger"></span> | ||
</div> | ||
<button type="submit" class="btn btn-primary">Update password</button> | ||
</form> | ||
</div> | ||
</div> | ||
|
||
@section Scripts { | ||
<partial name="_ValidationScriptsPartial" /> | ||
} |
100 changes: 100 additions & 0 deletions
100
SginalRChatTest/Areas/Identity/Pages/Account/Manage/ChangePassword.cshtml.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.ComponentModel.DataAnnotations; | ||
using System.Linq; | ||
using System.Threading.Tasks; | ||
using Microsoft.AspNetCore.Identity; | ||
using Microsoft.AspNetCore.Mvc; | ||
using Microsoft.AspNetCore.Mvc.RazorPages; | ||
using Microsoft.Extensions.Logging; | ||
namespace SginalRChatTest.Areas.Identity.Pages.Account.Manage | ||
{ | ||
public class ChangePasswordModel : PageModel | ||
{ | ||
private readonly UserManager<IdentityUser> _userManager; | ||
private readonly SignInManager<IdentityUser> _signInManager; | ||
private readonly ILogger<ChangePasswordModel> _logger; | ||
|
||
public ChangePasswordModel( | ||
UserManager<IdentityUser> userManager, | ||
SignInManager<IdentityUser> signInManager, | ||
ILogger<ChangePasswordModel> logger) | ||
{ | ||
_userManager = userManager; | ||
_signInManager = signInManager; | ||
_logger = logger; | ||
} | ||
|
||
[BindProperty] | ||
public InputModel Input { get; set; } | ||
|
||
[TempData] | ||
public string StatusMessage { get; set; } | ||
|
||
public class InputModel | ||
{ | ||
[Required] | ||
[DataType(DataType.Password)] | ||
[Display(Name = "Current password")] | ||
public string OldPassword { get; set; } | ||
|
||
[Required] | ||
[StringLength(100, ErrorMessage = "The {0} must be at least {2} and at max {1} characters long.", MinimumLength = 6)] | ||
[DataType(DataType.Password)] | ||
[Display(Name = "New password")] | ||
public string NewPassword { get; set; } | ||
|
||
[DataType(DataType.Password)] | ||
[Display(Name = "Confirm new password")] | ||
[Compare("NewPassword", ErrorMessage = "The new password and confirmation password do not match.")] | ||
public string ConfirmPassword { get; set; } | ||
} | ||
|
||
public async Task<IActionResult> OnGetAsync() | ||
{ | ||
var user = await _userManager.GetUserAsync(User); | ||
if (user == null) | ||
{ | ||
return NotFound($"Unable to load user with ID '{_userManager.GetUserId(User)}'."); | ||
} | ||
|
||
var hasPassword = await _userManager.HasPasswordAsync(user); | ||
if (!hasPassword) | ||
{ | ||
return RedirectToPage("./SetPassword"); | ||
} | ||
|
||
return Page(); | ||
} | ||
|
||
public async Task<IActionResult> OnPostAsync() | ||
{ | ||
if (!ModelState.IsValid) | ||
{ | ||
return Page(); | ||
} | ||
|
||
var user = await _userManager.GetUserAsync(User); | ||
if (user == null) | ||
{ | ||
return NotFound($"Unable to load user with ID '{_userManager.GetUserId(User)}'."); | ||
} | ||
|
||
var changePasswordResult = await _userManager.ChangePasswordAsync(user, Input.OldPassword, Input.NewPassword); | ||
if (!changePasswordResult.Succeeded) | ||
{ | ||
foreach (var error in changePasswordResult.Errors) | ||
{ | ||
ModelState.AddModelError(string.Empty, error.Description); | ||
} | ||
return Page(); | ||
} | ||
|
||
await _signInManager.RefreshSignInAsync(user); | ||
_logger.LogInformation("User changed their password successfully."); | ||
StatusMessage = "Your password has been changed."; | ||
|
||
return RedirectToPage(); | ||
} | ||
} | ||
} |
33 changes: 33 additions & 0 deletions
33
SginalRChatTest/Areas/Identity/Pages/Account/Manage/DeletePersonalData.cshtml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
@page | ||
@model DeletePersonalDataModel | ||
@{ | ||
ViewData["Title"] = "Delete Personal Data"; | ||
ViewData["ActivePage"] = ManageNavPages.PersonalData; | ||
} | ||
|
||
<h4>@ViewData["Title"]</h4> | ||
|
||
<div class="alert alert-warning" role="alert"> | ||
<p> | ||
<strong>Deleting this data will permanently remove your account, and this cannot be recovered.</strong> | ||
</p> | ||
</div> | ||
|
||
<div> | ||
<form id="delete-user" method="post" class="form-group"> | ||
<div asp-validation-summary="All" class="text-danger"></div> | ||
@if (Model.RequirePassword) | ||
{ | ||
<div class="form-group"> | ||
<label asp-for="Input.Password"></label> | ||
<input asp-for="Input.Password" class="form-control" /> | ||
<span asp-validation-for="Input.Password" class="text-danger"></span> | ||
</div> | ||
} | ||
<button class="btn btn-danger" type="submit">Delete data and close my account</button> | ||
</form> | ||
</div> | ||
|
||
@section Scripts { | ||
<partial name="_ValidationScriptsPartial" /> | ||
} |
83 changes: 83 additions & 0 deletions
83
SginalRChatTest/Areas/Identity/Pages/Account/Manage/DeletePersonalData.cshtml.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
using System; | ||
using System.ComponentModel.DataAnnotations; | ||
using System.Threading.Tasks; | ||
using Microsoft.AspNetCore.Identity; | ||
using Microsoft.AspNetCore.Mvc; | ||
using Microsoft.AspNetCore.Mvc.RazorPages; | ||
using Microsoft.Extensions.Logging; | ||
|
||
namespace SginalRChatTest.Areas.Identity.Pages.Account.Manage | ||
{ | ||
public class DeletePersonalDataModel : PageModel | ||
{ | ||
private readonly UserManager<IdentityUser> _userManager; | ||
private readonly SignInManager<IdentityUser> _signInManager; | ||
private readonly ILogger<DeletePersonalDataModel> _logger; | ||
|
||
public DeletePersonalDataModel( | ||
UserManager<IdentityUser> userManager, | ||
SignInManager<IdentityUser> signInManager, | ||
ILogger<DeletePersonalDataModel> logger) | ||
{ | ||
_userManager = userManager; | ||
_signInManager = signInManager; | ||
_logger = logger; | ||
} | ||
|
||
[BindProperty] | ||
public InputModel Input { get; set; } | ||
|
||
public class InputModel | ||
{ | ||
[Required] | ||
[DataType(DataType.Password)] | ||
public string Password { get; set; } | ||
} | ||
|
||
public bool RequirePassword { get; set; } | ||
|
||
public async Task<IActionResult> OnGet() | ||
{ | ||
var user = await _userManager.GetUserAsync(User); | ||
if (user == null) | ||
{ | ||
return NotFound($"Unable to load user with ID '{_userManager.GetUserId(User)}'."); | ||
} | ||
|
||
RequirePassword = await _userManager.HasPasswordAsync(user); | ||
return Page(); | ||
} | ||
|
||
public async Task<IActionResult> OnPostAsync() | ||
{ | ||
var user = await _userManager.GetUserAsync(User); | ||
if (user == null) | ||
{ | ||
return NotFound($"Unable to load user with ID '{_userManager.GetUserId(User)}'."); | ||
} | ||
|
||
RequirePassword = await _userManager.HasPasswordAsync(user); | ||
if (RequirePassword) | ||
{ | ||
if (!await _userManager.CheckPasswordAsync(user, Input.Password)) | ||
{ | ||
ModelState.AddModelError(string.Empty, "Incorrect password."); | ||
return Page(); | ||
} | ||
} | ||
|
||
var result = await _userManager.DeleteAsync(user); | ||
var userId = await _userManager.GetUserIdAsync(user); | ||
if (!result.Succeeded) | ||
{ | ||
throw new InvalidOperationException($"Unexpected error occurred deleting user with ID '{userId}'."); | ||
} | ||
|
||
await _signInManager.SignOutAsync(); | ||
|
||
_logger.LogInformation("User with ID '{UserId}' deleted themselves.", userId); | ||
|
||
return Redirect("~/"); | ||
} | ||
} | ||
} |
12 changes: 12 additions & 0 deletions
12
SginalRChatTest/Areas/Identity/Pages/Account/Manage/DownloadPersonalData.cshtml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
@page | ||
@model DownloadPersonalDataModel | ||
@{ | ||
ViewData["Title"] = "Download Your Data"; | ||
ViewData["ActivePage"] = ManageNavPages.PersonalData; | ||
} | ||
|
||
<h4>@ViewData["Title"]</h4> | ||
|
||
@section Scripts { | ||
<partial name="_ValidationScriptsPartial" /> | ||
} |
56 changes: 56 additions & 0 deletions
56
SginalRChatTest/Areas/Identity/Pages/Account/Manage/DownloadPersonalData.cshtml.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Text; | ||
using System.Text.Json; | ||
using System.Threading.Tasks; | ||
using Microsoft.AspNetCore.Identity; | ||
using Microsoft.AspNetCore.Mvc; | ||
using Microsoft.AspNetCore.Mvc.RazorPages; | ||
using Microsoft.Extensions.Logging; | ||
|
||
namespace SginalRChatTest.Areas.Identity.Pages.Account.Manage | ||
{ | ||
public class DownloadPersonalDataModel : PageModel | ||
{ | ||
private readonly UserManager<IdentityUser> _userManager; | ||
private readonly ILogger<DownloadPersonalDataModel> _logger; | ||
|
||
public DownloadPersonalDataModel( | ||
UserManager<IdentityUser> userManager, | ||
ILogger<DownloadPersonalDataModel> logger) | ||
{ | ||
_userManager = userManager; | ||
_logger = logger; | ||
} | ||
|
||
public async Task<IActionResult> OnPostAsync() | ||
{ | ||
var user = await _userManager.GetUserAsync(User); | ||
if (user == null) | ||
{ | ||
return NotFound($"Unable to load user with ID '{_userManager.GetUserId(User)}'."); | ||
} | ||
|
||
_logger.LogInformation("User with ID '{UserId}' asked for their personal data.", _userManager.GetUserId(User)); | ||
|
||
// Only include personal data for download | ||
var personalData = new Dictionary<string, string>(); | ||
var personalDataProps = typeof(IdentityUser).GetProperties().Where( | ||
prop => Attribute.IsDefined(prop, typeof(PersonalDataAttribute))); | ||
foreach (var p in personalDataProps) | ||
{ | ||
personalData.Add(p.Name, p.GetValue(user)?.ToString() ?? "null"); | ||
} | ||
|
||
var logins = await _userManager.GetLoginsAsync(user); | ||
foreach (var l in logins) | ||
{ | ||
personalData.Add($"{l.LoginProvider} external login provider key", l.ProviderKey); | ||
} | ||
|
||
Response.Headers.Add("Content-Disposition", "attachment; filename=PersonalData.json"); | ||
return new FileContentResult(JsonSerializer.SerializeToUtf8Bytes(personalData), "application/json"); | ||
} | ||
} | ||
} |
43 changes: 43 additions & 0 deletions
43
SginalRChatTest/Areas/Identity/Pages/Account/Manage/Email.cshtml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
@page | ||
@model EmailModel | ||
@{ | ||
ViewData["Title"] = "Manage Email"; | ||
ViewData["ActivePage"] = ManageNavPages.Email; | ||
} | ||
|
||
<h4>@ViewData["Title"]</h4> | ||
<partial name="_StatusMessage" model="Model.StatusMessage" /> | ||
<div class="row"> | ||
<div class="col-md-6"> | ||
<form id="email-form" method="post"> | ||
<div asp-validation-summary="All" class="text-danger"></div> | ||
<div class="form-group"> | ||
<label asp-for="Email"></label> | ||
@if (Model.IsEmailConfirmed) | ||
{ | ||
<div class="input-group"> | ||
<input asp-for="Email" class="form-control" disabled /> | ||
<div class="input-group-append"> | ||
<span class="input-group-text text-success font-weight-bold">✓</span> | ||
</div> | ||
</div> | ||
} | ||
else | ||
{ | ||
<input asp-for="Email" class="form-control" disabled /> | ||
<button id="email-verification" type="submit" asp-page-handler="SendVerificationEmail" class="btn btn-link">Send verification email</button> | ||
} | ||
</div> | ||
<div class="form-group"> | ||
<label asp-for="Input.NewEmail"></label> | ||
<input asp-for="Input.NewEmail" class="form-control" /> | ||
<span asp-validation-for="Input.NewEmail" class="text-danger"></span> | ||
</div> | ||
<button id="change-email-button" type="submit" asp-page-handler="ChangeEmail" class="btn btn-primary">Change email</button> | ||
</form> | ||
</div> | ||
</div> | ||
|
||
@section Scripts { | ||
<partial name="_ValidationScriptsPartial" /> | ||
} |
Oops, something went wrong.