Skip to content

Add HTML sanitizer for translated message resources#4

Open
akshayutture-augment wants to merge 1 commit into
feature-html-sanitizer-baselinefrom
feature-html-sanitizer-implementation
Open

Add HTML sanitizer for translated message resources#4
akshayutture-augment wants to merge 1 commit into
feature-html-sanitizer-baselinefrom
feature-html-sanitizer-implementation

Conversation

@akshayutture-augment

@akshayutture-augment akshayutture-augment commented Nov 14, 2025

Copy link
Copy Markdown

Test 7

Summary by CodeRabbit

Release Notes

  • New Features

    • Added recovery code generation and management localization keys
    • Expanded authentication UI with new TOTP configuration labels and recovery authentication support
    • Implemented HTML safety validation for translation properties
  • Bug Fixes

    • Corrected malformed HTML tags and spacing in email and login messages across multiple languages
    • Fixed message pluralization formatting for attribute validation errors
    • Resolved HTML attribute syntax errors in translated templates
  • Chores

    • Added dependencies for enhanced HTML security validation

✏️ Tip: You can customize this high-level summary in your review settings.


Replicated from ai-code-review-evaluation/keycloak-coderabbit#7

Closes #37428

Signed-off-by: Alexander Schwartz <alexander.schwartz@gmx.net>
@akshayutture-augment

Copy link
Copy Markdown
Author

@coderabbitai review

@akshayutture-augment

Copy link
Copy Markdown
Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Nov 22, 2025

Copy link
Copy Markdown
✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai

coderabbitai Bot commented Nov 22, 2025

Copy link
Copy Markdown

Walkthrough

This pull request updates theme localization across 40+ language-specific properties files, introduces HTML safety verification to the theme verifier, adds recovery code and expanded TOTP configuration localization keys, fixes HTML formatting issues, and adds dependencies for HTML sanitization and text processing.

Changes

Cohort / File(s) Summary
Account UI Localization
js/apps/account-ui/maven-resources/theme/keycloak.v3/account/messages/messages_en.properties
Updated error-invalid-multivalued-size from braces-placeholder format to ICU-style pluralization; added recovery-codes-number-used, recovery-codes-number-remaining, recovery-codes-generate-new-codes keys.
Admin UI Localization
js/apps/admin-ui/maven-resources-community/theme/keycloak.v2/admin/messages/messages_zh_CN.properties
Removed extra space in templateHelp field placeholder format (CLAIM. → CLAIM.).
Admin UI English Localization
js/apps/admin-ui/maven-resources/theme/keycloak.v2/admin/messages/messages_en.properties
Updated error-invalid-multivalued-size to ICU pluralization format; added 17+ new keys for logout token handling, attribute translations, and language translation management.
Theme Verifier Dependencies
misc/theme-verifier/pom.xml
Added owasp-java-html-sanitizer (20240325.1) and commons-text (1.13.0) dependencies.
Theme Verifier Implementation
misc/theme-verifier/src/main/java/org/keycloak/themeverifier/VerifyMessageProperties.java
Introduced HTML safety verification with PolicyFactory, sanitization logic, anchor tag synchronization, HTML detection helpers, and error reporting for illegal HTML in translations.
Theme Verifier Tests
misc/theme-verifier/src/test/java/org/keycloak/themeverifier/VerifyMessagePropertiesTest.java
Updated duplicateKeys test; added verifyIllegalHtmlTagDetected, verifyNoHtmlAllowed, verifyNoChangedAnchors tests.
Theme Verifier Test Resources
misc/theme-verifier/src/test/resources/changedAnchor_{en,de}.properties, illegalHtmlTag_en.properties, noHtml_{en,de}.properties
Added 5 new test resource files with HTML content for testing anchor changes and HTML validation.
Account Theme Localization - TOTP Updates
themes/src/main/resources-community/theme/base/account/messages/messages_{fi,lt,sk,sv,zh_CN}.properties
Replaced app-specific TOTP instructions with generic prompts; added totpStep2, totpStep3, totpManualStep2, totpManualStep3, totpUnableToScan, totpScanBarcode, totp.totp, totp.hotp, totpType, totpAlgorithm, totpDigits, totpInterval, totpCounter, totpDeviceName keys.
Email Theme HTML Fixes
themes/src/main/resources-community/theme/base/email/messages/messages_{da,fa,hu,lt,nl,no,tr,uk}.properties
Fixed malformed HTML tags, corrected closing tags, removed stray spaces, standardized href attributes, reordered placeholders in identity provider messages.
Login Theme Localization - WebAuthn Formatting
themes/src/main/resources-community/theme/base/login/messages/messages_{ar,ca,cs,de,el,es,fa,fi,fr,hr,ka,ko,lt,no,th,tr,uk,zh_CN,zh_TW}.properties
Standardized HTML line break tags from <br/> to <br /> across 19 language files in WebAuthn error messages.
Login Theme Localization - TOTP & Other Updates
themes/src/main/resources-community/theme/base/login/messages/messages_{sk,sv}.properties
Updated loginTotpStep1 to generic instruction; added loginTotpManualStep2, loginTotpManualStep3, loginTotpUnableToScan, loginTotpScanBarcode, loginCredential, loginOtpOneTime, loginTotpType/Algorithm/Digits/Interval/Counter/DeviceName keys; fixed impersonateTitleHtml; standardized WebAuthn break tags.
Login Theme English Localization
themes/src/main/resources/theme/base/login/messages/messages_en.properties
Updated WebAuthn error line breaks from <br/> to <br />; updated error-invalid-multivalued-size to ICU pluralization format in two locations.
Admin Theme English Localization
themes/src/main/resources/theme/base/admin/messages/messages_en.properties
Updated error-invalid-multivalued-size to use ICU choice pluralization for plural-aware rendering.

Sequence Diagram(s)

