-
Notifications
You must be signed in to change notification settings - Fork 0
Automated Test: feature-html-sanitizer-implementation #326
Automated Test: feature-html-sanitizer-implementation #326
Conversation
Closes #37428 Signed-off-by: Alexander Schwartz <alexander.schwartz@gmx.net>
📝 WalkthroughWalkthroughThis PR updates localization messages across multiple languages, standardizes HTML formatting in WebAuthn errors, implements ICU-style pluralization for attribute validation messages, and enhances the theme verifier with comprehensive HTML sanitization and validation capabilities. Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Poem
🚥 Pre-merge checks | ✅ 1 | ❌ 1❌ Failed checks (1 inconclusive)
✅ Passed checks (1 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 12
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
js/apps/account-ui/maven-resources/theme/keycloak.v3/account/messages/messages_en.properties (1)
192-194:⚠️ Potential issue | 🟡 MinorSame placeholder inconsistency on the new recovery code keys.
Lines 192–193 use
{0}(Java MessageFormat) while surrounding keys in this file use{{0}}(i18next). If these are rendered by the React i18next layer, the{0}placeholders will appear literally in the UI instead of being interpolated.If this is intentional (server-side rendering), please disregard. Otherwise:
Proposed fix if these keys are consumed by i18next
-recovery-codes-number-used={0} recovery codes used -recovery-codes-number-remaining={0} recovery codes remaining +recovery-codes-number-used={{0}} recovery codes used +recovery-codes-number-remaining={{0}} recovery codes remaining
🤖 Fix all issues with AI agents
In `@misc/theme-verifier/pom.xml`:
- Around line 75-85: Update the vulnerable dependency versions in the POM: bump
com.googlecode.owasp-java-html-sanitizer:owasp-java-html-sanitizer from
20240325.1 to 20260102.1 (or at minimum 20260101.1) to mitigate CVE-2025-66021,
and update org.apache.commons:commons-text from 1.13.0 to 1.15.0; ensure the
version strings are changed in the <dependency> entries for those artifactIds
and run a build to verify compatibility.
In
`@misc/theme-verifier/src/main/java/org/keycloak/themeverifier/VerifyMessageProperties.java`:
- Around line 150-161: The santizeAnchors method currently uses matcher.find()
to locate anchors but value.replaceFirst(...) to remove them, which can remove
the wrong occurrence; change the logic to perform positional removals using the
Matcher API (e.g., use matcher.start()/matcher.end() indices or build a new
StringBuilder result while iterating) so you remove the exact matched substring
from value rather than the first global occurrence; update uses of
ANCHOR_PATTERN, matcher and englishMatcher inside santizeAnchors (and preserve
adding to messages on mismatch) to compute and return the correctly sanitized
string.
- Around line 99-111: In VerifyMessageProperties (around the messages.add call)
clamp the computed end so it never overlaps with start: after computing start
and end, set end = Math.min(end, Math.max(0, sanitized.length() - start)); then
use the clamped end when taking substrings from both value and sanitized to
ensure beginIndex <= endIndex and avoid IllegalArgumentException; keep
references to start, end, value, sanitized, key and file unchanged.
- Around line 65-80: verifySafeHtml() currently wraps IO failures in
RuntimeException which bypasses verify()'s IOException->MojoExecutionException
flow; change verifySafeHtml() to declare/throw IOException (or throw
MojoExecutionException) instead of RuntimeException and rethrow the caught
IOException so verify() can handle it. Also add a guard before opening
englishFile: compute englishFile from file, check that englishFile is not equal
to file.getAbsolutePath() and that new File(englishFile).exists() (handle
missing English file by skipping or throwing a clear IOException), and replace
the two RuntimeException throws around bundle and bundleEnglish creation with
rethrown IOExceptions (or wrap into MojoExecutionException if you prefer
consistent plugin error types) so callers get consistent checked exceptions;
refer to verifySafeHtml(), verify(), file, bundleEnglish, englishFile when
making these changes.
In
`@themes/src/main/resources-community/theme/base/account/messages/messages_lt.properties`:
- Line 101: The totpStep1 message in the Lithuanian locale
(messages_lt.properties) is erroneously Italian; replace the Italian string with
the correct Lithuanian text for the TOTP setup prompt by updating the totpStep1
value to: Įdiekite vieną iš šių programėlių savo mobiliajame telefone: and
ensure the file remains UTF-8 encoded so special characters are preserved.
In
`@themes/src/main/resources-community/theme/base/account/messages/messages_zh_CN.properties`:
- Line 112: The value for the resource key totpStep1 uses Traditional Chinese
characters but belongs in the Simplified Chinese (zh_CN) messages file; update
the totpStep1 entry to use Simplified Chinese characters (e.g., replace 手機→手机,
安裝→安装, 應用程式→应用程序) so the string matches the rest of the zh_CN file and remains
consistent for Simplified Chinese users.
In
`@themes/src/main/resources-community/theme/base/email/messages/messages_da.properties`:
- Line 9: The property identityProviderLinkBodyHtml contains a stray character
"n" before the last paragraph ("nHvis...") that will render in emails; remove
that stray "n" so the last <p> starts with "Hvis" (i.e., edit the
identityProviderLinkBodyHtml value to delete the leading "n" in the final <p>
segment).
In
`@themes/src/main/resources-community/theme/base/email/messages/messages_lt.properties`:
- Line 6: The localization string identityProviderLinkBodyHtml is missing the
leading "Ka" (it starts "žas pageidauja" instead of "Kažas pageidauja"); update
the value for identityProviderLinkBodyHtml to prepend "Ka" so the sentence reads
correctly ("Kažas pageidauja susieti..."), ensuring the rest of the placeholders
and HTML remain unchanged.
- Line 3: The localization string emailVerificationBodyHtml contains two typos:
change "Jei tao buvote" to "Jei tai buvote" and remove the stray leading "n" so
"nJei paskyros nekūrėte" becomes "Jei paskyros nekūrėte"; update the value for
emailVerificationBodyHtml accordingly in the messages_lt.properties entry.
In
`@themes/src/main/resources-community/theme/base/login/messages/messages_ca.properties`:
- Around line 423-427: The WebAuthn message entries
webauthn-error-auth-verification and webauthn-error-register-verification are
missing a space between the <br /> tag and the {0} placeholder; make them
consistent with webauthn-error-registration and webauthn-error-api-get by adding
a single space before `{0}` in the values for webauthn-error-auth-verification
and webauthn-error-register-verification so all four messages use "<br /> {0}".
In
`@themes/src/main/resources-community/theme/base/login/messages/messages_lt.properties`:
- Line 71: The value for the key loginTotpStep1 is Italian ("Installa una delle
seguenti applicazioni sul tuo cellulare:") but lives in the Lithuanian locale;
replace it with the correct Lithuanian translation (for example: "Įdiekite vieną
iš šių programėlių savo telefone:") so the loginTotpStep1 message is properly
localized in Lithuanian.
In
`@themes/src/main/resources-community/theme/base/login/messages/messages_tr.properties`:
- Line 469: Fix the typo in the properties value for the key
webauthn-error-registration: change "Anahatarınızı" to "Anahtarınızı" so the
message matches the correct spelling used elsewhere and reads "Geçiş
Anahtarınızı kaydederken hata oluştu.<br /> {0},".
🧹 Nitpick comments (2)
misc/theme-verifier/src/main/java/org/keycloak/themeverifier/VerifyMessageProperties.java (2)
58-63: Policy fields should beprivate static final.
POLICY_SOME_HTMLandPOLICY_NO_HTMLare immutable, reusable factories named with constant conventions. Declaring them as instance fields creates a new pair perVerifyMessagePropertiesobject and violates naming conventions.Similarly,
HTML_TAGSon line 139 should also beprivate static final.Proposed fix
- PolicyFactory POLICY_SOME_HTML = new org.owasp.html.HtmlPolicyBuilder() + private static final PolicyFactory POLICY_SOME_HTML = new org.owasp.html.HtmlPolicyBuilder() .allowElements( "br", "p", "strong", "b" ).toFactory(); - PolicyFactory POLICY_NO_HTML = new org.owasp.html.HtmlPolicyBuilder().toFactory(); + private static final PolicyFactory POLICY_NO_HTML = new org.owasp.html.HtmlPolicyBuilder().toFactory();And on line 139:
- Pattern HTML_TAGS = Pattern.compile("<[a-z]+[^>]*>"); + private static final Pattern HTML_TAGS = Pattern.compile("<[a-z]+[^>]*>");
150-162: Typo:santizeAnchors→sanitizeAnchors.Minor naming typo (missing
i). Also referenced on line 88.Proposed rename
- private String santizeAnchors(String key, String value, String englishValue) { + private String sanitizeAnchors(String key, String value, String englishValue) {And on line 88:
- value = santizeAnchors(key, value, englishValue); + value = sanitizeAnchors(key, value, englishValue);
| <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> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Check latest versions from Maven Central
echo "=== OWASP Java HTML Sanitizer Latest Version ==="
curl -s "https://search.maven.org/solrsearch/select?q=g:com.googlecode.owasp-java-html-sanitizer+AND+a:owasp-java-html-sanitizer&rows=1&wt=json" | jq -r '.response.docs[0].latestVersion // "Not found"'
echo "=== Apache Commons Text Latest Version ==="
curl -s "https://search.maven.org/solrsearch/select?q=g:org.apache.commons+AND+a:commons-text&rows=1&wt=json" | jq -r '.response.docs[0].latestVersion // "Not found"'Repository: admin-coderabbit/coderabbit-keycloak-mirror
Length of output: 196
🌐 Web query:
owasp-java-html-sanitizer 20240325.1 latest version 2025 2026
💡 Result:
- Latest released version (as of Feb 2026):
20260102.1— published to Maven Central on Jan 3, 2026 (with20260101.1also present from Jan 1, 2026). [1][2] - GitHub “Releases” page still shows
20240325.1(Mar 25, 2024) as “Latest”, so Maven Central has newer artifacts than what’s shown in GitHub releases. [3][1] - Security note: CVE-2025-66021 is reported against
20240325.1(configuration-dependent XSS). [4] GitLab’s advisory database lists20260101.1as the fix version (i.e., upgrade to20260101.1+). [5]
Answer: For 2025/2026, the latest version is 20260102.1. [1][2]
🌐 Web query:
commons-text 1.13.0 latest version 2025 2026 security
💡 Result:
- commons-text 1.13.0 is not the latest: it was released 2024-12-10. The latest Apache Commons Text release (as of Feb 2026) is 1.15.0, released 2025-12-04 (with interim releases 1.13.1 on 2025-04-07 and 1.14.0 on 2025-07-20). [1] [2]
- Security (2025–2026):
- The Apache Commons Text project’s own security page highlights the well-known interpolation RCE issue affecting versions prior to 1.10.0 (CVE-2022-42889), centered on unsafe use of
StringSubstitutorwith untrusted input. Versions >= 1.10.0 mitigate this class of issue, but applications still must avoid passing untrusted input into powerful interpolators without sanitization. [3] - CVE-2025-46295 is listed by NVD with essentially the same “commons-text < 1.10.0 interpolation can lead to RCE if untrusted input is used” condition; it notes it was “fully addressed in FileMaker Server 22.0.4.” This does not indicate a new flaw in 1.13.0+; it again points to the <1.10.0 risk pattern. [4]
- The Apache Commons Text project’s own security page highlights the well-known interpolation RCE issue affecting versions prior to 1.10.0 (CVE-2022-42889), centered on unsafe use of
Practical takeaway: If you’re on 1.13.0, you’re already beyond the <1.10.0 vulnerable range; upgrade to 1.15.0 anyway for the newest fixes/maintenance. [1] [2]
Sources: [1] Apache Commons Text “Changes / Release History” • [2] Apache Commons Text download page • [3] Apache Commons Text security reports page • [4] NVD entry for CVE-2025-46295
Update owasp-java-html-sanitizer to 20260102.1 (or at minimum 20260101.1) — CVE-2025-66021 affects version 20240325.1.
Version 20240325.1 has a known configuration-dependent XSS vulnerability (CVE-2025-66021). The latest stable release 20260102.1 (Jan 3, 2026) addresses this. Additionally, update commons-text to 1.15.0 (currently at 1.13.0), the latest stable release as of Dec 2025.
🤖 Prompt for AI Agents
In `@misc/theme-verifier/pom.xml` around lines 75 - 85, Update the vulnerable
dependency versions in the POM: bump
com.googlecode.owasp-java-html-sanitizer:owasp-java-html-sanitizer from
20240325.1 to 20260102.1 (or at minimum 20260101.1) to mitigate CVE-2025-66021,
and update org.apache.commons:commons-text from 1.13.0 to 1.15.0; ensure the
version strings are changed in the <dependency> entries for those artifactIds
and run a build to verify compatibility.
| 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); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
verifySafeHtml() throws unchecked RuntimeException, inconsistent with verify()'s IOException handling.
The caller verify() (line 46) wraps IOException in MojoExecutionException, but verifySafeHtml() throws raw RuntimeException on lines 70 and 79, which will bypass that handling and propagate as an unexpected crash. Consider throwing IOException (or MojoExecutionException) instead, or catch the RuntimeException in verify().
Also, if the English counterpart file doesn't exist (e.g., the file is already the English file or has no locale suffix the regex can match), line 76 will throw a RuntimeException with a confusing message. Consider a guard check.
Proposed fix — propagate IOException
- private void verifySafeHtml() {
+ private void verifySafeHtml() throws IOException {
PropertyResourceBundle bundle;
- try (FileInputStream fis = new FileInputStream(file)) {
+ try (var fis = Files.newInputStream(file.toPath())) {
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)) {
+ File englishPath = new File(englishFile);
+ if (!englishPath.exists()) {
+ return; // Skip HTML verification when no English baseline is available
+ }
+ try (var fis = Files.newInputStream(englishPath.toPath())) {
bundleEnglish = new PropertyResourceBundle(fis);
- } catch (IOException e) {
- throw new RuntimeException("unable to read file " + englishFile, e);
}🤖 Prompt for AI Agents
In
`@misc/theme-verifier/src/main/java/org/keycloak/themeverifier/VerifyMessageProperties.java`
around lines 65 - 80, verifySafeHtml() currently wraps IO failures in
RuntimeException which bypasses verify()'s IOException->MojoExecutionException
flow; change verifySafeHtml() to declare/throw IOException (or throw
MojoExecutionException) instead of RuntimeException and rethrow the caught
IOException so verify() can handle it. Also add a guard before opening
englishFile: compute englishFile from file, check that englishFile is not equal
to file.getAbsolutePath() and that new File(englishFile).exists() (handle
missing English file by skipping or throwing a clear IOException), and replace
the two RuntimeException throws around bundle and bundleEnglish creation with
rethrown IOExceptions (or wrap into MojoExecutionException if you prefer
consistent plugin error types) so callers get consistent checked exceptions;
refer to verifySafeHtml(), verify(), file, bundleEnglish, englishFile when
making these changes.
| if (!Objects.equals(sanitized, value)) { | ||
|
|
||
| // Strip identical characters from the beginning and the end to show where the difference is | ||
| int start = 0; | ||
| while (start < sanitized.length() && start < value.length() && value.charAt(start) == sanitized.charAt(start)) { | ||
| start++; | ||
| } | ||
| int end = 0; | ||
| while (end < sanitized.length() && end < value.length() && value.charAt(value.length() - end - 1) == sanitized.charAt(sanitized.length() - end - 1)) { | ||
| end++; | ||
| } | ||
|
|
||
| messages.add("Illegal HTML in key " + key + " for file " + file + ": '" + value.substring(start, value.length() - end) + "' vs. '" + sanitized.substring(start, sanitized.length() - end) + "'"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bug: start and end indices can overlap, causing IllegalArgumentException in substring.
When the sanitizer removes characters (making sanitized shorter than value), the prefix-scan (start) and suffix-scan (end) are computed independently. If start + end >= sanitized.length(), then sanitized.substring(start, sanitized.length() - end) will have beginIndex > endIndex.
Example: value = "aa", sanitized = "a" → start=1, end=1 → sanitized.substring(1, 0) throws.
Proposed fix — clamp end to prevent overlap
int end = 0;
while (end < sanitized.length() && end < value.length() && value.charAt(value.length() - end - 1) == sanitized.charAt(sanitized.length() - end - 1)) {
end++;
}
+ // Prevent overlap between start and end
+ end = Math.min(end, Math.min(sanitized.length(), value.length()) - start);
+ if (end < 0) end = 0;
messages.add("Illegal HTML in key " + key + " for file " + file + ": '" + value.substring(start, value.length() - end) + "' vs. '" + sanitized.substring(start, sanitized.length() - end) + "'");📝 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.
| if (!Objects.equals(sanitized, value)) { | |
| // Strip identical characters from the beginning and the end to show where the difference is | |
| int start = 0; | |
| while (start < sanitized.length() && start < value.length() && value.charAt(start) == sanitized.charAt(start)) { | |
| start++; | |
| } | |
| int end = 0; | |
| while (end < sanitized.length() && end < value.length() && value.charAt(value.length() - end - 1) == sanitized.charAt(sanitized.length() - end - 1)) { | |
| end++; | |
| } | |
| messages.add("Illegal HTML in key " + key + " for file " + file + ": '" + value.substring(start, value.length() - end) + "' vs. '" + sanitized.substring(start, sanitized.length() - end) + "'"); | |
| if (!Objects.equals(sanitized, value)) { | |
| // Strip identical characters from the beginning and the end to show where the difference is | |
| int start = 0; | |
| while (start < sanitized.length() && start < value.length() && value.charAt(start) == sanitized.charAt(start)) { | |
| start++; | |
| } | |
| int end = 0; | |
| while (end < sanitized.length() && end < value.length() && value.charAt(value.length() - end - 1) == sanitized.charAt(sanitized.length() - end - 1)) { | |
| end++; | |
| } | |
| // Prevent overlap between start and end | |
| end = Math.min(end, Math.min(sanitized.length(), value.length()) - start); | |
| if (end < 0) end = 0; | |
| messages.add("Illegal HTML in key " + key + " for file " + file + ": '" + value.substring(start, value.length() - end) + "' vs. '" + sanitized.substring(start, sanitized.length() - end) + "'"); |
🤖 Prompt for AI Agents
In
`@misc/theme-verifier/src/main/java/org/keycloak/themeverifier/VerifyMessageProperties.java`
around lines 99 - 111, In VerifyMessageProperties (around the messages.add call)
clamp the computed end so it never overlaps with start: after computing start
and end, set end = Math.min(end, Math.max(0, sanitized.length() - start)); then
use the clamped end when taking substrings from both value and sanitized to
ensure beginIndex <= endIndex and avoid IllegalArgumentException; keep
references to start, end, value, sanitized, key and file unchanged.
| 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; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Anchor stripping uses replaceFirst which may remove the wrong occurrence.
matcher.find() locates an anchor at a specific position in value, but value.replaceFirst(...) removes the first occurrence of that anchor string — which might be at an earlier position if the same anchor tag appears multiple times. This could corrupt the value by removing the wrong anchor.
Consider using matcher's position to do a positional replacement, or build the result string incrementally.
🤖 Prompt for AI Agents
In
`@misc/theme-verifier/src/main/java/org/keycloak/themeverifier/VerifyMessageProperties.java`
around lines 150 - 161, The santizeAnchors method currently uses matcher.find()
to locate anchors but value.replaceFirst(...) to remove them, which can remove
the wrong occurrence; change the logic to perform positional removals using the
Matcher API (e.g., use matcher.start()/matcher.end() indices or build a new
StringBuilder result while iterating) so you remove the exact matched substring
from value rather than the first global occurrence; update uses of
ANCHOR_PATTERN, matcher and englishMatcher inside santizeAnchors (and preserve
adding to messages on mismatch) to compute and return the correctly sanitized
string.
| @@ -98,7 +98,7 @@ revoke=Atšaukti įgaliojimą | |||
|
|
|||
| 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: | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wrong language: Italian text in the Lithuanian locale file.
The totpStep1 value is in Italian ("Installa una delle seguenti applicazioni sul tuo cellulare:") instead of Lithuanian. Every other string in this file is correctly in Lithuanian. This will cause Lithuanian-locale users to see a single Italian sentence in the TOTP setup flow.
This should be replaced with the Lithuanian equivalent, e.g.:
Proposed fix
-totpStep1=Installa una delle seguenti applicazioni sul tuo cellulare:
+totpStep1=\u012ediekite vien\u0105 i\u0161 \u0161i\u0173 program\u0117li\u0173 savo mobiliajame telefone:(The escaped form represents: Įdiekite vieną iš šių programėlių savo mobiliajame telefone:)
,
📝 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.
| totpStep1=Installa una delle seguenti applicazioni sul tuo cellulare: | |
| totpStep1=\u012ediekite vien\u0105 i\u0161 \u0161i\u0173 program\u0117li\u0173 savo mobiliajame telefone: |
🤖 Prompt for AI Agents
In
`@themes/src/main/resources-community/theme/base/account/messages/messages_lt.properties`
at line 101, The totpStep1 message in the Lithuanian locale
(messages_lt.properties) is erroneously Italian; replace the Italian string with
the correct Lithuanian text for the TOTP setup prompt by updating the totpStep1
value to: Įdiekite vieną iš šių programėlių savo mobiliajame telefone: and
ensure the file remains UTF-8 encoded so special characters are preserved.
| @@ -1,15 +1,15 @@ | |||
| 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> | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Two apparent typos in Lithuanian email verification HTML.
"Jei tao buvote"—taoshould likely betai(matching the plain-text variant on line 2:"Jei tai buvote")."nJei paskyros nekūrėte"— straynprefix; should be"Jei paskyros nekūrėte".
Proposed fix
-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 tai 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>📝 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.
| 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 tai 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`
at line 3, The localization string emailVerificationBodyHtml contains two typos:
change "Jei tao buvote" to "Jei tai buvote" and remove the stray leading "n" so
"nJei paskyros nekūrėte" becomes "Jei paskyros nekūrėte"; update the value for
emailVerificationBodyHtml accordingly in the messages_lt.properties entry.
| 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> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Truncated word at the start of identityProviderLinkBodyHtml.
The value starts with "žas pageidauja", but the plain-text version on line 5 begins with "Kažas pageidauja" ("Someone wants to…"). The leading "Ka" is missing, producing a broken sentence.
Proposed fix
-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>📝 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.
| 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`
at line 6, The localization string identityProviderLinkBodyHtml is missing the
leading "Ka" (it starts "žas pageidauja" instead of "Kažas pageidauja"); update
the value for identityProviderLinkBodyHtml to prepend "Ka" so the sentence reads
correctly ("Kažas pageidauja susieti..."), ensuring the rest of the placeholders
and HTML remain unchanged.
| webauthn-error-registration=No s''ha pogut registrar la vostra clau de seguretat.<br /> {0} | ||
| webauthn-error-api-get=No s''ha pogut identificar amb la clau de seguretat.<br /> {0} | ||
| webauthn-error-different-user=L''usuari identificat primer no és l''autenticat per la clau de seguretat. | ||
| 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-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} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Inconsistent spacing before {0} placeholder across WebAuthn error messages.
Lines 423–424 have a space between <br /> and {0}, while lines 426–427 do not. This should be consistent across all four messages.
Proposed fix (pick one style — here, with space for consistency with lines 423–424)
-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-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}📝 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.
| webauthn-error-registration=No s''ha pogut registrar la vostra clau de seguretat.<br /> {0} | |
| webauthn-error-api-get=No s''ha pogut identificar amb la clau de seguretat.<br /> {0} | |
| webauthn-error-different-user=L''usuari identificat primer no és l''autenticat per la clau de seguretat. | |
| 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-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-registration=No s''ha pogut registrar la vostra clau de seguretat.<br /> {0} | |
| webauthn-error-api-get=No s''ha pogut identificar amb la clau de seguretat.<br /> {0} | |
| webauthn-error-different-user=L''usuari identificat primer no és l''autenticat per la clau de seguretat. | |
| 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} |
🤖 Prompt for AI Agents
In
`@themes/src/main/resources-community/theme/base/login/messages/messages_ca.properties`
around lines 423 - 427, The WebAuthn message entries
webauthn-error-auth-verification and webauthn-error-register-verification are
missing a space between the <br /> tag and the {0} placeholder; make them
consistent with webauthn-error-registration and webauthn-error-api-get by adding
a single space before `{0}` in the values for webauthn-error-auth-verification
and webauthn-error-register-verification so all four messages use "<br /> {0}".
| @@ -68,7 +68,7 @@ country=Šalis | |||
| emailVerified=El. pašto adresas patvirtintas | |||
| 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: | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wrong language: Italian text in Lithuanian locale file.
The value "Installa una delle seguenti applicazioni sul tuo cellulare:" is Italian, not Lithuanian. This will cause Lithuanian users to see an Italian instruction for the TOTP setup step. The correct Lithuanian translation should be used instead, e.g.:
Proposed fix
-loginTotpStep1=Installa una delle seguenti applicazioni sul tuo cellulare:
+loginTotpStep1=Įdiekite vieną iš šių programėlių į savo mobilųjį telefoną:📝 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.
| loginTotpStep1=Installa una delle seguenti applicazioni sul tuo cellulare: | |
| loginTotpStep1=Įdiekite vieną iš šių programėlių į savo mobilųjį telefoną: |
🤖 Prompt for AI Agents
In
`@themes/src/main/resources-community/theme/base/login/messages/messages_lt.properties`
at line 71, The value for the key loginTotpStep1 is Italian ("Installa una delle
seguenti applicazioni sul tuo cellulare:") but lives in the Lithuanian locale;
replace it with the correct Lithuanian translation (for example: "Įdiekite vieną
iš šių programėlių savo telefone:") so the loginTotpStep1 message is properly
localized in Lithuanian.
| @@ -466,11 +466,11 @@ webauthn-unsupported-browser-text= WebAuthn tarayıcınız tarafından desteklen | |||
| webauthn-doAuthenticate= Geçiş Anahtarı ile giriş yap, | |||
| webauthn-createdAt-label= Oluşturuldu, | |||
| webauthn-error-title= Geçiş Anahtarı hatası, | |||
| webauthn-error-registration= Geçiş Anahatarınızı kaydederken hata oluştu.<br/> {0}, | |||
| webauthn-error-api-get= Geçiş Anahtarınızı doğrularken hata oluştu.<br/> {0}, | |||
| webauthn-error-registration= Geçiş Anahatarınızı kaydederken hata oluştu.<br /> {0}, | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typo: "Anahatarınızı" should be "Anahtarınızı".
Line 469 has a transposed letter — "Anahatarınızı" vs. the correct "Anahtarınızı" used on line 470. Since this line is already being touched, it's a good opportunity to fix it.
🔤 Proposed fix
-webauthn-error-registration= Geçiş Anahatarınızı kaydederken hata oluştu.<br /> {0},
+webauthn-error-registration= Geçiş Anahtarınızı kaydederken hata oluştu.<br /> {0},📝 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.
| webauthn-error-registration= Geçiş Anahatarınızı kaydederken hata oluştu.<br /> {0}, | |
| webauthn-error-registration= Geçiş Anahtarınızı kaydederken hata oluştu.<br /> {0}, |
🤖 Prompt for AI Agents
In
`@themes/src/main/resources-community/theme/base/login/messages/messages_tr.properties`
at line 469, Fix the typo in the properties value for the key
webauthn-error-registration: change "Anahatarınızı" to "Anahtarınızı" so the
message matches the correct spelling used elsewhere and reads "Geçiş
Anahtarınızı kaydederken hata oluştu.<br /> {0},".
This pull request was automatically created by
@coderabbitai/e2e-reviewer.Batch created pull request.
Summary by CodeRabbit
New Features
Bug Fixes
Localization