Skip to content

Commit 33294be

Browse files
committed
fix(user): make registration more resilient to email failures
- Add BeforeCreate hook to validate email syntax before user creation - Make email verification sending non-fatal during account creation - Log warning when email fails to send but allow registration to succeed - Track failed email sends with metrics - Configure HELO domain for mail server to improve SMTP handshakes
1 parent d368541 commit 33294be

File tree

3 files changed

+28
-1
lines changed

3 files changed

+28
-1
lines changed

db/models/user.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,19 @@ type User struct {
3232
PasswordResets []PasswordReset
3333
}
3434

35+
func (u *User) BeforeCreate(tx *gorm.DB) error {
36+
if u.Email != "" {
37+
verify, err := getEmailVerifier().Verify(u.Email)
38+
if err != nil {
39+
return err
40+
}
41+
if !verify.Syntax.Valid {
42+
return errors.New("email is invalid")
43+
}
44+
}
45+
return nil
46+
}
47+
3548
func (u *User) BeforeUpdate(tx *gorm.DB) error {
3649
var email string
3750
var changed bool

service/mailer.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,14 @@ func NewMailerService(templateRegistry *mailer.TemplateRegistry) (core.Service,
162162
options = append(options, mail.WithUsername(mailCfg.Username))
163163
options = append(options, mail.WithPassword(mailCfg.Password))
164164

165+
if mailCfg.Host != "" {
166+
domain := mailCfg.Host
167+
if ctx.Config().Config().Core.Domain != "" {
168+
domain = ctx.Config().Config().Core.Domain
169+
}
170+
options = append(options, mail.WithHELO(domain))
171+
}
172+
165173
client, err := mail.NewClient(mailCfg.Host, options...)
166174
if err != nil {
167175
ctx.Logger().Error("Failed to create mail client",

service/user.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,10 @@ import (
1313
"go.lumeweb.com/portal/db/models"
1414
"go.lumeweb.com/portal/event"
1515
dbHelper "go.lumeweb.com/portal/service/internal/db"
16+
"go.lumeweb.com/portal/service/internal/mailer"
1617
"go.lumeweb.com/portal/service/internal/user"
1718
userInternal "go.lumeweb.com/portal/service/internal/user"
19+
"go.uber.org/zap"
1820
"golang.org/x/crypto/bcrypt"
1921
"gorm.io/gorm"
2022
"gorm.io/gorm/clause"
@@ -273,7 +275,11 @@ func (u UserServiceDefault) CreateAccount(ctx context.Context, email string, pas
273275
}
274276
} else if verifyEmail {
275277
if err := u.SendEmailVerification(ctx, _user.ID); err != nil {
276-
return nil, err
278+
u.Logger().Warn("Failed to send email verification during account creation, but account was created successfully",
279+
zap.Uint("user_id", _user.ID),
280+
zap.String("email", _user.Email),
281+
zap.Error(err))
282+
mailer.MailerFailed.WithLabelValues(mailer.LabelOpSend).Inc()
277283
}
278284
}
279285

0 commit comments

Comments
 (0)