Skip to content

Commit f930708

Browse files
Facilitate 'Ask Password' Email Resend and Alter 'Reset Password' Button Logic (wso2#7992)
* Add resend options for ask password and force password reset flows * Add set password option for ask passwrod flow * Update the force password reset disabling logic
1 parent d24136b commit f930708

File tree

12 files changed

+480
-41
lines changed

12 files changed

+480
-41
lines changed

.changeset/grumpy-frogs-travel.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
"@wso2is/admin.users.v1": patch
3+
"@wso2is/admin.core.v1": patch
4+
"@wso2is/i18n": patch
5+
"@wso2is/console": patch
6+
---
7+
8+
Facilitate 'Ask Password' Email Resend and Alter 'Reset Password' Button Logic

features/admin.core.v1/store/reducers/config.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@ export const commonConfigReducerInitialState: CommonConfigReducerStateInterface<
147147
remoteLogPublishEndpoint: "",
148148
remoteLogging: "",
149149
requestPathAuthenticators: "",
150+
resendCode: "",
150151
resourceTypes: "",
151152
roles: "",
152153
rolesV2: "",

features/admin.users.v1/api/users.ts

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import { AxiosError, AxiosResponse } from "axios";
3131
import { UserManagementConstants } from "../constants";
3232
import { SCIMBulkEndpointInterface } from "../models/endpoints";
3333
import {
34+
ResendCodeRequestData,
3435
UserDetailsInterface,
3536
UserListInterface,
3637
UserSessionsInterface
@@ -470,3 +471,48 @@ export const terminateAllUserSessions = (userId: string): Promise<AxiosResponse>
470471
error.config);
471472
});
472473
};
474+
475+
/**
476+
* Resends the verification code/link for a user. This supports scenarios such as resending the
477+
* verification link or code needed to complete an admin-forced password reset, resending an account
478+
* confirmation link or code, and similar use cases.
479+
*
480+
* @param data - The request payload containing user information and properties.
481+
* @returns A promise that resolves when the code is sent successfully.
482+
* @throws `IdentityAppsApiException` if the request fails or if the response status is not as expected.
483+
*/
484+
export const resendCode = (data: ResendCodeRequestData): Promise<void> => {
485+
486+
const requestConfig: RequestConfigInterface = {
487+
data,
488+
headers: {
489+
"Content-Type": "application/json"
490+
},
491+
method: HttpMethods.POST,
492+
url: store.getState().config.endpoints.resendCode
493+
};
494+
495+
return httpClient(requestConfig)
496+
.then((response: AxiosResponse) => {
497+
if (response.status !== 201) {
498+
throw new IdentityAppsApiException(
499+
UserManagementConstants.RESEND_CODE_REQUEST_ERROR,
500+
null,
501+
response.status,
502+
response.request,
503+
response,
504+
response.config);
505+
}
506+
507+
return Promise.resolve();
508+
})
509+
.catch((error: AxiosError) => {
510+
throw new IdentityAppsApiException(
511+
UserManagementConstants.RESEND_CODE_REQUEST_ERROR,
512+
error.stack,
513+
error.code,
514+
error.request,
515+
error.response,
516+
error.config);
517+
});
518+
};

features/admin.users.v1/components/user-change-password.tsx

Lines changed: 43 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,11 @@ interface ChangePasswordPropsInterface extends TestableComponentInterface {
8383
* Handles force password reset trigger.
8484
*/
8585
handleForcePasswordResetTrigger?: () => void;
86+
/**
87+
* Flag to identify if this is a password reset operation.
88+
* When false, it indicates that a new password is being set (Usage: in the ask password flow).
89+
*/
90+
isResetPassword?: boolean;
8691
}
8792

