Skip to content

Commit

Permalink
[pocketbase#1069] added default Message-ID and more options to custom…
Browse files Browse the repository at this point in the history
…ize the mail message
  • Loading branch information
ganigeorgiev committed Nov 21, 2022
1 parent c4a660d commit 3e1a196
Show file tree
Hide file tree
Showing 11 changed files with 186 additions and 157 deletions.
24 changes: 12 additions & 12 deletions apis/settings_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -303,12 +303,12 @@ func TestSettingsTestEmail(t *testing.T) {
t.Fatalf("[verification] Expected 1 sent email, got %d", app.TestMailer.TotalSend)
}

if app.TestMailer.LastToAddress.Address != "[email protected]" {
t.Fatalf("[verification] Expected the email to be sent to %s, got %s", "[email protected]", app.TestMailer.LastToAddress.Address)
if app.TestMailer.LastMessage.To.Address != "[email protected]" {
t.Fatalf("[verification] Expected the email to be sent to %s, got %s", "[email protected]", app.TestMailer.LastMessage.To.Address)
}

if !strings.Contains(app.TestMailer.LastHtmlBody, "Verify") {
t.Fatalf("[verification] Expected to sent a verification email, got \n%v\n%v", app.TestMailer.LastHtmlSubject, app.TestMailer.LastHtmlBody)
if !strings.Contains(app.TestMailer.LastMessage.HTML, "Verify") {
t.Fatalf("[verification] Expected to sent a verification email, got \n%v\n%v", app.TestMailer.LastMessage.Subject, app.TestMailer.LastMessage.HTML)
}
},
ExpectedStatus: 204,
Expand All @@ -334,12 +334,12 @@ func TestSettingsTestEmail(t *testing.T) {
t.Fatalf("[password-reset] Expected 1 sent email, got %d", app.TestMailer.TotalSend)
}

if app.TestMailer.LastToAddress.Address != "[email protected]" {
t.Fatalf("[password-reset] Expected the email to be sent to %s, got %s", "[email protected]", app.TestMailer.LastToAddress.Address)
if app.TestMailer.LastMessage.To.Address != "[email protected]" {
t.Fatalf("[password-reset] Expected the email to be sent to %s, got %s", "[email protected]", app.TestMailer.LastMessage.To.Address)
}

if !strings.Contains(app.TestMailer.LastHtmlBody, "Reset password") {
t.Fatalf("[password-reset] Expected to sent a password-reset email, got \n%v\n%v", app.TestMailer.LastHtmlSubject, app.TestMailer.LastHtmlBody)
if !strings.Contains(app.TestMailer.LastMessage.HTML, "Reset password") {
t.Fatalf("[password-reset] Expected to sent a password-reset email, got \n%v\n%v", app.TestMailer.LastMessage.Subject, app.TestMailer.LastMessage.HTML)
}
},
ExpectedStatus: 204,
Expand All @@ -365,12 +365,12 @@ func TestSettingsTestEmail(t *testing.T) {
t.Fatalf("[email-change] Expected 1 sent email, got %d", app.TestMailer.TotalSend)
}

if app.TestMailer.LastToAddress.Address != "[email protected]" {
t.Fatalf("[email-change] Expected the email to be sent to %s, got %s", "[email protected]", app.TestMailer.LastToAddress.Address)
if app.TestMailer.LastMessage.To.Address != "[email protected]" {
t.Fatalf("[email-change] Expected the email to be sent to %s, got %s", "[email protected]", app.TestMailer.LastMessage.To.Address)
}

if !strings.Contains(app.TestMailer.LastHtmlBody, "Confirm new email") {
t.Fatalf("[email-change] Expected to sent a confirm new email email, got \n%v\n%v", app.TestMailer.LastHtmlSubject, app.TestMailer.LastHtmlBody)
if !strings.Contains(app.TestMailer.LastMessage.HTML, "Confirm new email") {
t.Fatalf("[email-change] Expected to sent a confirm new email email, got \n%v\n%v", app.TestMailer.LastMessage.Subject, app.TestMailer.LastMessage.HTML)
}
},
ExpectedStatus: 204,
Expand Down
2 changes: 2 additions & 0 deletions core/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,14 @@ type ModelEvent struct {

type MailerRecordEvent struct {
MailClient mailer.Mailer
Message *mailer.Message
Record *models.Record
Meta map[string]any
}

type MailerAdminEvent struct {
MailClient mailer.Mailer
Message *mailer.Message
Admin *models.Admin
Meta map[string]any
}
Expand Down
4 changes: 2 additions & 2 deletions forms/test_email_send_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,8 @@ func TestEmailSendValidateAndSubmit(t *testing.T) {
expectedContent = "Confirm new email"
}

if !strings.Contains(app.TestMailer.LastHtmlBody, expectedContent) {
t.Errorf("(%d) Expected the email to contains %s, got \n%v", i, expectedContent, app.TestMailer.LastHtmlBody)
if !strings.Contains(app.TestMailer.LastMessage.HTML, expectedContent) {
t.Errorf("(%d) Expected the email to contains %s, got \n%v", i, expectedContent, app.TestMailer.LastMessage.HTML)
}
}
}
35 changes: 19 additions & 16 deletions mails/admin.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"github.com/pocketbase/pocketbase/mails/templates"
"github.com/pocketbase/pocketbase/models"
"github.com/pocketbase/pocketbase/tokens"
"github.com/pocketbase/pocketbase/tools/mailer"
"github.com/pocketbase/pocketbase/tools/rest"
)

Expand Down Expand Up @@ -43,29 +44,31 @@ func SendAdminPasswordReset(app core.App, admin *models.Admin) error {

mailClient := app.NewMailClient()

// resolve body template
body, renderErr := resolveTemplateContent(params, templates.Layout, templates.AdminPasswordResetBody)
if renderErr != nil {
return renderErr
}

message := &mailer.Message{
From: mail.Address{
Name: app.Settings().Meta.SenderName,
Address: app.Settings().Meta.SenderAddress,
},
To: mail.Address{Address: admin.Email},
Subject: "Reset admin password",
HTML: body,
}

event := &core.MailerAdminEvent{
MailClient: mailClient,
Message: message,
Admin: admin,
Meta: map[string]any{"token": token},
}

sendErr := app.OnMailerBeforeAdminResetPasswordSend().Trigger(event, func(e *core.MailerAdminEvent) error {
// resolve body template
body, renderErr := resolveTemplateContent(params, templates.Layout, templates.AdminPasswordResetBody)
if renderErr != nil {
return renderErr
}

return e.MailClient.Send(
mail.Address{
Name: app.Settings().Meta.SenderName,
Address: app.Settings().Meta.SenderAddress,
},
mail.Address{Address: e.Admin.Email},
"Reset admin password",
body,
nil,
)
return e.MailClient.Send(e.Message)
})

if sendErr == nil {
Expand Down
4 changes: 2 additions & 2 deletions mails/admin_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ func TestSendAdminPasswordReset(t *testing.T) {
"http://localhost:8090/_/#/confirm-password-reset/eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.",
}
for _, part := range expectedParts {
if !strings.Contains(testApp.TestMailer.LastHtmlBody, part) {
t.Fatalf("Couldn't find %s \nin\n %s", part, testApp.TestMailer.LastHtmlBody)
if !strings.Contains(testApp.TestMailer.LastMessage.HTML, part) {
t.Fatalf("Couldn't find %s \nin\n %s", part, testApp.TestMailer.LastMessage.HTML)
}
}
}
110 changes: 58 additions & 52 deletions mails/record.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import (
"github.com/pocketbase/pocketbase/core"
"github.com/pocketbase/pocketbase/mails/templates"
"github.com/pocketbase/pocketbase/models"
"github.com/pocketbase/pocketbase/models/schema"
"github.com/pocketbase/pocketbase/tokens"
"github.com/pocketbase/pocketbase/tools/mailer"
)

// SendRecordPasswordReset sends a password reset request email to the specified user.
Expand All @@ -20,30 +20,32 @@ func SendRecordPasswordReset(app core.App, authRecord *models.Record) error {

mailClient := app.NewMailClient()

settings := app.Settings()

subject, body, err := resolveEmailTemplate(app, token, settings.Meta.ResetPasswordTemplate)
if err != nil {
return err
}

message := &mailer.Message{
From: mail.Address{
Name: settings.Meta.SenderName,
Address: settings.Meta.SenderAddress,
},
To: mail.Address{Address: authRecord.Email()},
Subject: subject,
HTML: body,
}

event := &core.MailerRecordEvent{
MailClient: mailClient,
Message: message,
Record: authRecord,
Meta: map[string]any{"token": token},
}

sendErr := app.OnMailerBeforeRecordResetPasswordSend().Trigger(event, func(e *core.MailerRecordEvent) error {
settings := app.Settings()

subject, body, err := resolveEmailTemplate(app, token, settings.Meta.ResetPasswordTemplate)
if err != nil {
return err
}

return e.MailClient.Send(
mail.Address{
Name: settings.Meta.SenderName,
Address: settings.Meta.SenderAddress,
},
mail.Address{Address: e.Record.GetString(schema.FieldNameEmail)},
subject,
body,
nil,
)
return e.MailClient.Send(e.Message)
})

if sendErr == nil {
Expand All @@ -62,30 +64,32 @@ func SendRecordVerification(app core.App, authRecord *models.Record) error {

mailClient := app.NewMailClient()

settings := app.Settings()

subject, body, err := resolveEmailTemplate(app, token, settings.Meta.VerificationTemplate)
if err != nil {
return err
}

message := &mailer.Message{
From: mail.Address{
Name: settings.Meta.SenderName,
Address: settings.Meta.SenderAddress,
},
To: mail.Address{Address: authRecord.Email()},
Subject: subject,
HTML: body,
}

event := &core.MailerRecordEvent{
MailClient: mailClient,
Message: message,
Record: authRecord,
Meta: map[string]any{"token": token},
}

sendErr := app.OnMailerBeforeRecordVerificationSend().Trigger(event, func(e *core.MailerRecordEvent) error {
settings := app.Settings()

subject, body, err := resolveEmailTemplate(app, token, settings.Meta.VerificationTemplate)
if err != nil {
return err
}

return e.MailClient.Send(
mail.Address{
Name: settings.Meta.SenderName,
Address: settings.Meta.SenderAddress,
},
mail.Address{Address: e.Record.GetString(schema.FieldNameEmail)},
subject,
body,
nil,
)
return e.MailClient.Send(e.Message)
})

if sendErr == nil {
Expand All @@ -104,8 +108,26 @@ func SendRecordChangeEmail(app core.App, record *models.Record, newEmail string)

mailClient := app.NewMailClient()

settings := app.Settings()

subject, body, err := resolveEmailTemplate(app, token, settings.Meta.ConfirmEmailChangeTemplate)
if err != nil {
return err
}

message := &mailer.Message{
From: mail.Address{
Name: settings.Meta.SenderName,
Address: settings.Meta.SenderAddress,
},
To: mail.Address{Address: newEmail},
Subject: subject,
HTML: body,
}

event := &core.MailerRecordEvent{
MailClient: mailClient,
Message: message,
Record: record,
Meta: map[string]any{
"token": token,
Expand All @@ -114,23 +136,7 @@ func SendRecordChangeEmail(app core.App, record *models.Record, newEmail string)
}

sendErr := app.OnMailerBeforeRecordChangeEmailSend().Trigger(event, func(e *core.MailerRecordEvent) error {
settings := app.Settings()

subject, body, err := resolveEmailTemplate(app, token, settings.Meta.ConfirmEmailChangeTemplate)
if err != nil {
return err
}

return e.MailClient.Send(
mail.Address{
Name: settings.Meta.SenderName,
Address: settings.Meta.SenderAddress,
},
mail.Address{Address: newEmail},
subject,
body,
nil,
)
return e.MailClient.Send(e.Message)
})

if sendErr == nil {
Expand Down
12 changes: 6 additions & 6 deletions mails/record_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ func TestSendRecordPasswordReset(t *testing.T) {
"http://localhost:8090/_/#/auth/confirm-password-reset/eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.",
}
for _, part := range expectedParts {
if !strings.Contains(testApp.TestMailer.LastHtmlBody, part) {
t.Fatalf("Couldn't find %s \nin\n %s", part, testApp.TestMailer.LastHtmlBody)
if !strings.Contains(testApp.TestMailer.LastMessage.HTML, part) {
t.Fatalf("Couldn't find %s \nin\n %s", part, testApp.TestMailer.LastMessage.HTML)
}
}
}
Expand All @@ -55,8 +55,8 @@ func TestSendRecordVerification(t *testing.T) {
"http://localhost:8090/_/#/auth/confirm-verification/eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.",
}
for _, part := range expectedParts {
if !strings.Contains(testApp.TestMailer.LastHtmlBody, part) {
t.Fatalf("Couldn't find %s \nin\n %s", part, testApp.TestMailer.LastHtmlBody)
if !strings.Contains(testApp.TestMailer.LastMessage.HTML, part) {
t.Fatalf("Couldn't find %s \nin\n %s", part, testApp.TestMailer.LastMessage.HTML)
}
}
}
Expand All @@ -80,8 +80,8 @@ func TestSendRecordChangeEmail(t *testing.T) {
"http://localhost:8090/_/#/auth/confirm-email-change/eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.",
}
for _, part := range expectedParts {
if !strings.Contains(testApp.TestMailer.LastHtmlBody, part) {
t.Fatalf("Couldn't find %s \nin\n %s", part, testApp.TestMailer.LastHtmlBody)
if !strings.Contains(testApp.TestMailer.LastMessage.HTML, part) {
t.Fatalf("Couldn't find %s \nin\n %s", part, testApp.TestMailer.LastMessage.HTML)
}
}
}
25 changes: 7 additions & 18 deletions tests/mailer.go
Original file line number Diff line number Diff line change
@@ -1,38 +1,27 @@
package tests

import (
"io"
"net/mail"

"github.com/pocketbase/pocketbase/tools/mailer"
)

var _ mailer.Mailer = (*TestMailer)(nil)

// TestMailer is a mock `mailer.Mailer` implementation.
type TestMailer struct {
TotalSend int
LastFromAddress mail.Address
LastToAddress mail.Address
LastHtmlSubject string
LastHtmlBody string
TotalSend int
LastMessage mailer.Message
}

// Reset clears any previously test collected data.
func (m *TestMailer) Reset() {
m.TotalSend = 0
m.LastFromAddress = mail.Address{}
m.LastToAddress = mail.Address{}
m.LastHtmlSubject = ""
m.LastHtmlBody = ""
m.LastMessage = mailer.Message{}
}

// Send implements `mailer.Mailer` interface.
func (m *TestMailer) Send(fromEmail mail.Address, toEmail mail.Address, subject string, html string, attachments map[string]io.Reader) error {
m.LastFromAddress = fromEmail
m.LastToAddress = toEmail
m.LastHtmlSubject = subject
m.LastHtmlBody = html
m.TotalSend++
func (c *TestMailer) Send(m *mailer.Message) error {
c.TotalSend++
c.LastMessage = *m

return nil
}
Loading

0 comments on commit 3e1a196

Please sign in to comment.