This commit is contained in:
binwiederhier
2026-03-30 08:26:56 -04:00
parent 61dd788dac
commit 6aebc5c677
12 changed files with 83 additions and 65 deletions
+2 -2
View File
@@ -135,7 +135,7 @@ type Config struct {
SMTPSenderUser string
SMTPSenderPass string
SMTPSenderFrom string
SMTPSenderEmailVerify bool
SMTPSenderVerify bool
SMTPServerListen string
SMTPServerDomain string
SMTPServerAddrPrefix string
@@ -240,7 +240,7 @@ func NewConfig() *Config {
SMTPSenderUser: "",
SMTPSenderPass: "",
SMTPSenderFrom: "",
SMTPSenderEmailVerify: false,
SMTPSenderVerify: false,
SMTPServerListen: "",
SMTPServerDomain: "",
SMTPServerAddrPrefix: "",
+7 -4
View File
@@ -441,6 +441,9 @@ func (s *Server) Stop() {
if s.smtpServer != nil {
s.smtpServer.Close()
}
if s.mailSender != nil {
s.mailSender.Close()
}
if s.attachment != nil {
s.attachment.Close()
}
@@ -883,14 +886,14 @@ func (s *Server) handlePublishInternal(r *http.Request, v *visitor) (*model.Mess
return nil, errHTTPInsufficientStorageUnifiedPush.With(t)
} else if !util.ContainsIP(s.config.VisitorRequestExemptPrefixes, v.ip) && !vrate.MessageAllowed() {
return nil, errHTTPTooManyRequestsLimitMessages.With(t)
} else if email != "" {
if !vrate.EmailAllowed() {
return nil, errHTTPTooManyRequestsLimitEmails.With(t)
}
}
if email != "" {
var httpErr *errHTTP
email, httpErr = s.convertEmailAddress(v.User(), email)
if httpErr != nil {
return nil, httpErr.With(t)
} else if !vrate.EmailAllowed() {
return nil, errHTTPTooManyRequestsLimitEmails.With(t)
}
}
if call != "" {
+3 -7
View File
@@ -193,18 +193,14 @@
# - smtp-sender-addr is the hostname:port of the SMTP server
# - smtp-sender-from is the e-mail address of the sender
# - smtp-sender-user/smtp-sender-pass are the username and password of the SMTP user (leave blank for no auth)
# - smtp-sender-verify is a flag that forces email recipient verification when enabled. If set to true,
# only verified email recipients can be used in the X-Email header.
#
# smtp-sender-addr:
# smtp-sender-from:
# smtp-sender-user:
# smtp-sender-pass:
# If set to true, only verified email recipients will receive email notifications.
# Anonymous users will not be able to send emails, and authenticated users must verify
# their email addresses first. Users can use "yes"/"true"/"1" as the email value to
# send to their first verified address.
#
# smtp-sender-email-verify: false
# smtp-sender-verify: false
# If enabled, ntfy will launch a lightweight SMTP server for incoming messages. Once configured, users can send
# emails to a topic e-mail address to publish messages to a topic.
+9 -8
View File
@@ -636,6 +636,10 @@ func (s *Server) handleAccountEmailVerify(w http.ResponseWriter, r *http.Request
} else if util.Contains(emails, req.Email) {
return errHTTPConflictEmailExists
}
// Check email rate limit (counts against the user's email quota)
if !v.EmailAllowed() {
return errHTTPTooManyRequestsLimitEmails
}
// Send verification email
logvr(v, r).Tag(tagAccount).Field("email", req.Email).Debug("Sending email verification")
if err := s.mailSender.SendVerification(req.Email); err != nil {
@@ -680,24 +684,21 @@ func (s *Server) handleAccountEmailDelete(w http.ResponseWriter, r *http.Request
}
// convertEmailAddress checks the email address against the user's verified email list.
// If smtp-sender-email-verify is false (default), the email is passed through as-is for
// If smtp-sender-verify is false (default), the email is passed through as-is for
// backwards compatibility. If true, the user must be authenticated and the email must be
// in their verified list. "yes"/"true"/"1" resolves to the first verified email.
func (s *Server) convertEmailAddress(u *user.User, email string) (string, *errHTTP) {
if !s.config.SMTPSenderEmailVerify {
if !s.config.SMTPSenderVerify {
return email, nil
}
if u == nil {
} else if u == nil {
return "", errHTTPBadRequestAnonymousEmailNotAllowed
}
if s.userManager == nil {
} else if s.userManager == nil {
return email, nil
}
emails, err := s.userManager.Emails(u.ID)
if err != nil {
return "", errHTTPInternalError
}
if len(emails) == 0 {
} else if len(emails) == 0 {
return "", errHTTPBadRequestEmailAddressNotVerified
}
if toBool(email) {
-3
View File
@@ -15,9 +15,6 @@ func (s *Server) execManager() {
s.pruneAttachments()
s.pruneMessages()
s.pruneAndNotifyWebPushSubscriptions()
if s.mailSender != nil {
s.mailSender.ExpireVerificationCodes()
}
// Message count
messagesCached, err := s.messageCache.MessagesCount()