Skip to content

Commit

Permalink
fix: optional smtp block should not override remote
Browse files Browse the repository at this point in the history
  • Loading branch information
sweatybridge committed Dec 7, 2024
1 parent 0e8d7c4 commit 2157392
Show file tree
Hide file tree
Showing 7 changed files with 63 additions and 45 deletions.
2 changes: 1 addition & 1 deletion internal/start/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -500,7 +500,7 @@ EOF
fmt.Sprintf("GOTRUE_MFA_MAX_ENROLLED_FACTORS=%v", utils.Config.Auth.MFA.MaxEnrolledFactors),
}

if utils.Config.Auth.Email.Smtp != nil {
if utils.Config.Auth.Email.Smtp != nil && utils.Config.Auth.Email.Smtp.IsEnabled() {
env = append(env,
fmt.Sprintf("GOTRUE_SMTP_HOST=%s", utils.Config.Auth.Email.Smtp.Host),
fmt.Sprintf("GOTRUE_SMTP_PORT=%d", utils.Config.Auth.Email.Smtp.Port),
Expand Down
66 changes: 41 additions & 25 deletions pkg/config/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ type (
}

smtp struct {
Enabled *bool `toml:"enabled"`
Host string `toml:"host"`
Port uint16 `toml:"port"`
User string `toml:"user"`
Expand Down Expand Up @@ -380,16 +381,9 @@ func (e email) toAuthConfigBody(body *v1API.UpdateAuthConfigBody) {
body.MailerOtpExp = cast.UintToIntPtr(&e.OtpExpiry)
body.SecurityUpdatePasswordRequireReauthentication = &e.SecurePasswordChange
body.SmtpMaxFrequency = cast.Ptr(int(e.MaxFrequency.Seconds()))
// When local config is not set, we assume platform defaults should not change
if e.Smtp != nil {
body.SmtpHost = &e.Smtp.Host
body.SmtpPort = cast.Ptr(strconv.Itoa(int(e.Smtp.Port)))
body.SmtpUser = &e.Smtp.User
body.SmtpPass = &e.Smtp.Pass
body.SmtpAdminEmail = &e.Smtp.AdminEmail
body.SmtpSenderName = &e.Smtp.SenderName
} else {
// Setting a single empty string disables SMTP
body.SmtpHost = cast.Ptr("")
e.Smtp.toAuthConfigBody(body)
}
if len(e.Template) == 0 {
return
Expand Down Expand Up @@ -423,27 +417,14 @@ func (e *email) fromAuthConfig(remoteConfig v1API.AuthConfigResponse) {
e.OtpExpiry = cast.IntToUint(remoteConfig.MailerOtpExp)
e.SecurePasswordChange = cast.Val(remoteConfig.SecurityUpdatePasswordRequireReauthentication, false)
e.MaxFrequency = time.Duration(cast.Val(remoteConfig.SmtpMaxFrequency, 0)) * time.Second
// Api resets all values when SMTP is disabled
if remoteConfig.SmtpHost != nil {
e.Smtp = &smtp{
Host: *remoteConfig.SmtpHost,
User: cast.Val(remoteConfig.SmtpUser, ""),
Pass: hashPrefix + cast.Val(remoteConfig.SmtpPass, ""),
AdminEmail: cast.Val(remoteConfig.SmtpAdminEmail, ""),
SenderName: cast.Val(remoteConfig.SmtpSenderName, ""),
}
portStr := cast.Val(remoteConfig.SmtpPort, "")
if port, err := strconv.ParseUint(portStr, 10, 16); err == nil {
e.Smtp.Port = uint16(port)
}
} else {
e.Smtp = nil
// When local config is not set, we assume platform defaults should not change
if e.Smtp != nil {
e.Smtp.fromAuthConfig(remoteConfig)
}
if len(e.Template) == 0 {
return
}
var tmpl emailTemplate
// When local config is not set, we assume platform defaults should not change
tmpl = e.Template["invite"]
if tmpl.Subject != nil {
tmpl.Subject = remoteConfig.MailerSubjectsInvite
Expand Down Expand Up @@ -499,6 +480,41 @@ func (e *email) fromAuthConfig(remoteConfig v1API.AuthConfigResponse) {
e.Template["reauthentication"] = tmpl
}

func (s smtp) IsEnabled() bool {
// If Enabled is not defined, or defined and set to true
return cast.Val(s.Enabled, true)
}

func (s smtp) toAuthConfigBody(body *v1API.UpdateAuthConfigBody) {
if !s.IsEnabled() {
// Setting a single empty string disables SMTP
body.SmtpHost = cast.Ptr("")
return
}
body.SmtpHost = &s.Host
body.SmtpPort = cast.Ptr(strconv.Itoa(int(s.Port)))
body.SmtpUser = &s.User
body.SmtpPass = &s.Pass
body.SmtpAdminEmail = &s.AdminEmail
body.SmtpSenderName = &s.SenderName
}

func (s *smtp) fromAuthConfig(remoteConfig v1API.AuthConfigResponse) {
s.Host = cast.Val(remoteConfig.SmtpHost, "")
s.User = cast.Val(remoteConfig.SmtpUser, "")
s.Pass = hashPrefix + cast.Val(remoteConfig.SmtpPass, "")
s.AdminEmail = cast.Val(remoteConfig.SmtpAdminEmail, "")
s.SenderName = cast.Val(remoteConfig.SmtpSenderName, "")
portStr := cast.Val(remoteConfig.SmtpPort, "0")
if port, err := strconv.ParseUint(portStr, 10, 16); err == nil {
s.Port = uint16(port)
}
// Api resets all values when SMTP is disabled
if enabled := len(s.Host) > 0; s.Enabled != nil {
*s.Enabled = enabled
}
}

func (s sms) toAuthConfigBody(body *v1API.UpdateAuthConfigBody) {
body.ExternalPhoneEnabled = &s.EnableSignup
body.SmsMaxFrequency = cast.Ptr(int(s.MaxFrequency.Seconds()))
Expand Down
10 changes: 10 additions & 0 deletions pkg/config/auth_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,7 @@ func TestEmailDiff(t *testing.T) {
},
},
Smtp: &smtp{
Enabled: cast.Ptr(true),
Host: "smtp.sendgrid.net",
Port: 587,
User: "apikey",
Expand Down Expand Up @@ -535,6 +536,15 @@ func TestEmailDiff(t *testing.T) {
"email_change": {},
"reauthentication": {},
},
Smtp: &smtp{
Enabled: cast.Ptr(false),
Host: "smtp.sendgrid.net",
Port: 587,
User: "apikey",
Pass: "test-key",
AdminEmail: "[email protected]",
SenderName: "Admin",
},
MaxFrequency: time.Minute,
OtpLength: 6,
OtpExpiry: 3600,
Expand Down
2 changes: 1 addition & 1 deletion pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -843,7 +843,7 @@ func (e *email) validate(fsys fs.FS) (err error) {
}
e.Template[name] = tmpl
}
if e.Smtp != nil {
if e.Smtp != nil && e.Smtp.IsEnabled() {
if len(e.Smtp.Host) == 0 {
return errors.New("Missing required field in config: auth.email.smtp.host")
}
Expand Down
1 change: 1 addition & 0 deletions pkg/config/templates/config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ otp_expiry = 3600

# Use a production-ready SMTP server
# [auth.email.smtp]
# enabled = true
# host = "smtp.sendgrid.net"
# port = 587
# user = "apikey"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,3 @@ diff remote[auth] local[auth]
[email.template]
[email.template.confirmation]
content_path = ""
@@ -71,13 +71,6 @@
content_path = ""
[email.template.recovery]
content_path = ""
-[email.smtp]
-host = "smtp.sendgrid.net"
-port = 587
-user = "apikey"
-pass = "hash:ed64b7695a606bc6ab4fcb41fe815b5ddf1063ccbc87afe1fa89756635db520e"
-admin_email = "[email protected]"
-sender_name = "Admin"

[sms]
enable_signup = false
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
diff remote[auth] local[auth]
--- remote[auth]
+++ local[auth]
@@ -51,28 +51,43 @@
@@ -51,35 +51,43 @@
inactivity_timeout = "0s"

[email]
Expand Down Expand Up @@ -40,10 +40,15 @@ diff remote[auth] local[auth]
+content = ""
content_path = ""
[email.template.recovery]
-content_path = ""
+content = "recovery-content"
+content_path = ""
+[email.smtp]
content_path = ""
[email.smtp]
-host = ""
-port = 0
-user = ""
-pass = "hash:"
-admin_email = ""
-sender_name = ""
+host = "smtp.sendgrid.net"
+port = 587
+user = "apikey"
Expand Down

0 comments on commit 2157392

Please sign in to comment.