Skip to content

Fix password policy validation messages to support localization in Flow Builder UI#10358

Open
Thisara-Welmilla wants to merge 2 commits into
wso2:masterfrom
Thisara-Welmilla:fix/issue-27787
Open

Fix password policy validation messages to support localization in Flow Builder UI#10358
Thisara-Welmilla wants to merge 2 commits into
wso2:masterfrom
Thisara-Welmilla:fix/issue-27787

Conversation

@Thisara-Welmilla

Copy link
Copy Markdown
Contributor

Summary

  • Password policy validation criteria messages in the Flow Builder UI were hardcoded in English inside getRuleLabel() (validation-criteria.js) and never looked up through the existing I18nContext translation system.
  • Added getTranslatedRuleLabel(rule, translations) that maps each validator case to i18n keys with {param} interpolation, and wired it into ValidationCriteria via useTranslations().
  • Added interpolate(template, params) utility to i18n-utils.js to support {minLen}-style placeholder substitution in translation strings.
  • Added 16 translation keys to en-US.json covering all validator variants (length between/min/max/required, numeral, uppercase, lowercase, special, confirm password, email, alphanumeric, unique, repeated).
  • Error-matching logic (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

  • Configure a non-English locale in IS Console → Branding
  • Add a locale JSON file (e.g. fr-FR.json) alongside en-US.json with translated keys
  • Trigger the Flow Builder registration/password-creation step
  • Verify validation messages render in the configured locale
  • Enter a valid password and confirm the green check icon appears (error-matching still works)
  • Remove the locale file; confirm messages fall back to English gracefully

🤖 Generated with Claude Code

@coderabbitai

coderabbitai Bot commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Adds 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.

Changes

Validation Criteria Localization

Layer / File(s) Summary
String interpolation utility
identity-apps-core/react-ui-core/src/utils/i18n-utils.js
New interpolate(template, params) replaces {key} placeholders with param values, returns empty string for falsy templates, and preserves unresolved placeholders.
Rule checker extraction and hook integration
identity-apps-core/react-ui-core/src/hooks/use-field-validations.js
Extracted per-rule validation into exported checkValidationRule(rule, value, compareValue) and updated useFieldValidation to call this helper; simplified validate useCallback dependencies.
ValidationCriteria translation support
identity-apps-core/react-ui-core/src/components/validation-criteria.js
Added translation imports, isRuleActive, exported getTranslatedRuleLabel, and updated ValidationCriteria to fetch translations, compute displayLabel (translated or English fallback), use checkValidationRule for validity, render translated labels, and accept compareValue prop.
Password field adapter wiring
identity-apps-core/react-ui-core/src/components/adapters/password-field-adapter.js
Adapter now passes value and compareValue to ValidationCriteria for confirm-password and password criteria instead of errors arrays.
English translation entries
identity-apps-core/apps/authentication-portal/src/main/webapp/i18n/translations/en-US.json
Added validation.criteria.* keys covering username, password, and email validation rules (alphanumeric, match, email format, length, casing, numeric/special char minima, uniqueness, repeated-char limits).

Suggested reviewers

  • NipuniBhagya
  • pavinduLakshan
  • DonOmalVindula

Important

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

❌ Failed checks (1 error)

Check name Status Explanation Resolution
Changeset Required ❌ Error The PR changes files in identity-apps-core (not in exempt directories), so a changeset is required, but no changeset files appear in the PR's changed file list. Add a .changeset/*.md file documenting the version updates for affected packages in this PR (e.g., @wso2is/identity-apps-core with appropriate version bump).
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Fix password policy validation messages to support localization in Flow Builder UI' accurately and clearly summarizes the primary change in the PR—enabling localization for password validation messages.
Description check ✅ Passed The PR description provides a comprehensive summary including purpose, technical approach, files changed, and a test plan, covering all critical information needed for review.
Linked Issues check ✅ Passed The PR fully addresses issue #27787 by adding i18n support for password validation messages, implementing getTranslatedRuleLabel(), interpolate() utility, and 16 translation keys while preserving validation behavior.
Out of Scope Changes check ✅ Passed All changes are directly aligned with issue #27787 objectives: translation infrastructure, i18n utilities, validation component refactoring, and English translation keys for localization support.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
⚔️ Resolve merge conflicts
  • Resolve merge conflict in branch fix/issue-27787
  • 🛠️ create changeset

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

📥 Commits

Reviewing files that changed from the base of the PR and between c970cb3 and 033f090.

📒 Files selected for processing (3)
  • identity-apps-core/react-ui-core/src/components/adapters/password-field-adapter.js
  • identity-apps-core/react-ui-core/src/components/validation-criteria.js
  • identity-apps-core/react-ui-core/src/hooks/use-field-validations.js

Comment on lines 100 to 104
<ValidationCriteria
validationConfig={ CONFIRM_PASSWORD_RULE }
errors={ confirmPasswordErrors }
value={ confirmPassword }
compareValue={ password }
/>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

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.

Suggested change
<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.

Comment on lines +19 to +21
import { useCallback, useState } from “react”;
import { DEFAULT_ALPHANUMERIC_REGEX, DEFAULT_EMAIL_REGEX } from “../constants/validation-constants”;
import { validateWithRegex } from “../utils/validation-utils”;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

🧩 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}")
PY

Repository: 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.

Comment on lines +39 to +179
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;
};

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

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.

@codecov

codecov Bot commented Jun 7, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 98.79%. Comparing base (ccb2eab) to head (49ff2b1).
⚠️ Report is 319 commits behind head on master.

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           
Flag Coverage Δ
@wso2is/core 58.95% <ø> (ø)
@wso2is/i18n 100.00% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.
see 2 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Password policy validation messages do not support localization in the Flow Builder UI

1 participant