Skip to content

Facilitate 'Ask Password' Email Resend and Alter 'Reset Password' Button Logic #7992

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
7 changes: 7 additions & 0 deletions .changeset/grumpy-frogs-travel.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"@wso2is/admin.users.v1": patch
"@wso2is/admin.core.v1": patch
"@wso2is/i18n": patch
---

Facilitate 'Ask Password' Email Resend and Alter 'Reset Password' Button Logic
1 change: 1 addition & 0 deletions features/admin.core.v1/store/reducers/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ export const commonConfigReducerInitialState: CommonConfigReducerStateInterface<
publicCertificates: "",
remoteLogging: "",
requestPathAuthenticators: "",
resendCode: "",
resourceTypes: "",
roles: "",
rolesV2: "",
Expand Down
44 changes: 44 additions & 0 deletions features/admin.users.v1/api/users.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import { AxiosError, AxiosResponse } from "axios";
import { UserManagementConstants } from "../constants";
import { SCIMBulkEndpointInterface } from "../models/endpoints";
import {
ResendCodeRequest,
UserDetailsInterface,
UserListInterface,
UserSessionsInterface
Expand Down Expand Up @@ -470,3 +471,46 @@ export const terminateAllUserSessions = (userId: string): Promise<AxiosResponse>
error.config);
});
};

/**
* Resends the verification code for the for recovery-related scenarios.
*
* @param data - The request payload containing user information and properties.
* @returns A promise containing the response.
* @throws `IdentityAppsApiException` if the request fails or if the response status is not as expected.
*/
export const resendCode = (data: ResendCodeRequest): Promise<any> => {

const requestConfig: RequestConfigInterface = {
data,
headers: {
"Content-Type": "application/json"
},
method: HttpMethods.POST,
url: store.getState().config.endpoints.resendCode
};

return httpClient(requestConfig)
.then((response: AxiosResponse) => {
if (response.status !== 201) {
throw new IdentityAppsApiException(
UserManagementConstants.RESEND_CODE_REQUEST_ERROR,
null,
response.status,
response.request,
response,
response.config);
}

return Promise.resolve(response.data);
})
.catch((error: AxiosError) => {
throw new IdentityAppsApiException(
UserManagementConstants.RESEND_CODE_REQUEST_ERROR,
error.stack,
error.code,
error.request,
error.response,
error.config);
});
};
61 changes: 46 additions & 15 deletions features/admin.users.v1/components/user-change-password.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,11 @@ interface ChangePasswordPropsInterface extends TestableComponentInterface {
* Handles force password reset trigger.
*/
handleForcePasswordResetTrigger?: () => void;
/**
* Flag to identify if this is a password reset operation.
* When false, it indicates that a new password is being set (Usage: in the ask password flow).
*/
isResetPassword?: boolean;
}

/**
Expand All @@ -103,6 +108,7 @@ export const ChangePasswordComponent: FunctionComponent<ChangePasswordPropsInter
handleCloseChangePasswordModal,
connectorProperties,
handleForcePasswordResetTrigger,
isResetPassword = true,
[ "data-testid" ]: testId
} = props;

Expand Down Expand Up @@ -585,11 +591,15 @@ export const ChangePasswordComponent: FunctionComponent<ChangePasswordPropsInter
updateUserInfo(user.id, data).then(() => {
onAlertFired({
description: t(
"user:profile.notifications.changeUserPassword.success.description"
isResetPassword
? "user:profile.notifications.changeUserPassword.success.description"
: "user:profile.notifications.setUserPassword.success.description"
),
level: AlertLevels.SUCCESS,
message: t(
"user:profile.notifications.changeUserPassword.success.message"
isResetPassword
? "user:profile.notifications.changeUserPassword.success.message"
: "user:profile.notifications.setUserPassword.success.message"
)
});
handleCloseChangePasswordModal();
Expand All @@ -599,22 +609,35 @@ export const ChangePasswordComponent: FunctionComponent<ChangePasswordPropsInter
.catch((error: any) => {
if (error.response && error.response.data && error.response.data.detail) {
onAlertFired({
description: t("user:profile.notifications.changeUserPassword.error.description",
{ description: error.response.data.detail }),
description: t(
isResetPassword
? "user:profile.notifications.changeUserPassword.error.description"
: "user:profile.notifications.setUserPassword.error.description",
{ description: error.response.data.detail }
),
level: AlertLevels.ERROR,
message: t("user:profile.notifications.changeUserPassword.error." +
"message")
message: t(
isResetPassword
? "user:profile.notifications.changeUserPassword.error.message"
: "user:profile.notifications.setUserPassword.error.message"
)
});

return;
}

onAlertFired({
description: t("user:profile.notifications.changeUserPassword" +
".genericError.description"),
description: t(
isResetPassword
? "user:profile.notifications.changeUserPassword.genericError.description"
: "user:profile.notifications.setUserPassword.genericError.description"
),
level: AlertLevels.ERROR,
message: t("user:profile.notifications.changeUserPassword.genericError." +
"message")
message: t(
isResetPassword
? "user:profile.notifications.changeUserPassword.genericError.message"
: "user:profile.notifications.setUserPassword.genericError.message"
)
});
handleCloseChangePasswordModal();
handleModalClose();
Expand All @@ -629,7 +652,7 @@ export const ChangePasswordComponent: FunctionComponent<ChangePasswordPropsInter
* configured in the server.
*/
const resolveModalContent = () => {
if (governanceConnectorProperties?.length > 1) {
if (isResetPassword && governanceConnectorProperties?.length > 1) {
return (
<>
<Grid.Row>
Expand Down Expand Up @@ -657,7 +680,9 @@ export const ChangePasswordComponent: FunctionComponent<ChangePasswordPropsInter
<Grid.Column mobile={ 16 } tablet={ 16 } computer={ 14 }>
<Message
type="warning"
content={ t("user:modals.changePasswordModal.message") }
content={ isResetPassword
? t("user:modals.changePasswordModal.message")
: t("user:modals.setPasswordModal.message") }
/>
</Grid.Column>
</Grid.Row>
Expand All @@ -671,7 +696,9 @@ export const ChangePasswordComponent: FunctionComponent<ChangePasswordPropsInter
<Grid.Column mobile={ 16 } tablet={ 16 } computer={ 14 }>
<Message
type="warning"
content={ t("user:modals.changePasswordModal.message") }
content={ isResetPassword
? t("user:modals.changePasswordModal.message")
: t("user:modals.setPasswordModal.message") }
/>
</Grid.Column>
</Grid.Row>
Expand All @@ -687,7 +714,9 @@ export const ChangePasswordComponent: FunctionComponent<ChangePasswordPropsInter
size="tiny"
>
<Modal.Header>
{ t("user:modals.changePasswordModal.header") }
{ isResetPassword
? t("user:modals.changePasswordModal.header")
: t("user:modals.setPasswordModal.header") }
</Modal.Header>
<Modal.Content>
<Forms
Expand Down Expand Up @@ -717,7 +746,9 @@ export const ChangePasswordComponent: FunctionComponent<ChangePasswordPropsInter
disabled={ isSubmitting }
onClick={ () => setTriggerSubmit() }
>
{ t("user:modals.changePasswordModal.button") }
{ isResetPassword
? t("user:modals.changePasswordModal.button")
: t("user:modals.setPasswordModal.button") }
</PrimaryButton>
<LinkButton
data-testid={ `${ testId }-cancel-button` }
Expand Down
Loading
Loading