User forgot password functionality for Management API (#14704)

* Added attribute filter to ensure a request is taking a minimum time to response

* Added functionality to management api to send forgot password emails and verify these + do the actual reset using the token

* Renamed UserKey to UserId and updated OpenApi.json

* Update src/Umbraco.Core/Services/IUserService.cs

Co-authored-by: Elitsa Marinovska <21998037+elit0451@users.noreply.github.com>

* Cleanup

* Renaming param

* Fixing send user username instead of email + wrong EmailTypes

* Fixed issue with forgot password functionality after reusing other functionality

* Rename prop

* Adding docs and renaming param

* Handle password validation return types

* More cleanup

---------

Co-authored-by: Elitsa <elm@umbraco.dk>
Co-authored-by: Elitsa Marinovska <21998037+elit0451@users.noreply.github.com>
This commit is contained in:
Bjarke Berg
2023-08-28 12:14:16 +02:00
committed by GitHub
parent b17a7689ab
commit b8af4bab7d
34 changed files with 902 additions and 27 deletions

View File

@@ -1,4 +1,5 @@
using System.ComponentModel.DataAnnotations;
using System.Globalization;
using System.Security.Claims;
using System.Security.Principal;
using Microsoft.AspNetCore.Http;
@@ -317,6 +318,19 @@ public class BackOfficeUserManager : UmbracoUserManager<BackOfficeIdentityUser,
return new IdentityCreationResult { Succeded = true, InitialPassword = password };
}
public async Task<Attempt<string, UserOperationStatus>> GeneratePasswordResetTokenAsync(IUser user)
{
BackOfficeIdentityUser? identityUser = await FindByIdAsync(user.Id.ToString());
if (identityUser is null)
{
return Attempt.FailWithStatus(UserOperationStatus.UserNotFound, string.Empty);
}
var token = await GeneratePasswordResetTokenAsync(identityUser);
return Attempt.SucceedWithStatus(UserOperationStatus.Success, token);
}
public async Task<Attempt<string, UserOperationStatus>> GenerateEmailConfirmationTokenAsync(IUser user)
{
BackOfficeIdentityUser? identityUser = await FindByIdAsync(user.Id.ToString());
@@ -344,7 +358,7 @@ public class BackOfficeUserManager : UmbracoUserManager<BackOfficeIdentityUser,
public async Task<bool> IsEmailConfirmationTokenValidAsync(IUser user, string token)
{
BackOfficeIdentityUser? identityUser = await FindByIdAsync(user.Id.ToString());
BackOfficeIdentityUser? identityUser = await FindByIdAsync(user.Id.ToString(CultureInfo.InvariantCulture));
if (identityUser != null && await VerifyUserTokenAsync(identityUser, Options.Tokens.EmailConfirmationTokenProvider, ConfirmEmailTokenPurpose, token).ConfigureAwait(false))
{
@@ -353,4 +367,16 @@ public class BackOfficeUserManager : UmbracoUserManager<BackOfficeIdentityUser,
return false;
}
public async Task<bool> IsResetPasswordTokenValidAsync(IUser user, string token)
{
BackOfficeIdentityUser? identityUser = await FindByIdAsync(user.Id.ToString(CultureInfo.InvariantCulture));
if (identityUser != null && await VerifyUserTokenAsync(identityUser, Options.Tokens.PasswordResetTokenProvider, ResetPasswordTokenPurpose, token).ConfigureAwait(false))
{
return true;
}
return false;
}
}