Skip to content

Commit 417119a

Browse files
Merge pull request #7995 from Malith-19/force-password-reset-config-page-update
Update the force password reset config page with new configurations.
2 parents be93278 + 414ada5 commit 417119a

15 files changed

+682
-312
lines changed

.changeset/thirty-buttons-do.md

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
"@wso2is/admin.server-configurations.v1": minor
3+
"@wso2is/admin.users.v1": minor
4+
"@wso2is/console": minor
5+
---
6+
7+
Update the forced password reset configuration page and force password reset modal message to support email Link and email OTP.

apps/console/src/extensions/i18n/models/extensions.ts

+30-1
Original file line numberDiff line numberDiff line change
@@ -2876,6 +2876,31 @@ export interface Extensions {
28762876
recoveryOptionHeading: string;
28772877
},
28782878
heading: string;
2879+
};
2880+
forcedPasswordRecovery: {
2881+
form: {
2882+
fields: {
2883+
enableEmailLinkBasedReset: {
2884+
label: string;
2885+
},
2886+
enableEmailOTPBasedReset: {
2887+
label: string;
2888+
},
2889+
enableSMSOTPBasedReset: {
2890+
label: string;
2891+
},
2892+
expiryTime: {
2893+
label: string;
2894+
hint: string;
2895+
placeholder: string;
2896+
}
2897+
},
2898+
heading: {
2899+
label: string;
2900+
hint: string;
2901+
}
2902+
subheading: string;
2903+
}
28792904
}
28802905
};
28812906
accountSecurity: {
@@ -3123,7 +3148,11 @@ export interface Extensions {
31233148
resetPassword: {
31243149
changePasswordModal: {
31253150
emailUnavailableWarning: string;
3126-
emailResetWarning: string;
3151+
emailResetWarning: {
3152+
emailLink: string;
3153+
emailOTP: string;
3154+
smsOTP: string;
3155+
}
31273156
passwordResetConfigDisabled: string;
31283157
};
31293158
};

apps/console/src/extensions/i18n/resources/en-US/extensions.ts

+32-1
Original file line numberDiff line numberDiff line change
@@ -3355,6 +3355,31 @@ export const extensions: Extensions = {
33553355
},
33563356
heading: "Enable self-service username recovery for users on the login page."
33573357
},
3358+
forcedPasswordRecovery: {
3359+
form: {
3360+
fields: {
3361+
enableEmailLinkBasedReset: {
3362+
label: "Email Link"
3363+
},
3364+
enableEmailOTPBasedReset: {
3365+
label: "Email OTP"
3366+
},
3367+
enableSMSOTPBasedReset: {
3368+
label: "SMS OTP"
3369+
},
3370+
expiryTime: {
3371+
label: "Reset link/OTP expiry time",
3372+
hint: "Password Reset Link/OTP expiry time in minutes.",
3373+
placeholder: "Enter expiry time"
3374+
}
3375+
},
3376+
heading: {
3377+
label: "Enable password reset via recovery Email",
3378+
hint: "User gets notified with a link/OTP to reset password."
3379+
},
3380+
subheading: "Choose password reset option"
3381+
}
3382+
},
33583383
subHeading: "Account Recovery related settings."
33593384
},
33603385
accountSecurity: {
@@ -3709,8 +3734,14 @@ export const extensions: Extensions = {
37093734
changePasswordModal: {
37103735
emailUnavailableWarning: "WARNING: Cannot find an email address for the user account." +
37113736
"Please provide an email address to proceed with inviting the user to reset the password.",
3712-
emailResetWarning: "An email with a link to reset the password will be sent to the provided " +
3737+
emailResetWarning: {
3738+
emailLink: "An email with a link to reset the password will be sent to the provided " +
3739+
"email address for the user to set their own password.",
3740+
emailOTP: "An email with a OTP to reset the password will be sent to the provided " +
37133741
"email address for the user to set their own password.",
3742+
smsOTP: "An SMS with a OTP to reset the password will be sent to the provided " +
3743+
"mobile number for the user to set their own password."
3744+
},
37143745
passwordResetConfigDisabled: "Password reset via recovery email is not enabled. Please make " +
37153746
"sure to enable it from <1> " +
37163747
" Login and Registration </1> configurations."

apps/console/src/public/deployment.config.json

+10
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,16 @@
168168
"description": "This SMS is sent to verify the user's mobile number after an update.",
169169
"displayName": "Verify Mobile On Update",
170170
"id": "dmVyaWZ5TW9iaWxlT25VcGRhdGU"
171+
},
172+
{
173+
"description": "This SMS is sent to provide a one-time password when admin initiates a password reset for a user",
174+
"displayName": "Admin forced Password Reset",
175+
"id": "YWRtaW5Gb3JjZWRQYXNzd29yZFJlc2V0"
176+
},
177+
{
178+
"description": "This SMS is sent to provide a one-time password when admin resends a password reset request",
179+
"displayName": "Admin Resent Password Reset",
180+
"id": "cmVzZW5kQWRtaW5Gb3JjZWRQYXNzd29yZFJlc2V0"
171181
}
172182
]
173183
},
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/**
2+
* Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com).
3+
*
4+
* WSO2 LLC. licenses this file to you under the Apache License,
5+
* Version 2.0 (the "License"); you may not use this file except
6+
* in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing,
12+
* software distributed under the License is distributed on an
13+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
* KIND, either express or implied. See the License for the
15+
* specific language governing permissions and limitations
16+
* under the License.
17+
*/
18+
19+
import { ServerConfigurationsConstants } from "./server-configurations-constants";
20+
21+
export class AdminForcedPasswordResetFormConstants {
22+
23+
/**
24+
* Private constructor to avoid object instantiation from outside the class.
25+
*
26+
*/
27+
/* eslint-disable @typescript-eslint/no-empty-function */
28+
private constructor() { }
29+
30+
public static readonly allowedConnectorFields: string[] = [
31+
ServerConfigurationsConstants.ADMIN_FORCE_PASSWORD_RESET_EMAIL_LINK,
32+
ServerConfigurationsConstants.ADMIN_FORCE_PASSWORD_RESET_EMAIL_OTP,
33+
ServerConfigurationsConstants.ADMIN_FORCE_PASSWORD_RESET_SMS_OTP,
34+
ServerConfigurationsConstants.ADMIN_FORCED_PASSWORD_RESET_EXPIRY_TIME
35+
];
36+
}
37+

