This commit is contained in:
binwiederhier
2026-06-15 22:33:30 -04:00
parent 44d5bcf875
commit b75d0e582c
5 changed files with 27 additions and 26 deletions
+3 -3
View File
@@ -34,7 +34,7 @@ type Config struct {
// SMTP-backed implementation; tests inject a fake. // SMTP-backed implementation; tests inject a fake.
type Sender interface { type Sender interface {
SendNotification(to string, m *model.Message, senderIP string) error SendNotification(to string, m *model.Message, senderIP string) error
Counts() (total int64, success int64, failure int64) NotificationCounts() (total int64, success int64, failure int64)
SendEmailVerification(to, link string) error SendEmailVerification(to, link string) error
SendPasswordReset(to, link string) error SendPasswordReset(to, link string) error
} }
@@ -67,8 +67,8 @@ func (s *realSender) SendNotification(to string, m *model.Message, senderIP stri
return err return err
} }
// Counts returns the number of notification emails sent, broken down into total, success and failure // NotificationCounts returns the number of notification emails sent, broken down into total, success and failure
func (s *realSender) Counts() (total int64, success int64, failure int64) { func (s *realSender) NotificationCounts() (total int64, success int64, failure int64) {
s.mu.Lock() s.mu.Lock()
defer s.mu.Unlock() defer s.mu.Unlock()
return s.success + s.failure, s.success, s.failure return s.success + s.failure, s.success, s.failure
+21 -20
View File
@@ -79,23 +79,26 @@ type handleFunc func(http.ResponseWriter, *http.Request, *visitor) error
var ( var (
// If changed, don't forget to update Android App and auth_sqlite.go // If changed, don't forget to update Android App and auth_sqlite.go
topicRegex = regexp.MustCompile(`^[-_A-Za-z0-9]{1,64}$`) // No /! topicRegex = regexp.MustCompile(`^[-_A-Za-z0-9]{1,64}$`) // No /!
topicPathRegex = regexp.MustCompile(`^/[-_A-Za-z0-9]{1,64}$`) // Regex must match JS & Android app! topicPathRegex = regexp.MustCompile(`^/[-_A-Za-z0-9]{1,64}$`) // Regex must match JS & Android app!
externalTopicPathRegex = regexp.MustCompile(`^/[^/]+\.[^/]+/[-_A-Za-z0-9]{1,64}$`) // Extended topic path, for web-app, e.g. /example.com/mytopic externalTopicPathRegex = regexp.MustCompile(`^/[^/]+\.[^/]+/[-_A-Za-z0-9]{1,64}$`) // Extended topic path, for web-app, e.g. /example.com/mytopic
webAppEmailVerifyRegex = regexp.MustCompile(`^/account/email/verify/[-_A-Za-z0-9]+$`) // Magic-link landing (served by the web app) jsonPathRegex = regexp.MustCompile(`^/[-_A-Za-z0-9]{1,64}(,[-_A-Za-z0-9]{1,64})*/json$`)
webAppPasswordResetRegex = regexp.MustCompile(`^/account/password/reset/[-_A-Za-z0-9]+$`) // Password-reset landing (served by the web app) ssePathRegex = regexp.MustCompile(`^/[-_A-Za-z0-9]{1,64}(,[-_A-Za-z0-9]{1,64})*/sse$`)
jsonPathRegex = regexp.MustCompile(`^/[-_A-Za-z0-9]{1,64}(,[-_A-Za-z0-9]{1,64})*/json$`) rawPathRegex = regexp.MustCompile(`^/[-_A-Za-z0-9]{1,64}(,[-_A-Za-z0-9]{1,64})*/raw$`)
ssePathRegex = regexp.MustCompile(`^/[-_A-Za-z0-9]{1,64}(,[-_A-Za-z0-9]{1,64})*/sse$`) wsPathRegex = regexp.MustCompile(`^/[-_A-Za-z0-9]{1,64}(,[-_A-Za-z0-9]{1,64})*/ws$`)
rawPathRegex = regexp.MustCompile(`^/[-_A-Za-z0-9]{1,64}(,[-_A-Za-z0-9]{1,64})*/raw$`) authPathRegex = regexp.MustCompile(`^/[-_A-Za-z0-9]{1,64}(,[-_A-Za-z0-9]{1,64})*/auth$`)
wsPathRegex = regexp.MustCompile(`^/[-_A-Za-z0-9]{1,64}(,[-_A-Za-z0-9]{1,64})*/ws$`) publishPathRegex = regexp.MustCompile(`^/[-_A-Za-z0-9]{1,64}/(publish|send|trigger)$`)
authPathRegex = regexp.MustCompile(`^/[-_A-Za-z0-9]{1,64}(,[-_A-Za-z0-9]{1,64})*/auth$`) updatePathRegex = regexp.MustCompile(`^/[-_A-Za-z0-9]{1,64}/[-_A-Za-z0-9]{1,64}$`)
publishPathRegex = regexp.MustCompile(`^/[-_A-Za-z0-9]{1,64}/(publish|send|trigger)$`) clearPathRegex = regexp.MustCompile(`^/[-_A-Za-z0-9]{1,64}/[-_A-Za-z0-9]{1,64}/(read|clear)$`)
updatePathRegex = regexp.MustCompile(`^/[-_A-Za-z0-9]{1,64}/[-_A-Za-z0-9]{1,64}$`) sequenceIDRegex = topicRegex
clearPathRegex = regexp.MustCompile(`^/[-_A-Za-z0-9]{1,64}/[-_A-Za-z0-9]{1,64}/(read|clear)$`)
sequenceIDRegex = topicRegex webAppConfigPath = "/config.js"
webAppManifestPath = "/manifest.webmanifest"
webAppEmailVerifyPathPrefix = "/account/email/verify/" // Browser landing route; raw token appended
webAppEmailVerifyRegex = regexp.MustCompile(`^/account/email/verify/[-_A-Za-z0-9]+$`) // Magic-link landing (served by the web app)
webAppPasswordResetPathPrefix = "/account/password/reset/" // Browser landing route; raw token appended
webAppPasswordResetRegex = regexp.MustCompile(`^/account/password/reset/[-_A-Za-z0-9]+$`) // Password-reset landing (served by the web app)
webConfigPath = "/config.js"
webManifestPath = "/manifest.webmanifest"
accountPath = "/account" accountPath = "/account"
matrixPushPath = "/_matrix/push/v1/notify" matrixPushPath = "/_matrix/push/v1/notify"
metricsPath = "/metrics" metricsPath = "/metrics"
@@ -121,8 +124,6 @@ var (
apiAccountEmailResendPath = "/v1/account/email/resend" apiAccountEmailResendPath = "/v1/account/email/resend"
apiAccountPasswordResetRequestPath = "/v1/account/password/reset/request" apiAccountPasswordResetRequestPath = "/v1/account/password/reset/request"
apiAccountPasswordResetPath = "/v1/account/password/reset" apiAccountPasswordResetPath = "/v1/account/password/reset"
webAppEmailVerifyPathPrefix = "/account/email/verify/" // Browser landing route; raw token appended
webAppPasswordResetPathPrefix = "/account/password/reset/" // Browser landing route; raw token appended
apiAccountBillingPortalPath = "/v1/account/billing/portal" apiAccountBillingPortalPath = "/v1/account/billing/portal"
apiAccountBillingWebhookPath = "/v1/account/billing/webhook" apiAccountBillingWebhookPath = "/v1/account/billing/webhook"
apiAccountBillingSubscriptionPath = "/v1/account/billing/subscription" apiAccountBillingSubscriptionPath = "/v1/account/billing/subscription"
@@ -553,9 +554,9 @@ func (s *Server) handleInternal(w http.ResponseWriter, r *http.Request, v *visit
return s.ensureAdmin(s.handleVersion)(w, r, v) return s.ensureAdmin(s.handleVersion)(w, r, v)
} else if r.Method == http.MethodGet && r.URL.Path == apiConfigPath { } else if r.Method == http.MethodGet && r.URL.Path == apiConfigPath {
return s.handleConfig(w, r, v) return s.handleConfig(w, r, v)
} else if r.Method == http.MethodGet && r.URL.Path == webConfigPath { } else if r.Method == http.MethodGet && r.URL.Path == webAppConfigPath {
return s.ensureWebEnabled(s.handleWebConfig)(w, r, v) return s.ensureWebEnabled(s.handleWebConfig)(w, r, v)
} else if r.Method == http.MethodGet && r.URL.Path == webManifestPath { } else if r.Method == http.MethodGet && r.URL.Path == webAppManifestPath {
return s.ensureWebPushEnabled(s.handleWebManifest)(w, r, v) return s.ensureWebPushEnabled(s.handleWebManifest)(w, r, v)
} else if r.Method == http.MethodGet && r.URL.Path == apiUsersPath { } else if r.Method == http.MethodGet && r.URL.Path == apiUsersPath {
return s.ensureAdmin(s.handleUsersGet)(w, r, v) return s.ensureAdmin(s.handleUsersGet)(w, r, v)
+1 -1
View File
@@ -37,7 +37,7 @@ func (c *captureMailer) SendNotification(to string, m *model.Message, senderIP s
return nil return nil
} }
func (c *captureMailer) Counts() (total int64, success int64, failure int64) { func (c *captureMailer) NotificationCounts() (total int64, success int64, failure int64) {
return 0, 0, 0 return 0, 0, 0
} }
+1 -1
View File
@@ -55,7 +55,7 @@ func (s *Server) execManager() {
} }
var sentMailTotal, sentMailSuccess, sentMailFailure int64 var sentMailTotal, sentMailSuccess, sentMailFailure int64
if s.mailer != nil { if s.mailer != nil {
sentMailTotal, sentMailSuccess, sentMailFailure = s.mailer.Counts() sentMailTotal, sentMailSuccess, sentMailFailure = s.mailer.NotificationCounts()
} }
// Users // Users
+1 -1
View File
@@ -1326,7 +1326,7 @@ func (t *testMailer) SendNotification(to string, m *model.Message, senderIP stri
return nil return nil
} }
func (t *testMailer) Counts() (total int64, success int64, failure int64) { func (t *testMailer) NotificationCounts() (total int64, success int64, failure int64) {
return 0, 0, 0 return 0, 0, 0
} }