From 6b44873e950faae977949f73298f2ca37809b3cc Mon Sep 17 00:00:00 2001 From: Steven Nguyen Date: Tue, 6 Feb 2024 16:18:15 -0800 Subject: [PATCH 1/3] Add support for SMTP provider --- .../messaging/provider.svelte | 17 +++- .../messaging/providers/create.svelte | 18 ++++ .../provider-[provider]/updateStatus.svelte | 35 +++++++ .../messaging/providers/store.ts | 94 ++++++++++++++++++- .../messaging/providers/update.svelte | 17 ++++ .../providers/wizard/configure.svelte | 14 +++ .../providers/wizard/provider.svelte | 22 ++++- .../messaging/providers/wizard/store.ts | 18 +++- 8 files changed, 226 insertions(+), 9 deletions(-) diff --git a/src/routes/console/project-[project]/messaging/provider.svelte b/src/routes/console/project-[project]/messaging/provider.svelte index 861060c7cd..e130ea23ff 100644 --- a/src/routes/console/project-[project]/messaging/provider.svelte +++ b/src/routes/console/project-[project]/messaging/provider.svelte @@ -7,6 +7,7 @@ Vonage = 'vonage', Mailgun = 'mailgun', Sendgrid = 'sendgrid', + SMTP = 'smtp', FCM = 'fcm', APNS = 'apns' } @@ -49,6 +50,10 @@ case Providers.Mailgun: icon = 'mailgun'; break; + case Providers.SMTP: + icon = 'smtp'; + displayName = name || 'SMTP'; + break; case Providers.Twilio: icon = 'twilio'; break; @@ -78,10 +83,14 @@ class="avatar" class:is-size-large={size === 'l'} class:is-size-small={size === 's'}> - {displayName} + {#if provider === Providers.SMTP} + + {:else} + {displayName} + {/if} {/if} diff --git a/src/routes/console/project-[project]/messaging/providers/create.svelte b/src/routes/console/project-[project]/messaging/providers/create.svelte index 33f0884bc6..6c96cac2e9 100644 --- a/src/routes/console/project-[project]/messaging/providers/create.svelte +++ b/src/routes/console/project-[project]/messaging/providers/create.svelte @@ -96,6 +96,24 @@ $providerParams[$provider].enabled ); break; + case Providers.SMTP: + response = await sdk.forProject.messaging.createSMTPProvider( + providerId, + $providerParams[$provider].name, + $providerParams[$provider].host, + $providerParams[$provider].port || undefined, + $providerParams[$provider].username || undefined, + $providerParams[$provider].password || undefined, + $providerParams[$provider].encryption, + $providerParams[$provider].autoTLS, + $providerParams[$provider].mailer || undefined, + $providerParams[$provider].fromName || undefined, + $providerParams[$provider].fromEmail, + $providerParams[$provider].replyToName || undefined, + $providerParams[$provider].replyToEmail || undefined, + $providerParams[$provider].enabled + ); + break; case Providers.FCM: response = await sdk.forProject.messaging.createFCMProvider( providerId, diff --git a/src/routes/console/project-[project]/messaging/providers/provider-[provider]/updateStatus.svelte b/src/routes/console/project-[project]/messaging/providers/provider-[provider]/updateStatus.svelte index 83f7111dde..c17d744609 100644 --- a/src/routes/console/project-[project]/messaging/providers/provider-[provider]/updateStatus.svelte +++ b/src/routes/console/project-[project]/messaging/providers/provider-[provider]/updateStatus.svelte @@ -105,6 +105,24 @@ fromEmail: $provider.options['from'] }; break; + case Providers.SMTP: + $providerParams[$wizardProvider] = { + providerId: $provider.$id, + name: $provider.name, + enabled: $provider.enabled, + host: $provider.credentials['host'], + port: $provider.credentials['port'], + username: $provider.credentials['username'], + password: $provider.credentials['password'], + fromName: $provider.options['fromName'], + fromEmail: $provider.options['fromEmail'], + replyToName: $provider.options['replyToName'], + replyToEmail: $provider.options['replyToEmail'], + encryption: $provider.options['encryption'], + autoTLS: $provider.options['autoTLS'], + mailer: $provider.options['mailer'] + }; + break; case Providers.FCM: $providerParams[$wizardProvider] = { providerId: $provider.$id, @@ -186,6 +204,23 @@ enabled ); break; + case Providers.SMTP: + response = await sdk.forProject.messaging.updateSMTPProvider( + providerId, + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + enabled + ); + break; case Providers.FCM: response = await sdk.forProject.messaging.updateFCMProvider( providerId, diff --git a/src/routes/console/project-[project]/messaging/providers/store.ts b/src/routes/console/project-[project]/messaging/providers/store.ts index 61cf5e006d..0960815ea1 100644 --- a/src/routes/console/project-[project]/messaging/providers/store.ts +++ b/src/routes/console/project-[project]/messaging/providers/store.ts @@ -1,7 +1,7 @@ import type { Column } from '$lib/helpers/types'; import { writable } from 'svelte/store'; import { Providers } from '../provider.svelte'; -import { MessagingProviderType } from '@appwrite.io/console'; +import { MessagingProviderType, SMTPEncryption } from '@appwrite.io/console'; export const columns = writable([ { id: '$id', title: 'Provider ID', type: 'string', show: true }, @@ -18,17 +18,20 @@ type ProvidersMap = { icon: string; providers: { [key in Providers]?: { - imageIcon: string; + imageIcon?: string; + classIcon?: string; title: string; description: string; configure: { label: string; name: string; - type: 'text' | 'phone' | 'email' | 'domain' | 'file' | 'switch'; + type: 'text' | 'phone' | 'email' | 'domain' | 'file' | 'switch' | 'select'; placeholder?: string; description?: string; popover?: string[]; allowedFileExtensions?: string[]; + optional?: boolean; + options?: { label: string; value: string | number | boolean }[]; }[]; }; }; @@ -241,6 +244,91 @@ export const providers: ProvidersMap = { placeholder: 'Enter name' } ] + }, + [Providers.SMTP]: { + classIcon: 'mail', + title: 'SMTP', + description: '', + configure: [ + { + label: 'Host', + name: 'host', + type: 'text', + placeholder: 'Enter host' + }, + { + label: 'Port', + name: 'port', + type: 'text', + optional: true, + placeholder: 'Enter port' + }, + { + label: 'Username', + name: 'username', + type: 'text', + optional: true, + placeholder: 'Enter username' + }, + { + label: 'Password', + name: 'password', + type: 'text', + optional: true, + placeholder: 'Enter password' + }, + { + label: 'Encryption', + name: 'encryption', + type: 'select', + options: [ + { label: 'None', value: SMTPEncryption.None }, + { label: 'SSL', value: SMTPEncryption.Ssl }, + { label: 'TLS', value: SMTPEncryption.Tls } + ] + }, + { + label: 'Auto TLS', + name: 'autoTLS', + description: 'Automatically uses TLS encryption', + type: 'switch', + optional: true + }, + { + label: 'Mailer', + name: 'mailer', + type: 'text', + optional: true, + placeholder: 'Enter mailer' + }, + { + label: 'Sender email', + name: 'fromEmail', + type: 'email', + placeholder: 'Enter email' + }, + { + label: 'Sender name', + name: 'fromName', + type: 'text', + optional: true, + placeholder: 'Enter name' + }, + { + label: 'Reply-to email', + name: 'replyToEmail', + type: 'email', + optional: true, + placeholder: 'Enter email' + }, + { + label: 'Reply-to name', + name: 'replyToName', + type: 'text', + optional: true, + placeholder: 'Enter name' + } + ] } } }, diff --git a/src/routes/console/project-[project]/messaging/providers/update.svelte b/src/routes/console/project-[project]/messaging/providers/update.svelte index ea2ed7b708..9533156294 100644 --- a/src/routes/console/project-[project]/messaging/providers/update.svelte +++ b/src/routes/console/project-[project]/messaging/providers/update.svelte @@ -95,6 +95,23 @@ $providerParams[$provider].replyToEmail ); break; + case Providers.SMTP: + response = await sdk.forProject.messaging.updateSMTPProvider( + providerId, + $providerParams[$provider].name, + $providerParams[$provider].host, + $providerParams[$provider].port || undefined, + $providerParams[$provider].username || undefined, + $providerParams[$provider].password || undefined, + $providerParams[$provider].encryption, + $providerParams[$provider].autoTLS, + $providerParams[$provider].fromName || undefined, + $providerParams[$provider].fromEmail, + $providerParams[$provider].replyToName || undefined, + $providerParams[$provider].replyToEmail || undefined, + $providerParams[$provider].enabled + ); + break; case Providers.FCM: response = await sdk.forProject.messaging.updateFCMProvider( providerId, diff --git a/src/routes/console/project-[project]/messaging/providers/wizard/configure.svelte b/src/routes/console/project-[project]/messaging/providers/wizard/configure.svelte index 404b4f69ad..9a80696773 100644 --- a/src/routes/console/project-[project]/messaging/providers/wizard/configure.svelte +++ b/src/routes/console/project-[project]/messaging/providers/wizard/configure.svelte @@ -4,6 +4,7 @@ InputDomain, InputEmail, InputFile, + InputSelect, InputSwitch, InputText } from '$lib/elements/forms'; @@ -56,6 +57,7 @@ id={input.name} label={input.label} placeholder={input.placeholder} + required={!input.optional} bind:value={$providerParams[$provider][input.name]}> {@html input.popover?.join('

')} @@ -66,6 +68,7 @@ id={input.name} label={input.label} placeholder={input.placeholder} + required={!input.optional} bind:value={$providerParams[$provider][input.name]}>

@@ -78,6 +81,7 @@ id={input.name} label={input.label} placeholder={input.placeholder} + required={!input.optional} bind:value={$providerParams[$provider][input.name]}>

@@ -90,6 +94,7 @@ id={input.name} label={input.label} placeholder={input.placeholder} + required={!input.optional} bind:value={$providerParams[$provider][input.name]}>

@@ -101,6 +106,7 @@

@@ -112,11 +118,19 @@ {input.description} + {:else if input.type === 'select'} + {/if} {/each} diff --git a/src/routes/console/project-[project]/messaging/providers/wizard/provider.svelte b/src/routes/console/project-[project]/messaging/providers/wizard/provider.svelte index 22682db74e..9be84f1217 100644 --- a/src/routes/console/project-[project]/messaging/providers/wizard/provider.svelte +++ b/src/routes/console/project-[project]/messaging/providers/wizard/provider.svelte @@ -6,6 +6,7 @@ import { FormList, InputText } from '$lib/elements/forms'; import { Pill } from '$lib/elements'; import { Providers } from '../../provider.svelte'; + import { SMTPEncryption } from '@appwrite.io/console'; let name = ''; let showCustomId = false; @@ -91,6 +92,24 @@ replyToName: '' }; break; + case Providers.SMTP: + $providerParams[$provider] = { + providerId: id, + name: name, + enabled: true, + host: '', + port: 587, + username: '', + password: '', + autoTLS: true, + encryption: SMTPEncryption.Tls, + mailer: '', + fromEmail: '', + fromName: '', + replyToEmail: '', + replyToName: '' + }; + break; case Providers.FCM: $providerParams[$provider] = { providerId: id, @@ -144,7 +163,8 @@ name="provider" {value} bind:group={$provider} - imageIcon={option.imageIcon}> + imageIcon={option.imageIcon} + icon={option.classIcon}> {option.title} {#if option.description} {option.description} diff --git a/src/routes/console/project-[project]/messaging/providers/wizard/store.ts b/src/routes/console/project-[project]/messaging/providers/wizard/store.ts index 07b097e075..f6894ad47e 100644 --- a/src/routes/console/project-[project]/messaging/providers/wizard/store.ts +++ b/src/routes/console/project-[project]/messaging/providers/wizard/store.ts @@ -1,6 +1,6 @@ import { writable } from 'svelte/store'; import type { Providers } from '../../provider.svelte'; -import type { MessagingProviderType } from '@appwrite.io/console'; +import type { MessagingProviderType, SMTPEncryption } from '@appwrite.io/console'; type ProviderParams = { providerId: string; @@ -64,6 +64,20 @@ export type SendgridProviderParams = ProviderParams & { apiKey: string; }; +export type SMTPProviderParams = ProviderParams & { + fromEmail: string; + fromName: string; + replyToEmail: string; + replyToName: string; + host: string; + port: number; + username: string; + password: string; + encryption: SMTPEncryption; + autoTLS: boolean; + mailer: string; +}; + /** * Push providers */ @@ -93,6 +107,7 @@ export const providerParams = writable<{ vonage: Partial; mailgun: Partial; sendgrid: Partial; + smtp: Partial; fcm: Partial; apns: Partial; }>({ @@ -103,6 +118,7 @@ export const providerParams = writable<{ vonage: null, mailgun: null, sendgrid: null, + smtp: null, fcm: null, apns: null }); From 44f48baadf9fce2acc22ec6e8cb4cc396f6c64f1 Mon Sep 17 00:00:00 2001 From: Steven Nguyen Date: Tue, 6 Feb 2024 16:23:29 -0800 Subject: [PATCH 2/3] Make some provider fields optional --- .../console/project-[project]/messaging/providers/store.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/routes/console/project-[project]/messaging/providers/store.ts b/src/routes/console/project-[project]/messaging/providers/store.ts index 0960815ea1..db2fa83f6b 100644 --- a/src/routes/console/project-[project]/messaging/providers/store.ts +++ b/src/routes/console/project-[project]/messaging/providers/store.ts @@ -187,18 +187,21 @@ export const providers: ProvidersMap = { label: 'Sender name', name: 'fromName', type: 'text', + optional: true, placeholder: 'Enter name' }, { label: 'Reply-to email', name: 'replyToEmail', type: 'email', + optional: true, placeholder: 'Enter email' }, { label: 'Reply-to name', name: 'replyToName', type: 'text', + optional: true, placeholder: 'Enter name' } ] @@ -229,18 +232,21 @@ export const providers: ProvidersMap = { label: 'Sender name', name: 'fromName', type: 'text', + optional: true, placeholder: 'Enter name' }, { label: 'Reply-to email', name: 'replyToEmail', type: 'email', + optional: true, placeholder: 'Enter email' }, { label: 'Reply-to name', name: 'replyToName', type: 'text', + optional: true, placeholder: 'Enter name' } ] From 9182a5b48c0dad6674b3ac2d65d62a53850162b0 Mon Sep 17 00:00:00 2001 From: Steven Nguyen Date: Tue, 6 Feb 2024 16:49:51 -0800 Subject: [PATCH 3/3] Fixes from design review --- src/lib/components/labelCard.svelte | 15 ++++++++------- .../messaging/providers/wizard/provider.svelte | 2 +- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/lib/components/labelCard.svelte b/src/lib/components/labelCard.svelte index 461e5a53f7..f0d0020d9c 100644 --- a/src/lib/components/labelCard.svelte +++ b/src/lib/components/labelCard.svelte @@ -60,13 +60,14 @@ {#if icon}