Browse Source

Merge pull request #14442 from abpframework/VerifyPasswordResetTokenAsync

Invalidate the token after changing the password.
pull/14450/head
liangshiwei 4 years ago
committed by GitHub
parent
commit
005322667a
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      modules/account/src/Volo.Abp.Account.Application.Contracts/Volo/Abp/Account/IAccountAppService.cs
  2. 12
      modules/account/src/Volo.Abp.Account.Application.Contracts/Volo/Abp/Account/VerifyPasswordResetTokenInput.cs
  3. 10
      modules/account/src/Volo.Abp.Account.Application/Volo/Abp/Account/AccountAppService.cs
  4. 8
      modules/account/src/Volo.Abp.Account.HttpApi.Client/ClientProxies/AccountClientProxy.Generated.cs
  5. 2
      modules/account/src/Volo.Abp.Account.HttpApi.Client/ClientProxies/ProfileClientProxy.Generated.cs
  6. 45
      modules/account/src/Volo.Abp.Account.HttpApi.Client/ClientProxies/account-generate-proxy.json
  7. 7
      modules/account/src/Volo.Abp.Account.HttpApi/Volo/Abp/Account/AccountController.cs
  8. 29
      modules/account/src/Volo.Abp.Account.Web/Pages/Account/ResetPassword.cshtml
  9. 17
      modules/account/src/Volo.Abp.Account.Web/Pages/Account/ResetPassword.cshtml.cs
  10. 60
      modules/account/src/Volo.Abp.Account.Web/wwwroot/client-proxies/account-proxy.js

2
modules/account/src/Volo.Abp.Account.Application.Contracts/Volo/Abp/Account/IAccountAppService.cs

@ -10,5 +10,7 @@ public interface IAccountAppService : IApplicationService
Task SendPasswordResetCodeAsync(SendPasswordResetCodeDto input); Task SendPasswordResetCodeAsync(SendPasswordResetCodeDto input);
Task<bool> VerifyPasswordResetTokenAsync(VerifyPasswordResetTokenInput input);
Task ResetPasswordAsync(ResetPasswordDto input); Task ResetPasswordAsync(ResetPasswordDto input);
} }

12
modules/account/src/Volo.Abp.Account.Application.Contracts/Volo/Abp/Account/VerifyPasswordResetTokenInput.cs

@ -0,0 +1,12 @@
using System;
using System.ComponentModel.DataAnnotations;
namespace Volo.Abp.Account;
public class VerifyPasswordResetTokenInput
{
public Guid UserId { get; set; }
[Required]
public string ResetToken { get; set; }
}

10
modules/account/src/Volo.Abp.Account.Application/Volo/Abp/Account/AccountAppService.cs

