feat: add http as smtp provider (#8545)

# Which Problems Are Solved

Send Email messages as a HTTP call to a relay, for own logic on handling
different Email providers

# How the Problems Are Solved

Create endpoints under Email provider to manage SMTP and HTTP in the
notification handlers.

# Additional Changes

Clean up old logic in command and query side to handle the general Email
providers with deactivate, activate and remove.

# Additional Context

Partially closes #8270

---------

Co-authored-by: Livio Spring <livio.a@gmail.com>
This commit is contained in:
Stefan Benz
2024-09-12 06:27:29 +02:00
committed by GitHub
parent d8a71d217c
commit 21c38b061d
28 changed files with 3575 additions and 1152 deletions

View File

@@ -7,8 +7,8 @@ import (
"github.com/zitadel/zitadel/internal/database"
"github.com/zitadel/zitadel/internal/eventstore"
"github.com/zitadel/zitadel/internal/i18n"
"github.com/zitadel/zitadel/internal/notification/channels/email"
"github.com/zitadel/zitadel/internal/notification/channels/sms"
"github.com/zitadel/zitadel/internal/notification/channels/smtp"
"github.com/zitadel/zitadel/internal/notification/channels/webhook"
"github.com/zitadel/zitadel/internal/notification/senders"
"github.com/zitadel/zitadel/internal/notification/templates"
@@ -23,7 +23,7 @@ type Notify func(
) error
type ChannelChains interface {
Email(context.Context) (*senders.Chain, *smtp.Config, error)
Email(context.Context) (*senders.Chain, *email.Config, error)
SMS(context.Context) (*senders.Chain, *sms.Config, error)
Webhook(context.Context, webhook.Config) (*senders.Chain, error)
}
@@ -54,8 +54,9 @@ func SendEmail(
ctx,
channels,
user,
data.Subject,
template,
data,
args,
allowUnverifiedNotificationChannel,
triggeringEvent,
)

View File

@@ -3,9 +3,13 @@ package types
import (
"context"
"html"
"strings"
"github.com/zitadel/logging"
"github.com/zitadel/zitadel/internal/eventstore"
"github.com/zitadel/zitadel/internal/notification/messages"
"github.com/zitadel/zitadel/internal/notification/templates"
"github.com/zitadel/zitadel/internal/query"
"github.com/zitadel/zitadel/internal/zerrors"
)
@@ -14,29 +18,56 @@ func generateEmail(
ctx context.Context,
channels ChannelChains,
user *query.NotifyUser,
subject,
content string,
template string,
data templates.TemplateData,
args map[string]interface{},
lastEmail bool,
triggeringEvent eventstore.Event,
) error {
content = html.UnescapeString(content)
message := &messages.Email{
Recipients: []string{user.VerifiedEmail},
Subject: subject,
Content: content,
TriggeringEvent: triggeringEvent,
}
if lastEmail {
message.Recipients = []string{user.LastEmail}
}
emailChannels, _, err := channels.Email(ctx)
if err != nil {
return err
}
emailChannels, config, err := channels.Email(ctx)
logging.OnError(err).Error("could not create email channel")
if emailChannels == nil || emailChannels.Len() == 0 {
return zerrors.ThrowPreconditionFailed(nil, "MAIL-83nof", "Errors.Notification.Channels.NotPresent")
return zerrors.ThrowPreconditionFailed(nil, "PHONE-w8nfow", "Errors.Notification.Channels.NotPresent")
}
return emailChannels.HandleMessage(message)
recipient := user.VerifiedEmail
if lastEmail {
recipient = user.LastEmail
}
if config.SMTPConfig != nil {
message := &messages.Email{
Recipients: []string{recipient},
Subject: data.Subject,
Content: html.UnescapeString(template),
TriggeringEvent: triggeringEvent,
}
return emailChannels.HandleMessage(message)
}
if config.WebhookConfig != nil {
caseArgs := make(map[string]interface{}, len(args))
for k, v := range args {
caseArgs[strings.ToLower(string(k[0]))+k[1:]] = v
}
contextInfo := map[string]interface{}{
"recipientEmailAddress": recipient,
"eventType": triggeringEvent.Type(),
"provider": config.ProviderConfig,
}
message := &messages.JSON{
Serializable: &serializableData{
ContextInfo: contextInfo,
TemplateData: data,
Args: caseArgs,
},
TriggeringEvent: triggeringEvent,
}
webhookChannels, err := channels.Webhook(ctx, *config.WebhookConfig)
if err != nil {
return err
}
return webhookChannels.HandleMessage(message)
}
return zerrors.ThrowPreconditionFailed(nil, "MAIL-83nof", "Errors.Notification.Channels.NotPresent")
}
func mapNotifyUserToArgs(user *query.NotifyUser, args map[string]interface{}) map[string]interface{} {