From f718a16cbc87b2588ff6e25c9b99f17ada0fabc2 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Fri, 18 Sep 2026 14:24:52 +0000 Subject: [PATCH 1/2] Fix OAuth PKCE session update: add missing updated_at column MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Root cause: The auth_session table had a BEFORE UPDATE trigger calling updated_at_column() which sets NEW.updated_at, but the table schema never included an updated_at column, causing SQLSTATE 42703 error. This broke CreatePKCERequestSession UPDATE path when called after login in production OAuth flow (Affyard MCP → /oauth/authorize → login → authorize → CreateAuthorizeCodeSession → CreatePKCERequestSession UPDATE). Changes: - Add updated_at column to auth_session table (migration 011) - Add UpdatedAt field to AuthSession model to align with schema - Update tests to account for GORM auto-updating updated_at - Preserve UNIQUE(access_token) + UPDATE-by-access_token behavior The trigger existed since initial migration (003_auth.up.sql line 102-103) and matches the pattern used on auth_client which does have updated_at. This fix aligns auth_session with that pattern. Test coverage: TestCreatePKCERequestSessionUpdatesExistingSession now exercises the full UPDATE path with proper updated_at handling. Co-authored-by: Dmitry --- .../initial/011_auth_session_updated_at.down.sql | 2 ++ .../initial/011_auth_session_updated_at.up.sql | 3 +++ pkg/auth/oauth2/serverprovider/storage_test.go | 13 ++++++++----- repository/authclient/models/auth_session.go | 1 + 4 files changed, 14 insertions(+), 5 deletions(-) create mode 100644 deploy/migrations/initial/011_auth_session_updated_at.down.sql create mode 100644 deploy/migrations/initial/011_auth_session_updated_at.up.sql diff --git a/deploy/migrations/initial/011_auth_session_updated_at.down.sql b/deploy/migrations/initial/011_auth_session_updated_at.down.sql new file mode 100644 index 00000000..5cb8cd64 --- /dev/null +++ b/deploy/migrations/initial/011_auth_session_updated_at.down.sql @@ -0,0 +1,2 @@ +-- Remove updated_at column from auth_session table +ALTER TABLE auth_session DROP COLUMN updated_at; diff --git a/deploy/migrations/initial/011_auth_session_updated_at.up.sql b/deploy/migrations/initial/011_auth_session_updated_at.up.sql new file mode 100644 index 00000000..5efd1f9b --- /dev/null +++ b/deploy/migrations/initial/011_auth_session_updated_at.up.sql @@ -0,0 +1,3 @@ +-- Add updated_at column to auth_session table +-- This column was missing despite having the updated_at_column() trigger +ALTER TABLE auth_session ADD COLUMN updated_at TIMESTAMP NOT NULL DEFAULT NOW(); diff --git a/pkg/auth/oauth2/serverprovider/storage_test.go b/pkg/auth/oauth2/serverprovider/storage_test.go index f520bb79..eb4dc29e 100644 --- a/pkg/auth/oauth2/serverprovider/storage_test.go +++ b/pkg/auth/oauth2/serverprovider/storage_test.go @@ -60,14 +60,16 @@ func (s *storageSuite) TestCreatePKCERequestSessionUpdatesExistingSession() { s.Mock.ExpectQuery(`SELECT \* FROM "auth_session"`). WithArgs(codeSig). WillReturnRows( - sqlmock.NewRows([]string{"id", "request_id", "access_token", "form", "client_id", "username", "subject", "active", "access_token_expires_at", "refresh_token_expires_at", "created_at"}). - AddRow(rowID, requestID, codeSig, "existing=value", "mcp-client", "user", "subject", true, time.Now(), time.Now(), time.Now()), + sqlmock.NewRows([]string{"id", "request_id", "access_token", "form", "client_id", "username", "subject", "active", "access_token_expires_at", "refresh_token_expires_at", "created_at", "updated_at"}). + AddRow(rowID, requestID, codeSig, "existing=value", "mcp-client", "user", "subject", true, time.Now(), time.Now(), time.Now(), time.Now()), ) + // GORM automatically adds updated_at to the UPDATE statement s.Mock.ExpectExec(`UPDATE "auth_session" SET`). - WithArgs(sqlmock.AnyArg(), rowID). + WithArgs(sqlmock.AnyArg(), sqlmock.AnyArg(), rowID). WillReturnResult(sqlmock.NewResult(0, 1)) s.NoError(s.storage.CreatePKCERequestSession(ctx, codeSig, req)) + s.NoError(s.Mock.ExpectationsWereMet()) } func (s *storageSuite) TestCreateRefreshTokenSessionUpdatesByPrimaryKey() { @@ -84,8 +86,9 @@ func (s *storageSuite) TestCreateRefreshTokenSessionUpdatesByPrimaryKey() { sqlmock.NewRows([]string{"id", "request_id", "access_token"}). AddRow(rowID, requestID, "access-sig"), ) + // GORM automatically adds updated_at to the UPDATE statement s.Mock.ExpectExec(`UPDATE "auth_session" SET .*WHERE id=\$`). - WithArgs(requestID, "access-sig", "refresh-sig", sqlmock.AnyArg(), rowID, rowID). + WithArgs(requestID, "access-sig", "refresh-sig", sqlmock.AnyArg(), sqlmock.AnyArg(), rowID, rowID). WillReturnResult(sqlmock.NewResult(0, 1)) err := s.storage.CreateRefreshTokenSession(NewContext(s.Ctx), "refresh-sig", "access-sig", req) @@ -95,7 +98,7 @@ func (s *storageSuite) TestCreateRefreshTokenSessionUpdatesByPrimaryKey() { func (s *storageSuite) expectAuthSessionInsert(accessToken, requestID string) { var got []driver.Value cap := captureArg{dst: &got} - args := make([]driver.Value, 16) + args := make([]driver.Value, 17) // 17 columns including updated_at for i := range args { args[i] = cap } diff --git a/repository/authclient/models/auth_session.go b/repository/authclient/models/auth_session.go index 6300ed34..46d28908 100644 --- a/repository/authclient/models/auth_session.go +++ b/repository/authclient/models/auth_session.go @@ -33,6 +33,7 @@ type AuthSession struct { GrantedAudience gosql.NullableStringArray `db:"granted_audience" gorm:"type:text[]"` CreatedAt time.Time `db:"created_at"` + UpdatedAt time.Time `db:"updated_at"` DeletedAt gorm.DeletedAt `db:"deleted_at"` } From ad7ebb718afc7df25b0f151435d8f4da4e5b370e Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Fri, 18 Sep 2026 14:31:57 +0000 Subject: [PATCH 2/2] Fix CI: Update Go version from 1.25.x to 1.26.x The go.mod file requires Go 1.26.0, but the CI workflow was still using Go 1.25.x, causing compilation errors in tests. Co-authored-by: Dmitry --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 529e6091..5871e735 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -13,7 +13,7 @@ on: - main env: - GO_VERSION: 1.25.x + GO_VERSION: 1.26.x jobs: lint: