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<bool> VerifyPasswordResetTokenAsync(VerifyPasswordResetTokenInput 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);
}
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)
{
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)
{
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.DependencyInjection;
using Volo.Abp.Http.Client.ClientProxying;
using Volo.Abp.Identity;
using Volo.Abp.Account;
// ReSharper disable once CheckNamespace
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": {
"controllerName": "Account",
"controllerGroupName": "Account",
"isRemoteService": true,
"apiVersion": null,
"type": "Volo.Abp.Account.AccountController",
"interfaces": [
{
@ -88,6 +90,43 @@
"allowAnonymous": null,
"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": {
"uniqueName": "ResetPasswordAsyncByInput",
"name": "ResetPasswordAsync",
@ -130,6 +169,8 @@
"Volo.Abp.Account.Web.Areas.Account.Controllers.AccountController": {
"controllerName": "Account",
"controllerGroupName": "Login",
"isRemoteService": true,
"apiVersion": null,
"type": "Volo.Abp.Account.Web.Areas.Account.Controllers.AccountController",
"interfaces": [],
"actions": {
@ -227,6 +268,8 @@
"Volo.Abp.Account.ProfileController": {
"controllerName": "Profile",
"controllerGroupName": "Profile",
"isRemoteService": true,
"apiVersion": null,
"type": "Volo.Abp.Account.ProfileController",
"interfaces": [
{
@ -329,4 +372,4 @@
}
},
"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);
}
[HttpPost]
[Route("verify-password-reset-token")]
public Task<bool> VerifyPasswordResetTokenAsync(VerifyPasswordResetTokenInput input)
{
return AccountAppService.VerifyPasswordResetTokenAsync(input);
}
[HttpPost]
[Route("reset-password")]
public virtual Task ResetPasswordAsync(ResetPasswordDto input)

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

@ -1,20 +1,31 @@
@page
@inject IHtmlLocalizer<AccountResource> L
@inject IHtmlLocalizer<IdentityResource> LI
@using Microsoft.AspNetCore.Mvc.Localization
@using Volo.Abp.Account.Localization
@using Volo.Abp.Identity.Localization
@model Volo.Abp.Account.Web.Pages.Account.ResetPasswordModel
@inject Volo.Abp.AspNetCore.Mvc.UI.Layout.IPageLayout PageLayout
<div class="card mt-3 shadow-sm rounded">
<div class="card-body p-5">
<h4>@L["ResetPassword"]</h4>
<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>
@if (Model.InvalidToken)
{
<div class="alert alert-danger">
@LI["Volo.Abp.Identity:InvalidToken"]
</div>
}
else
{
<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>

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

@ -1,6 +1,7 @@
using System;
using System.ComponentModel.DataAnnotations;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Volo.Abp.Auditing;
using Volo.Abp.Identity;
@ -43,9 +44,21 @@ public class ResetPasswordModel : AccountPageModel
[DisableAuditing]
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()

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

@ -5,67 +5,75 @@
(function(){
// controller volo.abp.account.web.areas.account.controllers.account
// controller volo.abp.account.account
(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, {
url: abp.appPath + 'api/account/login',
url: abp.appPath + 'api/account/register',
type: 'POST',
data: JSON.stringify(login)
data: JSON.stringify(input)
}, 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, {
url: abp.appPath + 'api/account/logout',
type: 'GET',
dataType: null
url: abp.appPath + 'api/account/send-password-reset-code',
type: 'POST',
dataType: null,
data: JSON.stringify(input)
}, 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, {
url: abp.appPath + 'api/account/check-password',
url: abp.appPath + 'api/account/verify-password-reset-token',
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));
};
})();
// controller volo.abp.account.account
// controller volo.abp.account.web.areas.account.controllers.account
(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, {
url: abp.appPath + 'api/account/register',
url: abp.appPath + 'api/account/login',
type: 'POST',
data: JSON.stringify(input)
data: JSON.stringify(login)
}, 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, {
url: abp.appPath + 'api/account/send-password-reset-code',
type: 'POST',
dataType: null,
data: JSON.stringify(input)
url: abp.appPath + 'api/account/logout',
type: 'GET',
dataType: null
}, 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, {
url: abp.appPath + 'api/account/reset-password',
url: abp.appPath + 'api/account/check-password',
type: 'POST',
dataType: null,
data: JSON.stringify(input)
data: JSON.stringify(login)
}, ajaxParams));
};

Loading…
Cancel
Save