Skip to content

Update the force password reset config page with new configurations. #7995

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/thirty-buttons-do.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"@wso2is/admin.server-configurations.v1": minor
"@wso2is/admin.users.v1": minor
"@wso2is/console": minor
---

Update the forced password reset configuration page and force password reset modal message to support email Link and email OTP.
31 changes: 30 additions & 1 deletion apps/console/src/extensions/i18n/models/extensions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2876,6 +2876,31 @@ export interface Extensions {
recoveryOptionHeading: string;
},
heading: string;
};
forcedPasswordRecovery: {
form: {
fields: {
enableEmailLinkBasedReset: {
label: string;
},
enableEmailOTPBasedReset: {
label: string;
},
enableSMSOTPBasedReset: {
label: string;
},
expiryTime: {
label: string;
hint: string;
placeholder: string;
}
},
heading: {
label: string;
hint: string;
}
subheading: string;
}
}
};
accountSecurity: {
Expand Down Expand Up @@ -3123,7 +3148,11 @@ export interface Extensions {
resetPassword: {
changePasswordModal: {
emailUnavailableWarning: string;
emailResetWarning: string;
emailResetWarning: {
emailLink: string;
emailOTP: string;
smsOTP: string;
}
passwordResetConfigDisabled: string;
};
};
Expand Down
33 changes: 32 additions & 1 deletion apps/console/src/extensions/i18n/resources/en-US/extensions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3355,6 +3355,31 @@ export const extensions: Extensions = {
},
heading: "Enable self-service username recovery for users on the login page."
},
forcedPasswordRecovery: {
form: {
fields: {
enableEmailLinkBasedReset: {
label: "Email Link"
},
enableEmailOTPBasedReset: {
label: "Email OTP"
},
enableSMSOTPBasedReset: {
label: "SMS OTP"
},
expiryTime: {
label: "Reset link/OTP expiry time",
hint: "Password Reset Link/OTP expiry time in minutes.",
placeholder: "Enter expiry time"
}
},
heading: {
label: "Enable password reset via recovery Email",
hint: "User gets notified with a link/OTP to reset password."
},
subheading: "Choose password reset option"
}
},
subHeading: "Account Recovery related settings."
},
accountSecurity: {
Expand Down Expand Up @@ -3709,8 +3734,14 @@ export const extensions: Extensions = {
changePasswordModal: {
emailUnavailableWarning: "WARNING: Cannot find an email address for the user account." +
"Please provide an email address to proceed with inviting the user to reset the password.",
emailResetWarning: "An email with a link to reset the password will be sent to the provided " +
emailResetWarning: {
emailLink: "An email with a link to reset the password will be sent to the provided " +
"email address for the user to set their own password.",
emailOTP: "An email with a OTP to reset the password will be sent to the provided " +
"email address for the user to set their own password.",
smsOTP: "An SMS with a OTP to reset the password will be sent to the provided " +
"mobile number for the user to set their own password."
},
passwordResetConfigDisabled: "Password reset via recovery email is not enabled. Please make " +
"sure to enable it from <1> " +
" Login and Registration </1> configurations."
Expand Down
10 changes: 10 additions & 0 deletions apps/console/src/public/deployment.config.json
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,16 @@
"description": "This SMS is sent to verify the user's mobile number after an update.",
"displayName": "Verify Mobile On Update",
"id": "dmVyaWZ5TW9iaWxlT25VcGRhdGU"
},
{
"description": "This SMS is sent to provide a one-time password when admin initiates a password reset for a user",
"displayName": "Admin forced Password Reset",
"id": "YWRtaW5Gb3JjZWRQYXNzd29yZFJlc2V0"
},
{
"description": "This SMS is sent to provide a one-time password when admin resends a password reset request",
"displayName": "Admin Resent Password Reset",
"id": "cmVzZW5kQWRtaW5Gb3JjZWRQYXNzd29yZFJlc2V0"
}
]
},
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/**
* Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com).
*
* WSO2 LLC. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

import { ServerConfigurationsConstants } from "./server-configurations-constants";

export class AdminForcedPasswordResetFormConstants {

/**
* Private constructor to avoid object instantiation from outside the class.
*
*/
/* eslint-disable @typescript-eslint/no-empty-function */
private constructor() { }

