Skip to content

Fix : custom email templates add translation support magic session keys#11235

Open
HarshMN2345 wants to merge 3 commits into1.8.xfrom
fix-SER-1090-custom-email-templates-add-translation-support-magic-session-keys
Open

Fix : custom email templates add translation support magic session keys#11235
HarshMN2345 wants to merge 3 commits into1.8.xfrom
fix-SER-1090-custom-email-templates-add-translation-support-magic-session-keys

Conversation

@HarshMN2345
Copy link
Member

What does this PR do?

image

Test Plan

(Write your test plan here. If you changed any code, please provide us with clear instructions on how you verified your changes work. Screenshots may also be helpful.)

Related PRs and Issues

  • (Related PR or issue)

Checklist

  • Have you read the Contributing Guidelines on issues?
  • If the PR includes a change to an API's metadata (desc, label, params, etc.), does it also include updated API specs and example docs?

@HarshMN2345 HarshMN2345 changed the base branch from main to 1.8.x February 3, 2026 12:27
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 3, 2026

📝 Walkthrough

Walkthrough

The changes introduce email template translation and retrieval enhancements across multiple endpoints. Three new translation entries are added for magicsession email templates. Helper functions for custom template retrieval (getCustomTemplate), template key normalization (normalizeEmailLocaleKey), and email translation (translateEmailTemplate) are introduced globally in account and teams controllers, and as protected methods in the MFA challenges class. Template lookups are refactored to use these helpers with support for case-insensitive type matching and locale-aware fallbacks. Custom email template content is passed through translation logic to resolve locale-specific placeholders.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Reasoning

The review demands attention to multiple distinct contexts: global helper functions in controllers, protected methods in a class-based module, and translation logic with placeholder resolution patterns. While the helper functions repeat across files, each implementation context requires separate reasoning. The translation logic is non-trivial, involving placeholder detection, key normalization with field remapping for magicsession variants, and fallback behavior. The changes span five files with heterogeneous purposes, though some patterns are consistent. Total line additions (~311) are substantial, and the logic density in template translation handling increases complexity beyond simple refactoring.

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title directly reflects the main change: adding translation support for custom email templates with magic session keys.
Description check ✅ Passed The description includes an image demonstrating the email template functionality in action, which relates to the changeset's focus on custom email templates.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ 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 fix-SER-1090-custom-email-templates-add-translation-support-magic-session-keys

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@pkg-pr-new
Copy link

pkg-pr-new bot commented Feb 3, 2026

Open in StackBlitz

npm i https://pkg.pr.new/appwrite/appwrite/@appwrite.io/console@11235

commit: ae392fe

@github-actions
Copy link

github-actions bot commented Feb 3, 2026

Security Scan Results for PR

Docker Image Scan Results

Package Version Vulnerability Severity
libcrypto3 3.5.4-r0 CVE-2025-15467 CRITICAL
libcrypto3 3.5.4-r0 CVE-2025-69419 HIGH
libcrypto3 3.5.4-r0 CVE-2025-69421 HIGH
libpng 1.6.51-r0 CVE-2025-66293 HIGH
libpng 1.6.51-r0 CVE-2026-22695 HIGH
libpng 1.6.51-r0 CVE-2026-22801 HIGH
libpng-dev 1.6.51-r0 CVE-2025-66293 HIGH
libpng-dev 1.6.51-r0 CVE-2026-22695 HIGH
libpng-dev 1.6.51-r0 CVE-2026-22801 HIGH
libssl3 3.5.4-r0 CVE-2025-15467 CRITICAL
libssl3 3.5.4-r0 CVE-2025-69419 HIGH
libssl3 3.5.4-r0 CVE-2025-69421 HIGH
libxml2 2.13.8-r0 CVE-2025-49794 CRITICAL
libxml2 2.13.8-r0 CVE-2025-49796 CRITICAL
libxml2 2.13.8-r0 CVE-2025-49795 HIGH
libxml2 2.13.8-r0 CVE-2025-6021 HIGH
openssl 3.5.4-r0 CVE-2025-15467 CRITICAL
openssl 3.5.4-r0 CVE-2025-69419 HIGH
openssl 3.5.4-r0 CVE-2025-69421 HIGH
openssl-dev 3.5.4-r0 CVE-2025-15467 CRITICAL
openssl-dev 3.5.4-r0 CVE-2025-69419 HIGH
openssl-dev 3.5.4-r0 CVE-2025-69421 HIGH
py3-urllib3 1.26.20-r0 CVE-2026-21441 HIGH
py3-urllib3-pyc 1.26.20-r0 CVE-2026-21441 HIGH
github.com/containerd/containerd/v2 v2.0.2 CVE-2024-25621 HIGH
golang.org/x/crypto v0.31.0 CVE-2025-22869 HIGH
golang.org/x/oauth2 v0.24.0 CVE-2025-22868 HIGH
stdlib 1.22.10 CVE-2025-47907 HIGH
stdlib 1.22.10 CVE-2025-58183 HIGH
stdlib 1.22.10 CVE-2025-61726 HIGH
stdlib 1.22.10 CVE-2025-61728 HIGH
stdlib 1.22.10 CVE-2025-61729 HIGH

