diff --git a/pkg/notifications/notify_disabled_test.go b/pkg/notifications/notify_disabled_test.go index 363046c46..430d9fb67 100644 --- a/pkg/notifications/notify_disabled_test.go +++ b/pkg/notifications/notify_disabled_test.go @@ -28,10 +28,10 @@ import ( type disabledMailNotifiable struct{} -func (d *disabledMailNotifiable) RouteForMail() (string, error) { return "test@example.com", nil } -func (d *disabledMailNotifiable) RouteForDB() int64 { return 1 } +func (d *disabledMailNotifiable) RouteForMail() (string, error) { return "test@example.com", nil } +func (d *disabledMailNotifiable) RouteForDB() int64 { return 1 } func (d *disabledMailNotifiable) ShouldNotify(_ ...*xorm.Session) (bool, error) { return true, nil } -func (d *disabledMailNotifiable) Lang() string { return "en" } +func (d *disabledMailNotifiable) Lang() string { return "en" } type disabledMailNotification struct{} diff --git a/pkg/user/delete.go b/pkg/user/delete.go index e985a5869..154c9f741 100644 --- a/pkg/user/delete.go +++ b/pkg/user/delete.go @@ -17,6 +17,7 @@ package user import ( + "fmt" "time" "code.vikunja.io/api/pkg/cron" @@ -50,6 +51,9 @@ func notifyUsersScheduledForDeletion() { return } + // Close the read-only session before processing each user in its own transaction. + s.Close() + log.Debugf("Found %d users scheduled for deletion to notify", len(users)) for _, user := range users { @@ -67,27 +71,33 @@ func notifyUsersScheduledForDeletion() { log.Debugf("Notifying user %d of the deletion of their account...", user.ID) - err = notifications.Notify(user, &AccountDeletionNotification{ - User: user, - NotificationNumber: number, - }, s) - if err != nil { - log.Errorf("Could not notify user %d of their deletion: %s", user.ID, err) - continue - } - - user.DeletionLastReminderSent = time.Now() - _, err = s.Where("id = ?", user.ID). - Cols("deletion_last_reminder_sent"). - Update(user) - if err != nil { - log.Errorf("Could update user %d last deletion reminder sent date: %s", user.ID, err) + if err := notifyUserOfDeletion(user, number); err != nil { + log.Errorf("Could not process deletion notification for user %d: %s", user.ID, err) } } +} - if err := s.Commit(); err != nil { - log.Errorf("Could not commit user deletion notifications: %s", err) +func notifyUserOfDeletion(user *User, number int) error { + s := db.NewSession() + defer s.Close() + + err := notifications.Notify(user, &AccountDeletionNotification{ + User: user, + NotificationNumber: number, + }, s) + if err != nil { + return fmt.Errorf("could not notify user: %w", err) } + + user.DeletionLastReminderSent = time.Now() + _, err = s.Where("id = ?", user.ID). + Cols("deletion_last_reminder_sent"). + Update(user) + if err != nil { + return fmt.Errorf("could not update last deletion reminder sent date: %w", err) + } + + return s.Commit() } // RequestDeletion creates a user deletion confirm token and sends a notification to the user diff --git a/pkg/user/user_password_reset.go b/pkg/user/user_password_reset.go index 4450b0e93..27d8cedfc 100644 --- a/pkg/user/user_password_reset.go +++ b/pkg/user/user_password_reset.go @@ -93,7 +93,6 @@ func ResetPassword(s *xorm.Session, reset *PasswordReset) (userID int64, err err return } - // PasswordTokenRequest defines the request format for password reset resqest type PasswordTokenRequest struct { Email string `json:"email" valid:"email,length(0|250)" maxLength:"250"`