From 17f0eea4a111159b5d7885bcd363c4363362dd7b Mon Sep 17 00:00:00 2001 From: Fabi <38692350+fgerschwiler@users.noreply.github.com> Date: Tue, 9 Jun 2020 15:11:42 +0200 Subject: [PATCH] feat: Notification translation (#192) * feat: translate emails * feat: translate emails * fix: add notification statik to build * fix: add codes to templates --- .github/workflows/release.yml | 2 + build/notification/generate-static.sh | 5 ++ cmd/zitadel/startup.yaml | 1 + cmd/zitadel/system-defaults.yaml | 48 +++++++++---------- internal/i18n/i18n.go | 4 +- internal/notification/notification.go | 8 +++- .../eventsourcing/handler/handler.go | 12 ++++- .../eventsourcing/handler/notification.go | 10 ++-- .../repository/eventsourcing/repository.go | 18 +++++-- .../eventsourcing/spooler/spooler.go | 5 +- internal/notification/static/i18n/de.yaml | 29 +++++++++++ internal/notification/static/i18n/en.yaml | 29 +++++++++++ internal/notification/statik/generate.go | 3 ++ .../notification/templates/templateData.go | 14 ++++++ .../types/email_verification_code.go | 15 ++++-- internal/notification/types/init_code.go | 15 ++++-- internal/notification/types/password_code.go | 9 +++- .../types/phone_verification_code.go | 16 ++++--- 18 files changed, 186 insertions(+), 57 deletions(-) create mode 100755 build/notification/generate-static.sh create mode 100644 internal/notification/static/i18n/de.yaml create mode 100644 internal/notification/static/i18n/en.yaml create mode 100644 internal/notification/statik/generate.go diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 7ddcd7ec7f..debde81b9d 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -103,6 +103,8 @@ jobs: - run: cat pkg/console/statik/statik.go - run: ./build/login/generate-static.sh - run: cat internal/login/statik/statik.go + - run: ./build/notification/generate-static.sh + - run: cat internal/notification/statik/statik.go - run: CGO_ENABLED=0 GOOS=${{ matrix.goos }} GOARCH=${{ matrix.goarch }} go build -a -installsuffix cgo -ldflags '-extldflags "-static"' -o zitadel-${{ matrix.goos }}-${{ matrix.goarch }} cmd/zitadel/main.go - uses: actions/upload-artifact@v1 with: diff --git a/build/notification/generate-static.sh b/build/notification/generate-static.sh new file mode 100755 index 0000000000..68a3bf7286 --- /dev/null +++ b/build/notification/generate-static.sh @@ -0,0 +1,5 @@ +#! /bin/sh + +set -eux + +go generate internal/notification/statik/generate.go \ No newline at end of file diff --git a/cmd/zitadel/startup.yaml b/cmd/zitadel/startup.yaml index f589ab0362..414939cfbe 100644 --- a/cmd/zitadel/startup.yaml +++ b/cmd/zitadel/startup.yaml @@ -196,6 +196,7 @@ Console: Notification: Repository: + DefaultLanguage: 'de' Eventstore: ServiceName: 'Notification' Repository: diff --git a/cmd/zitadel/system-defaults.yaml b/cmd/zitadel/system-defaults.yaml index 21cbd99403..324536c90e 100644 --- a/cmd/zitadel/system-defaults.yaml +++ b/cmd/zitadel/system-defaults.yaml @@ -133,30 +133,30 @@ SystemDefaults: From: $TWILIO_SENDER_NAME TemplateData: InitCode: - Title: 'Zitadel - User initialisieren' - PreHeader: 'User initialisieren' - Subject: 'User initialisieren' - Greeting: 'Hallo {{.FirstName}} {{.LastName}},' - Text: 'Dieser Benutzer wurde soeben im Zitadel erstellt. Du kannst den Button unten verwenden, um die Initialisierung abzuschliesen. Falls du dieses Mail nicht angefordert hast, kannst du es einfach ignorieren.' - ButtonText: 'Initialisierung abschliessen' + Title: 'InitCode.Title' + PreHeader: 'InitCode.PreHeader' + Subject: 'InitCode.Subject' + Greeting: 'InitCode.Greeting' + Text: 'InitCode.Text' + ButtonText: 'InitCode.ButtonText' PasswordReset: - Title: 'Zitadel - Passwort zurücksetzen' - PreHeader: 'Passwort zurücksetzen' - Subject: 'Passwort zurücksetzen' - Greeting: 'Hallo {{.FirstName}} {{.LastName}},' - Text: 'Wir haben eine Anfrage für das Zurücksetzen deines Passwortes bekommen. Du kannst den untenstehenden Button verwenden, um dein Passwort zurückzusetzen. Falls du dieses Mail nicht angefordert hast, kannst du es ignorieren.' - ButtonText: 'Passwort zurücksetzen' + Title: 'PasswordReset.Title' + PreHeader: 'PasswordReset.PreHeader' + Subject: 'PasswordReset.Subject' + Greeting: 'PasswordReset.Greeting' + Text: 'PasswordReset.Text' + ButtonText: 'PasswordReset.ButtonText' VerifyEmail: - Title: 'Zitadel - Email verifizieren' - PreHeader: 'Email verifizieren' - Subject: 'Email verifizieren' - Greeting: 'Hallo {{.FirstName}} {{.LastName}},' - Text: 'Eine neue E-Mail Adresse wurde hinzugefügt. Bitte verwende den untenstehenden Button um diese zu verifizieren. Falls du deine E-Mail Adresse nicht selber hinzugefügt hast, kannst du dieses E-Mail ignorieren.' - ButtonText: 'Email verifizieren' + Title: 'VerifyEmail.Title' + PreHeader: 'VerifyEmail.PreHeader' + Subject: 'VerifyEmail.Subject' + Greeting: 'VerifyEmail.Greeting' + Text: 'VerifyEmail.Text' + ButtonText: 'VerifyEmail.ButtonText' VerifyPhone: - Title: 'Zitadel - Telefonnummer verifizieren' - PreHeader: 'Telefonnummer verifizieren' - Subject: 'Telefonnummer verifizieren' - Greeting: 'Hallo {{.FirstName}} {{.LastName}},' - Text: 'Eine Telefonnummer wurde hinzugefügt. Bitte verifiziere diese in dem du folgenden Code eingibst: {{.Code}}' - ButtonText: 'Telefon verifizieren' \ No newline at end of file + Title: 'VerifyPhone.Title' + PreHeader: 'VerifyPhone.PreHeader' + Subject: 'VerifyPhone.Subject' + Greeting: 'VerifyPhone.Greeting' + Text: 'VerifyPhone.Text' + ButtonText: 'VerifyPhone.ButtonText' \ No newline at end of file diff --git a/internal/i18n/i18n.go b/internal/i18n/i18n.go index 6c48c0fb04..a7b45f03b8 100644 --- a/internal/i18n/i18n.go +++ b/internal/i18n/i18n.go @@ -89,8 +89,8 @@ func (t *Translator) LocalizeFromRequest(r *http.Request, id string, args map[st return s } -func (t *Translator) Localize(id string, args map[string]interface{}) string { - s, _ := t.localizer().Localize(&i18n.LocalizeConfig{ +func (t *Translator) Localize(id string, args map[string]interface{}, langs ...string) string { + s, _ := t.localizer(langs...).Localize(&i18n.LocalizeConfig{ MessageID: id, TemplateData: args, }) diff --git a/internal/notification/notification.go b/internal/notification/notification.go index b7af6e6e2e..631df76eeb 100644 --- a/internal/notification/notification.go +++ b/internal/notification/notification.go @@ -5,6 +5,9 @@ import ( "github.com/caos/logging" sd "github.com/caos/zitadel/internal/config/systemdefaults" "github.com/caos/zitadel/internal/notification/repository/eventsourcing" + "github.com/rakyll/statik/fs" + + _ "github.com/caos/zitadel/internal/notification/statik" ) type Config struct { @@ -12,6 +15,9 @@ type Config struct { } func Start(ctx context.Context, config Config, systemDefaults sd.SystemDefaults) { - _, err := eventsourcing.Start(config.Repository, systemDefaults) + statikFS, err := fs.NewWithNamespace("notification") + logging.Log("CONFI-7usEW").OnError(err).Panic("unable to start listener") + + _, err = eventsourcing.Start(config.Repository, statikFS, systemDefaults) logging.Log("MAIN-9uBxp").OnError(err).Panic("unable to start app") } diff --git a/internal/notification/repository/eventsourcing/handler/handler.go b/internal/notification/repository/eventsourcing/handler/handler.go index 268c5a31b3..9367c6932e 100644 --- a/internal/notification/repository/eventsourcing/handler/handler.go +++ b/internal/notification/repository/eventsourcing/handler/handler.go @@ -7,6 +7,7 @@ import ( "github.com/caos/zitadel/internal/crypto" "github.com/caos/zitadel/internal/eventstore" "github.com/caos/zitadel/internal/eventstore/spooler" + "github.com/caos/zitadel/internal/i18n" "github.com/caos/zitadel/internal/notification/repository/eventsourcing/view" usr_event "github.com/caos/zitadel/internal/user/repository/eventsourcing" "time" @@ -29,14 +30,21 @@ type EventstoreRepos struct { UserEvents *usr_event.UserEventstore } -func Register(configs Configs, bulkLimit, errorCount uint64, view *view.View, eventstore eventstore.Eventstore, repos EventstoreRepos, systemDefaults sd.SystemDefaults) []spooler.Handler { +func Register(configs Configs, bulkLimit, errorCount uint64, view *view.View, eventstore eventstore.Eventstore, repos EventstoreRepos, systemDefaults sd.SystemDefaults, i18n *i18n.Translator) []spooler.Handler { aesCrypto, err := crypto.NewAESCrypto(systemDefaults.UserVerificationKey) if err != nil { logging.Log("HANDL-s90ew").WithError(err).Debug("error create new aes crypto") } return []spooler.Handler{ &NotifyUser{handler: handler{view, bulkLimit, configs.cycleDuration("User"), errorCount}}, - &Notification{handler: handler{view, bulkLimit, configs.cycleDuration("Notification"), errorCount}, eventstore: eventstore, userEvents: repos.UserEvents, systemDefaults: systemDefaults, AesCrypto: aesCrypto}, + &Notification{ + handler: handler{view, bulkLimit, configs.cycleDuration("Notification"), errorCount}, + eventstore: eventstore, + userEvents: repos.UserEvents, + systemDefaults: systemDefaults, + AesCrypto: aesCrypto, + i18n: i18n, + }, } } diff --git a/internal/notification/repository/eventsourcing/handler/notification.go b/internal/notification/repository/eventsourcing/handler/notification.go index 38acd5286a..6c25d07106 100644 --- a/internal/notification/repository/eventsourcing/handler/notification.go +++ b/internal/notification/repository/eventsourcing/handler/notification.go @@ -6,6 +6,7 @@ import ( sd "github.com/caos/zitadel/internal/config/systemdefaults" "github.com/caos/zitadel/internal/crypto" "github.com/caos/zitadel/internal/eventstore" + "github.com/caos/zitadel/internal/i18n" "github.com/caos/zitadel/internal/notification/types" usr_event "github.com/caos/zitadel/internal/user/repository/eventsourcing" es_model "github.com/caos/zitadel/internal/user/repository/eventsourcing/model" @@ -24,6 +25,7 @@ type Notification struct { userEvents *usr_event.UserEventstore systemDefaults sd.SystemDefaults AesCrypto crypto.EncryptionAlgorithm + i18n *i18n.Translator } const ( @@ -75,7 +77,7 @@ func (n *Notification) handleInitUserCode(event *models.Event) (err error) { if err != nil { return err } - err = types.SendUserInitCode(user, initCode, n.systemDefaults, n.AesCrypto) + err = types.SendUserInitCode(n.i18n, user, initCode, n.systemDefaults, n.AesCrypto) if err != nil { return err } @@ -93,7 +95,7 @@ func (n *Notification) handlePasswordCode(event *models.Event) (err error) { if err != nil { return err } - err = types.SendPasswordCode(user, pwCode, n.systemDefaults, n.AesCrypto) + err = types.SendPasswordCode(n.i18n, user, pwCode, n.systemDefaults, n.AesCrypto) if err != nil { return err } @@ -111,7 +113,7 @@ func (n *Notification) handleEmailVerificationCode(event *models.Event) (err err if err != nil { return err } - err = types.SendEmailVerificationCode(user, emailCode, n.systemDefaults, n.AesCrypto) + err = types.SendEmailVerificationCode(n.i18n, user, emailCode, n.systemDefaults, n.AesCrypto) if err != nil { return err } @@ -129,7 +131,7 @@ func (n *Notification) handlePhoneVerificationCode(event *models.Event) (err err if err != nil { return err } - err = types.SendPhoneVerificationCode(user, phoneCode, n.systemDefaults, n.AesCrypto) + err = types.SendPhoneVerificationCode(n.i18n, user, phoneCode, n.systemDefaults, n.AesCrypto) if err != nil { return err } diff --git a/internal/notification/repository/eventsourcing/repository.go b/internal/notification/repository/eventsourcing/repository.go index 83778d7afd..b766a77522 100644 --- a/internal/notification/repository/eventsourcing/repository.go +++ b/internal/notification/repository/eventsourcing/repository.go @@ -5,23 +5,27 @@ import ( "github.com/caos/zitadel/internal/config/types" es_int "github.com/caos/zitadel/internal/eventstore" es_spol "github.com/caos/zitadel/internal/eventstore/spooler" + "github.com/caos/zitadel/internal/i18n" "github.com/caos/zitadel/internal/notification/repository/eventsourcing/handler" "github.com/caos/zitadel/internal/notification/repository/eventsourcing/spooler" noti_view "github.com/caos/zitadel/internal/notification/repository/eventsourcing/view" es_usr "github.com/caos/zitadel/internal/user/repository/eventsourcing" + "golang.org/x/text/language" + "net/http" ) type Config struct { - Eventstore es_int.Config - View types.SQL - Spooler spooler.SpoolerConfig + DefaultLanguage language.Tag + Eventstore es_int.Config + View types.SQL + Spooler spooler.SpoolerConfig } type EsRepository struct { spooler *es_spol.Spooler } -func Start(conf Config, systemDefaults sd.SystemDefaults) (*EsRepository, error) { +func Start(conf Config, dir http.FileSystem, systemDefaults sd.SystemDefaults) (*EsRepository, error) { es, err := es_int.Start(conf.Eventstore) if err != nil { return nil, err @@ -43,8 +47,12 @@ func Start(conf Config, systemDefaults sd.SystemDefaults) (*EsRepository, error) if err != nil { return nil, err } + i18n, err := i18n.NewTranslator(dir, i18n.TranslatorConfig{DefaultLanguage: conf.DefaultLanguage}) + if err != nil { + return nil, err + } eventstoreRepos := handler.EventstoreRepos{UserEvents: user} - spool := spooler.StartSpooler(conf.Spooler, es, view, sqlClient, eventstoreRepos, systemDefaults) + spool := spooler.StartSpooler(conf.Spooler, es, view, sqlClient, eventstoreRepos, systemDefaults, i18n) return &EsRepository{ spool, diff --git a/internal/notification/repository/eventsourcing/spooler/spooler.go b/internal/notification/repository/eventsourcing/spooler/spooler.go index 4842c08762..6ae3d99139 100644 --- a/internal/notification/repository/eventsourcing/spooler/spooler.go +++ b/internal/notification/repository/eventsourcing/spooler/spooler.go @@ -5,6 +5,7 @@ import ( sd "github.com/caos/zitadel/internal/config/systemdefaults" "github.com/caos/zitadel/internal/eventstore" "github.com/caos/zitadel/internal/eventstore/spooler" + "github.com/caos/zitadel/internal/i18n" "github.com/caos/zitadel/internal/notification/repository/eventsourcing/handler" "github.com/caos/zitadel/internal/notification/repository/eventsourcing/view" usr_event "github.com/caos/zitadel/internal/user/repository/eventsourcing" @@ -21,12 +22,12 @@ type EventstoreRepos struct { UserEvents *usr_event.UserEventstore } -func StartSpooler(c SpoolerConfig, es eventstore.Eventstore, view *view.View, sql *sql.DB, eventstoreRepos handler.EventstoreRepos, systemDefaults sd.SystemDefaults) *spooler.Spooler { +func StartSpooler(c SpoolerConfig, es eventstore.Eventstore, view *view.View, sql *sql.DB, eventstoreRepos handler.EventstoreRepos, systemDefaults sd.SystemDefaults, i18n *i18n.Translator) *spooler.Spooler { spoolerConfig := spooler.Config{ Eventstore: es, Locker: &locker{dbClient: sql}, ConcurrentTasks: c.ConcurrentTasks, - ViewHandlers: handler.Register(c.Handlers, c.BulkLimit, c.FailureCountUntilSkip, view, es, eventstoreRepos, systemDefaults), + ViewHandlers: handler.Register(c.Handlers, c.BulkLimit, c.FailureCountUntilSkip, view, es, eventstoreRepos, systemDefaults, i18n), } spool := spoolerConfig.New() spool.Start() diff --git a/internal/notification/static/i18n/de.yaml b/internal/notification/static/i18n/de.yaml new file mode 100644 index 0000000000..fb7b73cd09 --- /dev/null +++ b/internal/notification/static/i18n/de.yaml @@ -0,0 +1,29 @@ +InitCode: + Title: Zitadel - User initialisieren + PreHeader: User initialisieren + Subject: User initialisieren + Greeting: Hallo {{.FirstName}} {{.LastName}}, + Text: Dieser Benutzer wurde soeben im Zitadel erstellt. Du kannst den Button unten verwenden, um die Initialisierung abzuschliesen. (Code {{.Code}}) Falls du dieses Mail nicht angefordert hast, kannst du es einfach ignorieren. + ButtonText: Initialisierung abschliessen +PasswordReset: + Title: Zitadel - Passwort zurücksetzen + PreHeader: Passwort zurücksetzen + Subject: Passwort zurücksetzen + Greeting: Hallo {{.FirstName}} {{.LastName}}, + Text: Wir haben eine Anfrage für das Zurücksetzen deines Passwortes bekommen. Du kannst den untenstehenden Button verwenden, um dein Passwort zurückzusetzen. (Code {{.Code}}) Falls du dieses Mail nicht angefordert hast, kannst du es ignorieren. + ButtonText: Passwort zurücksetzen +VerifyEmail: + Title: Zitadel - Email verifizieren + PreHeader: Email verifizieren + Subject: Email verifizieren + Greeting: Hallo {{.FirstName}} {{.LastName}}, + Text: Eine neue E-Mail Adresse wurde hinzugefügt. Bitte verwende den untenstehenden Button um diese zu verifizieren. (Code {{.Code}}) Falls du deine E-Mail Adresse nicht selber hinzugefügt hast, kannst du dieses E-Mail ignorieren. + ButtonText: Email verifizieren +VerifyPhone: + Title: Zitadel - Telefonnummer verifizieren + PreHeader: Telefonnummer verifizieren + Subject: Telefonnummer verifizieren + Greeting: Hallo {{.FirstName}} {{.LastName}}, + Text: Eine Telefonnummer wurde hinzugefügt. Bitte verifiziere diese in dem du folgenden Code eingibst {{.Code}} + ButtonText: Telefon verifizieren + diff --git a/internal/notification/static/i18n/en.yaml b/internal/notification/static/i18n/en.yaml new file mode 100644 index 0000000000..f0c3079428 --- /dev/null +++ b/internal/notification/static/i18n/en.yaml @@ -0,0 +1,29 @@ +InitCode: + Title: Zitadel - Initialize User + PreHeader: Initialize User + Subject: Initialize User + Greeting: Hello {{.FirstName}} {{.LastName}}, + Text: This user was created in Zitadel. Please click the button below to finish the initialization process. (Code {{.Code}}) If you didn't ask for this mail, please ignore it. + ButtonText: Finish initialization +PasswordReset: + Title: Zitadel - Reset password + PreHeader: Reset password + Subject: Reset password + Greeting: Hello {{.FirstName}} {{.LastName}}, + Text: We received a password reset request. Please use the button below to reset your password. (Code {{.Code}}) If you didn't ask for this mail, please ignore it. + ButtonText: Reset password +VerifyEmail: + Title: Zitadel - Verify email + PreHeader: Verify email + Subject: Verify email + Greeting: Hello {{.FirstName}} {{.LastName}}, + Text: A new email has been added. Please use the button below to verify your mail. (Code {{.Code}}) If you din't add a new email, please ignore this email. + ButtonText: Verify email +VerifyPhone: + Title: Zitadel - Verify phone + PreHeader: Verify phone + Subject: Verify phone + Greeting: Hello {{.FirstName}} {{.LastName}}, + Text: A new phonenumber has been added. Please use the following code to verify it {{.Code}} + ButtonText: Verify phone + diff --git a/internal/notification/statik/generate.go b/internal/notification/statik/generate.go new file mode 100644 index 0000000000..0f9e4ac17a --- /dev/null +++ b/internal/notification/statik/generate.go @@ -0,0 +1,3 @@ +package statik + +//go:generate statik -src=../static -dest=.. -ns=notification diff --git a/internal/notification/templates/templateData.go b/internal/notification/templates/templateData.go index 6e3d6bbf77..a19aef9876 100644 --- a/internal/notification/templates/templateData.go +++ b/internal/notification/templates/templateData.go @@ -1,5 +1,9 @@ package templates +import ( + "github.com/caos/zitadel/internal/i18n" +) + type TemplateData struct { Title string PreHeader string @@ -9,3 +13,13 @@ type TemplateData struct { Href string ButtonText string } + +func (data *TemplateData) Translate(i18n *i18n.Translator, args map[string]interface{}, langs ...string) { + data.Title = i18n.Localize(data.Title, nil, langs...) + data.PreHeader = i18n.Localize(data.PreHeader, nil, langs...) + data.Subject = i18n.Localize(data.Subject, nil, langs...) + data.Greeting = i18n.Localize(data.Greeting, args, langs...) + data.Text = i18n.Localize(data.Text, args, langs...) + data.Href = i18n.Localize(data.Href, nil, langs...) + data.ButtonText = i18n.Localize(data.ButtonText, nil, langs...) +} diff --git a/internal/notification/types/email_verification_code.go b/internal/notification/types/email_verification_code.go index fd0a6d043c..8706dfa795 100644 --- a/internal/notification/types/email_verification_code.go +++ b/internal/notification/types/email_verification_code.go @@ -3,6 +3,7 @@ package types import ( "github.com/caos/zitadel/internal/config/systemdefaults" "github.com/caos/zitadel/internal/crypto" + "github.com/caos/zitadel/internal/i18n" "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" @@ -10,12 +11,10 @@ import ( type EmailVerificationCodeData struct { templates.TemplateData - FirstName string - LastName string - URL string + URL string } -func SendEmailVerificationCode(user *view_model.NotifyUser, code *es_model.EmailCode, systemDefaults systemdefaults.SystemDefaults, alg crypto.EncryptionAlgorithm) error { +func SendEmailVerificationCode(i18n *i18n.Translator, 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 @@ -24,7 +23,13 @@ func SendEmailVerificationCode(user *view_model.NotifyUser, code *es_model.Email if err != nil { return err } - emailCodeData := &EmailVerificationCodeData{TemplateData: systemDefaults.Notifications.TemplateData.VerifyEmail, FirstName: user.FirstName, LastName: user.LastName, URL: url} + var args = map[string]interface{}{ + "FirstName": user.FirstName, + "LastName": user.LastName, + "Code": codeString, + } + systemDefaults.Notifications.TemplateData.VerifyEmail.Translate(i18n, args, user.PreferredLanguage) + emailCodeData := &EmailVerificationCodeData{TemplateData: systemDefaults.Notifications.TemplateData.VerifyEmail, URL: url} template, err := templates.GetParsedTemplate(emailCodeData) if err != nil { diff --git a/internal/notification/types/init_code.go b/internal/notification/types/init_code.go index 0c73e3f7d8..0dab2c74aa 100644 --- a/internal/notification/types/init_code.go +++ b/internal/notification/types/init_code.go @@ -3,6 +3,7 @@ package types import ( "github.com/caos/zitadel/internal/config/systemdefaults" "github.com/caos/zitadel/internal/crypto" + "github.com/caos/zitadel/internal/i18n" "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" @@ -10,9 +11,7 @@ import ( type InitCodeEmailData struct { templates.TemplateData - FirstName string - LastName string - URL string + URL string } type UrlData struct { @@ -20,7 +19,7 @@ type UrlData struct { Code string } -func SendUserInitCode(user *view_model.NotifyUser, code *es_model.InitUserCode, systemDefaults systemdefaults.SystemDefaults, alg crypto.EncryptionAlgorithm) error { +func SendUserInitCode(i18n *i18n.Translator, 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 @@ -29,7 +28,13 @@ func SendUserInitCode(user *view_model.NotifyUser, code *es_model.InitUserCode, if err != nil { return err } - initCodeData := &InitCodeEmailData{TemplateData: systemDefaults.Notifications.TemplateData.InitCode, FirstName: user.FirstName, LastName: user.LastName, URL: url} + var args = map[string]interface{}{ + "FirstName": user.FirstName, + "LastName": user.LastName, + "Code": codeString, + } + systemDefaults.Notifications.TemplateData.InitCode.Translate(i18n, args, user.PreferredLanguage) + initCodeData := &InitCodeEmailData{TemplateData: systemDefaults.Notifications.TemplateData.InitCode, URL: url} template, err := templates.GetParsedTemplate(initCodeData) if err != nil { diff --git a/internal/notification/types/password_code.go b/internal/notification/types/password_code.go index b3843185de..ee63a65817 100644 --- a/internal/notification/types/password_code.go +++ b/internal/notification/types/password_code.go @@ -3,6 +3,7 @@ package types import ( "github.com/caos/zitadel/internal/config/systemdefaults" "github.com/caos/zitadel/internal/crypto" + "github.com/caos/zitadel/internal/i18n" "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" @@ -15,7 +16,7 @@ type PasswordCodeData struct { URL string } -func SendPasswordCode(user *view_model.NotifyUser, code *es_model.PasswordCode, systemDefaults systemdefaults.SystemDefaults, alg crypto.EncryptionAlgorithm) error { +func SendPasswordCode(i18n *i18n.Translator, 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 @@ -24,6 +25,12 @@ func SendPasswordCode(user *view_model.NotifyUser, code *es_model.PasswordCode, if err != nil { return err } + var args = map[string]interface{}{ + "FirstName": user.FirstName, + "LastName": user.LastName, + "Code": codeString, + } + systemDefaults.Notifications.TemplateData.PasswordReset.Translate(i18n, args, user.PreferredLanguage) passwordCodeData := &PasswordCodeData{TemplateData: systemDefaults.Notifications.TemplateData.PasswordReset, FirstName: user.FirstName, LastName: user.LastName, URL: url} template, err := templates.GetParsedTemplate(passwordCodeData) diff --git a/internal/notification/types/phone_verification_code.go b/internal/notification/types/phone_verification_code.go index 93d937267d..0cb1eb472c 100644 --- a/internal/notification/types/phone_verification_code.go +++ b/internal/notification/types/phone_verification_code.go @@ -3,24 +3,28 @@ package types import ( "github.com/caos/zitadel/internal/config/systemdefaults" "github.com/caos/zitadel/internal/crypto" + "github.com/caos/zitadel/internal/i18n" "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 + UserID string } -func SendPhoneVerificationCode(user *view_model.NotifyUser, code *es_model.PhoneCode, systemDefaults systemdefaults.SystemDefaults, alg crypto.EncryptionAlgorithm) error { +func SendPhoneVerificationCode(i18n *i18n.Translator, 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} + var args = map[string]interface{}{ + "FirstName": user.FirstName, + "LastName": user.LastName, + "Code": codeString, + } + systemDefaults.Notifications.TemplateData.VerifyPhone.Translate(i18n, args, user.PreferredLanguage) + codeData := &PhoneVerificationCodeData{UserID: user.ID} template, err := templates.ParseTemplateText(systemDefaults.Notifications.TemplateData.VerifyPhone.Text, codeData) if err != nil { return err