Source Code Scan Results

🎉 No vulnerabilities found!

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In `@app/controllers/api/teams.php`:
- Around line 879-882: The custom SMS template returned by
getCustomTemplate(...) may lack a 'message' key which can make $message null and
later break setParam; update the block that reads $customTemplate to check
isset($customTemplate['message']) or array_key_exists('message',
$customTemplate) before assigning $message, and if missing leave $message as the
base template value (or explicitly fall back to the base template variable) so
setParam always receives a valid string.

In
`@src/Appwrite/Platform/Modules/Account/Http/Account/MFA/Challenges/Create.php`:
- Around line 253-256: The code currently replaces the Template object in
$message with a string when a custom SMS template exists, causing fatal errors
at later $message->setParam() calls; instead, keep $message as the Template
instance and inject the custom text into it (e.g. call
$message->setParam('message', $customTemplate['message']) or use the Template
object's appropriate setter) after verifying $customTemplate is non-empty, so
you never reassign $message to a string; update the block around
getCustomTemplate(...) to set the template text on the Template object rather
than overwrite $message.

Comment on lines +879 to 882
$customTemplate = getCustomTemplate($project, 'invitation', $locale, 'sms');
if (!empty($customTemplate)) {
$message = $customTemplate['message'];
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Guard against missing SMS template message key.
If a custom SMS template lacks message, $message becomes null and setParam will fatal; fall back to the base template.

🔧 Suggested fix
-                $message = $customTemplate['message'];
+                $message = $customTemplate['message'] ?? $message;
📝 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
$customTemplate = getCustomTemplate($project, 'invitation', $locale, 'sms');
if (!empty($customTemplate)) {
$message = $customTemplate['message'];
}
$customTemplate = getCustomTemplate($project, 'invitation', $locale, 'sms');
if (!empty($customTemplate)) {
$message = $customTemplate['message'] ?? $message;
}
🤖 Prompt for AI Agents
In `@app/controllers/api/teams.php` around lines 879 - 882, The custom SMS
template returned by getCustomTemplate(...) may lack a 'message' key which can
make $message null and later break setParam; update the block that reads
$customTemplate to check isset($customTemplate['message']) or
array_key_exists('message', $customTemplate) before assigning $message, and if
missing leave $message as the base template value (or explicitly fall back to
the base template variable) so setParam always receives a valid string.

Comment on lines +253 to 256
$customTemplate = $this->getCustomTemplate($project, 'mfaChallenge', $locale, 'sms');
if (!empty($customTemplate)) {
$message = $customTemplate['message'] ?? $message;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Custom SMS template replaces a Template object with a string.
Later calls to $message->setParam() will fatally error when a custom template is present.

🐛 Proposed fix
-                $customTemplate = $this->getCustomTemplate($project, 'mfaChallenge', $locale, 'sms');
-                if (!empty($customTemplate)) {
-                    $message = $customTemplate['message'] ?? $message;
-                }
+                $customTemplate = $this->getCustomTemplate($project, 'mfaChallenge', $locale, 'sms');
+                if (!empty($customTemplate['message'])) {
+                    $message = Template::fromString($customTemplate['message']);
+                }
🤖 Prompt for AI Agents
In `@src/Appwrite/Platform/Modules/Account/Http/Account/MFA/Challenges/Create.php`
around lines 253 - 256, The code currently replaces the Template object in
$message with a string when a custom SMS template exists, causing fatal errors
at later $message->setParam() calls; instead, keep $message as the Template
instance and inject the custom text into it (e.g. call
$message->setParam('message', $customTemplate['message']) or use the Template
object's appropriate setter) after verifying $customTemplate is non-empty, so
you never reassign $message to a string; update the block around
getCustomTemplate(...) to set the template text on the Template object rather
than overwrite $message.

@github-actions
Copy link

github-actions bot commented Feb 3, 2026

✨ Benchmark results

  • Requests per second: 2,289
  • Requests with 200 status code: 412,029
  • P99 latency: 0.06870723

⚡ Benchmark Comparison

Metric This PR Latest version
RPS 2,289 1,143
200 412,029 205,841
P99 0.06870723 0.180564462

@HarshMN2345 HarshMN2345 requested a review from hmacr February 3, 2026 13:52
$oauthDefaultFailure = '/console/auth/oauth2/failure';

if (!function_exists('getCustomTemplate')) {
function getCustomTemplate(Document $project, string $type, Locale $locale, string $prefix = 'email'): array
Copy link
Contributor

Choose a reason for hiding this comment

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

Avoid need for global function by fixing root cause - finding what write with lowercase instead of properCase

"emails.magicSession.securityPhrase": "Security phrase for this email is {{b}}{{phrase}}{{/b}}. You can trust this email if this phrase matches the phrase shown during sign in.",
"emails.magicSession.thanks": "Thanks,",
"emails.magicSession.signature": "{{project}} team",
"emails.magicsession.body": "Click the button below to securely sign in to your {{b}}{{project}}{{/b}} account. This link will expire in 1 hour.",
Copy link
Contributor

Choose a reason for hiding this comment

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

Let's update tests too - add custom smtp translation scenrio that was a bug, and ensure it is now working

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