public static readonly allowedConnectorFields: string[] = [
ServerConfigurationsConstants.ADMIN_FORCE_PASSWORD_RESET_EMAIL_LINK,
ServerConfigurationsConstants.ADMIN_FORCE_PASSWORD_RESET_EMAIL_OTP,
ServerConfigurationsConstants.ADMIN_FORCE_PASSWORD_RESET_SMS_OTP,
ServerConfigurationsConstants.ADMIN_FORCED_PASSWORD_RESET_EXPIRY_TIME
];
}

Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Copyright (c) 2021-2024, WSO2 LLC. (https://www.wso2.com).
* Copyright (c) 2021-2025, WSO2 LLC. (https://www.wso2.com).
*
* WSO2 LLC. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
Expand Down Expand Up @@ -30,11 +30,11 @@ export class GovernanceConnectorConstants {
EXPIRY_TIME_MIN_LENGTH: number;
EXPIRY_TIME_MIN_VALUE: number;
} = {
EXPIRY_TIME_MAX_LENGTH: 5,
EXPIRY_TIME_MAX_VALUE: 10080,
EXPIRY_TIME_MIN_LENGTH: 1,
EXPIRY_TIME_MIN_VALUE: -1
};
EXPIRY_TIME_MAX_LENGTH: 5,
EXPIRY_TIME_MAX_VALUE: 10080,
EXPIRY_TIME_MIN_LENGTH: 1,
EXPIRY_TIME_MIN_VALUE: -1
};

/**
* Self Registration Form element constraints.
Expand All @@ -45,11 +45,11 @@ export class GovernanceConnectorConstants {
EXPIRY_TIME_MIN_LENGTH: number;
EXPIRY_TIME_MIN_VALUE: number;
} = {
EXPIRY_TIME_MAX_LENGTH: 5,
EXPIRY_TIME_MAX_VALUE: 10080,
EXPIRY_TIME_MIN_LENGTH: 1,
EXPIRY_TIME_MIN_VALUE: 1
};
EXPIRY_TIME_MAX_LENGTH: 5,
EXPIRY_TIME_MAX_VALUE: 10080,
EXPIRY_TIME_MIN_LENGTH: 1,
EXPIRY_TIME_MIN_VALUE: 1
};

/**
* Password Recovery Form element constraints.
Expand All @@ -74,25 +74,25 @@ export class GovernanceConnectorConstants {
SMS_OTP_CODE_LENGTH_MIN_LENGTH: number;
SMS_OTP_CODE_LENGTH_MIN_VALUE: number;
} = {
EXPIRY_TIME_MAX_LENGTH: 5,
EXPIRY_TIME_MAX_VALUE: 10080,
EXPIRY_TIME_MIN_LENGTH: 1,
EXPIRY_TIME_MIN_VALUE: 1,
MAX_FAILED_ATTEMPT_COUNT_MAX_LENGTH: 2,
MAX_FAILED_ATTEMPT_COUNT_MAX_VALUE: 10,
MAX_FAILED_ATTEMPT_COUNT_MIN_LENGTH: 1,
MAX_FAILED_ATTEMPT_COUNT_MIN_VALUE: 1,
MAX_RESEND_COUNT_MAX_LENGTH: 1,
MAX_RESEND_COUNT_MAX_VALUE: 5,
MAX_RESEND_COUNT_MIN_LENGTH: 1,
MAX_RESEND_COUNT_MIN_VALUE: 1,
SMS_OTP_CODE_LENGTH_MAX_LENGTH: 2,
SMS_OTP_CODE_LENGTH_MAX_VALUE: 10,
SMS_OTP_CODE_LENGTH_MIN_LENGTH: 1,
SMS_OTP_CODE_LENGTH_MIN_VALUE: 4,
SMS_OTP_EXPIRY_TIME_MAX_LENGTH: 4,
SMS_OTP_EXPIRY_TIME_MAX_VALUE: 1440
};
EXPIRY_TIME_MAX_LENGTH: 5,
EXPIRY_TIME_MAX_VALUE: 10080,
EXPIRY_TIME_MIN_LENGTH: 1,
EXPIRY_TIME_MIN_VALUE: 1,
MAX_FAILED_ATTEMPT_COUNT_MAX_LENGTH: 2,
MAX_FAILED_ATTEMPT_COUNT_MAX_VALUE: 10,
MAX_FAILED_ATTEMPT_COUNT_MIN_LENGTH: 1,
MAX_FAILED_ATTEMPT_COUNT_MIN_VALUE: 1,
MAX_RESEND_COUNT_MAX_LENGTH: 1,
MAX_RESEND_COUNT_MAX_VALUE: 5,
MAX_RESEND_COUNT_MIN_LENGTH: 1,
MAX_RESEND_COUNT_MIN_VALUE: 1,
SMS_OTP_CODE_LENGTH_MAX_LENGTH: 2,
SMS_OTP_CODE_LENGTH_MAX_VALUE: 10,
SMS_OTP_CODE_LENGTH_MIN_LENGTH: 1,
SMS_OTP_CODE_LENGTH_MIN_VALUE: 4,
SMS_OTP_EXPIRY_TIME_MAX_LENGTH: 4,
SMS_OTP_EXPIRY_TIME_MAX_VALUE: 1440
};

/**
* Login Attempt Security Form element constraints.
Expand All @@ -111,19 +111,19 @@ export class GovernanceConnectorConstants {
FAILED_ATTEMPTS_MIN_LENGTH: number;
FAILED_ATTEMPTS_MIN_VALUE: number;
} = {
ACCOUNT_LOCK_INCREMENT_FACTOR_MAX_LENGTH: 2,
ACCOUNT_LOCK_INCREMENT_FACTOR_MAX_VALUE: 10,
ACCOUNT_LOCK_INCREMENT_FACTOR_MIN_LENGTH: 1,
ACCOUNT_LOCK_INCREMENT_FACTOR_MIN_VALUE: 1,
ACCOUNT_LOCK_TIME_MAX_LENGTH: 4,
ACCOUNT_LOCK_TIME_MAX_VALUE: 1440,
ACCOUNT_LOCK_TIME_MIN_LENGTH: 1,
ACCOUNT_LOCK_TIME_MIN_VALUE: 1,
FAILED_ATTEMPTS_MAX_LENGTH: 2,
FAILED_ATTEMPTS_MAX_VALUE: 10,
FAILED_ATTEMPTS_MIN_LENGTH: 1,
FAILED_ATTEMPTS_MIN_VALUE: 1
};
ACCOUNT_LOCK_INCREMENT_FACTOR_MAX_LENGTH: 2,
ACCOUNT_LOCK_INCREMENT_FACTOR_MAX_VALUE: 10,
ACCOUNT_LOCK_INCREMENT_FACTOR_MIN_LENGTH: 1,
ACCOUNT_LOCK_INCREMENT_FACTOR_MIN_VALUE: 1,
ACCOUNT_LOCK_TIME_MAX_LENGTH: 4,
ACCOUNT_LOCK_TIME_MAX_VALUE: 1440,
ACCOUNT_LOCK_TIME_MIN_LENGTH: 1,
ACCOUNT_LOCK_TIME_MIN_VALUE: 1,
FAILED_ATTEMPTS_MAX_LENGTH: 2,
FAILED_ATTEMPTS_MAX_VALUE: 10,
FAILED_ATTEMPTS_MIN_LENGTH: 1,
FAILED_ATTEMPTS_MIN_VALUE: 1
};

/**
* Password Expiry Form element constraints.
Expand All @@ -136,20 +136,33 @@ export class GovernanceConnectorConstants {
EXPIRY_RULES_MAX_COUNT: number;
EXPIRY_RULE_MAX_VALUES_PER_RULE: number;
} = {
EXPIRY_RULES_MAX_COUNT: 10,
EXPIRY_RULE_MAX_VALUES_PER_RULE: 5,
EXPIRY_TIME_MAX_LENGTH: 5,
EXPIRY_TIME_MAX_VALUE: 10080,
EXPIRY_TIME_MIN_LENGTH: 1,
EXPIRY_TIME_MIN_VALUE: 1
};
EXPIRY_RULES_MAX_COUNT: 10,
EXPIRY_RULE_MAX_VALUES_PER_RULE: 5,
EXPIRY_TIME_MAX_LENGTH: 5,
EXPIRY_TIME_MAX_VALUE: 10080,
EXPIRY_TIME_MIN_LENGTH: 1,
EXPIRY_TIME_MIN_VALUE: 1
};

/**
* Analytics Form element constraints.
*/
public static readonly ANALYTICS_FORM_FIELD_CONSTRAINTS: {
TIMEOUT_MIN_LENGTH: number;
} = {
TIMEOUT_MIN_LENGTH: 0
};
TIMEOUT_MIN_LENGTH: 0
};

