(null);
@@ -47,13 +50,14 @@ export default function ResetPassword(): React.JSX.Element {
if (ex.modelState)
setModelState(ex.modelState);
}
+ else
+ setShowRequestNewLink(true);
throw ex;
}
}
}
-
function validateNewPassword(): boolean {
if (!newPassword.current!.value) {
setModelState({ "newPassword": [LoginAuthMessage.PasswordMustHaveAValue.niceToString()] });
@@ -79,6 +83,19 @@ export default function ResetPassword(): React.JSX.Element {
return ms && ms[field] && ms[field].length > 0 ? ms[field][0] : undefined;
}
+ if (successRequestNewLink) {
+ return (
+
+
+
+
{ResetPasswordAuthMessage.RequestNewLink.niceToString()}
+
{ResetPasswordAuthMessage.NewLinkToResetPasswordHasBeenSentSuccessfully.niceToString()}
+
+
+
+ );
+ }
+
if (success || code == "OK") {
return (
@@ -111,10 +128,20 @@ export default function ResetPassword(): React.JSX.Element {
-
+
+
+ {showRequestNewLink &&
+ }
+
);
+
+ function handleRequestNewLinkClick(e: React.MouseEvent) {
+ e.preventDefault();
+ ResetPasswordClient.API.requestNewLink(code)
+ .then(() => setSuccessRquestNewLink(true));
+ }
}
diff --git a/Extensions/Signum.Authorization.ResetPassword/ResetPasswordClient.tsx b/Extensions/Signum.Authorization.ResetPassword/ResetPasswordClient.tsx
index 5da66f1ef0..7ec3b28a2a 100644
--- a/Extensions/Signum.Authorization.ResetPassword/ResetPasswordClient.tsx
+++ b/Extensions/Signum.Authorization.ResetPassword/ResetPasswordClient.tsx
@@ -30,10 +30,14 @@ export namespace ResetPasswordClient {
return ajaxPost({ url: "/api/auth/forgotPasswordEmail" }, request);
}
- export function resetPassword(request: ResetPasswordRequest): Promise {
+ export function resetPassword(request: ResetPasswordRequest): Promise {
return ajaxPost({ url: "/api/auth/resetPassword" }, request);
}
+ export function requestNewLink(code: string): Promise {
+ return ajaxPost({ url: "/api/auth/requestNewLink" }, code);
+ }
+
export interface ResetPasswordRequest {
code: string;
newPassword: string;
diff --git a/Extensions/Signum.Authorization.ResetPassword/ResetPasswordController.cs b/Extensions/Signum.Authorization.ResetPassword/ResetPasswordController.cs
index e2b188099f..df1d9bcfd5 100644
--- a/Extensions/Signum.Authorization.ResetPassword/ResetPasswordController.cs
+++ b/Extensions/Signum.Authorization.ResetPassword/ResetPasswordController.cs
@@ -58,6 +58,15 @@ public ActionResult ResetPassword([Required, FromBody] ResetPassw
return new LoginResponse { userEntity = rpr.User, token = AuthTokenServer.CreateToken(rpr.User), authenticationType = "resetPassword" };
}
+ [HttpPost("api/auth/requestNewLink"), SignumAllowAnonymous]
+ public void RequestNewLink([Required, FromBody] string code)
+ {
+ if (string.IsNullOrWhiteSpace(code))
+ throw new ApplicationException(ResetPasswordMessage.TheCodeOfYourLinkIsIncorrect.NiceToString());
+
+ ResetPasswordRequestLogic.RequestNewLink(code);
+ }
+
private BadRequestObjectResult ModelError(string field, string error)
{
ModelState.AddModelError(field, error);
diff --git a/Extensions/Signum.Authorization.ResetPassword/ResetPasswordRequest.cs b/Extensions/Signum.Authorization.ResetPassword/ResetPasswordRequest.cs
index 5192eec10e..69ee399375 100644
--- a/Extensions/Signum.Authorization.ResetPassword/ResetPasswordRequest.cs
+++ b/Extensions/Signum.Authorization.ResetPassword/ResetPasswordRequest.cs
@@ -33,9 +33,9 @@ public class ResetPasswordRequestEntity : Entity
return null;
if (this.Used)
- return ResetPasswordMessage.TheCodeOfYourLinkHasAlreadyBeenUsed.NiceToString();
+ return $"{ResetPasswordMessage.TheCodeOfYourLinkHasAlreadyBeenUsed.NiceToString()}. {ResetPasswordAuthMessage.PleaseConsiderRequestingANewLink.NiceToString()}";
- return ResetPasswordMessage.YourResetPasswordRequestHasExpired.NiceToString();
+ return $"{ResetPasswordMessage.YourResetPasswordRequestHasExpired.NiceToString()}. {ResetPasswordAuthMessage.PleaseConsiderRequestingANewLink.NiceToString()}";
}
}
@@ -45,7 +45,6 @@ public static class ResetPasswordRequestOperation
public static readonly ExecuteSymbol Execute;
}
-
public enum ResetPasswordMessage
{
[Description("You recently requested a new password")]
@@ -71,6 +70,14 @@ public enum ResetPasswordMessage
IfEmailIsValidWeWillSendYouAnEmailToResetYourPassword,
}
+[AllowUnauthenticated]
+public enum ResetPasswordAuthMessage
+{
+ PleaseConsiderRequestingANewLink,
+ RequestNewLink,
+ NewLinkToResetPasswordHasBeenSentSuccessfully,
+}
+
public class ResetPasswordException : Exception
{
public ResetPasswordException() { }
diff --git a/Extensions/Signum.Authorization.ResetPassword/ResetPasswordRequestLogic.cs b/Extensions/Signum.Authorization.ResetPassword/ResetPasswordRequestLogic.cs
index f728003b95..4499cf15ee 100644
--- a/Extensions/Signum.Authorization.ResetPassword/ResetPasswordRequestLogic.cs
+++ b/Extensions/Signum.Authorization.ResetPassword/ResetPasswordRequestLogic.cs
@@ -116,6 +116,21 @@ public static ResetPasswordRequestEntity ResetPasswordRequestExecute(string code
}
}
+ public static void RequestNewLink(string code)
+ {
+ using (AuthLogic.Disable())
+ {
+ var rpr = Database.Query()
+ .Where(r => r.Code == code)
+ .SingleOrDefaultEx();
+
+ if (rpr == null)
+ throw new ResetPasswordException(ResetPasswordMessage.TheCodeOfYourLinkIsIncorrect.NiceToString());
+
+ SendResetPasswordRequestEmail(rpr.User.Email!);
+ }
+ }
+
public static void SendResetPasswordRequestEmail(string email)
{
try
@@ -213,7 +228,7 @@ private static void CancelExcess(UserEntity user, int maxValidCodes)
.Execute();
}
- private static void CancelResetPasswordReques(UserEntity user)
+ private static void CancelResetPasswordRequests(UserEntity user)
{
Database.Query()
.Where(r => r.User.Is(user) && r.IsValid)
diff --git a/Extensions/Signum.Authorization.ResetPassword/Signum.Authorization.ResetPassword.csproj b/Extensions/Signum.Authorization.ResetPassword/Signum.Authorization.ResetPassword.csproj
index 7404733029..51da79c0c9 100644
--- a/Extensions/Signum.Authorization.ResetPassword/Signum.Authorization.ResetPassword.csproj
+++ b/Extensions/Signum.Authorization.ResetPassword/Signum.Authorization.ResetPassword.csproj
@@ -15,7 +15,7 @@
-
+