From cb7894e1119d27d527dedcca22d8b3d433beddac Mon Sep 17 00:00:00 2001 From: Chris Stockton <180184+cstockton@users.noreply.github.com> Date: Wed, 13 Nov 2024 07:24:12 -0700 Subject: [PATCH] fix: rate limits of 0 take precedence over MAILER_AUTO_CONFIRM (#1837) This does not fix lower restrictions from being bypassed, but does help in the case the rate limit is explicitly set to 0. Co-authored-by: Chris Stockton --- internal/api/mail.go | 10 ++++++++++ internal/conf/configuration_test.go | 22 ++++++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/internal/api/mail.go b/internal/api/mail.go index f7ce3d0c0c..80d74f6794 100644 --- a/internal/api/mail.go +++ b/internal/api/mail.go @@ -627,6 +627,16 @@ func (a *API) sendEmail(r *http.Request, tx *storage.Connection, u *models.User, } } + // if the number of events is set to zero, we immediately apply rate limits. + if config.RateLimitEmailSent.Events == 0 { + emailRateLimitCounter.Add( + ctx, + 1, + metric.WithAttributeSet(attribute.NewSet(attribute.String("path", r.URL.Path))), + ) + return EmailRateLimitExceeded + } + // TODO(km): Deprecate this behaviour - rate limits should still be applied to autoconfirm if !config.Mailer.Autoconfirm { // apply rate limiting before the email is sent out diff --git a/internal/conf/configuration_test.go b/internal/conf/configuration_test.go index 5c1b65f6ed..d139e1ea3f 100644 --- a/internal/conf/configuration_test.go +++ b/internal/conf/configuration_test.go @@ -3,6 +3,7 @@ package conf import ( "os" "testing" + "time" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -32,6 +33,27 @@ func TestGlobal(t *testing.T) { require.NotNil(t, gc) assert.Equal(t, "X-Request-ID", gc.API.RequestIDHeader) assert.Equal(t, "pg-functions://postgres/auth/count_failed_attempts", gc.Hook.MFAVerificationAttempt.URI) + +} + +func TestRateLimits(t *testing.T) { + { + os.Setenv("GOTRUE_RATE_LIMIT_EMAIL_SENT", "0/1h") + + gc, err := LoadGlobal("") + require.NoError(t, err) + assert.Equal(t, float64(0), gc.RateLimitEmailSent.Events) + assert.Equal(t, time.Hour, gc.RateLimitEmailSent.OverTime) + } + + { + os.Setenv("GOTRUE_RATE_LIMIT_EMAIL_SENT", "10/1h") + + gc, err := LoadGlobal("") + require.NoError(t, err) + assert.Equal(t, float64(10), gc.RateLimitEmailSent.Events) + assert.Equal(t, time.Hour, gc.RateLimitEmailSent.OverTime) + } } func TestPasswordRequiredCharactersDecode(t *testing.T) {