public static readonly FORCED_PASSWORD_RESET_FORM_FIELD_CONSTRAINTS: {

EXPIRY_TIME_MAX_LENGTH: number;
EXPIRY_TIME_MAX_VALUE: number;
EXPIRY_TIME_MIN_LENGTH: number;
EXPIRY_TIME_MIN_VALUE: number;
} = {
EXPIRY_TIME_MAX_LENGTH: 5,
EXPIRY_TIME_MAX_VALUE: 10080,
EXPIRY_TIME_MIN_LENGTH: 1,
EXPIRY_TIME_MIN_VALUE: 1
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -377,9 +377,10 @@ export class ServerConfigurationsConstants {
*/
public static readonly ACCOUNT_MANAGEMENT_CATEGORY_ID: string = "QWNjb3VudCBNYW5hZ2VtZW50";
public static readonly ADMIN_FORCE_PASSWORD_RESET_CONNECTOR_ID: string = "YWRtaW4tZm9yY2VkLXBhc3N3b3JkLXJlc2V0";
public static readonly RECOVERY_LINK_PASSWORD_RESET: string = "Recovery.AdminPasswordReset.RecoveryLink";
public static readonly OTP_PASSWORD_RESET: string = "Recovery.AdminPasswordReset.OTP";
public static readonly OFFLINE_PASSWORD_RESET: string = "Recovery.AdminPasswordReset.Offline";
public static readonly ADMIN_FORCE_PASSWORD_RESET_EMAIL_LINK: string = "Recovery.AdminPasswordReset.RecoveryLink";
public static readonly ADMIN_FORCE_PASSWORD_RESET_EMAIL_OTP: string = "Recovery.AdminPasswordReset.OTP";
public static readonly ADMIN_FORCE_PASSWORD_RESET_SMS_OTP: string = "Recovery.AdminPasswordReset.SMSOTP";
public static readonly ADMIN_FORCE_PASSWORD_RESET_OFFLINE: string = "Recovery.AdminPasswordReset.Offline";
public static readonly ADMIN_FORCED_PASSWORD_RESET_EXPIRY_TIME: string = "Recovery.AdminPasswordReset.ExpiryTime";

public static readonly MULTI_ATTRIBUTE_CLAIM_LIST: string = "account-multiattributelogin-handler-allowedattributes";
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/**
* Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com).
*
* WSO2 LLC. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

.connector-form.admin-forced-password-reset-form {
.sub-header {
margin-bottom: 10px;
margin-top: 10px;
}
.radio {
margin-bottom: 7px;
}
}
Loading
Loading