8893
/**
@@ -103,6 +108,7 @@ export const ChangePasswordComponent: FunctionComponent<ChangePasswordPropsInter
103108
handleCloseChangePasswordModal,
104109
connectorProperties,
105110
handleForcePasswordResetTrigger,
111+
isResetPassword = true,
106112
[ "data-testid" ]: testId
107113
} = props;
108114

@@ -585,11 +591,15 @@ export const ChangePasswordComponent: FunctionComponent<ChangePasswordPropsInter
585591
updateUserInfo(user.id, data).then(() => {
586592
onAlertFired({
587593
description: t(
588-
"user:profile.notifications.changeUserPassword.success.description"
594+
isResetPassword
595+
? "user:profile.notifications.changeUserPassword.success.description"
596+
: "user:profile.notifications.setUserPassword.success.description"
589597
),
590598
level: AlertLevels.SUCCESS,
591599
message: t(
592-
"user:profile.notifications.changeUserPassword.success.message"
600+
isResetPassword
601+
? "user:profile.notifications.changeUserPassword.success.message"
602+
: "user:profile.notifications.setUserPassword.success.message"
593603
)
594604
});
595605
handleCloseChangePasswordModal();
@@ -599,22 +609,35 @@ export const ChangePasswordComponent: FunctionComponent<ChangePasswordPropsInter
599609
.catch((error: any) => {
600610
if (error.response && error.response.data && error.response.data.detail) {
601611
onAlertFired({
602-
description: t("user:profile.notifications.changeUserPassword.error.description",
603-
{ description: error.response.data.detail }),
612+
description: t(
613+
isResetPassword
614+
? "user:profile.notifications.changeUserPassword.error.description"
615+
: "user:profile.notifications.setUserPassword.error.description",
616+
{ description: error.response.data.detail }
617+
),
604618
level: AlertLevels.ERROR,
605-
message: t("user:profile.notifications.changeUserPassword.error." +
606-
"message")
619+
message: t(
620+
isResetPassword
621+
? "user:profile.notifications.changeUserPassword.error.message"
622+
: "user:profile.notifications.setUserPassword.error.message"
623+
)
607624
});
608625

609626
return;
610627
}
611628

612629
onAlertFired({
613-
description: t("user:profile.notifications.changeUserPassword" +
614-
".genericError.description"),
630+
description: t(
631+
isResetPassword
632+
? "user:profile.notifications.changeUserPassword.genericError.description"
633+
: "user:profile.notifications.setUserPassword.genericError.description"
634+
),
615635
level: AlertLevels.ERROR,
616-
message: t("user:profile.notifications.changeUserPassword.genericError." +
617-
"message")
636+
message: t(
637+
isResetPassword
638+
? "user:profile.notifications.changeUserPassword.genericError.message"
639+
: "user:profile.notifications.setUserPassword.genericError.message"
640+
)
618641
});
619642
handleCloseChangePasswordModal();
620643
handleModalClose();
@@ -629,7 +652,7 @@ export const ChangePasswordComponent: FunctionComponent<ChangePasswordPropsInter
629652
* configured in the server.
630653
*/
631654
const resolveModalContent = () => {
632-
if (governanceConnectorProperties?.length > 1) {
655+
if (isResetPassword && governanceConnectorProperties?.length > 1) {
633656
return (
634657
<>
635658
<Grid.Row>
@@ -671,7 +694,9 @@ export const ChangePasswordComponent: FunctionComponent<ChangePasswordPropsInter
671694
<Grid.Column mobile={ 16 } tablet={ 16 } computer={ 14 }>
672695
<Message
673696
type="warning"
674-
content={ t("user:modals.changePasswordModal.message") }
697+
content={ isResetPassword
698+
? t("user:modals.changePasswordModal.message")
699+
: t("user:modals.setPasswordModal.message") }
675700
/>
676701
</Grid.Column>
677702
</Grid.Row>
@@ -687,7 +712,9 @@ export const ChangePasswordComponent: FunctionComponent<ChangePasswordPropsInter
687712
size="tiny"
688713
>
689714
<Modal.Header>
690-
{ t("user:modals.changePasswordModal.header") }
715+
{ isResetPassword
716+
? t("user:modals.changePasswordModal.header")
717+
: t("user:modals.setPasswordModal.header") }
691718
</Modal.Header>
692719
<Modal.Content>
693720
<Forms
@@ -717,7 +744,9 @@ export const ChangePasswordComponent: FunctionComponent<ChangePasswordPropsInter
717744
disabled={ isSubmitting }
718745
onClick={ () => setTriggerSubmit() }
719746
>
720-
{ t("user:modals.changePasswordModal.button") }
747+
{ isResetPassword
748+
? t("user:modals.changePasswordModal.button")
749+
: t("user:modals.setPasswordModal.button") }
721750
</PrimaryButton>
722751
<LinkButton
723752
data-testid={ `${ testId }-cancel-button` }

features/admin.users.v1/components/user-profile.scss

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,3 +66,9 @@
6666
flex-direction: row;
6767
}
6868
}
69+
70+
.user-profile-alert {
71+
.link.pointing {
72+
margin-left: 0.2em;
73+
}
74+
}

0 commit comments

Comments
 (0)