Identity UI fixes (#11768)

This commit is contained in:
Hao Kung 2019-07-19 16:23:43 -07:00 committed by GitHub
parent 775314b142
commit 79283cf2de
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 118 additions and 89 deletions

View File

@ -314,7 +314,7 @@ namespace Microsoft.AspNetCore.Identity.UI.V3.Pages.Account.Manage.Internal
[Microsoft.AspNetCore.Mvc.TempDataAttribute]
public string StatusMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
public virtual System.Threading.Tasks.Task<Microsoft.AspNetCore.Mvc.IActionResult> OnGetAsync() { throw null; }
public virtual System.Threading.Tasks.Task<Microsoft.AspNetCore.Mvc.IActionResult> OnPostAsync() { throw null; }
public virtual System.Threading.Tasks.Task<Microsoft.AspNetCore.Mvc.IActionResult> OnPostChangeEmailAsync() { throw null; }
public virtual System.Threading.Tasks.Task<Microsoft.AspNetCore.Mvc.IActionResult> OnPostSendVerificationEmailAsync() { throw null; }
public partial class InputModel
{
@ -764,7 +764,7 @@ namespace Microsoft.AspNetCore.Identity.UI.V4.Pages.Account.Manage.Internal
[Microsoft.AspNetCore.Mvc.TempDataAttribute]
public string StatusMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
public virtual System.Threading.Tasks.Task<Microsoft.AspNetCore.Mvc.IActionResult> OnGetAsync() { throw null; }
public virtual System.Threading.Tasks.Task<Microsoft.AspNetCore.Mvc.IActionResult> OnPostAsync() { throw null; }
public virtual System.Threading.Tasks.Task<Microsoft.AspNetCore.Mvc.IActionResult> OnPostChangeEmailAsync() { throw null; }
public virtual System.Threading.Tasks.Task<Microsoft.AspNetCore.Mvc.IActionResult> OnPostSendVerificationEmailAsync() { throw null; }
public partial class InputModel
{

View File

@ -210,7 +210,7 @@ namespace Microsoft.AspNetCore.Identity.UI.V3.Pages.Account.Internal
var callbackUrl = Url.Page(
"/Account/ConfirmEmail",
pageHandler: null,
values: new { userId = userId, code = code },
values: new { area = "Identity", userId = userId, code = code },
protocol: Request.Scheme);
await _emailSender.SendEmailAsync(Input.Email, "Confirm your email",

View File

@ -81,7 +81,7 @@ namespace Microsoft.AspNetCore.Identity.UI.V3.Pages.Account.Internal
var callbackUrl = Url.Page(
"/Account/ResetPassword",
pageHandler: null,
values: new { code },
values: new { area = "Identity", code },
protocol: Request.Scheme);
await _emailSender.SendEmailAsync(

View File

@ -31,7 +31,7 @@
<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" class="btn btn-default">Change email</button>
<button id="change-email-button" type="submit" asp-page-handler="ChangeEmail" class="btn btn-default">Change email</button>
</form>
</div>
</div>

View File

@ -73,7 +73,7 @@ namespace Microsoft.AspNetCore.Identity.UI.V3.Pages.Account.Manage.Internal
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
/// directly from your code. This API may change or be removed in future releases.
/// </summary>
public virtual Task<IActionResult> OnPostAsync() => throw new NotImplementedException();
public virtual Task<IActionResult> OnPostChangeEmailAsync() => throw new NotImplementedException();
/// <summary>
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
@ -98,15 +98,9 @@ namespace Microsoft.AspNetCore.Identity.UI.V3.Pages.Account.Manage.Internal
_emailSender = emailSender;
}
public override async Task<IActionResult> OnGetAsync()
private async Task LoadAsync(TUser user)
{
var user = await _userManager.GetUserAsync(User);
if (user == null)
{
return NotFound($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
}
var email = await _userManager.GetEmailAsync(user);
Email = email;
Input = new InputModel
@ -115,23 +109,34 @@ namespace Microsoft.AspNetCore.Identity.UI.V3.Pages.Account.Manage.Internal
};
IsEmailConfirmed = await _userManager.IsEmailConfirmedAsync(user);
return Page();
}
public override async Task<IActionResult> OnPostAsync()
public override async Task<IActionResult> OnGetAsync()
{
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)}'.");
}
await LoadAsync(user);
return Page();
}
public override async Task<IActionResult> OnPostChangeEmailAsync()
{
var user = await _userManager.GetUserAsync(User);
if (user == null)
{
return NotFound($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
}
if (!ModelState.IsValid)
{
await LoadAsync(user);
return Page();
}
var email = await _userManager.GetEmailAsync(user);
if (Input.NewEmail != email)
{
@ -141,7 +146,7 @@ namespace Microsoft.AspNetCore.Identity.UI.V3.Pages.Account.Manage.Internal
var callbackUrl = Url.Page(
"/Account/ConfirmEmailChange",
pageHandler: null,
values: new { userId = userId, email = Input.NewEmail, code = code },
values: new { area = "Identity", userId = userId, email = Input.NewEmail, code = code },
protocol: Request.Scheme);
await _emailSender.SendEmailAsync(
Input.NewEmail,
@ -172,10 +177,14 @@ namespace Microsoft.AspNetCore.Identity.UI.V3.Pages.Account.Manage.Internal
var userId = await _userManager.GetUserIdAsync(user);
var email = await _userManager.GetEmailAsync(user);
var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
while (code.Contains('+'))
{
code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
}
var callbackUrl = Url.Page(
"/Account/ConfirmEmail",
pageHandler: null,
values: new { userId = userId, code = code },
values: new { area = "Identity", userId = userId, code = code },
protocol: Request.Scheme);
await _emailSender.SendEmailAsync(
email,

View File

@ -119,8 +119,8 @@ namespace Microsoft.AspNetCore.Identity.UI.V3.Pages.Account.Manage.Internal
var result = await _userManager.RemoveLoginAsync(user, loginProvider, providerKey);
if (!result.Succeeded)
{
var userId = await _userManager.GetUserIdAsync(user);
throw new InvalidOperationException($"Unexpected error occurred removing external login for user with ID '{userId}'.");
StatusMessage = "The external login was not removed.";
return RedirectToPage();
}
await _signInManager.RefreshSignInAsync(user);
@ -157,7 +157,8 @@ namespace Microsoft.AspNetCore.Identity.UI.V3.Pages.Account.Manage.Internal
var result = await _userManager.AddLoginAsync(user, info);
if (!result.Succeeded)
{
throw new InvalidOperationException($"Unexpected error occurred adding external login for user with ID '{userId}'.");
StatusMessage = "The external login was not added. External logins can only be associated with one account.";
return RedirectToPage();
}
// Clear the existing external cookie to ensure a clean login process

View File

@ -77,13 +77,8 @@ namespace Microsoft.AspNetCore.Identity.UI.V3.Pages.Account.Manage.Internal
_signInManager = signInManager;
}
public override async Task<IActionResult> OnGetAsync()
private async Task LoadAsync(TUser user)
{
var user = await _userManager.GetUserAsync(User);
if (user == null)
{
return NotFound($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
}
var userName = await _userManager.GetUserNameAsync(user);
var phoneNumber = await _userManager.GetPhoneNumberAsync(user);
@ -93,31 +88,42 @@ namespace Microsoft.AspNetCore.Identity.UI.V3.Pages.Account.Manage.Internal
{
PhoneNumber = phoneNumber
};
}
public override async Task<IActionResult> OnGetAsync()
{
var user = await _userManager.GetUserAsync(User);
if (user == null)
{
return NotFound($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
}
await LoadAsync(user);
return Page();
}
public override 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)}'.");
}
if (!ModelState.IsValid)
{
await LoadAsync(user);
return Page();
}
var phoneNumber = await _userManager.GetPhoneNumberAsync(user);
if (Input.PhoneNumber != phoneNumber)
{
var setPhoneResult = await _userManager.SetPhoneNumberAsync(user, Input.PhoneNumber);
if (!setPhoneResult.Succeeded)
{
var userId = await _userManager.GetUserIdAsync(user);
throw new InvalidOperationException($"Unexpected error occurred setting phone number for user with ID '{userId}'.");
StatusMessage = "Unexpected error when trying to set phone number.";
return RedirectToPage();
}
}

View File

@ -147,7 +147,7 @@ namespace Microsoft.AspNetCore.Identity.UI.V3.Pages.Account.Internal
var callbackUrl = Url.Page(
"/Account/ConfirmEmail",
pageHandler: null,
values: new { userId = userId, code = code },
values: new { area = "Identity", userId = userId, code = code },
protocol: Request.Scheme);
await _emailSender.SendEmailAsync(Input.Email, "Confirm your email",

View File

@ -210,7 +210,7 @@ namespace Microsoft.AspNetCore.Identity.UI.V4.Pages.Account.Internal
var callbackUrl = Url.Page(
"/Account/ConfirmEmail",
pageHandler: null,
values: new { userId = userId, code = code },
values: new { area = "Identity", userId = userId, code = code },
protocol: Request.Scheme);
await _emailSender.SendEmailAsync(Input.Email, "Confirm your email",

View File

@ -80,7 +80,7 @@ namespace Microsoft.AspNetCore.Identity.UI.V4.Pages.Account.Internal
var callbackUrl = Url.Page(
"/Account/ResetPassword",
pageHandler: null,
values: new { code },
values: new { area = "Identity", code },
protocol: Request.Scheme);
await _emailSender.SendEmailAsync(

View File

@ -1,4 +1,4 @@
@page
@page
@model DeletePersonalDataModel
@{
ViewData["Title"] = "Delete Personal Data";
@ -9,7 +9,6 @@
<div class="alert alert-warning" role="alert">
<p>
<span class="glyphicon glyphicon-warning-sign"></span>
<strong>Deleting this data will permanently remove your account, and this cannot be recovered.</strong>
</p>
</div>

View File

@ -1,4 +1,4 @@
@page
@page
@model Disable2faModel
@{
ViewData["Title"] = "Disable two-factor authentication (2FA)";
@ -10,7 +10,6 @@
<div class="alert alert-warning" role="alert">
<p>
<span class="glyphicon glyphicon-warning-sign"></span>
<strong>This action only disables 2FA.</strong>
</p>
<p>

View File

@ -17,7 +17,9 @@
{
<div class="input-group">
<input asp-for="Email" class="form-control" disabled />
<span class="input-group-addon" aria-hidden="true"><span class="glyphicon glyphicon-ok text-success"></span></span>
<div class="input-group-append">
<span class="input-group-text text-success font-weight-bold">✓</span>
</div>
</div>
}
else
@ -31,7 +33,7 @@
<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" class="btn btn-primary">Change email</button>
<button id="change-email-button" type="submit" asp-page-handler="ChangeEmail" class="btn btn-primary">Change email</button>
</form>
</div>
</div>

View File

@ -72,7 +72,7 @@ namespace Microsoft.AspNetCore.Identity.UI.V4.Pages.Account.Manage.Internal
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
/// directly from your code. This API may change or be removed in future releases.
/// </summary>
public virtual Task<IActionResult> OnPostAsync() => throw new NotImplementedException();
public virtual Task<IActionResult> OnPostChangeEmailAsync() => throw new NotImplementedException();
/// <summary>
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
@ -97,15 +97,9 @@ namespace Microsoft.AspNetCore.Identity.UI.V4.Pages.Account.Manage.Internal
_emailSender = emailSender;
}
public override async Task<IActionResult> OnGetAsync()
private async Task LoadAsync(TUser user)
{
var user = await _userManager.GetUserAsync(User);
if (user == null)
{
return NotFound($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
}
var email = await _userManager.GetEmailAsync(user);
Email = email;
Input = new InputModel
@ -114,23 +108,34 @@ namespace Microsoft.AspNetCore.Identity.UI.V4.Pages.Account.Manage.Internal
};
IsEmailConfirmed = await _userManager.IsEmailConfirmedAsync(user);
return Page();
}
public override async Task<IActionResult> OnPostAsync()
public override async Task<IActionResult> OnGetAsync()
{
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)}'.");
}
await LoadAsync(user);
return Page();
}
public override async Task<IActionResult> OnPostChangeEmailAsync()
{
var user = await _userManager.GetUserAsync(User);
if (user == null)
{
return NotFound($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
}
if (!ModelState.IsValid)
{
await LoadAsync(user);
return Page();
}
var email = await _userManager.GetEmailAsync(user);
if (Input.NewEmail != email)
{
@ -140,7 +145,7 @@ namespace Microsoft.AspNetCore.Identity.UI.V4.Pages.Account.Manage.Internal
var callbackUrl = Url.Page(
"/Account/ConfirmEmailChange",
pageHandler: null,
values: new { userId = userId, email = Input.NewEmail, code = code },
values: new { area = "Identity", userId = userId, email = Input.NewEmail, code = code },
protocol: Request.Scheme);
await _emailSender.SendEmailAsync(
Input.NewEmail,
@ -157,24 +162,26 @@ namespace Microsoft.AspNetCore.Identity.UI.V4.Pages.Account.Manage.Internal
public override async Task<IActionResult> OnPostSendVerificationEmailAsync()
{
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)}'.");
}
if (!ModelState.IsValid)
{
await LoadAsync(user);
return Page();
}
var userId = await _userManager.GetUserIdAsync(user);
var email = await _userManager.GetEmailAsync(user);
var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
code = WebEncoders.Base64UrlEncode(Encoding.UTF8.GetBytes(code));
var callbackUrl = Url.Page(
"/Account/ConfirmEmail",
pageHandler: null,
values: new { userId = userId, code = code },
values: new { area = "Identity", userId = userId, code = code },
protocol: Request.Scheme);
await _emailSender.SendEmailAsync(
email,

View File

@ -119,8 +119,8 @@ namespace Microsoft.AspNetCore.Identity.UI.V4.Pages.Account.Manage.Internal
var result = await _userManager.RemoveLoginAsync(user, loginProvider, providerKey);
if (!result.Succeeded)
{
var userId = await _userManager.GetUserIdAsync(user);
throw new InvalidOperationException($"Unexpected error occurred removing external login for user with ID '{userId}'.");
StatusMessage = "The external login was not removed.";
return RedirectToPage();
}
await _signInManager.RefreshSignInAsync(user);
@ -157,7 +157,8 @@ namespace Microsoft.AspNetCore.Identity.UI.V4.Pages.Account.Manage.Internal
var result = await _userManager.AddLoginAsync(user, info);
if (!result.Succeeded)
{
throw new InvalidOperationException($"Unexpected error occurred adding external login for user with ID '{userId}'.");
StatusMessage = "The external login was not added. External logins can only be associated with one account.";
return RedirectToPage();
}
// Clear the existing external cookie to ensure a clean login process

View File

@ -79,13 +79,8 @@ namespace Microsoft.AspNetCore.Identity.UI.V4.Pages.Account.Manage.Internal
_signInManager = signInManager;
}
public override async Task<IActionResult> OnGetAsync()
private async Task LoadAsync(TUser user)
{
var user = await _userManager.GetUserAsync(User);
if (user == null)
{
return NotFound($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
}
var userName = await _userManager.GetUserNameAsync(user);
var phoneNumber = await _userManager.GetPhoneNumberAsync(user);
@ -95,31 +90,42 @@ namespace Microsoft.AspNetCore.Identity.UI.V4.Pages.Account.Manage.Internal
{
PhoneNumber = phoneNumber
};
}
public override async Task<IActionResult> OnGetAsync()
{
var user = await _userManager.GetUserAsync(User);
if (user == null)
{
return NotFound($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
}
await LoadAsync(user);
return Page();
}
public override 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)}'.");
}
if (!ModelState.IsValid)
{
await LoadAsync(user);
return Page();
}
var phoneNumber = await _userManager.GetPhoneNumberAsync(user);
if (Input.PhoneNumber != phoneNumber)
{
var setPhoneResult = await _userManager.SetPhoneNumberAsync(user, Input.PhoneNumber);
if (!setPhoneResult.Succeeded)
{
var userId = await _userManager.GetUserIdAsync(user);
throw new InvalidOperationException($"Unexpected error occurred setting phone number for user with ID '{userId}'.");
StatusMessage = "Unexpected error when trying to set phone number.";
return RedirectToPage();
}
}

View File

@ -9,7 +9,6 @@
<h4>@ViewData["Title"]</h4>
<div class="alert alert-warning" role="alert">
<p>
<span class="glyphicon glyphicon-warning-sign"></span>
<strong>Put these codes in a safe place.</strong>
</p>
<p>

View File

@ -146,7 +146,7 @@ namespace Microsoft.AspNetCore.Identity.UI.V4.Pages.Account.Internal
var callbackUrl = Url.Page(
"/Account/ConfirmEmail",
pageHandler: null,
values: new { userId = userId, code = code },
values: new { area = "Identity", userId = userId, code = code },
protocol: Request.Scheme);
await _emailSender.SendEmailAsync(Input.Email, "Confirm your email",