fix: add session alert email template translations for all languages#11395
fix: add session alert email template translations for all languages#11395slegarraga wants to merge 1 commit intoappwrite:mainfrom
Conversation
The session alert email template only had translation keys defined in
en.json. For all other languages, the raw template key names (e.g.,
{{emails.sessionAlert.subject}}) were displayed instead of actual text.
This adds the English session alert translation keys as fallback to all
72 non-English locale files, ensuring users receive readable emails
regardless of their locale setting.
Closes appwrite#8659
📝 WalkthroughWalkthroughThis pull request adds session alert email translation keys to 70+ locale files in the Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Security Scan Results for PRDocker Image Scan Results
Source Code Scan Results🎉 No vulnerabilities found! |
There was a problem hiding this comment.
Actionable comments posted: 3
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (5)
app/config/locale/translations/el.json (1)
2-3:⚠️ Potential issue | 🟡 MinorChange
settings.localefrom"gr"to"el"for consistency with filename and pattern.The file
el.jsonhas"settings.locale": "gr"on line 3, but it should be"el"to match the filename and be consistent with all other locale files (e.g.,en.jsonhas"en",fr.jsonhas"fr"). While this won't break locale resolution—which uses the filenameel.jsonrather than thesettings.localevalue—the inconsistency should be corrected for data integrity.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/config/locale/translations/el.json` around lines 2 - 3, Update the value for the "settings.locale" key in el.json from "gr" to "el" so it matches the filename and the convention used by other locale files; locate the "settings.locale" entry in app/config/locale/translations/el.json and replace the value with "el".app/config/locale/translations/fa.json (2)
198-198:⚠️ Potential issue | 🟡 MinorPre-existing:
countries.sz(Swaziland/Eswatini) is mapped to "سوئیس" (Switzerland).
ch(Line 62) is already correctly mapped to "سوئیس". Theszslot needs a distinct Eswatini/Swaziland translation (e.g., "سوازیلند").🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/config/locale/translations/fa.json` at line 198, The translation for the key "countries.sz" is incorrect (currently set to "سوئیس" which is Switzerland); update the value for "countries.sz" to the correct Eswatini/Swaziland translation (e.g., "سوازیلند") so it differs from "countries.ch" which is correctly "سوئیس"; ensure no other duplicate country mappings exist and run a quick grep for "countries.sz" to confirm the change is applied consistently.
12-30:⚠️ Potential issue | 🟠 MajorPre-existing: all signature keys use
{{user}}instead of{{project}}.Lines 12, 16, 23, and 30 use
{{user}}as the template variable, so every outgoing email in thefalocale renders the signed-in user's name (e.g., "تیم Alice") as the sender signature instead of the project name. This affects verification, magic-session, recovery, and invitation emails.🐛 Proposed fix (all four signature keys)
- "emails.verification.signature": "تیم {{user}}", + "emails.verification.signature": "تیم {{project}}", ... - "emails.magicSession.signature": "تیم {{user}}", + "emails.magicSession.signature": "تیم {{project}}", ... - "emails.recovery.signature": "تیم {{user}}", + "emails.recovery.signature": "تیم {{project}}", ... - "emails.invitation.signature": "تیم {{user}}", + "emails.invitation.signature": "تیم {{project}}",🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/config/locale/translations/fa.json` around lines 12 - 30, The four email signature translations mistakenly use the user variable; update the template variable from {{user}} to {{project}} for the keys emails.verification.signature, emails.magicSession.signature, emails.recovery.signature, and emails.invitation.signature so the project name is rendered as the sender; ensure you only change the template placeholder text (preserve surrounding quotes and punctuation) in the fa.json entries for those keys.app/config/locale/translations/ur.json (1)
181-182:⚠️ Potential issue | 🟡 MinorPre-existing:
countries.rwandcountries.savalues are swapped.Line 181 (
countries.rw— Rwanda) is an empty string, while Line 182 (countries.sa— Saudi Arabia) holds "روانڈا", which is the Urdu transliteration of Rwanda. Saudi Arabia should be "سعودی عرب".🐛 Proposed fix
- "countries.rw": "", - "countries.sa": "روانڈا", + "countries.rw": "روانڈا", + "countries.sa": "سعودی عرب",🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/config/locale/translations/ur.json` around lines 181 - 182, Swap and correct the values for the locale keys countries.rw and countries.sa in ur.json: set countries.rw to "روانڈا" (Rwanda) and set countries.sa to "سعودی عرب" (Saudi Arabia), ensuring no extra whitespace or trailing commas are introduced and that the keys remain unchanged.app/config/locale/translations/or.json (1)
236-241:⚠️ Potential issue | 🟠 MajorPre-existing: multiple
magicSessionkeys contain wrong-language content.These values were not introduced by this PR, but since
or.jsonis being modified it is worth addressing:
Line Key Actual language in value 236 emails.magicSession.optionButtonCroatian/Bosnian 237 emails.magicSession.buttonTextSpanish 238 emails.magicSession.clientInfoCzech 240 emails.magicSession.securityPhrasePortuguese 241 emails.magicSession.optionUrlHebrew These keys currently serve garbled, mixed-language content to Odia (
or) users. They should be replaced with either proper Odia translations or the English fallback strings.Would you like me to open a separate issue to track the cleanup of
or.jsonmagic session keys?🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/config/locale/translations/or.json` around lines 236 - 241, The listed emails.magicSession keys (emails.magicSession.optionButton, emails.magicSession.buttonText, emails.magicSession.clientInfo, emails.magicSession.securityPhrase, emails.magicSession.optionUrl) contain text in incorrect languages; replace each value with either a correct Odia translation or the English fallback string, preserving all interpolation placeholders (e.g., {{project}}, {{agentClient}}, {{agentDevice}}, {{agentOs}}, {{phrase}}, {{secret}}) and punctuation/format (button vs. sentence), and ensure the updated strings match the style of other locale entries for magic session emails.
🧹 Nitpick comments (3)
app/config/locale/translations/id.json (1)
249-258: Add a locale key-parity check in CI to prevent regressions.Recommend a small validation step that asserts every locale includes the required
emails.sessionAlert.*keyset (and ideally all email key groups), so missing keys are caught before merge.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/config/locale/translations/id.json` around lines 249 - 258, Add a CI validation that asserts all locale files contain the required emails.sessionAlert.* keys (emails.sessionAlert.subject, preview, hello, body, listDevice, listIpAddress, listCountry, footer, thanks, signature) to prevent regressions; implement this by adding a small script (e.g., validateLocales or checkLocaleParity) that loads the default locale keys, iterates other locale JSONs, and fails with a non-zero exit code when any required key from the emails.sessionAlert group is missing, then wire that script into the existing CI job (run-locales or locale-check step) so PRs cannot merge with missing email keys.app/config/locale/translations/ar-ma.json (1)
238-248: Optional: keepemails.*namespaces grouped together in the file.This works as-is, but placing
emails.sessionAlert.*near the otheremails.*entries would improve discoverability and reduce future merge friction.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/config/locale/translations/ar-ma.json` around lines 238 - 248, The emails.sessionAlert.* keys are placed away from the other emails.* entries; move the block of keys ("emails.sessionAlert.subject", "emails.sessionAlert.preview", "emails.sessionAlert.hello", "emails.sessionAlert.body", "emails.sessionAlert.listDevice", "emails.sessionAlert.listIpAddress", "emails.sessionAlert.listCountry", "emails.sessionAlert.footer", "emails.sessionAlert.thanks", "emails.sessionAlert.signature") into the existing emails.* group so all email-related translations are contiguous, preserving the exact keys and values and maintaining surrounding JSON ordering/commas to keep the file valid.app/config/locale/translations/jv.json (1)
249-258: Add automated locale key-parity validation.This backfill fixes the immediate issue, but future template-key additions can regress similarly. Consider a CI check that verifies every locale includes the full
emails.*keyset fromen.json.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/config/locale/translations/jv.json` around lines 249 - 258, The Javanese locale (jv.json) is missing the full emails.* keyset parity with en.json, causing potential template regressions; add a CI validation that loads en.json as the canonical emails.* keyset and compares keys against each locale file (e.g., jv.json) to fail the build on any missing or extra keys. Implement this as a script (run in CI) that reads the top-level emails.* keys from en.json, recursively enumerates keys, then checks each locale file for exact key parity and reports diffs; hook it into the existing CI test stage so any addition to emails.* requires corresponding updates to all locale files.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@app/config/locale/translations/de.json`:
- Line 249: Remove the stray "mock" translation entry from the de.json locale by
deleting the "mock": "Eine Beispielübersetzung für Testzwecke." key/value pair;
ensure the JSON remains valid (no trailing commas) and run the locale validation
or i18n extraction/test suite to confirm no tooling expects that test key.
In `@app/config/locale/translations/es.json`:
- Line 248: Restore the missing trailing period in the translation for
emails.otpSession.signature by updating the value back to "El equipo de
{{project}}." (note the final period) so it matches the style of
emails.verification.signature; ensure you only add the period before the closing
quote and keep the surrounding JSON commas intact.
In `@app/config/locale/translations/ga.json`:
- Around line 249-258: The ga.json locale contains English text for the
emails.sessionAlert.* keys (emails.sessionAlert.subject, preview, hello, body,
listDevice, listIpAddress, listCountry, footer, thanks, signature), which causes
unreadable security emails for non-English users; either (preferred) wire up a
locale fallback chain so the i18n loader/template engine falls back to en.json
for missing keys (implement fallback resolution in the i18n initialization or
template helper used to render these email templates), or (if fallback cannot be
added now) provide proper Irish translations for all emails.sessionAlert.* keys
in ga.json so security alerts are readable; update the i18n configuration or
template helper that resolves keys (and tests) to ensure missing-key lookup
falls back to English.
---
Outside diff comments:
In `@app/config/locale/translations/el.json`:
- Around line 2-3: Update the value for the "settings.locale" key in el.json
from "gr" to "el" so it matches the filename and the convention used by other
locale files; locate the "settings.locale" entry in
app/config/locale/translations/el.json and replace the value with "el".
In `@app/config/locale/translations/fa.json`:
- Line 198: The translation for the key "countries.sz" is incorrect (currently
set to "سوئیس" which is Switzerland); update the value for "countries.sz" to the
correct Eswatini/Swaziland translation (e.g., "سوازیلند") so it differs from
"countries.ch" which is correctly "سوئیس"; ensure no other duplicate country
mappings exist and run a quick grep for "countries.sz" to confirm the change is
applied consistently.
- Around line 12-30: The four email signature translations mistakenly use the
user variable; update the template variable from {{user}} to {{project}} for the
keys emails.verification.signature, emails.magicSession.signature,
emails.recovery.signature, and emails.invitation.signature so the project name
is rendered as the sender; ensure you only change the template placeholder text
(preserve surrounding quotes and punctuation) in the fa.json entries for those
keys.
In `@app/config/locale/translations/or.json`:
- Around line 236-241: The listed emails.magicSession keys
(emails.magicSession.optionButton, emails.magicSession.buttonText,
emails.magicSession.clientInfo, emails.magicSession.securityPhrase,
emails.magicSession.optionUrl) contain text in incorrect languages; replace each
value with either a correct Odia translation or the English fallback string,
preserving all interpolation placeholders (e.g., {{project}}, {{agentClient}},
{{agentDevice}}, {{agentOs}}, {{phrase}}, {{secret}}) and punctuation/format
(button vs. sentence), and ensure the updated strings match the style of other
locale entries for magic session emails.
In `@app/config/locale/translations/ur.json`:
- Around line 181-182: Swap and correct the values for the locale keys
countries.rw and countries.sa in ur.json: set countries.rw to "روانڈا" (Rwanda)
and set countries.sa to "سعودی عرب" (Saudi Arabia), ensuring no extra whitespace
or trailing commas are introduced and that the keys remain unchanged.
---
Nitpick comments:
In `@app/config/locale/translations/ar-ma.json`:
- Around line 238-248: The emails.sessionAlert.* keys are placed away from the
other emails.* entries; move the block of keys ("emails.sessionAlert.subject",
"emails.sessionAlert.preview", "emails.sessionAlert.hello",
"emails.sessionAlert.body", "emails.sessionAlert.listDevice",
"emails.sessionAlert.listIpAddress", "emails.sessionAlert.listCountry",
"emails.sessionAlert.footer", "emails.sessionAlert.thanks",
"emails.sessionAlert.signature") into the existing emails.* group so all
email-related translations are contiguous, preserving the exact keys and values
and maintaining surrounding JSON ordering/commas to keep the file valid.
In `@app/config/locale/translations/id.json`:
- Around line 249-258: Add a CI validation that asserts all locale files contain
the required emails.sessionAlert.* keys (emails.sessionAlert.subject, preview,
hello, body, listDevice, listIpAddress, listCountry, footer, thanks, signature)
to prevent regressions; implement this by adding a small script (e.g.,
validateLocales or checkLocaleParity) that loads the default locale keys,
iterates other locale JSONs, and fails with a non-zero exit code when any
required key from the emails.sessionAlert group is missing, then wire that
script into the existing CI job (run-locales or locale-check step) so PRs cannot
merge with missing email keys.
In `@app/config/locale/translations/jv.json`:
- Around line 249-258: The Javanese locale (jv.json) is missing the full
emails.* keyset parity with en.json, causing potential template regressions; add
a CI validation that loads en.json as the canonical emails.* keyset and compares
keys against each locale file (e.g., jv.json) to fail the build on any missing
or extra keys. Implement this as a script (run in CI) that reads the top-level
emails.* keys from en.json, recursively enumerates keys, then checks each locale
file for exact key parity and reports diffs; hook it into the existing CI test
stage so any addition to emails.* requires corresponding updates to all locale
files.
ℹ️ Review info
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (72)
app/config/locale/translations/af.jsonapp/config/locale/translations/ar-ma.jsonapp/config/locale/translations/ar.jsonapp/config/locale/translations/as.jsonapp/config/locale/translations/az.jsonapp/config/locale/translations/be.jsonapp/config/locale/translations/bg.jsonapp/config/locale/translations/bh.jsonapp/config/locale/translations/bn.jsonapp/config/locale/translations/bs.jsonapp/config/locale/translations/ca.jsonapp/config/locale/translations/cs.jsonapp/config/locale/translations/da.jsonapp/config/locale/translations/de.jsonapp/config/locale/translations/el.jsonapp/config/locale/translations/eo.jsonapp/config/locale/translations/es.jsonapp/config/locale/translations/fa.jsonapp/config/locale/translations/fi.jsonapp/config/locale/translations/fo.jsonapp/config/locale/translations/fr.jsonapp/config/locale/translations/ga.jsonapp/config/locale/translations/gu.jsonapp/config/locale/translations/he.jsonapp/config/locale/translations/hi.jsonapp/config/locale/translations/hr.jsonapp/config/locale/translations/hu.jsonapp/config/locale/translations/hy.jsonapp/config/locale/translations/id.jsonapp/config/locale/translations/is.jsonapp/config/locale/translations/it.jsonapp/config/locale/translations/ja.jsonapp/config/locale/translations/jv.jsonapp/config/locale/translations/km.jsonapp/config/locale/translations/kn.jsonapp/config/locale/translations/ko.jsonapp/config/locale/translations/la.jsonapp/config/locale/translations/lb.jsonapp/config/locale/translations/lt.jsonapp/config/locale/translations/lv.jsonapp/config/locale/translations/ml.jsonapp/config/locale/translations/mr.jsonapp/config/locale/translations/ms.jsonapp/config/locale/translations/nb.jsonapp/config/locale/translations/ne.jsonapp/config/locale/translations/nl.jsonapp/config/locale/translations/nn.jsonapp/config/locale/translations/or.jsonapp/config/locale/translations/pa.jsonapp/config/locale/translations/pl.jsonapp/config/locale/translations/pt-br.jsonapp/config/locale/translations/pt-pt.jsonapp/config/locale/translations/ro.jsonapp/config/locale/translations/ru.jsonapp/config/locale/translations/sa.jsonapp/config/locale/translations/sd.jsonapp/config/locale/translations/si.jsonapp/config/locale/translations/sk.jsonapp/config/locale/translations/sl.jsonapp/config/locale/translations/sn.jsonapp/config/locale/translations/sq.jsonapp/config/locale/translations/sv.jsonapp/config/locale/translations/ta.jsonapp/config/locale/translations/te.jsonapp/config/locale/translations/th.jsonapp/config/locale/translations/tl.jsonapp/config/locale/translations/tr.jsonapp/config/locale/translations/uk.jsonapp/config/locale/translations/ur.jsonapp/config/locale/translations/vi.jsonapp/config/locale/translations/zh-cn.jsonapp/config/locale/translations/zh-tw.json
| "emails.otpSession.thanks": "Danke,", | ||
| "emails.otpSession.signature": "{{project}} Team", | ||
| "mock": "Eine Beispielübersetzung für Testzwecke." | ||
| "mock": "Eine Beispielübersetzung für Testzwecke.", |
There was a problem hiding this comment.
Remove the stray "mock" test key from the production locale file.
"Eine Beispielübersetzung für Testzwecke." translates to "A sample translation for test purposes." — this is a test artifact that has no place in a production locale catalog. Any consumer that iterates all translation keys (e.g., completeness checks, export tools) will pick this up as a real key.
🐛 Proposed fix
- "mock": "Eine Beispielübersetzung für Testzwecke.",
"emails.sessionAlert.subject": "Security alert: new session on your {{project}} account",🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@app/config/locale/translations/de.json` at line 249, Remove the stray "mock"
translation entry from the de.json locale by deleting the "mock": "Eine
Beispielübersetzung für Testzwecke." key/value pair; ensure the JSON remains
valid (no trailing commas) and run the locale validation or i18n extraction/test
suite to confirm no tooling expects that test key.
| "emails.otpSession.securityPhrase": "La frase de seguridad para este correo electrónico es {{phrase}}. Puedes confiar en este correo si esta frase coincide con la frase mostrada durante el inicio de sesión.", | ||
| "emails.otpSession.thanks": "Gracias.,", | ||
| "emails.otpSession.signature": "El equipo de {{project}}" | ||
| "emails.otpSession.signature": "El equipo de {{project}}", |
There was a problem hiding this comment.
Unintended period stripped from emails.otpSession.signature value.
The original value was "El equipo de {{project}}." (with a trailing period matching emails.verification.signature on Line 12). The period was dropped while adding the JSON trailing comma, changing the rendered signature text.
🐛 Proposed fix
- "emails.otpSession.signature": "El equipo de {{project}}",
+ "emails.otpSession.signature": "El equipo de {{project}}.",📝 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.
| "emails.otpSession.signature": "El equipo de {{project}}", | |
| "emails.otpSession.signature": "El equipo de {{project}}.", |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@app/config/locale/translations/es.json` at line 248, Restore the missing
trailing period in the translation for emails.otpSession.signature by updating
the value back to "El equipo de {{project}}." (note the final period) so it
matches the style of emails.verification.signature; ensure you only add the
period before the closing quote and keep the surrounding JSON commas intact.
| "emails.sessionAlert.subject": "Security alert: new session on your {{project}} account", | ||
| "emails.sessionAlert.preview": "New login detected on {{project}} at {{time}} UTC.", | ||
| "emails.sessionAlert.hello": "Hello {{user}},", | ||
| "emails.sessionAlert.body": "A new session has been created on your {{b}}{{project}}{{/b}} account, {{b}}on {{date}}, {{year}} at {{time}} UTC{{/b}}.\nHere are the details of the new session: ", | ||
| "emails.sessionAlert.listDevice": "Device: {{b}}{{device}}{{/b}}", | ||
| "emails.sessionAlert.listIpAddress": "IP Address: {{b}}{{ipAddress}}{{/b}}", | ||
| "emails.sessionAlert.listCountry": "Country: {{b}}{{country}}{{/b}}", | ||
| "emails.sessionAlert.footer": "If this was you, there's nothing more you need to do.\nIf you didn't initiate this session or suspect any unauthorized activity, please secure your account.", | ||
| "emails.sessionAlert.thanks": "Thanks,", | ||
| "emails.sessionAlert.signature": "{{project}} team" |
There was a problem hiding this comment.
Security emails in an unreadable language pose a UX risk.
All emails.sessionAlert.* keys are English across every non-English locale file. While the PR description explicitly frames this as a stopgap English fallback for issue #8659, a security alert that a user cannot read is worse than a broken layout — the user cannot act on it. Since the system apparently has no automatic English fallback (which is why raw keys were shown), consider whether the template engine supports a fallback chain to en.json instead of duplicating English strings into 72 files. That would also simplify future native-translation contributions.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@app/config/locale/translations/ga.json` around lines 249 - 258, The ga.json
locale contains English text for the emails.sessionAlert.* keys
(emails.sessionAlert.subject, preview, hello, body, listDevice, listIpAddress,
listCountry, footer, thanks, signature), which causes unreadable security emails
for non-English users; either (preferred) wire up a locale fallback chain so the
i18n loader/template engine falls back to en.json for missing keys (implement
fallback resolution in the i18n initialization or template helper used to render
these email templates), or (if fallback cannot be added now) provide proper
Irish translations for all emails.sessionAlert.* keys in ga.json so security
alerts are readable; update the i18n configuration or template helper that
resolves keys (and tests) to ensure missing-key lookup falls back to English.
What does this PR do?
Fixes #8659 — Session alert email template was broken for all languages except English.
Problem
The session alert email template keys (
emails.sessionAlert.*) were only defined inen.json. When a user's locale was set to any non-English language (e.g.,es,fr,de), the email displayed raw template key names like{{emails.sessionAlert.subject}}instead of actual readable text.Solution
Added the English session alert translation keys as fallback to all 72 non-English locale files. This ensures users receive readable session alert emails regardless of their locale setting.
While ideally each language would have its own native translation, having the English text as fallback is far better than showing raw template keys. Native translations can be contributed incrementally.
Changes
emails.sessionAlert.*keys to all 72 non-English translation JSON files inapp/config/locale/translations/Testing
en.jsonwas not modified