Fix password policy validation messages to support localization in Flow Builder UI#10358
Fix password policy validation messages to support localization in Flow Builder UI#10358Thisara-Welmilla wants to merge 2 commits into
Conversation
📝 WalkthroughWalkthroughAdds i18n support for validation criteria by introducing an interpolate utility, extracting a reusable rule checker, mapping rules to translation keys, updating ValidationCriteria to render translated labels and use the checker, wiring the password adapter, and adding English translation entries. ChangesValidation Criteria Localization
Suggested reviewers
Important Pre-merge checks failedPlease resolve all errors before merging. Addressing warnings is optional. ❌ Failed checks (1 error)
✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
⚔️ Resolve merge conflicts
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In
`@identity-apps-core/react-ui-core/src/components/adapters/password-field-adapter.js`:
- Around line 100-104: The confirm-password ValidationCriteria is comparing
against the local password state which is never populated, so change the
compareValue passed to ValidationCriteria from the unused local variable
password to the form state's password (e.g. formState.values.password or the
variable derived from formState used elsewhere in this component) so
CONFIRM_PASSWORD_RULE compares against the actual form value and the
icon/validation reflects the real field validity for confirmPassword.
In `@identity-apps-core/react-ui-core/src/hooks/use-field-validations.js`:
- Around line 39-179: checkValidationRule currently lacks handling for
UniqueCharacterValidator and RepeatedCharacterValidator so those rules never
produce errors; add two switch cases in checkValidationRule: implement a
UniqueCharacterValidator branch that reads the numeric condition (e.g.,
getNumCondition(conditions, "min.unique")) and counts distinct characters in
value (new Set(value).size) and returns an appropriate message when distinct
count is below the threshold, and implement a RepeatedCharacterValidator branch
that reads the numeric condition (e.g., getNumCondition(conditions,
"max.repeated")) and ensures no single character repeats more than that limit
(compute frequency map and check max frequency), returning a descriptive error
when violated; place these cases alongside the other validators (e.g., with the
same return style) so validate() emits errors for those rules.
- Around line 19-21: The file use-field-validations.js contains smart quotes (“
” and possibly ‘ ’) which break parsing; replace all smart-quote characters in
imports, switch-case labels, string literals and anywhere in the module with
standard ASCII quotes (double " or single ') so imports like import {
DEFAULT_ALPHANUMERIC_REGEX, DEFAULT_EMAIL_REGEX } from
"../constants/validation-constants"; and uses of validateWithRegex and any
switch/case string labels use ASCII quotes; run a quick project-wide
search/replace for “ and ” (and ‘ ’) and then run the linter/tests to confirm
the module parses and validation functions (e.g., validateWithRegex, the hook in
use-field-validations) load correctly.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yml
Review profile: CHILL
Plan: Pro
Run ID: eea18b48-4229-488a-aa79-4fb013d44adc
📒 Files selected for processing (3)
identity-apps-core/react-ui-core/src/components/adapters/password-field-adapter.jsidentity-apps-core/react-ui-core/src/components/validation-criteria.jsidentity-apps-core/react-ui-core/src/hooks/use-field-validations.js
| <ValidationCriteria | ||
| validationConfig={ CONFIRM_PASSWORD_RULE } | ||
| errors={ confirmPasswordErrors } | ||
| value={ confirmPassword } | ||
| compareValue={ password } | ||
| /> |
There was a problem hiding this comment.
Use the form state's password for the confirm-password criteria.
In the confirm-password adapter instance, local password state never gets populated, so compareValue={ password } is effectively always "". The effect above validates against formState.values.password, so the icon state here can stay red even when the actual field validation passes.
✅ Suggested fix
<ValidationCriteria
validationConfig={ CONFIRM_PASSWORD_RULE }
value={ confirmPassword }
- compareValue={ password }
+ compareValue={ formState.values.password || "" }
/>📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| <ValidationCriteria | |
| validationConfig={ CONFIRM_PASSWORD_RULE } | |
| errors={ confirmPasswordErrors } | |
| value={ confirmPassword } | |
| compareValue={ password } | |
| /> | |
| <ValidationCriteria | |
| validationConfig={ CONFIRM_PASSWORD_RULE } | |
| value={ confirmPassword } | |
| compareValue={ formState.values.password || "" } | |
| /> |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In
`@identity-apps-core/react-ui-core/src/components/adapters/password-field-adapter.js`
around lines 100 - 104, The confirm-password ValidationCriteria is comparing
against the local password state which is never populated, so change the
compareValue passed to ValidationCriteria from the unused local variable
password to the form state's password (e.g. formState.values.password or the
variable derived from formState used elsewhere in this component) so
CONFIRM_PASSWORD_RULE compares against the actual form value and the
icon/validation reflects the real field validity for confirmPassword.
| import { useCallback, useState } from “react”; | ||
| import { DEFAULT_ALPHANUMERIC_REGEX, DEFAULT_EMAIL_REGEX } from “../constants/validation-constants”; | ||
| import { validateWithRegex } from “../utils/validation-utils”; |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -e
python - <<'PY'
from pathlib import Path
path = Path("identity-apps-core/react-ui-core/src/hooks/use-field-validations.js")
for lineno, line in enumerate(path.read_text(encoding="utf-8").splitlines(), 1):
if "“" in line or "”" in line:
print(f"{lineno}: {line}")
PYRepository: wso2/identity-apps
Length of output: 1832
Replace smart quotes with ASCII quotes in use-field-validations.js to prevent parse failures.
identity-apps-core/react-ui-core/src/hooks/use-field-validations.js contains invalid JavaScript smart-quote tokens (“...”) in imports, switch case labels, and string literals (e.g., lines 19-21 and 40-194), so this module will not parse and none of the validation logic will load.
🔧 Minimal fix
-import { useCallback, useState } from “react”;
-import { DEFAULT_ALPHANUMERIC_REGEX, DEFAULT_EMAIL_REGEX } from “../constants/validation-constants”;
-import { validateWithRegex } from “../utils/validation-utils”;
+import { useCallback, useState } from "react";
+import { DEFAULT_ALPHANUMERIC_REGEX, DEFAULT_EMAIL_REGEX } from "../constants/validation-constants";
+import { validateWithRegex } from "../utils/validation-utils";
...
- if (rule.type !== “RULE”) return null;
+ if (rule.type !== "RULE") return null;Also applies to: 19-21 and 40-194
🧰 Tools
🪛 Biome (2.4.16)
[error] 19-19: Unexpected token “
(parse)
[error] 19-19: Unexpected token ”
(parse)
[error] 20-20: Unexpected token “
(parse)
[error] 20-20: Unexpected token ”
(parse)
[error] 21-21: Unexpected token “
(parse)
[error] 21-21: Unexpected token ”
(parse)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@identity-apps-core/react-ui-core/src/hooks/use-field-validations.js` around
lines 19 - 21, The file use-field-validations.js contains smart quotes (“ ” and
possibly ‘ ’) which break parsing; replace all smart-quote characters in
imports, switch-case labels, string literals and anywhere in the module with
standard ASCII quotes (double " or single ') so imports like import {
DEFAULT_ALPHANUMERIC_REGEX, DEFAULT_EMAIL_REGEX } from
"../constants/validation-constants"; and uses of validateWithRegex and any
switch/case string labels use ASCII quotes; run a quick project-wide
search/replace for “ and ” (and ‘ ’) and then run the linter/tests to confirm
the module parses and validation functions (e.g., validateWithRegex, the hook in
use-field-validations) load correctly.
| export const checkValidationRule = (rule, value, compareValue) => { | ||
| if (rule.type !== “RULE”) return null; | ||
|
|
||
| const { name, conditions } = rule; | ||
|
|
||
| switch (name) { | ||
| case “LengthValidator”: { | ||
| const minLen = getNumCondition(conditions, “min.length”); | ||
| const maxLen = getNumCondition(conditions, “max.length”); | ||
|
|
||
| /** | ||
| * Utility: Extract a numeric condition (e.g. "min.length") from the conditions array. | ||
| */ | ||
| const getNumCondition = (conditions = [], conditionKey) => { | ||
| const found = conditions.find(cond => cond.key === conditionKey); | ||
|
|
||
| return found ? parseInt(found.value, 10) : null; | ||
| }; | ||
|
|
||
| /** | ||
| * Utility: Extract a string condition (e.g. "pattern") from the conditions array. | ||
| */ | ||
| const getStrCondition = (conditions = [], conditionKey) => { | ||
| const found = conditions.find(cond => cond.key === conditionKey); | ||
|
|
||
| return found ? found.value : null; | ||
| }; | ||
|
|
||
| /** | ||
| * Validate a single rule object (e.g. { type: "RULE", name: "LengthValidator", conditions: [...] }). | ||
| * Return an error message if invalid, or `null` if valid. | ||
| */ | ||
| const validateRule = useCallback((rule, value, compareValue) => { | ||
| if (rule.type !== "RULE") return null; | ||
|
|
||
| const { name, conditions } = rule; | ||
|
|
||
| switch (name) { | ||
| case "LengthValidator": { | ||
| const minLen = getNumCondition(conditions, "min.length"); | ||
| const maxLen = getNumCondition(conditions, "max.length"); | ||
|
|
||
| if (minLen && maxLen) { | ||
| if (value.length < minLen || value.length > maxLen) { | ||
| return `Must be between ${minLen} and ${maxLen} characters long.`; | ||
| } | ||
| if (minLen && maxLen) { | ||
| if (value.length < minLen || value.length > maxLen) { | ||
| return `Must be between ${minLen} and ${maxLen} characters long.`; | ||
| } | ||
| else if (minLen) { | ||
| if (value.length < minLen) { | ||
| return `Must be at least ${minLen} characters long.`; | ||
| } | ||
| } else if (minLen) { | ||
| if (value.length < minLen) { | ||
| return `Must be at least ${minLen} characters long.`; | ||
| } | ||
| else if (maxLen) { | ||
| if (value.length > maxLen) { | ||
| return `Must be at most ${maxLen} characters long.`; | ||
| } | ||
| } else if (maxLen) { | ||
| if (value.length > maxLen) { | ||
| return `Must be at most ${maxLen} characters long.`; | ||
| } | ||
|
|
||
| break; | ||
| } | ||
|
|
||
| case "NumeralValidator": { | ||
| const minNumbers = getNumCondition(conditions, "min.length"); | ||
| break; | ||
| } | ||
|
|
||
| if (minNumbers) { | ||
| const digitCount = (value.match(/\d/g) || []).length; | ||
| case “NumeralValidator”: { | ||
| const minNumbers = getNumCondition(conditions, “min.length”); | ||
|
|
||
| if (digitCount < minNumbers) { | ||
| return `Must contain at least ${minNumbers} number(s).`; | ||
| } | ||
| } | ||
| if (minNumbers) { | ||
| const digitCount = (value.match(/\d/g) || []).length; | ||
|
|
||
| break; | ||
| if (digitCount < minNumbers) { | ||
| return `Must contain at least ${minNumbers} number(s).`; | ||
| } | ||
| } | ||
|
|
||
| case "UpperCaseValidator": { | ||
| const minUpper = getNumCondition(conditions, "min.length"); | ||
| break; | ||
| } | ||
|
|
||
| if (minUpper) { | ||
| const upperCount = (value.match(/[A-Z]/g) || []).length; | ||
| case “UpperCaseValidator”: { | ||
| const minUpper = getNumCondition(conditions, “min.length”); | ||
|
|
||
| if (upperCount < minUpper) { | ||
| return `Must contain at least ${minUpper} uppercase letter(s).`; | ||
| } | ||
| } | ||
| if (minUpper) { | ||
| const upperCount = (value.match(/[A-Z]/g) || []).length; | ||
|
|
||
| break; | ||
| if (upperCount < minUpper) { | ||
| return `Must contain at least ${minUpper} uppercase letter(s).`; | ||
| } | ||
| } | ||
|
|
||
| case "LowerCaseValidator": { | ||
| const minLower = getNumCondition(conditions, "min.length"); | ||
| break; | ||
| } | ||
|
|
||
| if (minLower) { | ||
| const lowerCount = (value.match(/[a-z]/g) || []).length; | ||
| case “LowerCaseValidator”: { | ||
| const minLower = getNumCondition(conditions, “min.length”); | ||
|
|
||
| if (lowerCount < minLower) { | ||
| return `Must contain at least ${minLower} lowercase letter(s).`; | ||
| } | ||
| } | ||
| if (minLower) { | ||
| const lowerCount = (value.match(/[a-z]/g) || []).length; | ||
|
|
||
| break; | ||
| if (lowerCount < minLower) { | ||
| return `Must contain at least ${minLower} lowercase letter(s).`; | ||
| } | ||
| } | ||
|
|
||
| case "SpecialCharacterValidator": { | ||
| const minSpecial = getNumCondition(conditions, "min.length"); | ||
| break; | ||
| } | ||
|
|
||
| case “SpecialCharacterValidator”: { | ||
| const minSpecial = getNumCondition(conditions, “min.length”); | ||
|
|
||
| if (minSpecial && minSpecial > 0) { | ||
| const specialCount = (value.match(/[^a-zA-Z0-9]/g) || []).length; | ||
| if (minSpecial && minSpecial > 0) { | ||
| const specialCount = (value.match(/[^a-zA-Z0-9]/g) || []).length; | ||
|
|
||
| if (specialCount < minSpecial) { | ||
| return `Must contain at least ${minSpecial} special character(s).`; | ||
| } | ||
| if (specialCount < minSpecial) { | ||
| return `Must contain at least ${minSpecial} special character(s).`; | ||
| } | ||
|
|
||
| break; | ||
| } | ||
|
|
||
| case "RegexValidator": { | ||
| const pattern = getStrCondition(conditions, "pattern"); | ||
| break; | ||
| } | ||
|
|
||
| case “RegexValidator”: { | ||
| const pattern = getStrCondition(conditions, “pattern”); | ||
|
|
||
| if (pattern) { | ||
| const re = new RegExp(pattern); | ||
| if (pattern) { | ||
| const re = new RegExp(pattern); | ||
|
|
||
| if (!re.test(value)) { | ||
| return "Invalid format."; | ||
| } | ||
| if (!re.test(value)) { | ||
| return “Invalid format.”; | ||
| } | ||
|
|
||
| break; | ||
| } | ||
|
|
||
| case "PhoneNumberValidator": { | ||
| const pattern = getStrCondition(conditions, "pattern"); | ||
| break; | ||
| } | ||
|
|
||
| case “PhoneNumberValidator”: { | ||
| const pattern = getStrCondition(conditions, “pattern”); | ||
|
|
||
| if (pattern) { | ||
| const re = new RegExp(pattern); | ||
| if (pattern) { | ||
| const re = new RegExp(pattern); | ||
|
|
||
| if (!re.test(value)) { | ||
| return "Please enter a valid phone number."; | ||
| } | ||
| if (!re.test(value)) { | ||
| return “Please enter a valid phone number.”; | ||
| } | ||
|
|
||
| break; | ||
| } | ||
|
|
||
| case "ConfirmPasswordValidator": { | ||
| if (value !== compareValue) { | ||
| return "Must match with the password."; | ||
| } | ||
| break; | ||
| } | ||
|
|
||
| break; | ||
| case “ConfirmPasswordValidator”: { | ||
| if (value !== compareValue) { | ||
| return “Must match with the password.”; | ||
| } | ||
|
|
||
| case "EmailFormatValidator": { | ||
| if (!validateWithRegex(value, DEFAULT_EMAIL_REGEX)) { | ||
| return "Must use a valid email address."; | ||
| } | ||
| break; | ||
| } | ||
|
|
||
| break; | ||
| case “EmailFormatValidator”: { | ||
| if (!validateWithRegex(value, DEFAULT_EMAIL_REGEX)) { | ||
| return “Must use a valid email address.”; | ||
| } | ||
|
|
||
| case "AlphanumericValidator": { | ||
| if (!validateWithRegex(value, DEFAULT_ALPHANUMERIC_REGEX)) { | ||
| return "Must contain only alphanumeric characters."; | ||
| } | ||
| break; | ||
| } | ||
|
|
||
| break; | ||
| case “AlphanumericValidator”: { | ||
| if (!validateWithRegex(value, DEFAULT_ALPHANUMERIC_REGEX)) { | ||
| return “Must contain only alphanumeric characters.”; | ||
| } | ||
|
|
||
| default: | ||
| return null; | ||
| break; | ||
| } | ||
|
|
||
| return null; | ||
| }, []); | ||
| default: | ||
| return null; | ||
| } | ||
|
|
||
| return null; | ||
| }; |
There was a problem hiding this comment.
Implement the unique/repeated character validators in the shared checker.
identity-apps-core/react-ui-core/src/components/validation-criteria.js now treats UniqueCharacterValidator and RepeatedCharacterValidator as active rules and renders labels for them, but this switch still falls through to default for both. That means validate() never emits those errors, and the criteria icon will go green even when the password still violates those policies.
🧩 Suggested coverage for the missing branches
case "AlphanumericValidator": {
if (!validateWithRegex(value, DEFAULT_ALPHANUMERIC_REGEX)) {
return "Must contain only alphanumeric characters.";
}
break;
}
+
+ case "UniqueCharacterValidator": {
+ const minUniqueChars = getNumCondition(conditions, "min.unique.character");
+
+ if (minUniqueChars != null) {
+ const uniqueCount = new Set(value.split("")).size;
+
+ if (uniqueCount < minUniqueChars) {
+ return `Must contain at least ${minUniqueChars} unique character(s).`;
+ }
+ }
+
+ break;
+ }
+
+ case "RepeatedCharacterValidator": {
+ const maxRepeatedChars = getNumCondition(conditions, "max.consecutive.character");
+
+ if (maxRepeatedChars != null) {
+ let longestRun = 0;
+ let currentRun = 0;
+ let previousChar = null;
+
+ for (const char of value) {
+ currentRun = char === previousChar ? currentRun + 1 : 1;
+ previousChar = char;
+ longestRun = Math.max(longestRun, currentRun);
+ }
+
+ if (longestRun > maxRepeatedChars) {
+ return `Must not contain more than ${maxRepeatedChars} repeated character(s).`;
+ }
+ }
+
+ break;
+ }🧰 Tools
🪛 Biome (2.4.16)
[error] 40-40: Unexpected token “
(parse)
[error] 40-40: expected ) but instead found RULE
(parse)
[error] 40-40: Unexpected token ”
(parse)
[error] 45-45: Unexpected token “
(parse)
[error] 45-45: expected : but instead found LengthValidator
(parse)
[error] 45-45: Unexpected token ”
(parse)
[error] 46-46: Unexpected token “
(parse)
[error] 46-46: expected , but instead found min
(parse)
[error] 46-46: Unexpected token ”
(parse)
[error] 47-47: Unexpected token “
(parse)
[error] 47-47: expected , but instead found max
(parse)
[error] 47-47: Unexpected token ”
(parse)
[error] 66-66: Unexpected token “
(parse)
[error] 66-66: expected : but instead found NumeralValidator
(parse)
[error] 66-66: Unexpected token ”
(parse)
[error] 67-67: Unexpected token “
(parse)
[error] 67-67: expected , but instead found min
(parse)
[error] 67-67: Unexpected token ”
(parse)
[error] 80-80: Unexpected token “
(parse)
[error] 80-80: expected : but instead found UpperCaseValidator
(parse)
[error] 80-80: Unexpected token ”
(parse)
[error] 81-81: Unexpected token “
(parse)
[error] 81-81: expected , but instead found min
(parse)
[error] 81-81: Unexpected token ”
(parse)
[error] 94-94: Unexpected token “
(parse)
[error] 94-94: expected : but instead found LowerCaseValidator
(parse)
[error] 94-94: Unexpected token ”
(parse)
[error] 95-95: Unexpected token “
(parse)
[error] 95-95: expected , but instead found min
(parse)
[error] 95-95: Unexpected token ”
(parse)
[error] 108-108: Unexpected token “
(parse)
[error] 108-108: expected : but instead found SpecialCharacterValidator
(parse)
[error] 108-108: Unexpected token ”
(parse)
[error] 109-109: Unexpected token “
(parse)
[error] 109-109: expected , but instead found min
(parse)
[error] 109-109: Unexpected token ”
(parse)
[error] 122-122: Unexpected token “
(parse)
[error] 122-122: expected : but instead found RegexValidator
(parse)
[error] 122-122: Unexpected token ”
(parse)
[error] 123-123: Unexpected token “
(parse)
[error] 123-123: expected , but instead found pattern
(parse)
[error] 123-123: Unexpected token ”
(parse)
[error] 129-129: Unexpected token “
(parse)
[error] 129-129: Expected a semicolon or an implicit semicolon after a statement, but found none
(parse)
[error] 129-129: Expected a semicolon or an implicit semicolon after a statement, but found none
(parse)
[error] 129-129: Unexpected token ”
(parse)
[error] 136-136: Unexpected token “
(parse)
[error] 136-136: expected : but instead found PhoneNumberValidator
(parse)
[error] 136-136: Unexpected token ”
(parse)
[error] 137-137: Unexpected token “
(parse)
[error] 137-137: expected , but instead found pattern
(parse)
[error] 137-137: Unexpected token ”
(parse)
[error] 143-143: Unexpected token “
(parse)
[error] 143-143: Expected a semicolon or an implicit semicolon after a statement, but found none
(parse)
[error] 143-143: Expected a semicolon or an implicit semicolon after a statement, but found none
(parse)
[error] 143-143: Expected a semicolon or an implicit semicolon after a statement, but found none
(parse)
[error] 143-143: Expected a semicolon or an implicit semicolon after a statement, but found none
(parse)
[error] 143-143: Expected a semicolon or an implicit semicolon after a statement, but found none
(parse)
[error] 143-143: Expected a semicolon or an implicit semicolon after a statement, but found none
(parse)
[error] 143-143: Unexpected token ”
(parse)
[error] 150-150: Unexpected token “
(parse)
[error] 150-150: expected : but instead found ConfirmPasswordValidator
(parse)
[error] 150-150: Unexpected token ”
(parse)
[error] 152-152: Unexpected token “
(parse)
[error] 152-152: Expected a semicolon or an implicit semicolon after a statement, but found none
(parse)
[error] 152-152: Expected a semicolon or an implicit semicolon after a statement, but found none
(parse)
[error] 152-152: Expected a semicolon or an implicit semicolon after a statement, but found none
(parse)
[error] 152-152: expected ( but instead found the
(parse)
[error] 152-152: expected ) but instead found password
(parse)
[error] 152-152: with statements are not allowed in strict mode
(parse)
[error] 152-152: Unexpected token ”
(parse)
[error] 158-158: Unexpected token “
(parse)
[error] 158-158: expected : but instead found EmailFormatValidator
(parse)
[error] 158-158: Unexpected token ”
(parse)
[error] 160-160: Unexpected token “
(parse)
[error] 160-160: Expected a semicolon or an implicit semicolon after a statement, but found none
(parse)
[error] 160-160: Expected a semicolon or an implicit semicolon after a statement, but found none
(parse)
[error] 160-160: Expected a semicolon or an implicit semicolon after a statement, but found none
(parse)
[error] 160-160: Expected a semicolon or an implicit semicolon after a statement, but found none
(parse)
[error] 160-160: Expected a semicolon or an implicit semicolon after a statement, but found none
(parse)
[error] 160-160: Expected a semicolon or an implicit semicolon after a statement, but found none
(parse)
[error] 160-160: Unexpected token ”
(parse)
[error] 166-166: Unexpected token “
(parse)
[error] 166-166: expected : but instead found AlphanumericValidator
(parse)
[error] 166-166: Unexpected token ”
(parse)
[error] 168-168: Unexpected token “
(parse)
[error] 168-168: Expected a semicolon or an implicit semicolon after a statement, but found none
(parse)
[error] 168-168: Expected a semicolon or an implicit semicolon after a statement, but found none
(parse)
[error] 168-168: Expected a semicolon or an implicit semicolon after a statement, but found none
(parse)
[error] 168-168: Expected a semicolon or an implicit semicolon after a statement, but found none
(parse)
[error] 168-168: Expected a semicolon or an implicit semicolon after a statement, but found none
(parse)
[error] 168-168: Unexpected token ”
(parse)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@identity-apps-core/react-ui-core/src/hooks/use-field-validations.js` around
lines 39 - 179, checkValidationRule currently lacks handling for
UniqueCharacterValidator and RepeatedCharacterValidator so those rules never
produce errors; add two switch cases in checkValidationRule: implement a
UniqueCharacterValidator branch that reads the numeric condition (e.g.,
getNumCondition(conditions, "min.unique")) and counts distinct characters in
value (new Set(value).size) and returns an appropriate message when distinct
count is below the threshold, and implement a RepeatedCharacterValidator branch
that reads the numeric condition (e.g., getNumCondition(conditions,
"max.repeated")) and ensures no single character repeats more than that limit
(compute frequency map and check max frequency), returning a descriptive error
when violated; place these cases alongside the other validators (e.g., with the
same return style) so validate() emits errors for those rules.
033f090 to
481393f
Compare
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #10358 +/- ##
=======================================
Coverage 98.79% 98.79%
=======================================
Files 165 165
Lines 51737 51764 +27
Branches 111 111
=======================================
+ Hits 51111 51138 +27
Misses 626 626
Flags with carried forward coverage won't be shown. Click here to find out more. 🚀 New features to boost your workflow:
|
Summary
getRuleLabel()(validation-criteria.js) and never looked up through the existingI18nContexttranslation system.getTranslatedRuleLabel(rule, translations)that maps each validator case to i18n keys with{param}interpolation, and wired it intoValidationCriteriaviauseTranslations().interpolate(template, params)utility toi18n-utils.jsto support{minLen}-style placeholder substitution in translation strings.en-US.jsoncovering all validator variants (length between/min/max/required, numeral, uppercase, lowercase, special, confirm password, email, alphanumeric, unique, repeated).errors.some((err) => err.includes(englishLabel))) continues to use the English label so the pass/fail icon logic is unaffected.Fixes wso2/product-is#27787
Test plan
fr-FR.json) alongsideen-US.jsonwith translated keys🤖 Generated with Claude Code