From d1806f5fb69c2fe5c9cd10c77d8ada98e2217b62 Mon Sep 17 00:00:00 2001 From: harsh mahajan Date: Tue, 19 May 2026 16:13:54 +0530 Subject: [PATCH 1/3] fix: allow clearing optional SMTP and email template sender fields MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Optional fields (senderEmail, replyToEmail, senderName, replyToName, username, password) could not be cleared once set. The frontend used || undefined which silently dropped empty strings, so the backend never received "" and the old value persisted on reload. smtp/+page.svelte: - Use ?? undefined instead of || undefined so empty strings are sent - Fix isButtonDisabled deepEqual comparison: normalize types on both sides (?? '' for strings, ?? null for port, normalizeSecure() for secure) to avoid false positives from null/undefined mismatches - Derive project from data.project so it stays reactive after invalidate() — fixes button not disabling after save without reload - Remove second $effect that cleared fields on disable, which fought the first effect and kept the button permanently enabled emailTemplate.svelte: - Use ?? undefined instead of || undefined for sender/reply fields - Add disabled={!isSmtpEnabled} to replyToEmail and replyToName, matching the existing behaviour of senderName and senderEmail --- .../auth/templates/emailTemplate.svelte | 14 +-- .../settings/smtp/+page.svelte | 90 +++++++++---------- 2 files changed, 48 insertions(+), 56 deletions(-) diff --git a/src/routes/(console)/project-[region]-[project]/auth/templates/emailTemplate.svelte b/src/routes/(console)/project-[region]-[project]/auth/templates/emailTemplate.svelte index 68e30d8b2e..d2eafa5005 100644 --- a/src/routes/(console)/project-[region]-[project]/auth/templates/emailTemplate.svelte +++ b/src/routes/(console)/project-[region]-[project]/auth/templates/emailTemplate.svelte @@ -63,10 +63,10 @@ locale, subject: $emailTemplate.subject || undefined, message: $emailTemplate.message || undefined, - senderName: $emailTemplate.senderName || undefined, - senderEmail: $emailTemplate.senderEmail || undefined, - replyToEmail: $emailTemplate.replyToEmail || undefined, - replyToName: $emailTemplate.replyToName || undefined + senderName: $emailTemplate.senderName ?? undefined, + senderEmail: $emailTemplate.senderEmail ?? undefined, + replyToEmail: $emailTemplate.replyToEmail ?? undefined, + replyToName: $emailTemplate.replyToName ?? undefined }); $baseEmailTemplate = { @@ -114,13 +114,15 @@ bind:value={$emailTemplate.replyToEmail} id="replyToEmail" label="Reply to email" - placeholder="noreply@appwrite.io" /> + placeholder="noreply@appwrite.io" + disabled={!isSmtpEnabled} /> + placeholder="Enter reply to name" + disabled={!isSmtpEnabled} /> {#if children}

diff --git a/src/routes/(console)/project-[region]-[project]/settings/smtp/+page.svelte b/src/routes/(console)/project-[region]-[project]/settings/smtp/+page.svelte index 68bb18c00d..6c48a2ce7c 100644 --- a/src/routes/(console)/project-[region]-[project]/settings/smtp/+page.svelte +++ b/src/routes/(console)/project-[region]-[project]/settings/smtp/+page.svelte @@ -21,7 +21,7 @@ const { data }: PageProps = $props(); - const { project } = data; + const project = $derived(data.project); let enabled: boolean = $state(false); @@ -44,31 +44,35 @@ { value: '', label: 'None' } ]; + function normalizeSecure(v: string): string { + return v === 'tls' || v === 'ssl' ? v : ''; + } + const isButtonDisabled = $derived.by(() => { return deepEqual( { enabled, - senderName, - senderEmail, - replyToEmail, - replyToName, - host, - port: port ?? '', - username, - password, + senderName: senderName ?? '', + senderEmail: senderEmail ?? '', + replyToEmail: replyToEmail ?? '', + replyToName: replyToName ?? '', + host: host ?? '', + port: port ?? null, + username: username ?? '', + password: password ?? '', secure }, { - enabled: project.smtpEnabled, - senderName: project.smtpSenderName, - senderEmail: project.smtpSenderEmail, - replyToEmail: project.smtpReplyToEmail, - replyToName: project.smtpReplyToName, - host: project.smtpHost, - port: project.smtpPort, - username: project.smtpUsername, - password: project.smtpPassword, - secure: project.smtpSecure + enabled: project.smtpEnabled ?? false, + senderName: project.smtpSenderName ?? '', + senderEmail: project.smtpSenderEmail ?? '', + replyToEmail: project.smtpReplyToEmail ?? '', + replyToName: project.smtpReplyToName ?? '', + host: project.smtpHost ?? '', + port: project.smtpPort ?? null, + username: project.smtpUsername ?? '', + password: project.smtpPassword ?? '', + secure: normalizeSecure(project.smtpSecure ?? '') } ); }); @@ -77,14 +81,14 @@ try { await sdk.forProject(project.region, project.$id).project.updateSMTP({ enabled, - senderName: senderName || undefined, - senderEmail: senderEmail || undefined, - replyToEmail: replyToEmail || undefined, - replyToName: replyToName || undefined, - host: host || undefined, - port: port || undefined, - username: username || undefined, - password: password || undefined, + senderName: senderName ?? undefined, + senderEmail: senderEmail ?? undefined, + replyToEmail: replyToEmail ?? undefined, + replyToName: replyToName ?? undefined, + host: host ?? undefined, + port: port ?? undefined, + username: username ?? undefined, + password: password ?? undefined, secure: secure ? (secure as ProjectSMTPSecure) : undefined }); @@ -105,29 +109,15 @@ $effect(() => { enabled = project.smtpEnabled ?? false; - senderName = project.smtpSenderName; - senderEmail = project.smtpSenderEmail; - replyToEmail = project.smtpReplyToEmail; - replyToName = project.smtpReplyToName; - host = project.smtpHost; - port = project.smtpPort; - username = project.smtpUsername; - password = project.smtpPassword; - secure = project.smtpSecure === 'tls' ? 'tls' : project.smtpSecure === 'ssl' ? 'ssl' : ''; - }); - - $effect(() => { - if (!enabled) { - senderName = ''; - senderEmail = ''; - replyToEmail = ''; - replyToName = ''; - host = ''; - port = null; - username = ''; - password = ''; - secure = ''; - } + senderName = project.smtpSenderName ?? ''; + senderEmail = project.smtpSenderEmail ?? ''; + replyToEmail = project.smtpReplyToEmail ?? ''; + replyToName = project.smtpReplyToName ?? ''; + host = project.smtpHost ?? ''; + port = project.smtpPort ?? null; + username = project.smtpUsername ?? ''; + password = project.smtpPassword ?? ''; + secure = normalizeSecure(project.smtpSecure ?? ''); }); From 97d5e33a21cf56deebb2025c3f27561ffd1d4c6f Mon Sep 17 00:00:00 2001 From: Harsh Mahajan <127186841+HarshMN2345@users.noreply.github.com> Date: Tue, 19 May 2026 16:35:00 +0530 Subject: [PATCH 2/3] Update src/routes/(console)/project-[region]-[project]/auth/templates/emailTemplate.svelte Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> --- .../auth/templates/emailTemplate.svelte | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/routes/(console)/project-[region]-[project]/auth/templates/emailTemplate.svelte b/src/routes/(console)/project-[region]-[project]/auth/templates/emailTemplate.svelte index d2eafa5005..a4010051f2 100644 --- a/src/routes/(console)/project-[region]-[project]/auth/templates/emailTemplate.svelte +++ b/src/routes/(console)/project-[region]-[project]/auth/templates/emailTemplate.svelte @@ -61,8 +61,8 @@ await sdk.forProject(project.region, project.$id).project.updateEmailTemplate({ templateId: $emailTemplate.type as ProjectEmailTemplateId, locale, - subject: $emailTemplate.subject || undefined, - message: $emailTemplate.message || undefined, + subject: $emailTemplate.subject ?? undefined, + message: $emailTemplate.message ?? undefined, senderName: $emailTemplate.senderName ?? undefined, senderEmail: $emailTemplate.senderEmail ?? undefined, replyToEmail: $emailTemplate.replyToEmail ?? undefined, From e74f49f8be8f7837c2d5e0647f5fc7e1abb05de8 Mon Sep 17 00:00:00 2001 From: harsh mahajan Date: Tue, 19 May 2026 16:50:19 +0530 Subject: [PATCH 3/3] feat: add reset to default button on email templates --- bun.lock | 4 +-- package.json | 2 +- .../auth/templates/emailTemplate.svelte | 30 +++++++++++++++++++ 3 files changed, 33 insertions(+), 3 deletions(-) diff --git a/bun.lock b/bun.lock index c85d19e7c4..df55a454ec 100644 --- a/bun.lock +++ b/bun.lock @@ -6,7 +6,7 @@ "name": "@appwrite/console", "dependencies": { "@ai-sdk/svelte": "^1.1.24", - "@appwrite.io/console": "https://pkg.vc/-/@appwrite/@appwrite.io/console@7789ae4", + "@appwrite.io/console": "https://pkg.vc/-/@appwrite/@appwrite.io/console@0387505", "@appwrite.io/pink-icons": "0.25.0", "@appwrite.io/pink-icons-svelte": "https://pkg.vc/-/@appwrite/@appwrite.io/pink-icons-svelte@bfe7ce3", "@appwrite.io/pink-legacy": "^1.0.3", @@ -125,7 +125,7 @@ "@analytics/type-utils": ["@analytics/type-utils@0.6.4", "", {}, "sha512-Ou1gQxFakOWLcPnbFVsrPb8g1wLLUZYYJXDPjHkG07+5mustGs5yqACx42UAu4A6NszNN6Z5gGxhyH45zPWRxw=="], - "@appwrite.io/console": ["@appwrite.io/console@https://pkg.vc/-/@appwrite/@appwrite.io/console@7789ae4", { "dependencies": { "json-bigint": "1.0.0" } }], + "@appwrite.io/console": ["@appwrite.io/console@https://pkg.vc/-/@appwrite/@appwrite.io/console@0387505", { "dependencies": { "json-bigint": "1.0.0" } }], "@appwrite.io/pink-icons": ["@appwrite.io/pink-icons@0.25.0", "", {}, "sha512-0O3i2oEuh5mWvjO80i+X6rbzrWLJ1m5wmv2/M3a1p2PyBJsFxN8xQMTEmTn3Wl/D26SsM7SpzbdW6gmfgoVU9Q=="], diff --git a/package.json b/package.json index c1b9df8208..a0eea62b71 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,7 @@ }, "dependencies": { "@ai-sdk/svelte": "^1.1.24", - "@appwrite.io/console": "https://pkg.vc/-/@appwrite/@appwrite.io/console@7789ae4", + "@appwrite.io/console": "https://pkg.vc/-/@appwrite/@appwrite.io/console@0387505", "@appwrite.io/pink-icons": "0.25.0", "@appwrite.io/pink-icons-svelte": "https://pkg.vc/-/@appwrite/@appwrite.io/pink-icons-svelte@bfe7ce3", "@appwrite.io/pink-legacy": "^1.0.3", diff --git a/src/routes/(console)/project-[region]-[project]/auth/templates/emailTemplate.svelte b/src/routes/(console)/project-[region]-[project]/auth/templates/emailTemplate.svelte index a4010051f2..70aea6ca91 100644 --- a/src/routes/(console)/project-[region]-[project]/auth/templates/emailTemplate.svelte +++ b/src/routes/(console)/project-[region]-[project]/auth/templates/emailTemplate.svelte @@ -28,6 +28,7 @@ } = $props(); let eventType = $state(Submit.EmailUpdateInviteTemplate); + let isResetting = $state(false); const isSmtpEnabled = $derived(project?.smtpEnabled); const isButtonDisabled = $derived(deepEqual($emailTemplate, $baseEmailTemplate)); @@ -88,6 +89,32 @@ }); } } + + async function resetToDefault() { + const locale = ($emailTemplate.locale || + ProjectEmailTemplateLocale.En) as ProjectEmailTemplateLocale; + isResetting = true; + try { + const defaults = await sdk.forConsole.console.getEmailTemplate({ + templateId: $emailTemplate.type as ProjectEmailTemplateId, + locale + }); + $emailTemplate = { + ...$emailTemplate, + subject: defaults.subject, + message: defaults.message, + senderName: defaults.senderName, + senderEmail: defaults.senderEmail, + replyToEmail: defaults.replyToEmail, + replyToName: defaults.replyToName + }; + await saveEmailTemplate(); + } catch (e) { + addNotification({ type: 'error', message: e.message }); + } finally { + isResetting = false; + } + }

@@ -162,6 +189,9 @@
+