diff --git a/cmd/zitadel/system-defaults.yaml b/cmd/zitadel/system-defaults.yaml index 1f22bf6185..cd84668dce 100644 --- a/cmd/zitadel/system-defaults.yaml +++ b/cmd/zitadel/system-defaults.yaml @@ -1,5 +1,5 @@ SystemDefaults: - DefaultLanguage: 'de' + DefaultLanguage: 'en' Domain: $ZITADEL_DEFAULT_DOMAIN ZitadelDocs: Issuer: $ZITADEL_ISSUER diff --git a/internal/iam/repository/view/mail_text_view.go b/internal/iam/repository/view/mail_text_view.go index 82262bf515..31f440293a 100644 --- a/internal/iam/repository/view/mail_text_view.go +++ b/internal/iam/repository/view/mail_text_view.go @@ -7,6 +7,7 @@ import ( global_model "github.com/caos/zitadel/internal/model" "github.com/caos/zitadel/internal/view/repository" "github.com/jinzhu/gorm" + "strings" ) func GetMailTexts(db *gorm.DB, table string, aggregateID string) ([]*model.MailTextView, error) { @@ -30,7 +31,7 @@ func GetMailTextByIDs(db *gorm.DB, table, aggregateID string, textType string, l mailText := new(model.MailTextView) aggregateIDQuery := &model.MailTextSearchQuery{Key: iam_model.MailTextSearchKeyAggregateID, Value: aggregateID, Method: global_model.SearchMethodEquals} textTypeQuery := &model.MailTextSearchQuery{Key: iam_model.MailTextSearchKeyMailTextType, Value: textType, Method: global_model.SearchMethodEquals} - languageQuery := &model.MailTextSearchQuery{Key: iam_model.MailTextSearchKeyLanguage, Value: language, Method: global_model.SearchMethodEquals} + languageQuery := &model.MailTextSearchQuery{Key: iam_model.MailTextSearchKeyLanguage, Value: strings.ToUpper(language), Method: global_model.SearchMethodEquals} query := repository.PrepareGetByQuery(table, aggregateIDQuery, textTypeQuery, languageQuery) err := query(db, mailText) if caos_errs.IsNotFound(err) { diff --git a/internal/notification/repository/eventsourcing/handler/notification.go b/internal/notification/repository/eventsourcing/handler/notification.go index 56af4c6f06..3841f1707a 100644 --- a/internal/notification/repository/eventsourcing/handler/notification.go +++ b/internal/notification/repository/eventsourcing/handler/notification.go @@ -3,6 +3,9 @@ package handler import ( "context" "encoding/json" + "github.com/caos/zitadel/internal/user/model" + model2 "github.com/caos/zitadel/internal/user/repository/view/model" + "golang.org/x/text/language" "net/http" "time" @@ -150,12 +153,12 @@ func (n *Notification) handleInitUserCode(event *models.Event) (err error) { return err } - user, err := n.view.NotifyUserByID(event.AggregateID) + user, err := n.getUserByID(event.AggregateID) if err != nil { return err } - text, err := n.getMailText(context.Background(), mailTextTypeInitCode, user.PreferredLanguage[len(user.PreferredLanguage)-2:]) + text, err := n.getMailText(context.Background(), mailTextTypeInitCode, user.PreferredLanguage) if err != nil { return err } @@ -189,12 +192,12 @@ func (n *Notification) handlePasswordCode(event *models.Event) (err error) { return err } - user, err := n.view.NotifyUserByID(event.AggregateID) + user, err := n.getUserByID(event.AggregateID) if err != nil { return err } - text, err := n.getMailText(context.Background(), mailTextTypePasswordReset, user.PreferredLanguage[len(user.PreferredLanguage)-2:]) + text, err := n.getMailText(context.Background(), mailTextTypePasswordReset, user.PreferredLanguage) if err != nil { return err } @@ -227,12 +230,12 @@ func (n *Notification) handleEmailVerificationCode(event *models.Event) (err err return err } - user, err := n.view.NotifyUserByID(event.AggregateID) + user, err := n.getUserByID(event.AggregateID) if err != nil { return err } - text, err := n.getMailText(context.Background(), mailTextTypeVerifyEmail, user.PreferredLanguage[len(user.PreferredLanguage)-2:]) + text, err := n.getMailText(context.Background(), mailTextTypeVerifyEmail, user.PreferredLanguage) if err != nil { return err } @@ -255,7 +258,7 @@ func (n *Notification) handlePhoneVerificationCode(event *models.Event) (err err if err != nil || alreadyHandled { return nil } - user, err := n.view.NotifyUserByID(event.AggregateID) + user, err := n.getUserByID(event.AggregateID) if err != nil { return err } @@ -276,7 +279,7 @@ func (n *Notification) handleDomainClaimed(event *models.Event) (err error) { logging.Log("HANDLE-Gghq2").WithError(err).Error("could not unmarshal event data") return caos_errs.ThrowInternal(err, "HANDLE-7hgj3", "could not unmarshal event") } - user, err := n.view.NotifyUserByID(event.AggregateID) + user, err := n.getUserByID(event.AggregateID) if err != nil { return err } @@ -290,7 +293,7 @@ func (n *Notification) handleDomainClaimed(event *models.Event) (err error) { return err } - text, err := n.getMailText(context.Background(), mailTextTypeDomainClaimed, user.PreferredLanguage[len(user.PreferredLanguage)-2:]) + text, err := n.getMailText(context.Background(), mailTextTypeDomainClaimed, user.PreferredLanguage) if err != nil { return err } @@ -382,12 +385,17 @@ func (n *Notification) getMailTemplate(ctx context.Context) (*iam_model.MailTemp } // Read organization specific texts -func (n *Notification) getMailText(ctx context.Context, textType string, language string) (*iam_model.MailTextView, error) { +func (n *Notification) getMailText(ctx context.Context, textType string, lang string) (*iam_model.MailTextView, error) { + langTag := language.Make(lang) + if langTag == language.Und { + langTag = n.systemDefaults.DefaultLanguage + } + base, _ := langTag.Base() // read from Org - mailText, err := n.view.MailTextByIDs(authz.GetCtxData(ctx).OrgID, textType, language, mailTextTableOrg) + mailText, err := n.view.MailTextByIDs(authz.GetCtxData(ctx).OrgID, textType, base.String(), mailTextTableOrg) if errors.IsNotFound(err) { // read from default - mailText, err = n.view.MailTextByIDs(n.systemDefaults.IamID, textType, language, mailTextTableDef) + mailText, err = n.view.MailTextByIDs(n.systemDefaults.IamID, textType, base.String(), mailTextTableDef) if err != nil { return nil, err } @@ -398,3 +406,27 @@ func (n *Notification) getMailText(ctx context.Context, textType string, languag } return iam_es_model.MailTextViewToModel(mailText), err } + +func (n *Notification) getUserByID(userID string) (*model2.NotifyUser, error) { + user, usrErr := n.view.NotifyUserByID(userID) + if usrErr != nil && !caos_errs.IsNotFound(usrErr) { + return nil, usrErr + } + if user == nil { + user = &model2.NotifyUser{} + } + events, err := n.getUserEvents(userID, user.Sequence) + if err != nil { + return user, usrErr + } + userCopy := *user + for _, event := range events { + if err := userCopy.AppendEvent(event); err != nil { + return user, nil + } + } + if userCopy.State == int32(model.UserStateDeleted) { + return nil, caos_errs.ThrowNotFound(nil, "HANDLER-3n8fs", "Errors.User.NotFound") + } + return &userCopy, nil +} diff --git a/internal/user/repository/view/model/notify_user.go b/internal/user/repository/view/model/notify_user.go index b5a5e687f6..6740febdbc 100644 --- a/internal/user/repository/view/model/notify_user.go +++ b/internal/user/repository/view/model/notify_user.go @@ -39,6 +39,7 @@ type NotifyUser struct { VerifiedPhone string `json:"-" gorm:"column:verified_phone"` PasswordSet bool `json:"-" gorm:"column:password_set"` Sequence uint64 `json:"-" gorm:"column:sequence"` + State int32 `json:"-" gorm:"-"` } func NotifyUserFromModel(user *model.NotifyUser) *NotifyUser { @@ -144,6 +145,8 @@ func (u *NotifyUser) AppendEvent(event *models.Event) (err error) { case es_model.UserPasswordChanged, es_model.HumanPasswordChanged: err = u.setPasswordData(event) + case es_model.UserRemoved: + u.State = int32(UserStateDeleted) } return err }