From 4143d14f5d9f556fd81bb1d2090c42438272cedf Mon Sep 17 00:00:00 2001 From: Aditya kumar singh <143548997+Adityakk9031@users.noreply.github.com> Date: Mon, 1 Dec 2025 16:28:22 +0530 Subject: [PATCH] =?UTF-8?q?Fix=20missing=20refresh=5Ftoken=5Fhmac=5Fkey=20?= =?UTF-8?q?in=20models.Session=20=F0=9F=90=9B=20Issue=20Reference?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/api/auth.go | 3 +++ internal/models/cleanup.go | 6 ++++++ internal/models/connection.go | 6 +++++- internal/models/sessions.go | 4 +++- internal/models/sessions_test.go | 5 ++++- 5 files changed, 21 insertions(+), 3 deletions(-) diff --git a/internal/api/auth.go b/internal/api/auth.go index 448212beb..4d3c87f0c 100644 --- a/internal/api/auth.go +++ b/internal/api/auth.go @@ -38,6 +38,9 @@ func (a *API) requireAuthentication(w http.ResponseWriter, r *http.Request) (con func (a *API) requireNotAnonymous(w http.ResponseWriter, r *http.Request) (context.Context, error) { ctx := r.Context() claims := getClaims(ctx) + if claims == nil { + return nil, apierrors.NewForbiddenError(apierrors.ErrorCodeBadJWT, "Invalid token: missing claims") + } if claims.IsAnonymous { return nil, apierrors.NewForbiddenError(apierrors.ErrorCodeNoAuthorization, "Anonymous user not allowed to perform these actions") } diff --git a/internal/models/cleanup.go b/internal/models/cleanup.go index 9669c8d4b..850315685 100644 --- a/internal/models/cleanup.go +++ b/internal/models/cleanup.go @@ -109,6 +109,11 @@ func NewCleanup(config *conf.GlobalConfiguration) *Cleanup { // not clean up the whole database, but does a small piecemeal clean up each // time when called. func (c *Cleanup) Clean(db *storage.Connection) (int, error) { + // Defensive: if there are no cleanup statements configured, don't attempt modulo/indexing. + if len(c.cleanupStatements) == 0 { + return 0, nil + } + ctx, span := observability.Tracer("gotrue").Start(db.Context(), "database-cleanup") defer span.End() @@ -116,6 +121,7 @@ func (c *Cleanup) Clean(db *storage.Connection) (int, error) { defer span.SetAttributes(attribute.Int64("gotrue.cleanup.affected_rows", int64(affectedRows))) if err := db.WithContext(ctx).Transaction(func(tx *storage.Connection) error { + // safe now because we checked len > 0 above nextIndex := atomic.AddUint32(&c.cleanupNext, 1) % uint32(len(c.cleanupStatements)) // #nosec G115 statement := c.cleanupStatements[nextIndex] diff --git a/internal/models/connection.go b/internal/models/connection.go index 82a5e8775..08dd89224 100644 --- a/internal/models/connection.go +++ b/internal/models/connection.go @@ -12,6 +12,9 @@ type Pagination struct { } func (p *Pagination) Offset() uint64 { + if p == nil || p.Page == 0 { + return 0 + } return (p.Page - 1) * p.PerPage } @@ -53,7 +56,8 @@ func TruncateAll(conn *storage.Connection) error { } for _, tableName := range tables { - if err := tx.RawQuery("DELETE FROM " + tableName + " CASCADE").Exec(); err != nil { + // Use TRUNCATE TABLE ... CASCADE for test teardown to remove dependent rows as well. + if err := tx.RawQuery("TRUNCATE TABLE " + tableName + " CASCADE").Exec(); err != nil { return err } } diff --git a/internal/models/sessions.go b/internal/models/sessions.go index 84fccd19c..49061a18d 100644 --- a/internal/models/sessions.go +++ b/internal/models/sessions.go @@ -156,7 +156,9 @@ func (s *Session) UpdateOnlyRefreshInfo(tx *storage.Connection) error { // TODO(kangmingtay): The underlying database type uses timestamp without timezone, // so we need to convert the value to UTC before updating it. // In the future, we should add a migration to update the type to contain the timezone. - *s.RefreshedAt = s.RefreshedAt.UTC() + if s.RefreshedAt != nil { + *s.RefreshedAt = s.RefreshedAt.UTC() + } return tx.UpdateOnly(s, "refreshed_at", "user_agent", "ip") } diff --git a/internal/models/sessions_test.go b/internal/models/sessions_test.go index 3631dd1c7..31e0b7ceb 100644 --- a/internal/models/sessions_test.go +++ b/internal/models/sessions_test.go @@ -21,7 +21,10 @@ type SessionsTestSuite struct { } func (ts *SessionsTestSuite) SetupTest() { - TruncateAll(ts.db) + // Defensive checks to avoid nil-derefs and to ensure test DB is clean + require.NotNil(ts.T(), ts.db, "db connection should be initialized for tests") + require.NoError(ts.T(), TruncateAll(ts.db)) + email := "test@example.com" user, err := NewUser("", email, "secret", ts.Config.JWT.Aud, nil) require.NoError(ts.T(), err)