sequenceDiagram
    participant V as VerifyMessageProperties
    participant SF as StructureFlowLogic
    participant SH as SafeHtmlVerifier
    participant S as Sanitizer

    V->>SF: readFileContents()
    SF-->>V: file content loaded

    V->>SH: verifySafeHtml()
    SH->>SH: getEnglishValue(key)
    SH->>S: normalize & sanitize translation
    S-->>SH: sanitized value

    alt HTML Mismatch Detected
        SH->>SH: compareAnchors(english, translation)
        SH->>SH: accumulateViolations(key, diff)
        SH-->>V: violation with diff details
    else Valid
        SH-->>V: no violations
    end

    V->>V: report accumulated errors
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Areas requiring extra attention:

  • HTML safety verification logic (VerifyMessageProperties.java): Review the sanitization rules, anchor synchronization, and normalization edge cases (templateHelp, time period units) to ensure correct HTML validation
  • ICU pluralization format changes: Verify the {2,choice,0#values|1#value|1<values} format is applied consistently across error-invalid-multivalued-size in multiple files
  • Test resource files: Confirm that test files (changedAnchor_*, illegalHtmlTag_*, noHtml_*) properly exercise the new HTML verification code paths
  • Large-scale localization updates: While many changes are repetitive HTML formatting (<br/><br />), verify that TOTP messaging changes are semantically correct and consistent across 25+ language files

Poem

🐰 Localization hops with care so keen,
HTML tags are now pristine!
Recovery codes and TOTPs bloom,
Sanitizers sweep through every room.
From app-specific paths to generic guides,
The theme verifier safely rides! 🔐

Pre-merge checks and finishing touches

❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Description check ⚠️ Warning The pull request description is essentially empty, containing only 'Test 7' and a reference note. It does not follow the repository's contribution guidelines template or provide any meaningful information about the changes. Provide a comprehensive description following the CONTRIBUTING.md guidelines. Include: purpose of changes, affected components, testing performed, and any relevant context for reviewers.
Docstring Coverage ⚠️ Warning Docstring coverage is 8.33% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Add HTML sanitizer for translated message resources' clearly and specifically describes the main change - introducing HTML sanitization functionality for translation resource files.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature-html-sanitizer-implementation

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 9

🧹 Nitpick comments (5)
themes/src/main/resources-community/theme/base/account/messages/messages_sk.properties (1)

101-118: Style/terminology nits in SK TOTP labels.

  • Line 115: “Číslica” reads singular; consider “Číslice” for the field label.
  • Line 109: “Skenovanie čiarového kódu?” sounds noun-ish; “Naskenovať čiarový kód?” is more natural.
misc/theme-verifier/src/test/java/org/keycloak/themeverifier/VerifyMessagePropertiesTest.java (1)

30-51: HTML-verifier tests cover main error paths; consider adding a clean/negative case

The four tests nicely exercise duplicate keys, illegal HTML, disallowed HTML, and changed anchors and use flexible containsString assertions that tolerate additional diagnostics. You might optionally add a “happy path” test (e.g., using changedAnchor_en.properties and an allowed-HTML key) to assert that verify() returns no HTML-related errors in the fully-correct case.

misc/theme-verifier/src/main/java/org/keycloak/themeverifier/VerifyMessageProperties.java (3)

117-137: Key-specific normalization is pragmatic; consider centralizing rules if they grow

normalizeValue handles a few special keys (templateHelp, optimizeLookupHelp, time-period/choice keys, and email RTL styles) to avoid false positives from benign < usage. That’s a practical way to get signal from the sanitizer without rewriting existing strings.

If more exceptions accumulate over time, you may want to:

  • Move these into a small configuration structure (e.g., map of key → normalization strategy) or
  • Document the rationale in a brief Javadoc to help future maintainers understand why these keys are special.

For now this is fine as-is.


58-64: Make HTML policies and tag patterns immutable static final fields

Verified: PolicyFactory instances from toFactory() are thread-safe and designed for reuse as shared static final constants.

Current state: POLICY_SOME_HTML (line 58), POLICY_NO_HTML (line 64), and HTML_TAGS (line 139) are instance fields without static final modifiers. Your existing ANCHOR_PATTERN (line 144) already follows the recommended pattern with private static final.

Refactoring all three to private static final will:

  • Avoid rebuilding policies/patterns per instance
  • Clarify they are immutable configuration
  • Follow the established pattern in the codebase

82-115: Enhance validation error messages with error codes and suggested fixes

The current messages include key, file, and a visual diff of the sanitization mismatch, which is helpful. However, per best practices in translation-validation tooling, consider adding:

  • A machine-readable error code (e.g., ILLEGAL_HTML_DETECTED) to enable tooling to group or filter related failures.
  • A brief suggested fix (e.g., "Remove HTML or allow it in the English source translation") to guide translators quickly.
  • Optionally, a structured format (e.g., JSON or key-value pairs) rather than freeform strings, aligning with conventions used by FormatJS/react-intl and other i18n libraries.

These additions materially speed debugging in large translation files with multiple errors without significantly increasing message size.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 21d5311 and 5d77e7e.

📒 Files selected for processing (47)
  • js/apps/account-ui/maven-resources/theme/keycloak.v3/account/messages/messages_en.properties (1 hunks)
  • js/apps/admin-ui/maven-resources-community/theme/keycloak.v2/admin/messages/messages_zh_CN.properties (1 hunks)
  • js/apps/admin-ui/maven-resources/theme/keycloak.v2/admin/messages/messages_en.properties (1 hunks)
  • misc/theme-verifier/pom.xml (1 hunks)
  • misc/theme-verifier/src/main/java/org/keycloak/themeverifier/VerifyMessageProperties.java (2 hunks)
  • misc/theme-verifier/src/test/java/org/keycloak/themeverifier/VerifyMessagePropertiesTest.java (1 hunks)
  • misc/theme-verifier/src/test/resources/changedAnchor_de.properties (1 hunks)
  • misc/theme-verifier/src/test/resources/changedAnchor_en.properties (1 hunks)
  • misc/theme-verifier/src/test/resources/illegalHtmlTag_en.properties (1 hunks)
  • misc/theme-verifier/src/test/resources/noHtml_de.properties (1 hunks)
  • misc/theme-verifier/src/test/resources/noHtml_en.properties (1 hunks)
  • themes/src/main/resources-community/theme/base/account/messages/messages_fi.properties (1 hunks)
  • themes/src/main/resources-community/theme/base/account/messages/messages_lt.properties (1 hunks)
  • themes/src/main/resources-community/theme/base/account/messages/messages_sk.properties (1 hunks)
  • themes/src/main/resources-community/theme/base/account/messages/messages_sv.properties (1 hunks)
  • themes/src/main/resources-community/theme/base/account/messages/messages_zh_CN.properties (1 hunks)
  • themes/src/main/resources-community/theme/base/email/messages/messages_da.properties (1 hunks)
  • themes/src/main/resources-community/theme/base/email/messages/messages_fa.properties (1 hunks)
  • themes/src/main/resources-community/theme/base/email/messages/messages_hu.properties (1 hunks)
  • themes/src/main/resources-community/theme/base/email/messages/messages_lt.properties (1 hunks)
  • themes/src/main/resources-community/theme/base/email/messages/messages_nl.properties (1 hunks)
  • themes/src/main/resources-community/theme/base/email/messages/messages_no.properties (1 hunks)
  • themes/src/main/resources-community/theme/base/email/messages/messages_tr.properties (1 hunks)
  • themes/src/main/resources-community/theme/base/email/messages/messages_uk.properties (1 hunks)
  • themes/src/main/resources-community/theme/base/login/messages/messages_ar.properties (1 hunks)
  • themes/src/main/resources-community/theme/base/login/messages/messages_ca.properties (1 hunks)
  • themes/src/main/resources-community/theme/base/login/messages/messages_cs.properties (1 hunks)
  • themes/src/main/resources-community/theme/base/login/messages/messages_de.properties (1 hunks)
  • themes/src/main/resources-community/theme/base/login/messages/messages_el.properties (1 hunks)
  • themes/src/main/resources-community/theme/base/login/messages/messages_es.properties (1 hunks)
  • themes/src/main/resources-community/theme/base/login/messages/messages_fa.properties (1 hunks)
  • themes/src/main/resources-community/theme/base/login/messages/messages_fi.properties (1 hunks)
  • themes/src/main/resources-community/theme/base/login/messages/messages_fr.properties (1 hunks)
  • themes/src/main/resources-community/theme/base/login/messages/messages_hr.properties (1 hunks)
  • themes/src/main/resources-community/theme/base/login/messages/messages_ka.properties (2 hunks)
  • themes/src/main/resources-community/theme/base/login/messages/messages_ko.properties (1 hunks)
  • themes/src/main/resources-community/theme/base/login/messages/messages_lt.properties (1 hunks)
  • themes/src/main/resources-community/theme/base/login/messages/messages_no.properties (1 hunks)
  • themes/src/main/resources-community/theme/base/login/messages/messages_sk.properties (4 hunks)
  • themes/src/main/resources-community/theme/base/login/messages/messages_sv.properties (1 hunks)
  • themes/src/main/resources-community/theme/base/login/messages/messages_th.properties (1 hunks)
  • themes/src/main/resources-community/theme/base/login/messages/messages_tr.properties (1 hunks)
  • themes/src/main/resources-community/theme/base/login/messages/messages_uk.properties (1 hunks)
  • themes/src/main/resources-community/theme/base/login/messages/messages_zh_CN.properties (1 hunks)
  • themes/src/main/resources-community/theme/base/login/messages/messages_zh_TW.properties (1 hunks)
  • themes/src/main/resources/theme/base/admin/messages/messages_en.properties (1 hunks)
  • themes/src/main/resources/theme/base/login/messages/messages_en.properties (2 hunks)
🔇 Additional comments (49)
themes/src/main/resources-community/theme/base/login/messages/messages_uk.properties (1)

459-463: LGTM!

The HTML formatting standardization in WebAuthn error messages (converting <br/> to <br />) is consistent with XML/XHTML conventions. These are purely formatting adjustments with no impact on the translated message content or functionality. The changes align with the broader PR objective to standardize HTML tag formatting across locale files.

themes/src/main/resources-community/theme/base/login/messages/messages_es.properties (1)

442-446: HTML formatting standards applied correctly to WebAuthn error messages.

The changes standardize the HTML line break syntax from <br/> to <br /> across four WebAuthn error messages (webauthn-error-registration, webauthn-error-api-get, webauthn-error-auth-verification, and webauthn-error-register-verification). This XHTML-compliant formatting improves compatibility with HTML sanitization tools and parsers.

The message content and translations remain unchanged and consistent. This aligns well with the PR objective of adding HTML safety verification to translated message resources.

themes/src/main/resources-community/theme/base/login/messages/messages_hr.properties (1)

479-483: Valid HTML formatting update aligns with sanitization effort.

The changes replace <br/> with <br /> (adding a space before the self-closing tag), which is consistent with XHTML standards and aligns with the PR's HTML sanitization objective. Both forms are valid HTML, and the change has no functional impact on the localized messages.

Please verify that this formatting change is applied consistently across all other language-specific properties files modified in this PR (the AI summary indicates 40+ files were updated). Confirm whether these changes were applied manually or auto-generated by the HTML sanitizer tool.

js/apps/admin-ui/maven-resources-community/theme/keycloak.v2/admin/messages/messages_zh_CN.properties (1)

1255-1255: Minor documentation fix in placeholder reference.

The spacing correction in the placeholder reference (CLAIM. instead of CLAIM.) is appropriate and aligns the documentation with the actual template syntax. The Chinese translation remains clear and accurate.

themes/src/main/resources-community/theme/base/login/messages/messages_tr.properties (2)

469-473: HTML formatting improvements align with sanitization goals.

The updates consistently convert <br/> to <br /> (adding space before the self-closing tag), which aligns with XHTML standards and supports proper HTML validation/sanitization. These formatting adjustments are low-risk and maintain backward compatibility in rendering.


476-476: Verify the identity-provider-login-label formatting consistency.

This line appears in the context of similar formatting updates. Ensure this change maintains consistency with the HTML sanitization requirements and doesn't introduce any unintended side effects in translation rendering.

themes/src/main/resources-community/theme/base/login/messages/messages_de.properties (1)

420-424: HTML formatting normalization for WebAuthn error messages.

The WebAuthn error message strings have been updated to use <br /> (with space) instead of <br/> for self-closing line break tags. This appears to be part of the systematic HTML formatting normalization mentioned in the PR summary for HTML sanitizer compliance.

Please confirm that this formatting change (<br/><br />) has been applied consistently across all affected locale files in this PR, as the broader context suggests multiple language files are being updated.

themes/src/main/resources-community/theme/base/login/messages/messages_ka.properties (1)

172-172: HTML tag formatting standardized for consistency and XHTML compliance.

The four WebAuthn error messages have been updated from self-closing <br/> to <br /> format. This change is consistent across all affected lines and aligns with XHTML best practices. The surrounding Georgian text and message keys remain intact.

Also applies to: 174-174, 451-451, 452-452

themes/src/main/resources-community/theme/base/email/messages/messages_fa.properties (1)

6-6: HTML structure is correct and well-formed.

The fixed HTML email template properly closes all tags and maintains consistent structure with other email templates in the file. The placeholder parameters are correctly positioned for interpolation.

themes/src/main/resources-community/theme/base/login/messages/messages_th.properties (1)

462-466: LGTM! HTML formatting standardization applied consistently.

The changes standardize the HTML line break tag format across WebAuthn error messages by adding a space before the self-closing slash (<br/><br />), which is more XHTML-compliant. All four affected error messages are updated consistently, and the Thai translation content remains unchanged. This aligns well with the PR's stated objective of implementing HTML sanitizer support.

themes/src/main/resources-community/theme/base/login/messages/messages_fr.properties (1)

377-381: HTML formatting standardization looks good.

The WebAuthn error messages have been consistently updated from <br/> to <br /> format. This aligns with the PR's HTML sanitizer objective and follows XHTML conventions. All four affected keys use the same pattern, ensuring consistency across error messaging.

js/apps/account-ui/maven-resources/theme/keycloak.v3/account/messages/messages_en.properties (1)

188-194: ICU pluralization and recovery code messages properly formatted.

Line 188 correctly migrates to ICU-style message formatting with choice-based pluralization for proper localization support. The new recovery code keys (lines 192-194) follow the same pattern and contain no unsafe markup.

themes/src/main/resources-community/theme/base/login/messages/messages_ko.properties (1)

480-484: LGTM – HTML formatting standardization aligns with PR sanitization goals.

The <br /> format respects XHTML standards and is appropriate for HTML sanitization. The space before /> is preferred for backwards compatibility.

This change standardizes the WebAuthn error messages to the XHTML-compliant self-closing tag format, which supports the PR's broader goal of HTML safety verification in theme resources.

Since this is one file of 40+ language-specific properties files mentioned in the PR summary, consider verifying:

  • Are all WebAuthn error messages across all locales (e.g., messages_en.properties, messages_fr.properties, etc.) updated consistently?
  • Do other self-closing tags in the localization files follow the same XHTML format, or does this represent a new standardization effort?
themes/src/main/resources-community/theme/base/email/messages/messages_lt.properties (2)

9-9: HTML attribute syntax appears correct.

The href attribute syntax in the password reset HTML template is properly formatted with correct quoting.


12-12: HTML attribute syntax appears correct.

The href attribute syntax in the execute actions HTML template is properly formatted with correct quoting.

themes/src/main/resources-community/theme/base/login/messages/messages_cs.properties (1)

466-470: HTML formatting normalization is consistent.

The WebAuthn error messages in this file use proper spacing with <br /> {0} format, maintaining consistency across all four error keys.

themes/src/main/resources-community/theme/base/login/messages/messages_el.properties (1)

418-422: HTML formatting normalization is consistent.

The WebAuthn error messages in this file use proper spacing with <br /> {0} format, maintaining consistency across all four error keys.

themes/src/main/resources-community/theme/base/login/messages/messages_ar.properties (1)

466-470: HTML formatting normalization is consistent.

The WebAuthn error messages in this file use proper spacing with <br /> {0} format, maintaining consistency across all four error keys.

themes/src/main/resources-community/theme/base/login/messages/messages_ca.properties (1)

423-425: Proper formatting in earlier error messages.

Lines 423-424 correctly use the <br /> {0} format with spacing.

themes/src/main/resources-community/theme/base/email/messages/messages_hu.properties (1)

6-6: Review comment is incorrect.

The raw URL pattern in emailUpdateConfirmationBodyHtml (<a href="{0}">{0}</a>) is not an inconsistency unique to Hungarian—it is consistently applied across all language templates (German, French, Spanish, and others). This is a deliberate design choice for this specific email template type, not a translation anomaly or security oversight affecting only the Hungarian localization.

The review conflated two different patterns: (1) different email template types within the Hungarian file using different link text strategies, and (2) a purported inconsistency. The presence of descriptive text in other email types (verification, password reset, etc.) does not indicate a bug in emailUpdateConfirmationBodyHtml; rather, it reflects intentional variation across email template types. No action is required.

Likely an incorrect or invalid review comment.

themes/src/main/resources-community/theme/base/email/messages/messages_da.properties (1)

9-9: HTML tag closure fix is correct.

The addition of the closing </p> tag properly completes the HTML structure in the identityProviderLinkBodyHtml message. The rest of the HTML elements (<b>, <a href>, <p>) are properly paired.

themes/src/main/resources-community/theme/base/email/messages/messages_tr.properties (1)

9-9: HTML structure is properly formatted.

The identityProviderLinkBodyHtml message contains properly paired HTML tags (<b>, <p>, <a href>), and all placeholder variables ({0}, {1}, {2}, {3}, {5}) are present and correctly positioned.

themes/src/main/resources-community/theme/base/login/messages/messages_zh_CN.properties (1)

466-470: HTML break tag formatting is standardized.

All four WebAuthn error messages have been consistently updated from <br/> to <br /> format, maintaining proper spacing. The placeholder variables {0} are correctly preserved in each message.

themes/src/main/resources-community/theme/base/login/messages/messages_fa.properties (1)

457-461: HTML break tag formatting is consistently standardized.

The four WebAuthn error messages have been updated with consistent <br /> formatting, matching the same pattern applied across other locale files. Placeholder variables are preserved correctly.

themes/src/main/resources-community/theme/base/login/messages/messages_fi.properties (1)

400-404: HTML break tag formatting is consistently applied.

The four WebAuthn error messages have been standardized to use <br /> format, consistent with other locale files. All content and placeholders are properly preserved.

themes/src/main/resources-community/theme/base/email/messages/messages_uk.properties (1)

6-6: HTML structure is properly formatted.

The emailUpdateConfirmationBodyHtml message contains properly paired paragraph tags and link elements, with all placeholder variables ({0}, {1}, {2}, {3}) correctly positioned.

themes/src/main/resources-community/theme/base/account/messages/messages_zh_CN.properties (1)

112-112: TOTP setup instruction text is appropriately updated.

The totpStep1 message has been updated to a simplified, non-HTML version that provides clear instruction in Simplified Chinese: "在您的手機上安裝以下應用程式之一:" (Install one of the following applications on your mobile phone).

themes/src/main/resources-community/theme/base/login/messages/messages_zh_TW.properties (1)

473-477: HTML break tag formatting is standardized consistently.

The four WebAuthn error messages have been updated with consistent <br /> formatting, matching the standardization applied across all other locale files. All placeholders and Traditional Chinese content are properly preserved.

themes/src/main/resources-community/theme/base/login/messages/messages_no.properties (1)

71-71: LGTM! Simplification of TOTP setup instruction aligns with PR objective to move toward generic instructions across locales.

themes/src/main/resources-community/theme/base/email/messages/messages_nl.properties (1)

3-3: LGTM! Malformed HTML tag sequence </p<p> correctly fixed to </p><p>, improving email template structure.

themes/src/main/resources-community/theme/base/login/messages/messages_sv.properties (1)

68-68: LGTM! Consistent TOTP instruction simplification across locales.

themes/src/main/resources-community/theme/base/login/messages/messages_sk.properties (4)

30-30: LGTM! HTML tag structure corrected; extraneous closing tag removed.


123-138: LGTM! Expansion of TOTP setup workflow with new localization keys (loginTotpManualStep2, loginTotpManualStep3, loginTotpUnableToScan, loginTotpScanBarcode, loginTotpType, etc.) provides granular control over TOTP configuration messaging.


466-470: LGTM! WebAuthn error messages consistently formatted with standardized <br /> tag spacing, improving HTML consistency.


501-501: LGTM! ICU pluralization syntax correctly applied to error-invalid-multivalued-size message, enabling context-aware plural forms: {2,choice,0#hodnôt|1#hodnotu|1<hodnoty|4<hodnôt}.

themes/src/main/resources/theme/base/admin/messages/messages_en.properties (1)

69-69: LGTM! ICU pluralization correctly applied to error-invalid-multivalued-size message: {2,choice,0#values|1#value|1<values} enables proper plural agreement across locales.

themes/src/main/resources-community/theme/base/account/messages/messages_sv.properties (1)

96-96: LGTM! Consistent TOTP instruction simplification across account and login message bundles.

themes/src/main/resources-community/theme/base/email/messages/messages_no.properties (1)

5-6: Verify placeholder parameter order alignment with calling code. The analysis confirms a placeholder inconsistency: Norwegian uses {4} for the expiry timeout while 23 other locales standardize on {5}. Norwegian is part of a minority group (6 total locales) diverging from the standard. Without access to the Java code that invokes these messages, the correct placeholder order cannot be definitively confirmed. Ensure the Norwegian placeholder sequence matches the actual parameter order passed by the message caller.

themes/src/main/resources/theme/base/login/messages/messages_en.properties (2)

487-491: Sanitizer allowlist check for
in error strings.

You normalized to "
{0}". Confirm the sanitizer allows br/HTML here and won’t strip it, otherwise users will see “{0}” on the next line as plain text.


530-531: Pluralization looks correct; good alignment with ChoiceFormat.

MessageFormat choice segment reads well for 0/1/>1. No issues.

js/apps/admin-ui/maven-resources/theme/keycloak.v2/admin/messages/messages_en.properties (1)

3136-3136: Pluralization switch to ChoiceFormat looks good.

Pattern is consistent with Java MessageFormat choice usage.

Please confirm the rendering path uses java.text.MessageFormat (or an ICU-compatible renderer) so the choice segment is evaluated, not shown literally.

themes/src/main/resources-community/theme/base/account/messages/messages_fi.properties (1)

141-145: TOTP step text LGTM.

Clear and consistent with subsequent steps.

misc/theme-verifier/src/test/resources/illegalHtmlTag_en.properties (1)

1-17: Fixture content correctly exercises illegal-HTML detection

Header and the key=Some <div>tag</div value look appropriate to trigger the sanitizer and the corresponding test; no changes needed.

misc/theme-verifier/src/test/resources/changedAnchor_en.properties (1)

1-17: Baseline anchor fixture looks good

Using key=Some <a href="http://example.com">link</a> as the reference string is clear and aligns with the changed-anchor test scenario.

misc/theme-verifier/src/test/resources/changedAnchor_de.properties (1)

1-17: Changed-anchor fixture matches test intent

The German fixture with http://malicious.com correctly diverges from the English URL to exercise the “changed anchor” path; content and header are consistent.

misc/theme-verifier/src/test/resources/noHtml_de.properties (1)

1-17: No-HTML (violation) fixture is appropriate

key=Some <b>HTML</b> is a good minimal example to ensure the verifier flags HTML when the English source has none.

misc/theme-verifier/src/test/resources/noHtml_en.properties (1)

1-17: No-HTML baseline fixture looks correct

The key=No HTML baseline cleanly represents a string with no markup for the “no HTML allowed” test; nothing to change here.

misc/theme-verifier/src/main/java/org/keycloak/themeverifier/VerifyMessageProperties.java (2)

46-52: Integration of HTML verification into verify() looks correct

Calling verifySafeHtml() after verifyNoDuplicateKeys(contents) ensures all messages are accumulated in a single run. This preserves existing duplicate-key behavior while adding HTML checks, with IO confined to a single try/catch. No issues from a control-flow standpoint.


164-172: Graceful handling of missing English keys is good

getEnglishValue returning an empty string when a key is absent from the English bundle avoids hard failures and still enforces the “no HTML” policy for that key. That’s a sensible fallback for partially-translated bundles.

Comment on lines 3138 to 3139
multivaluedHelp=If this attribute supports multiple values. This setting is an indicator and does not enable any validation.
to the attribute. For that, make sure to use any of the built-in validators to properly validate the size and the values.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

Broken properties entry: orphan line without key (parsing bug).

Line 3139 starts with plain text (“to the attribute...”) and will be parsed as key “to” with a long value, corrupting the bundle at runtime. Merge it with line 3138.

Apply this diff:

- multivaluedHelp=If this attribute supports multiple values. This setting is an indicator and does not enable any validation.
-to the attribute. For that, make sure to use any of the built-in validators to properly validate the size and the values.
+ multivaluedHelp=If this attribute supports multiple values. This setting is an indicator and does not enable any validation to the attribute. For that, make sure to use any of the built-in validators to properly validate the size and the values.

Run this repo-wide check for malformed .properties lines (missing '=' or ':' and not comments/blanks):


🏁 Script executed:

#!/bin/bash
# Find suspicious lines in .properties (not blank, not comment, without '=' or ':')
fd -t f -e properties \
| while read -r f; do
  awk '!/^\s*(#|!)|^\s*$/{ if ($0 !~ /=|:/) { printf("%s:%d:%s\n", FILENAME, NR, $0) } }' "$f"
done

Length of output: 4613


🏁 Script executed:

#!/bin/bash
# Verify the exact content and context around the reported malformed line
echo "=== messages_en.properties lines 3137-3140 ==="
sed -n '3137,3140p' js/apps/admin-ui/maven-resources/theme/keycloak.v2/admin/messages/messages_en.properties

echo ""
echo "=== messages_es.properties lines 3143-3146 ==="
sed -n '3143,3146p' js/apps/admin-ui/maven-resources-community/theme/keycloak.v2/admin/messages/messages_es.properties

Length of output: 368


🏁 Script executed:

#!/bin/bash
# Find the actual file paths
echo "=== Finding messages_en.properties ==="
fd -t f -n "messages_en.properties"

echo ""
echo "=== Finding messages_es.properties ==="
fd -t f -n "messages_es.properties"

Length of output: 540


🏁 Script executed:

#!/bin/bash
# Find the actual file paths (corrected syntax)
echo "=== Finding messages_en.properties ==="
fd -t f "messages_en.properties"

echo ""
echo "=== Finding messages_es.properties ==="
fd -t f "messages_es.properties"

Length of output: 1255


🏁 Script executed:

#!/bin/bash
# Verify the exact content and context around the reported malformed line
echo "=== messages_en.properties lines 3137-3140 ==="
sed -n '3137,3140p' js/apps/admin-ui/maven-resources/theme/keycloak.v2/admin/messages/messages_en.properties | cat -A

echo ""
echo "=== messages_es.properties lines 3143-3146 ==="
sed -n '3143,3146p' js/apps/admin-ui/maven-resources-community/theme/keycloak.v2/admin/messages/messages_es.properties | cat -A

Length of output: 787


Confirmed: Critical parsing bug in line 3139 needs merging with line 3138.

The verification shows that line 3139 in js/apps/admin-ui/maven-resources/theme/keycloak.v2/admin/messages/messages_en.properties lacks a key-value separator and contains orphaned text that belongs to the previous line's value. The .properties parser will treat "to" as a separate key, corrupting the message bundle. The proposed diff correctly merges the two lines into a single property entry.

The same issue exists in the Spanish translation at line 3145 of messages_es.properties.

🤖 Prompt for AI Agents
In
js/apps/admin-ui/maven-resources/theme/keycloak.v2/admin/messages/messages_en.properties
around lines 3138-3139, line 3139 is orphaned text ("to the attribute...") that
should be part of the value for the previous key (multivaluedHelp); merge line
3139 into the value of line 3138 (ensure a single space between sentences),
removing the stray newline so the property remains a single key=value entry;
apply the same fix to the Spanish file messages_es.properties at the reported
line (line ~3145) by joining the orphaned line into the preceding key's value to
prevent parser errors.

Comment on lines +75 to +85
<dependency>
<groupId>com.googlecode.owasp-java-html-sanitizer</groupId>
<artifactId>owasp-java-html-sanitizer</artifactId>
<version>20240325.1</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-text</artifactId>
<version>1.13.0</version>
<scope>compile</scope>
</dependency>

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

Validate sanitizer and commons-text versions against your platform baseline

Adding owasp-java-html-sanitizer and commons-text as compile dependencies makes sense for the new verification logic. Please ensure these versions align with your broader Keycloak/platform BOM and pass your security/compliance checks (CVEs, license policy, etc.), as the plugin will carry them transitively where it’s used.


🌐 Web query:

Check whether com.googlecode.owasp-java-html-sanitizer:owasp-java-html-sanitizer:20240325.1 and org.apache.commons:commons-text:1.13.0 are current recommended versions and if there are any known high/critical CVEs affecting them.

💡 Result:

Summary (checked Nov 22, 2025):

  • com.googlecode.owasp-java-html-sanitizer:owasp-java-html-sanitizer:20240325.1

    • 20240325.1 is the project's current release tag on GitHub (released Mar 25, 2024). [1]
    • Known past high/critical issues (CVE-2021-42575, CVSS 9.8) affected versions prior to 20211018.1 and were fixed; I found no public high/critical CVE that applies to the 20240325.1 release itself. [2][3]
  • org.apache.commons:commons-text:1.13.0

    • 1.13.0 was released Dec 10, 2024, but Commons Text has newer releases after that (1.13.1 and 1.14.0), so 1.13.0 is not the latest recommended release as of Jul 20, 2025 (1.14.0). Upgrading to the latest stable release is recommended. [4]
    • The well-known critical “Text4Shell” issue CVE-2022-42889 (RCE via StringSubstitutor defaults) affects commons-text versions 1.5–1.9 and was fixed in 1.10.0; it does not affect 1.13.0. I found no other public high/critical CVE explicitly affecting 1.13.0. [5][6]

Recommendations

  • OWASP sanitizer: 20240325.1 is current upstream and has known prior issues fixed; no high/critical CVE found against that tag. If you depend on an OS/distribution package, check your distro advisory for backported fixes. [1][2]
  • Commons Text: upgrade to the latest stable Commons Text (1.14.0 as of Jul 20, 2025) to stay current; 1.13.0 is not vulnerable to CVE-2022-42889 but using the newest release is recommended. [4][5]

Sources

  1. OWASP java-html-sanitizer releases (GitHub) — release 20240325.1. [GitHub release page]. (github.com)
  2. CVE-2021-42575 details and advisories (affects versions <20211018.1). (wiz.io)
  3. OWASP project page. (owasp.org)
  4. Apache Commons Text changes / releases (shows 1.13.0 and later 1.14.0 released Jul 20, 2025). (commons.apache.org)
  5. NVD / advisories for CVE-2022-42889 (“Text4Shell”) — affects 1.5–1.9; fixed in 1.10.0. (nvd.nist.gov)

If you want, I can: (a) check your project’s dependency tree for transitive versions, or (b) fetch distro-specific advisories (e.g., Red Hat, Debian) for these artifacts.

Citations:


Upgrade commons-text to 1.14.0 for latest stability

owasp-java-html-sanitizer:20240325.1 is the current upstream release, with no public high/critical CVE found for that version.

However, commons-text:1.13.0 is not the latest stable release; 1.14.0 was released in July 2025. While 1.13.0 is not vulnerable to CVE-2022-42889 (Text4Shell), upgrading to 1.14.0 aligns with best practices for dependency currency.

🤖 Prompt for AI Agents
In misc/theme-verifier/pom.xml around lines 75 to 85, the pom declares
commons-text version 1.13.0; update that dependency version to 1.14.0 to align
with the current stable release. Edit the <version> element for the
org.apache.commons:commons-text dependency to 1.14.0, save the pom, then run a
quick build (mvn -DskipTests package or mvn -U test) to ensure no compatibility
issues and commit the change.

Comment on lines +65 to +81
private void verifySafeHtml() {
PropertyResourceBundle bundle;
try (FileInputStream fis = new FileInputStream(file)) {
bundle = new PropertyResourceBundle(fis);
} catch (IOException e) {
throw new RuntimeException("unable to read file " + file, e);
}

PropertyResourceBundle bundleEnglish;
String englishFile = file.getAbsolutePath().replaceAll("resources-community", "resources")
.replaceAll("_[a-zA-Z-_]*\\.properties", "_en.properties");
try (FileInputStream fis = new FileInputStream(englishFile)) {
bundleEnglish = new PropertyResourceBundle(fis);
} catch (IOException e) {
throw new RuntimeException("unable to read file " + englishFile, e);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

English-bundle resolution is convention-based; ensure it matches all target layouts

verifySafeHtml() derives the English source file via:

  • Replacing resources-community with resources.
  • Rewriting _[a-zA-Z-_]*.properties to _en.properties.

This works for the tests and for conventional <base>_<locale>.properties layouts, but will throw a RuntimeException if the computed English file is missing or moved. If the plugin may run over files that don’t follow this convention (or where English is not _en), consider either:

  • Guarding the lookup and falling back to “no HTML allowed” when the English bundle is absent, or
  • Making the naming convention configurable and failing with a more explicit MojoExecutionException.

🏁 Script executed:

#!/bin/bash
# List all *.properties files this module normally verifies to check that
# each non-en file has a matching *_en.properties alongside it.

fd '\.properties$' -t f |
  gawk '
    /_([A-Za-z-]+)\.properties$/ {
      base=$0; sub(/_[A-Za-z-]+\.properties$/, "", base);
      en=base "_en.properties";
      if (system("[ -f \"" en "\" ]") != 0) {
        print "Missing English counterpart for: " $0 " (expected " en ")"
      }
    }
  '

Length of output: 36611


Fix English-bundle lookup to handle non-standard naming conventions

The verification script confirms that verifySafeHtml() will fail with RuntimeException for a significant number of properties files across the codebase. The regex-based English filename resolution produces non-existent paths for:

  • Compound locale files: messages_pt_BR.properties → expects messages_pt_en.properties (missing)
  • Regional variants: messages_de_AT.properties → expects messages_de_en.properties (missing)
  • Language-only files: en_US.properties → expects en_en.properties (missing)

Over 130+ localized properties files in themes/, js/apps/, and testsuite/ directories do not follow the assumed _en.properties naming pattern. At minimum, add a fallback:

try (FileInputStream fis = new FileInputStream(englishFile)) {
    bundleEnglish = new PropertyResourceBundle(fis);
} catch (IOException e) {
    // Fall back to current bundle if English variant is unavailable
    bundleEnglish = bundle;
}

Or make the convention configurable and fail explicitly with MojoExecutionException rather than a generic RuntimeException.

🤖 Prompt for AI Agents
In
misc/theme-verifier/src/main/java/org/keycloak/themeverifier/VerifyMessageProperties.java
around lines 65 to 81, the current regex-based lookup for the English bundle
produces non-existent paths for many locale variants and throws a
RuntimeException; replace the strict resolution with a resilient strategy:
attempt to open the computed englishFile as before, but on IOException fall back
to using the original bundle (bundleEnglish = bundle) so verification can
proceed when an _en.properties variant is absent, or alternatively make the
english file pattern configurable and throw a MojoExecutionException with a
clear message if you prefer failing explicitly; implement the fallback in the
catch block (or switch to the configurable approach) and ensure exceptions
include the file path in their message.

Comment on lines +145 to +162
private static final Pattern ANCHOR_PATTERN = Pattern.compile("</?a[^>]*>");

/**
* Allow only those anchor tags from the source key to also appear in the target key.
*/
private String santizeAnchors(String key, String value, String englishValue) {
Matcher matcher = ANCHOR_PATTERN.matcher(value);
Matcher englishMatcher = ANCHOR_PATTERN.matcher(englishValue);
while (matcher.find()) {
if (englishMatcher.find() && Objects.equals(matcher.group(), englishMatcher.group())) {
value = value.replaceFirst(Pattern.quote(englishMatcher.group()), "");
} else {
messages.add("Didn't find anchor tag " + matcher.group() + " in original string");
break;
}
}
return value;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

Anchor sanitization logic works; improve naming and diagnostics

The santizeAnchors method correctly:

  • Walks anchor tags in the translation and English source.
  • Flags any extra or changed anchors ("Didn't find anchor tag … in original string").
  • Removes matching anchors from the value before sanitizer comparison.

Two minor polish suggestions:

  • Rename santizeAnchorssanitizeAnchors for readability.
  • Include key and/or file path in the “Didn’t find anchor tag” message (similar to Illegal HTML in key … for file …) to make it easier to track down the offending entry in large bundles.

Behavior need not change; this is about debuggability.


🌐 Web query:

Check OWASP Java HTML Sanitizer and similar tools for any built-in patterns for safe anchor handling, to see if your custom anchor comparison aligns with common practices.

💡 Result:

Short answer: Yes — OWASP Java HTML Sanitizer provides built-in handling for safe anchors (via its LINKS sanitizer and HtmlPolicyBuilder allowUrlProtocols/requireRelNofollow options), and common practices used by OWASP and other sanitizers match the usual checks your custom anchor comparison should do: whitelist schemes, normalize/percent-decode and compare schemes/hosts, block dangerous schemes (javascript:, data:), and add rel="nofollow"/rel="noopener" for external/target=_blank links. See sources below for the exact APIs and behaviour.

Key points to align your comparator with common practice:

  • Whitelist allowed URL protocols (e.g., http, https, mailto); OWASP exposes allowUrlProtocols(...) and Sanitizers.LINKS for that. [1]
  • Normalize and percent-decode before comparing (case-insensitive scheme, canonical host) so comparisons aren’t bypassed by encoding or case tricks. (OWASP examples show using URL/protocol checks when allowing hrefs.) [1][2]
  • Explicitly block or strip dangerous schemes like javascript:, data:, vbscript:. DOMPurify and OWASP both validate URI schemes. [3][1]
  • Treat relative URLs as allowed (or resolve them to a base) and compare resolved origins when you mean “same-origin.” Many policies allow relative hrefs by default when protocols are safe. [1][3]
  • Add/require rel="nofollow" and for target="_blank" ensure rel includes noopener,noreferrer to avoid window.opener attacks; OWASP has requireRelNofollowOnLinks() and examples of adding rel. [1][2]

Sources:
[1] OWASP Java HTML Sanitizer — project page and examples (HtmlPolicyBuilder, Sanitizers.LINKS, allowUrlProtocols, requireRelNofollow).
[2] Baeldung / examples using OWASP sanitizer (shows LINKS behavior and rel handling).
[3] DOMPurify docs — URI-scheme validation and blocking javascript: / data: schemes.

If you want, paste your custom anchor-comparison code and I’ll check it line-by-line against these practices.


I need to understand the actual purpose of this method within the codebase to determine if the OWASP best practices are relevant. Let me check the usage context.


🏁 Script executed:

#!/bin/bash
# Find method calls to santizeAnchors to understand its usage context
rg -nP '\bsantizeAnchors\s*\(' misc/theme-verifier/src/main/java/org/keycloak/themeverifier/ -A 3 -B 3

Length of output: 2058


🏁 Script executed:

#!/bin/bash
# Check class-level documentation and overall structure
cat misc/theme-verifier/src/main/java/org/keycloak/themeverifier/VerifyMessageProperties.java | head -100

Length of output: 3871


🏁 Script executed:

#!/bin/bash
# Search for other sanitization methods in the file to understand scope
rg -nP 'private.*String.*\(' misc/theme-verifier/src/main/java/org/keycloak/themeverifier/VerifyMessageProperties.java -A 2

Length of output: 534


Fix typo in method name and enhance error diagnostics

The santizeAnchors method correctly validates that anchor tags in translations match the English source structure. The actual HTML security is handled by the downstream OWASP PolicyFactory.sanitize() call, so OWASP URI/scheme validation does not apply to this method's scope.

Two fixes remain valid:

  • Rename santizeAnchorssanitizeAnchors (typo).
  • Include key in the "Didn't find anchor tag" message (line 157) for consistency with other error messages like "Illegal HTML in key … for file …", improving debuggability in large translation bundles.
🤖 Prompt for AI Agents
In
misc/theme-verifier/src/main/java/org/keycloak/themeverifier/VerifyMessageProperties.java
around lines 145-162, rename the method from santizeAnchors to sanitizeAnchors
(fix the typo) and update its diagnostic message so that when an anchor tag is
missing it includes the message key (e.g., "Didn't find anchor tag <...> in
original string for key <key>") to match other errors; also update any call
sites to use the new method name. Ensure only the method name and the message
string are changed, preserving existing logic and return behavior.

configureAuthenticators=Sukonfigūruotas autentifikatorius
mobile=Mobilus
totpStep1=Įdiekite <a href="https://freeotp.github.io/" target="_blank">FreeOTP</a> arba Google Authenticator savo įrenginyje. Programėlės prieinamos <a href="https://play.google.com">Google Play</a> ir Apple App Store.
totpStep1=Installa una delle seguenti applicazioni sul tuo cellulare:

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

Fix language mismatch in Lithuanian localization. Line 101 contains Italian text ("Installa una delle seguenti applicazioni sul tuo cellulare:") instead of Lithuanian. This breaks the Lithuanian localization for TOTP setup. Correct this to the appropriate Lithuanian translation to match the file's language and align with the intent shown in lines 102–103.

Verify the correct Lithuanian translation for the TOTP setup instruction. The current value should be replaced with a Lithuanian translation (e.g., something similar to the Norwegian or Swedish equivalents in other files).


I'll verify the review comment by examining the actual file and comparing translations across language files.


---

🏁 Script executed:

```shell
#!/bin/bash
# Find and verify the Lithuanian properties file
find . -name "messages_lt.properties" -type f

Length of output: 555


🏁 Script executed:

#!/bin/bash
# Extract the content around line 101 from the Lithuanian file
sed -n '98,105p' "themes/src/main/resources-community/theme/base/account/messages/messages_lt.properties"

Length of output: 393


🏁 Script executed:

#!/bin/bash
# Find all messages_*.properties files to compare translations
find themes/src/main/resources-community/theme/base/account/messages -name "messages_*.properties" -type f | sort

Length of output: 2618


🏁 Script executed:

#!/bin/bash
# Extract the totpStep1 line from multiple language files to compare
for file in $(find themes/src/main/resources-community/theme/base/account/messages -name "messages_*.properties" -type f | sort); do
  echo "=== $(basename $file) ==="
  grep -n "^totpStep1=" "$file" || echo "NOT FOUND"
done

Length of output: 2988


🏁 Script executed:

#!/bin/bash
# Check other Lithuanian message files for the totpStep1 key to see if there's a correct translation elsewhere
for file in $(find . -name "messages_lt.properties" -type f); do
  echo "=== $(echo $file | sed 's|.*/||') ==="
  grep -n "totpStep1=" "$file" || echo "NOT FOUND"
done

Length of output: 309


🏁 Script executed:

#!/bin/bash
# Check if there are any other Lithuanian files with TOTP-related content
for file in $(find . -name "*_lt.properties" -o -name "*_lt*.properties" 2>/dev/null | grep -i totp); do
  echo "=== $(echo $file | sed 's|.*/||') ===" 
  grep -i "totp" "$file" | head -5
done

Length of output: 0


🏁 Script executed:

#!/bin/bash
# Look for any Italian content in Lithuanian files that shouldn't be there
grep -l "Installa una delle seguenti" themes/src/main/resources-community/theme/base/**/*_lt.properties 2>/dev/null

Length of output: 0


Fix language mismatch in Lithuanian localization at line 101 of themes/src/main/resources-community/theme/base/account/messages/messages_lt.properties. The value contains Italian text ("Installa una delle seguenti applicazioni sul tuo cellulare:") instead of a Lithuanian translation. This breaks the Lithuanian TOTP setup workflow. Replace with the correct Lithuanian translation (lines 102–103 are properly Lithuanian and can serve as a reference for the expected language).

🤖 Prompt for AI Agents
In
themes/src/main/resources-community/theme/base/account/messages/messages_lt.properties
around line 101, the value for totpStep1 is in Italian; replace "Installa una
delle seguenti applicazioni sul tuo cellulare:" with the proper Lithuanian
translation — e.g. "Įdiekite vieną iš šių programėlių savo telefone:" — save the
file with UTF-8 encoding and run the i18n/l10n checks to ensure the key now
matches the Lithuanian locale and renders correctly.

emailVerificationSubject=El. pašto patvirtinimas
emailVerificationBody=Paskyra {2} sukurta naudojant šį el. pašto adresą. Jei tai buvote Jūs, tuomet paspauskite žemiau esančią nuorodą\n\n{0}\n\nŠi nuoroda galioja {1} min.\n\nJei paskyros nekūrėte, tuomet ignuoruokite šį laišką.
emailVerificationBodyHtml=<p>Paskyra {2} sukurta naudojant šį el. pašto adresą. Jei tao buvote Jūs, tuomet paspauskite žemiau esančią nuorodą</p><p><a href=LT"{0}">{0}</a></p><p>Ši nuoroda galioja {1} min.</p><p>nJei paskyros nekūrėte, tuomet ignuoruokite šį laišką.</p>
emailVerificationBodyHtml=<p>Paskyra {2} sukurta naudojant šį el. pašto adresą. Jei tao buvote Jūs, tuomet paspauskite žemiau esančią nuorodą</p><p><a href="{0}">{0}</a></p><p>Ši nuoroda galioja {1} min.</p><p>nJei paskyros nekūrėte, tuomet ignuoruokite šį laišką.</p>

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Fix errant 'n' character in HTML message text.

Line 3 contains "nJei paskyros" which appears to be a formatting error. The 'n' should either be part of a newline/carriage return sequence (\n) or should be removed entirely. Based on the context and the HTML structure, this should likely be "Jei paskyros" with proper spacing.

Apply this diff to fix the typo:

-emailVerificationBodyHtml=<p>Paskyra {2} sukurta naudojant šį el. pašto adresą. Jei tao buvote Jūs, tuomet paspauskite žemiau esančią nuorodą</p><p><a href="{0}">{0}</a></p><p>Ši nuoroda galioja {1} min.</p><p>nJei paskyros nekūrėte, tuomet ignuoruokite šį laišką.</p>
+emailVerificationBodyHtml=<p>Paskyra {2} sukurta naudojant šį el. pašto adresą. Jei tao buvote Jūs, tuomet paspauskite žemiau esančią nuorodą</p><p><a href="{0}">{0}</a></p><p>Ši nuoroda galioja {1} min.</p><p>Jei paskyros nekūrėte, tuomet ignuoruokite šį laišką.</p>

Also note: "Jei tao buvote Jūs" appears to have a typo—should this be "Jei tai buvote Jūs"?

📝 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
emailVerificationBodyHtml=<p>Paskyra {2} sukurta naudojant šį el. pašto adresą. Jei tao buvote Jūs, tuomet paspauskite žemiau esančią nuorodą</p><p><a href="{0}">{0}</a></p><p>Ši nuoroda galioja {1} min.</p><p>nJei paskyros nekūrėte, tuomet ignuoruokite šį laišką.</p>
emailVerificationBodyHtml=<p>Paskyra {2} sukurta naudojant šį el. pašto adresą. Jei tao buvote Jūs, tuomet paspauskite žemiau esančią nuorodą</p><p><a href="{0}">{0}</a></p><p>Ši nuoroda galioja {1} min.</p><p>Jei paskyros nekūrėte, tuomet ignuoruokite šį laišką.</p>
🤖 Prompt for AI Agents
In
themes/src/main/resources-community/theme/base/email/messages/messages_lt.properties
around line 3, the HTML message contains a stray leading 'n' before "Jei
paskyros" and a probable typo "tao" instead of "tai"; remove the errant 'n' so
the sentence reads "Jei paskyros..." and correct "tao" to "tai" (so the fragment
becomes "Jei tai buvote Jūs"), preserving existing HTML structure and spacing.

identityProviderLinkSubject=Sąsaja {0}
identityProviderLinkBody=Kažas pageidauja susieti Jūsų "{1}" paskyrą su "{0}" {2} naudotojo paskyrą. Jei tai buvote Jūs, tuomet paspauskite žemiau esančią nuorodą norėdami susieti paskyras\n\n{3}\n\nŠi nuoroda galioja {4} min.\n\nJei paskyrų susieti nenorite, tuomet ignoruokite šį laišką. Jei paskyras susiesite, tuomet prie {1} galėsiste prisijungti per {0}.
identityProviderLinkBodyHtml=<p>žas pageidauja susieti Jūsų <b>{1}</b> paskyrą su <b>{0}</b> {2} naudotojo paskyrą. Jei tai buvote Jūs, tuomet paspauskite žemiau esančią nuorodą norėdami susieti paskyras</p><p><a href=LT"{3}">{3}</a></p><p>Ši nuoroda galioja {4} min.</p><p>Jei paskyrų susieti nenorite, tuomet ignoruokite šį laišką. Jei paskyras susiesite, tuomet prie {1} galėsiste prisijungti per {0}.</p>
identityProviderLinkBodyHtml=<p>žas pageidauja susieti Jūsų <b>{1}</b> paskyrą su <b>{0}</b> {2} naudotojo paskyrą. Jei tai buvote Jūs, tuomet paspauskite žemiau esančią nuorodą norėdami susieti paskyras</p><p><a href="{3}">{3}</a></p><p>Ši nuoroda galioja {4} min.</p><p>Jei paskyrų susieti nenorite, tuomet ignoruokite šį laišką. Jei paskyras susiesite, tuomet prie {1} galėsiste prisijungti per {0}.</p>

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Fix truncated message text in HTML template.

Line 6 begins with "

žas pageidauja..." but appears to be truncated. Comparing to the corresponding plain-text message on line 5 ("Kažas pageidauja..."), this should likely read "Kažas pageidauja..." at the start of the HTML message. The 'Ka' prefix is missing.

Apply this diff to fix the truncation:

-identityProviderLinkBodyHtml=<p>žas pageidauja susieti Jūsų <b>{1}</b> paskyrą su <b>{0}</b> {2} naudotojo paskyrą. Jei tai buvote Jūs, tuomet paspauskite žemiau esančią nuorodą norėdami susieti paskyras</p><p><a href="{3}">{3}</a></p><p>Ši nuoroda galioja {4} min.</p><p>Jei paskyrų susieti nenorite, tuomet ignoruokite šį laišką. Jei paskyras susiesite, tuomet prie {1} galėsiste prisijungti per {0}.</p>
+identityProviderLinkBodyHtml=<p>Kažas pageidauja susieti Jūsų <b>{1}</b> paskyrą su <b>{0}</b> {2} naudotojo paskyrą. Jei tai buvote Jūs, tuomet paspauskite žemiau esančią nuorodą norėdami susieti paskyras</p><p><a href="{3}">{3}</a></p><p>Ši nuoroda galioja {4} min.</p><p>Jei paskyrų susieti nenorite, tuomet ignoruokite šį laišką. Jei paskyras susiesite, tuomet prie {1} galėsiste prisijungti per {0}.</p>
🤖 Prompt for AI Agents
In
themes/src/main/resources-community/theme/base/email/messages/messages_lt.properties
around line 6, the HTML message is missing the initial "Ka" from the start ("žas
pageidauja...") causing truncation; edit that line so it begins with "Kažas
pageidauja..." (i.e., prepend "Ka" to the existing text), preserving the rest of
the HTML, placeholders and UTF-8 encoding.

Comment on lines +426 to +427
webauthn-error-auth-verification=El resultat de l''autenticació amb clau de seguretat no és vàlid.<br />{0}
webauthn-error-register-verification=El resultat del registre amb clau de seguretat no és vàlid.<br />{0}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Inconsistent spacing in WebAuthn error messages.

Lines 426-427 are missing the space between the <br /> tag and the {0} placeholder, breaking the consistency established in lines 423-424 and across all other locale files (Czech, Greek, Arabic). This creates a visual rendering inconsistency and deviates from the normalization pattern of this PR.

Apply this diff to correct the spacing:

-webauthn-error-auth-verification=El resultat de l''autenticació amb clau de seguretat no és vàlid.<br />{0}
+webauthn-error-auth-verification=El resultat de l''autenticació amb clau de seguretat no és vàlid.<br /> {0}

-webauthn-error-register-verification=El resultat del registre amb clau de seguretat no és vàlid.<br />{0}
+webauthn-error-register-verification=El resultat del registre amb clau de seguretat no és vàlid.<br /> {0}
🤖 Prompt for AI Agents
themes/src/main/resources-community/theme/base/login/messages/messages_ca.properties
around lines 426-427: the two WebAuthn error lines lack a space between the
closing <br /> tag and the {0} placeholder; update both lines to insert a single
space after "<br />" (making them consistent with lines 423-424 and other
locales) so the messages read "...<br /> {0}".

gssDelegationCredential=GSS prisijungimo duomenų delegavimas

loginTotpStep1=Įdiekite <a href="https://freeotp.github.io/" target="_blank">FreeOTP</a> arba Google Authenticator savo įrenginyje. Programėlės prieinamos <a href="https://play.google.com">Google Play</a> ir Apple App Store.
loginTotpStep1=Installa una delle seguenti applicazioni sul tuo cellulare:

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Critical: Lithuanian properties file contains Italian text.

Line 71 shows Italian text (Installa una delle seguenti applicazioni sul tuo cellulare) in a file designated for Lithuanian localization (messages_lt.properties). This breaks localization for Lithuanian users who will see Italian instead of their native language.

The AI summary indicates this was changed during HTML sanitization of TOTP setup instructions, but the language content was corrupted in the process.

Please restore the proper Lithuanian translation for the TOTP setup instruction. The current Italian text must be replaced with the correct Lithuanian equivalent before merging.

🤖 Prompt for AI Agents
themes/src/main/resources-community/theme/base/login/messages/messages_lt.properties
around line 71: the value for loginTotpStep1 is Italian ("Installa una delle
seguenti applicazioni sul tuo cellulare") but this file is Lithuanian; replace
that Italian text with the correct Lithuanian translation (for example:
"Įdiekite vieną iš šių programėlių savo telefone:"), ensuring encoding remains
UTF-8 and no extra HTML sanitization changes the language string.

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.

2 participants