features/admin.server-configurations.v1/constants/governance-connector-constants.ts

+65-52
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* Copyright (c) 2021-2024, WSO2 LLC. (https://www.wso2.com).
2+
* Copyright (c) 2021-2025, WSO2 LLC. (https://www.wso2.com).
33
*
44
* WSO2 LLC. licenses this file to you under the Apache License,
55
* Version 2.0 (the "License"); you may not use this file except
@@ -30,11 +30,11 @@ export class GovernanceConnectorConstants {
3030
EXPIRY_TIME_MIN_LENGTH: number;
3131
EXPIRY_TIME_MIN_VALUE: number;
3232
} = {
33-
EXPIRY_TIME_MAX_LENGTH: 5,
34-
EXPIRY_TIME_MAX_VALUE: 10080,
35-
EXPIRY_TIME_MIN_LENGTH: 1,
36-
EXPIRY_TIME_MIN_VALUE: -1
37-
};
33+
EXPIRY_TIME_MAX_LENGTH: 5,
34+
EXPIRY_TIME_MAX_VALUE: 10080,
35+
EXPIRY_TIME_MIN_LENGTH: 1,
36+
EXPIRY_TIME_MIN_VALUE: -1
37+
};
3838

3939
/**
4040
* Self Registration Form element constraints.
@@ -45,11 +45,11 @@ export class GovernanceConnectorConstants {
4545
EXPIRY_TIME_MIN_LENGTH: number;
4646
EXPIRY_TIME_MIN_VALUE: number;
4747
} = {
48-
EXPIRY_TIME_MAX_LENGTH: 5,
49-
EXPIRY_TIME_MAX_VALUE: 10080,
50-
EXPIRY_TIME_MIN_LENGTH: 1,
51-
EXPIRY_TIME_MIN_VALUE: 1
52-
};
48+
EXPIRY_TIME_MAX_LENGTH: 5,
49+
EXPIRY_TIME_MAX_VALUE: 10080,
50+
EXPIRY_TIME_MIN_LENGTH: 1,
51+
EXPIRY_TIME_MIN_VALUE: 1
52+
};
5353

5454
/**
5555
* Password Recovery Form element constraints.
@@ -74,25 +74,25 @@ export class GovernanceConnectorConstants {
7474
SMS_OTP_CODE_LENGTH_MIN_LENGTH: number;
7575
SMS_OTP_CODE_LENGTH_MIN_VALUE: number;
7676
} = {
77-
EXPIRY_TIME_MAX_LENGTH: 5,
78-
EXPIRY_TIME_MAX_VALUE: 10080,
79-
EXPIRY_TIME_MIN_LENGTH: 1,
80-
EXPIRY_TIME_MIN_VALUE: 1,
81-
MAX_FAILED_ATTEMPT_COUNT_MAX_LENGTH: 2,
82-
MAX_FAILED_ATTEMPT_COUNT_MAX_VALUE: 10,
83-
MAX_FAILED_ATTEMPT_COUNT_MIN_LENGTH: 1,
84-
MAX_FAILED_ATTEMPT_COUNT_MIN_VALUE: 1,
85-
MAX_RESEND_COUNT_MAX_LENGTH: 1,
86-
MAX_RESEND_COUNT_MAX_VALUE: 5,
87-
MAX_RESEND_COUNT_MIN_LENGTH: 1,
88-
MAX_RESEND_COUNT_MIN_VALUE: 1,
89-
SMS_OTP_CODE_LENGTH_MAX_LENGTH: 2,
90-
SMS_OTP_CODE_LENGTH_MAX_VALUE: 10,
91-
SMS_OTP_CODE_LENGTH_MIN_LENGTH: 1,
92-
SMS_OTP_CODE_LENGTH_MIN_VALUE: 4,
93-
SMS_OTP_EXPIRY_TIME_MAX_LENGTH: 4,
94-
SMS_OTP_EXPIRY_TIME_MAX_VALUE: 1440
95-
};
77+
EXPIRY_TIME_MAX_LENGTH: 5,
78+
EXPIRY_TIME_MAX_VALUE: 10080,
79+
EXPIRY_TIME_MIN_LENGTH: 1,
80+
EXPIRY_TIME_MIN_VALUE: 1,
81+
MAX_FAILED_ATTEMPT_COUNT_MAX_LENGTH: 2,
82+
MAX_FAILED_ATTEMPT_COUNT_MAX_VALUE: 10,
83+
MAX_FAILED_ATTEMPT_COUNT_MIN_LENGTH: 1,
84+
MAX_FAILED_ATTEMPT_COUNT_MIN_VALUE: 1,
85+
MAX_RESEND_COUNT_MAX_LENGTH: 1,
86+
MAX_RESEND_COUNT_MAX_VALUE: 5,
87+
MAX_RESEND_COUNT_MIN_LENGTH: 1,
88+
MAX_RESEND_COUNT_MIN_VALUE: 1,
89+
SMS_OTP_CODE_LENGTH_MAX_LENGTH: 2,
90+
SMS_OTP_CODE_LENGTH_MAX_VALUE: 10,
91+
SMS_OTP_CODE_LENGTH_MIN_LENGTH: 1,
92+
SMS_OTP_CODE_LENGTH_MIN_VALUE: 4,
93+
SMS_OTP_EXPIRY_TIME_MAX_LENGTH: 4,
94+
SMS_OTP_EXPIRY_TIME_MAX_VALUE: 1440
95+
};
9696

9797
/**
9898
* Login Attempt Security Form element constraints.
@@ -111,19 +111,19 @@ export class GovernanceConnectorConstants {
111111
FAILED_ATTEMPTS_MIN_LENGTH: number;
112112
FAILED_ATTEMPTS_MIN_VALUE: number;
113113
} = {
114-
ACCOUNT_LOCK_INCREMENT_FACTOR_MAX_LENGTH: 2,
115-
ACCOUNT_LOCK_INCREMENT_FACTOR_MAX_VALUE: 10,
116-
ACCOUNT_LOCK_INCREMENT_FACTOR_MIN_LENGTH: 1,
117-
ACCOUNT_LOCK_INCREMENT_FACTOR_MIN_VALUE: 1,
118-
ACCOUNT_LOCK_TIME_MAX_LENGTH: 4,
119-
ACCOUNT_LOCK_TIME_MAX_VALUE: 1440,
120-
ACCOUNT_LOCK_TIME_MIN_LENGTH: 1,
121-
ACCOUNT_LOCK_TIME_MIN_VALUE: 1,
122-
FAILED_ATTEMPTS_MAX_LENGTH: 2,
123-
FAILED_ATTEMPTS_MAX_VALUE: 10,
124-
FAILED_ATTEMPTS_MIN_LENGTH: 1,
125-
FAILED_ATTEMPTS_MIN_VALUE: 1
126-
};
114+
ACCOUNT_LOCK_INCREMENT_FACTOR_MAX_LENGTH: 2,
115+
ACCOUNT_LOCK_INCREMENT_FACTOR_MAX_VALUE: 10,
116+
ACCOUNT_LOCK_INCREMENT_FACTOR_MIN_LENGTH: 1,
117+
ACCOUNT_LOCK_INCREMENT_FACTOR_MIN_VALUE: 1,
118+
ACCOUNT_LOCK_TIME_MAX_LENGTH: 4,
119+
ACCOUNT_LOCK_TIME_MAX_VALUE: 1440,
120+
ACCOUNT_LOCK_TIME_MIN_LENGTH: 1,
121+
ACCOUNT_LOCK_TIME_MIN_VALUE: 1,
122+
FAILED_ATTEMPTS_MAX_LENGTH: 2,
123+
FAILED_ATTEMPTS_MAX_VALUE: 10,
124+
FAILED_ATTEMPTS_MIN_LENGTH: 1,
125+
FAILED_ATTEMPTS_MIN_VALUE: 1
126+
};
127127

128128
/**
129129
* Password Expiry Form element constraints.
@@ -136,20 +136,33 @@ export class GovernanceConnectorConstants {
136136
EXPIRY_RULES_MAX_COUNT: number;
137137
EXPIRY_RULE_MAX_VALUES_PER_RULE: number;
138138
} = {
139-
EXPIRY_RULES_MAX_COUNT: 10,
140-
EXPIRY_RULE_MAX_VALUES_PER_RULE: 5,
141-
EXPIRY_TIME_MAX_LENGTH: 5,
142-
EXPIRY_TIME_MAX_VALUE: 10080,
143-
EXPIRY_TIME_MIN_LENGTH: 1,
144-
EXPIRY_TIME_MIN_VALUE: 1
145-
};
139+
EXPIRY_RULES_MAX_COUNT: 10,
140+
EXPIRY_RULE_MAX_VALUES_PER_RULE: 5,
141+
EXPIRY_TIME_MAX_LENGTH: 5,
142+
EXPIRY_TIME_MAX_VALUE: 10080,
143+
EXPIRY_TIME_MIN_LENGTH: 1,
144+
EXPIRY_TIME_MIN_VALUE: 1
145+
};
146146

147147
/**
148148
* Analytics Form element constraints.
149149
*/
150150
public static readonly ANALYTICS_FORM_FIELD_CONSTRAINTS: {
151151
TIMEOUT_MIN_LENGTH: number;
152152
} = {
153-
TIMEOUT_MIN_LENGTH: 0
154-
};
153+
TIMEOUT_MIN_LENGTH: 0
154+
};
155+
156+
public static readonly FORCED_PASSWORD_RESET_FORM_FIELD_CONSTRAINTS: {
157+
158+
EXPIRY_TIME_MAX_LENGTH: number;
159+
EXPIRY_TIME_MAX_VALUE: number;
160+
EXPIRY_TIME_MIN_LENGTH: number;
161+
EXPIRY_TIME_MIN_VALUE: number;
162+
} = {
163+
EXPIRY_TIME_MAX_LENGTH: 5,
164+
EXPIRY_TIME_MAX_VALUE: 10080,
165+
EXPIRY_TIME_MIN_LENGTH: 1,
166+
EXPIRY_TIME_MIN_VALUE: 1
167+
};
155168
}

