mirror of
https://github.com/zitadel/zitadel.git
synced 2025-08-13 03:57:36 +00:00
feat: notifications (#109)
* implement notification providers * email provider * notification handler * notify users * implement code sent on user eventstore * send email implementation * send init code * handle codes * fix project member handler * add some logs for debug * send emails * text changes * send sms * notification process * send password code * format phone number * test format phone * remove fmts * remove unused code * rename files * add mocks * merge master * Update internal/notification/providers/email/message.go Co-authored-by: Silvan <silvan.reusser@gmail.com> * Update internal/notification/repository/eventsourcing/handler/notification.go Co-authored-by: Silvan <silvan.reusser@gmail.com> * Update internal/notification/repository/eventsourcing/handler/notification.go Co-authored-by: Silvan <silvan.reusser@gmail.com> * Update internal/notification/providers/email/provider.go Co-authored-by: Silvan <silvan.reusser@gmail.com> * requested changes of mr * move locker to eventstore pkg * Update internal/notification/providers/chat/message.go Co-authored-by: Livio Amstutz <livio.a@gmail.com> * move locker to eventstore pkg * linebreak * Update internal/notification/providers/email/provider.go Co-authored-by: Silvan <silvan.reusser@gmail.com> * Update internal/notification/repository/eventsourcing/handler/notification.go Co-authored-by: Silvan <silvan.reusser@gmail.com> * Update internal/notification/repository/eventsourcing/handler/notification.go Co-authored-by: Silvan <silvan.reusser@gmail.com> Co-authored-by: Silvan <silvan.reusser@gmail.com> Co-authored-by: Livio Amstutz <livio.a@gmail.com>
This commit is contained in:
34
internal/notification/types/email_verification_code.go
Normal file
34
internal/notification/types/email_verification_code.go
Normal file
@@ -0,0 +1,34 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"github.com/caos/zitadel/internal/config/systemdefaults"
|
||||
"github.com/caos/zitadel/internal/crypto"
|
||||
"github.com/caos/zitadel/internal/notification/templates"
|
||||
es_model "github.com/caos/zitadel/internal/user/repository/eventsourcing/model"
|
||||
view_model "github.com/caos/zitadel/internal/user/repository/view/model"
|
||||
)
|
||||
|
||||
type EmailVerificationCodeData struct {
|
||||
templates.TemplateData
|
||||
FirstName string
|
||||
LastName string
|
||||
URL string
|
||||
}
|
||||
|
||||
func SendEmailVerificationCode(user *view_model.NotifyUser, code *es_model.EmailCode, systemDefaults systemdefaults.SystemDefaults, alg crypto.EncryptionAlgorithm) error {
|
||||
codeString, err := crypto.DecryptString(code.Code, alg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
url, err := templates.ParseTemplateText(systemDefaults.Notifications.Endpoints.VerifyEmail, &UrlData{UserID: user.ID, Code: codeString})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
emailCodeData := &EmailVerificationCodeData{TemplateData: systemDefaults.Notifications.TemplateData.VerifyEmail, FirstName: user.FirstName, LastName: user.LastName, URL: url}
|
||||
|
||||
template, err := templates.GetParsedTemplate(emailCodeData)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return generateEmail(user, template, systemDefaults.Notifications, true)
|
||||
}
|
39
internal/notification/types/init_code.go
Normal file
39
internal/notification/types/init_code.go
Normal file
@@ -0,0 +1,39 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"github.com/caos/zitadel/internal/config/systemdefaults"
|
||||
"github.com/caos/zitadel/internal/crypto"
|
||||
"github.com/caos/zitadel/internal/notification/templates"
|
||||
es_model "github.com/caos/zitadel/internal/user/repository/eventsourcing/model"
|
||||
view_model "github.com/caos/zitadel/internal/user/repository/view/model"
|
||||
)
|
||||
|
||||
type InitCodeEmailData struct {
|
||||
templates.TemplateData
|
||||
FirstName string
|
||||
LastName string
|
||||
URL string
|
||||
}
|
||||
|
||||
type UrlData struct {
|
||||
UserID string
|
||||
Code string
|
||||
}
|
||||
|
||||
func SendUserInitCode(user *view_model.NotifyUser, code *es_model.InitUserCode, systemDefaults systemdefaults.SystemDefaults, alg crypto.EncryptionAlgorithm) error {
|
||||
codeString, err := crypto.DecryptString(code.Code, alg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
url, err := templates.ParseTemplateText(systemDefaults.Notifications.Endpoints.InitCode, &UrlData{UserID: user.ID, Code: codeString})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
initCodeData := &InitCodeEmailData{TemplateData: systemDefaults.Notifications.TemplateData.InitCode, FirstName: user.FirstName, LastName: user.LastName, URL: url}
|
||||
|
||||
template, err := templates.GetParsedTemplate(initCodeData)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return generateEmail(user, template, systemDefaults.Notifications, true)
|
||||
}
|
34
internal/notification/types/password_code.go
Normal file
34
internal/notification/types/password_code.go
Normal file
@@ -0,0 +1,34 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"github.com/caos/zitadel/internal/config/systemdefaults"
|
||||
"github.com/caos/zitadel/internal/crypto"
|
||||
"github.com/caos/zitadel/internal/notification/templates"
|
||||
es_model "github.com/caos/zitadel/internal/user/repository/eventsourcing/model"
|
||||
view_model "github.com/caos/zitadel/internal/user/repository/view/model"
|
||||
)
|
||||
|
||||
type PasswordCodeData struct {
|
||||
templates.TemplateData
|
||||
FirstName string
|
||||
LastName string
|
||||
URL string
|
||||
}
|
||||
|
||||
func SendPasswordCode(user *view_model.NotifyUser, code *es_model.PasswordCode, systemDefaults systemdefaults.SystemDefaults, alg crypto.EncryptionAlgorithm) error {
|
||||
codeString, err := crypto.DecryptString(code.Code, alg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
url, err := templates.ParseTemplateText(systemDefaults.Notifications.Endpoints.PasswordReset, &UrlData{UserID: user.ID, Code: codeString})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
passwordCodeData := &PasswordCodeData{TemplateData: systemDefaults.Notifications.TemplateData.PasswordReset, FirstName: user.FirstName, LastName: user.LastName, URL: url}
|
||||
|
||||
template, err := templates.GetParsedTemplate(passwordCodeData)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return generateEmail(user, template, systemDefaults.Notifications, false)
|
||||
}
|
29
internal/notification/types/phone_verification_code.go
Normal file
29
internal/notification/types/phone_verification_code.go
Normal file
@@ -0,0 +1,29 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"github.com/caos/zitadel/internal/config/systemdefaults"
|
||||
"github.com/caos/zitadel/internal/crypto"
|
||||
"github.com/caos/zitadel/internal/notification/templates"
|
||||
es_model "github.com/caos/zitadel/internal/user/repository/eventsourcing/model"
|
||||
view_model "github.com/caos/zitadel/internal/user/repository/view/model"
|
||||
)
|
||||
|
||||
type PhoneVerificationCodeData struct {
|
||||
FirstName string
|
||||
LastName string
|
||||
Code string
|
||||
UserID string
|
||||
}
|
||||
|
||||
func SendPhoneVerificationCode(user *view_model.NotifyUser, code *es_model.PhoneCode, systemDefaults systemdefaults.SystemDefaults, alg crypto.EncryptionAlgorithm) error {
|
||||
codeString, err := crypto.DecryptString(code.Code, alg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
codeData := &PhoneVerificationCodeData{FirstName: user.FirstName, LastName: user.LastName, UserID: user.ID, Code: codeString}
|
||||
template, err := templates.ParseTemplateText(systemDefaults.Notifications.TemplateData.VerifyPhone.Text, codeData)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return generateSms(user, template, systemDefaults.Notifications, true)
|
||||
}
|
41
internal/notification/types/user_email.go
Normal file
41
internal/notification/types/user_email.go
Normal file
@@ -0,0 +1,41 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"github.com/caos/zitadel/internal/config/systemdefaults"
|
||||
caos_errs "github.com/caos/zitadel/internal/errors"
|
||||
"github.com/caos/zitadel/internal/notification/providers"
|
||||
"github.com/caos/zitadel/internal/notification/providers/chat"
|
||||
"github.com/caos/zitadel/internal/notification/providers/email"
|
||||
view_model "github.com/caos/zitadel/internal/user/repository/view/model"
|
||||
)
|
||||
|
||||
func generateEmail(user *view_model.NotifyUser, content string, config systemdefaults.Notifications, lastEmail bool) error {
|
||||
provider, err := email.InitEmailProvider(config.Providers.Email)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
message := &email.EmailMessage{
|
||||
SenderEmail: config.Providers.Email.From,
|
||||
Recipients: []string{user.VerifiedEmail},
|
||||
Subject: config.TemplateData.InitCode.Subject,
|
||||
Content: content,
|
||||
}
|
||||
if lastEmail {
|
||||
message.Recipients = []string{user.LastEmail}
|
||||
}
|
||||
if provider.CanHandleMessage(message) {
|
||||
if config.DebugMode {
|
||||
return sendDebugEmail(message, config)
|
||||
}
|
||||
return provider.HandleMessage(message)
|
||||
}
|
||||
return caos_errs.ThrowInternalf(nil, "NOTIF-s8ipw", "Could not send init message: userid: %v", user.ID)
|
||||
}
|
||||
|
||||
func sendDebugEmail(message providers.Message, config systemdefaults.Notifications) error {
|
||||
provider, err := chat.InitChatProvider(config.Providers.Chat)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return provider.HandleMessage(message)
|
||||
}
|
37
internal/notification/types/user_phone.go
Normal file
37
internal/notification/types/user_phone.go
Normal file
@@ -0,0 +1,37 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"github.com/caos/zitadel/internal/config/systemdefaults"
|
||||
caos_errs "github.com/caos/zitadel/internal/errors"
|
||||
"github.com/caos/zitadel/internal/notification/providers"
|
||||
"github.com/caos/zitadel/internal/notification/providers/chat"
|
||||
"github.com/caos/zitadel/internal/notification/providers/twilio"
|
||||
view_model "github.com/caos/zitadel/internal/user/repository/view/model"
|
||||
)
|
||||
|
||||
func generateSms(user *view_model.NotifyUser, content string, config systemdefaults.Notifications, lastPhone bool) error {
|
||||
provider := twilio.InitTwilioProvider(config.Providers.Twilio)
|
||||
message := &twilio.TwilioMessage{
|
||||
SenderPhoneNumber: config.Providers.Twilio.From,
|
||||
RecipientPhoneNumber: user.VerifiedPhone,
|
||||
Content: content,
|
||||
}
|
||||
if lastPhone {
|
||||
message.RecipientPhoneNumber = user.LastPhone
|
||||
}
|
||||
if provider.CanHandleMessage(message) {
|
||||
if config.DebugMode {
|
||||
return sendDebugPhone(message, config)
|
||||
}
|
||||
return provider.HandleMessage(message)
|
||||
}
|
||||
return caos_errs.ThrowInternalf(nil, "NOTIF-s8ipw", "Could not send init message: userid: %v", user.ID)
|
||||
}
|
||||
|
||||
func sendDebugPhone(message providers.Message, config systemdefaults.Notifications) error {
|
||||
provider, err := chat.InitChatProvider(config.Providers.Chat)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return provider.HandleMessage(message)
|
||||
}
|
Reference in New Issue
Block a user