@ -60,6 +60,16 @@ public class AccountAppService : ApplicationService, IAccountAppService
await AccountEmailer.SendPasswordResetLinkAsync(user, resetToken, input.AppName, input.ReturnUrl, input.ReturnUrlHash); await AccountEmailer.SendPasswordResetLinkAsync(user, resetToken, input.AppName, input.ReturnUrl, input.ReturnUrlHash);
} }
public virtual async Task<bool> VerifyPasswordResetTokenAsync(VerifyPasswordResetTokenInput input)
{
var user = await UserManager.GetByIdAsync(input.UserId);
return await UserManager.VerifyUserTokenAsync(
user,
UserManager.Options.Tokens.PasswordResetTokenProvider,
UserManager<IdentityUser>.ResetPasswordTokenPurpose,
input.ResetToken);
}
public virtual async Task ResetPasswordAsync(ResetPasswordDto input) public virtual async Task ResetPasswordAsync(ResetPasswordDto input)
{ {
await IdentityOptions.SetAsync(); await IdentityOptions.SetAsync();

8
modules/account/src/Volo.Abp.Account.HttpApi.Client/ClientProxies/AccountClientProxy.Generated.cs

@ -32,6 +32,14 @@ public partial class AccountClientProxy : ClientProxyBase<IAccountAppService>, I
}); });
} }
public virtual async Task<bool> VerifyPasswordResetTokenAsync(VerifyPasswordResetTokenInput input)
{
return await RequestAsync<bool>(nameof(VerifyPasswordResetTokenAsync), new ClientProxyRequestTypeValue
{
{ typeof(VerifyPasswordResetTokenInput), input }
});
}
public virtual async Task ResetPasswordAsync(ResetPasswordDto input) public virtual async Task ResetPasswordAsync(ResetPasswordDto input)
{ {
await RequestAsync(nameof(ResetPasswordAsync), new ClientProxyRequestTypeValue await RequestAsync(nameof(ResetPasswordAsync), new ClientProxyRequestTypeValue

2
modules/account/src/Volo.Abp.Account.HttpApi.Client/ClientProxies/ProfileClientProxy.Generated.cs

@ -6,7 +6,7 @@ using Volo.Abp.Http.Client;
using Volo.Abp.Http.Modeling; using Volo.Abp.Http.Modeling;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
using Volo.Abp.Http.Client.ClientProxying; using Volo.Abp.Http.Client.ClientProxying;
using Volo.Abp.Identity; using Volo.Abp.Account;
// ReSharper disable once CheckNamespace // ReSharper disable once CheckNamespace
namespace Volo.Abp.Account.ClientProxies; namespace Volo.Abp.Account.ClientProxies;

45
modules/account/src/Volo.Abp.Account.HttpApi.Client/ClientProxies/account-generate-proxy.json

@ -7,6 +7,8 @@
"Volo.Abp.Account.AccountController": { "Volo.Abp.Account.AccountController": {
"controllerName": "Account", "controllerName": "Account",
"controllerGroupName": "Account", "controllerGroupName": "Account",
"isRemoteService": true,
"apiVersion": null,
"type": "Volo.Abp.Account.AccountController", "type": "Volo.Abp.Account.AccountController",
"interfaces": [ "interfaces": [
{ {
@ -88,6 +90,43 @@
"allowAnonymous": null, "allowAnonymous": null,
"implementFrom": "Volo.Abp.Account.IAccountAppService" "implementFrom": "Volo.Abp.Account.IAccountAppService"
}, },
"VerifyPasswordResetTokenAsyncByInput": {
"uniqueName": "VerifyPasswordResetTokenAsyncByInput",
"name": "VerifyPasswordResetTokenAsync",
"httpMethod": "POST",
"url": "api/account/verify-password-reset-token",
"supportedVersions": [],
"parametersOnMethod": [
{
"name": "input",
"typeAsString": "Volo.Abp.Account.VerifyPasswordResetTokenInput, Volo.Abp.Account.Application.Contracts",
"type": "Volo.Abp.Account.VerifyPasswordResetTokenInput",
"typeSimple": "Volo.Abp.Account.VerifyPasswordResetTokenInput",
"isOptional": false,
"defaultValue": null
}
],
"parameters": [
{
"nameOnMethod": "input",
"name": "input",
"jsonName": null,
"type": "Volo.Abp.Account.VerifyPasswordResetTokenInput",
"typeSimple": "Volo.Abp.Account.VerifyPasswordResetTokenInput",
"isOptional": false,
"defaultValue": null,
"constraintTypes": null,
"bindingSourceId": "Body",
"descriptorName": ""
}
],
"returnValue": {
"type": "System.Boolean",
"typeSimple": "boolean"
},
"allowAnonymous": null,
"implementFrom": "Volo.Abp.Account.IAccountAppService"
},
"ResetPasswordAsyncByInput": { "ResetPasswordAsyncByInput": {
"uniqueName": "ResetPasswordAsyncByInput", "uniqueName": "ResetPasswordAsyncByInput",
"name": "ResetPasswordAsync", "name": "ResetPasswordAsync",
@ -130,6 +169,8 @@
"Volo.Abp.Account.Web.Areas.Account.Controllers.AccountController": { "Volo.Abp.Account.Web.Areas.Account.Controllers.AccountController": {
"controllerName": "Account", "controllerName": "Account",
"controllerGroupName": "Login", "controllerGroupName": "Login",
"isRemoteService": true,
"apiVersion": null,
"type": "Volo.Abp.Account.Web.Areas.Account.Controllers.AccountController", "type": "Volo.Abp.Account.Web.Areas.Account.Controllers.AccountController",
"interfaces": [], "interfaces": [],
"actions": { "actions": {
@ -227,6 +268,8 @@
"Volo.Abp.Account.ProfileController": { "Volo.Abp.Account.ProfileController": {
"controllerName": "Profile", "controllerName": "Profile",
"controllerGroupName": "Profile", "controllerGroupName": "Profile",
"isRemoteService": true,
"apiVersion": null,
"type": "Volo.Abp.Account.ProfileController", "type": "Volo.Abp.Account.ProfileController",
"interfaces": [ "interfaces": [
{ {
@ -329,4 +372,4 @@
} }
}, },
"types": {} "types": {}
} }

7
modules/account/src/Volo.Abp.Account.HttpApi/Volo/Abp/Account/AccountController.cs

@ -31,6 +31,13 @@ public class AccountController : AbpControllerBase, IAccountAppService
return AccountAppService.SendPasswordResetCodeAsync(input); return AccountAppService.SendPasswordResetCodeAsync(input);
} }
[HttpPost]
[Route("verify-password-reset-token")]
public Task<bool> VerifyPasswordResetTokenAsync(VerifyPasswordResetTokenInput input)
{
return AccountAppService.VerifyPasswordResetTokenAsync(input);
}
[HttpPost] [HttpPost]
[Route("reset-password")] [Route("reset-password")]
public virtual Task ResetPasswordAsync(ResetPasswordDto input) public virtual Task ResetPasswordAsync(ResetPasswordDto input)

29
modules/account/src/Volo.Abp.Account.Web/Pages/Account/ResetPassword.cshtml

@ -1,20 +1,31 @@
@page @page
@inject IHtmlLocalizer<AccountResource> L @inject IHtmlLocalizer<AccountResource> L
@inject IHtmlLocalizer<IdentityResource> LI
@using Microsoft.AspNetCore.Mvc.Localization @using Microsoft.AspNetCore.Mvc.Localization
@using Volo.Abp.Account.Localization @using Volo.Abp.Account.Localization
@using Volo.Abp.Identity.Localization
@model Volo.Abp.Account.Web.Pages.Account.ResetPasswordModel @model Volo.Abp.Account.Web.Pages.Account.ResetPasswordModel
@inject Volo.Abp.AspNetCore.Mvc.UI.Layout.IPageLayout PageLayout @inject Volo.Abp.AspNetCore.Mvc.UI.Layout.IPageLayout PageLayout
<div class="card mt-3 shadow-sm rounded"> <div class="card mt-3 shadow-sm rounded">
<div class="card-body p-5"> <div class="card-body p-5">
<h4>@L["ResetPassword"]</h4> <h4>@L["ResetPassword"]</h4>
<form method="post"> @if (Model.InvalidToken)
<p>@L["ResetPassword_Information"]</p> {
<abp-input asp-for="UserId"/> <div class="alert alert-danger">
<abp-input asp-for="ResetToken"/> @LI["Volo.Abp.Identity:InvalidToken"]
<abp-input asp-for="Password" autocomplete="new-password" /> </div>
<abp-input asp-for="ConfirmPassword" autocomplete="new-password" /> }
<a abp-button="Secondary" asp-page="./Login">@L["Cancel"]</a> else
<abp-button type="submit" button-type="Primary" text="@L["Submit"].Value"/> {
</form> <form method="post">
<p>@L["ResetPassword_Information"]</p>
<abp-input asp-for="UserId"/>
<abp-input asp-for="ResetToken"/>
<abp-input asp-for="Password" autocomplete="new-password" />
<abp-input asp-for="ConfirmPassword" autocomplete="new-password" />
<a abp-button="Secondary" asp-page="./Login">@L["Cancel"]</a>
<abp-button type="submit" button-type="Primary" text="@L["Submit"].Value"/>
</form>
}
</div> </div>
</div> </div>

17
modules/account/src/Volo.Abp.Account.Web/Pages/Account/ResetPassword.cshtml.cs

@ -1,6 +1,7 @@
using System; using System;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Volo.Abp.Auditing; using Volo.Abp.Auditing;
using Volo.Abp.Identity; using Volo.Abp.Identity;
@ -43,9 +44,21 @@ public class ResetPasswordModel : AccountPageModel
[DisableAuditing] [DisableAuditing]
public string ConfirmPassword { get; set; } public string ConfirmPassword { get; set; }
public virtual Task<IActionResult> OnGetAsync() public bool InvalidToken { get; set; }
public virtual async Task<IActionResult> OnGetAsync()
{ {
return Task.FromResult<IActionResult>(Page()); ValidateModel();
InvalidToken = !await AccountAppService.VerifyPasswordResetTokenAsync(
new VerifyPasswordResetTokenInput
{
UserId = UserId,
ResetToken = ResetToken
}
);
return Page();
} }
public virtual async Task<IActionResult> OnPostAsync() public virtual async Task<IActionResult> OnPostAsync()

60
modules/account/src/Volo.Abp.Account.Web/wwwroot/client-proxies/account-proxy.js

@ -5,67 +5,75 @@
(function(){ (function(){
// controller volo.abp.account.web.areas.account.controllers.account // controller volo.abp.account.account
(function(){ (function(){
abp.utils.createNamespace(window, 'volo.abp.account.web.areas.account.controllers.account'); abp.utils.createNamespace(window, 'volo.abp.account.account');
volo.abp.account.web.areas.account.controllers.account.login = function(login, ajaxParams) { volo.abp.account.account.register = function(input, ajaxParams) {
return abp.ajax($.extend(true, { return abp.ajax($.extend(true, {
url: abp.appPath + 'api/account/login', url: abp.appPath + 'api/account/register',
type: 'POST', type: 'POST',
data: JSON.stringify(login) data: JSON.stringify(input)
}, ajaxParams)); }, ajaxParams));
}; };
volo.abp.account.web.areas.account.controllers.account.logout = function(ajaxParams) { volo.abp.account.account.sendPasswordResetCode = function(input, ajaxParams) {
return abp.ajax($.extend(true, { return abp.ajax($.extend(true, {
url: abp.appPath + 'api/account/logout', url: abp.appPath + 'api/account/send-password-reset-code',
type: 'GET', type: 'POST',
dataType: null dataType: null,
data: JSON.stringify(input)
}, ajaxParams)); }, ajaxParams));
}; };
volo.abp.account.web.areas.account.controllers.account.checkPassword = function(login, ajaxParams) { volo.abp.account.account.verifyPasswordResetToken = function(input, ajaxParams) {
return abp.ajax($.extend(true, { return abp.ajax($.extend(true, {
url: abp.appPath + 'api/account/check-password', url: abp.appPath + 'api/account/verify-password-reset-token',
type: 'POST', type: 'POST',
data: JSON.stringify(login) data: JSON.stringify(input)
}, ajaxParams));
};
volo.abp.account.account.resetPassword = function(input, ajaxParams) {
return abp.ajax($.extend(true, {
url: abp.appPath + 'api/account/reset-password',
type: 'POST',
dataType: null,
data: JSON.stringify(input)
}, ajaxParams)); }, ajaxParams));
}; };
})(); })();
// controller volo.abp.account.account // controller volo.abp.account.web.areas.account.controllers.account
(function(){ (function(){
abp.utils.createNamespace(window, 'volo.abp.account.account'); abp.utils.createNamespace(window, 'volo.abp.account.web.areas.account.controllers.account');
volo.abp.account.account.register = function(input, ajaxParams) { volo.abp.account.web.areas.account.controllers.account.login = function(login, ajaxParams) {
return abp.ajax($.extend(true, { return abp.ajax($.extend(true, {
url: abp.appPath + 'api/account/register', url: abp.appPath + 'api/account/login',
type: 'POST', type: 'POST',
data: JSON.stringify(input) data: JSON.stringify(login)
}, ajaxParams)); }, ajaxParams));
}; };
volo.abp.account.account.sendPasswordResetCode = function(input, ajaxParams) { volo.abp.account.web.areas.account.controllers.account.logout = function(ajaxParams) {
return abp.ajax($.extend(true, { return abp.ajax($.extend(true, {
url: abp.appPath + 'api/account/send-password-reset-code', url: abp.appPath + 'api/account/logout',
type: 'POST', type: 'GET',
dataType: null, dataType: null
data: JSON.stringify(input)
}, ajaxParams)); }, ajaxParams));
}; };
volo.abp.account.account.resetPassword = function(input, ajaxParams) { volo.abp.account.web.areas.account.controllers.account.checkPassword = function(login, ajaxParams) {
return abp.ajax($.extend(true, { return abp.ajax($.extend(true, {
url: abp.appPath + 'api/account/reset-password', url: abp.appPath + 'api/account/check-password',
type: 'POST', type: 'POST',
dataType: null, data: JSON.stringify(login)
data: JSON.stringify(input)
}, ajaxParams)); }, ajaxParams));
}; };

Loading…
Cancel
Save