features/admin.server-configurations.v1/constants/server-configurations-constants.ts

+4-3
Original file line numberDiff line numberDiff line change
@@ -377,9 +377,10 @@ export class ServerConfigurationsConstants {
377377
*/
378378
public static readonly ACCOUNT_MANAGEMENT_CATEGORY_ID: string = "QWNjb3VudCBNYW5hZ2VtZW50";
379379
public static readonly ADMIN_FORCE_PASSWORD_RESET_CONNECTOR_ID: string = "YWRtaW4tZm9yY2VkLXBhc3N3b3JkLXJlc2V0";
380-
public static readonly RECOVERY_LINK_PASSWORD_RESET: string = "Recovery.AdminPasswordReset.RecoveryLink";
381-
public static readonly OTP_PASSWORD_RESET: string = "Recovery.AdminPasswordReset.OTP";
382-
public static readonly OFFLINE_PASSWORD_RESET: string = "Recovery.AdminPasswordReset.Offline";
380+
public static readonly ADMIN_FORCE_PASSWORD_RESET_EMAIL_LINK: string = "Recovery.AdminPasswordReset.RecoveryLink";
381+
public static readonly ADMIN_FORCE_PASSWORD_RESET_EMAIL_OTP: string = "Recovery.AdminPasswordReset.OTP";
382+
public static readonly ADMIN_FORCE_PASSWORD_RESET_SMS_OTP: string = "Recovery.AdminPasswordReset.SMSOTP";
383+
public static readonly ADMIN_FORCE_PASSWORD_RESET_OFFLINE: string = "Recovery.AdminPasswordReset.Offline";
383384
public static readonly ADMIN_FORCED_PASSWORD_RESET_EXPIRY_TIME: string = "Recovery.AdminPasswordReset.ExpiryTime";
384385

385386
public static readonly MULTI_ATTRIBUTE_CLAIM_LIST: string = "account-multiattributelogin-handler-allowedattributes";
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/**
2+
* Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com).
3+
*
4+
* WSO2 LLC. licenses this file to you under the Apache License,
5+
* Version 2.0 (the "License"); you may not use this file except
6+
* in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing,
12+
* software distributed under the License is distributed on an
13+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
* KIND, either express or implied. See the License for the
15+
* specific language governing permissions and limitations
16+
* under the License.
17+
*/
18+
19+
.connector-form.admin-forced-password-reset-form {
20+
.sub-header {
21+
margin-bottom: 10px;
22+
margin-top: 10px;
23+
}
24+
.radio {
25+
margin-bottom: 7px;
26+
}
27+
}

0 commit comments

Comments
 (0)