Test Auth and Chat Merge - #53
Merged
Merged
Conversation
Ci/env setup
# Conflicts: # cmd/backend/main.go # go.mod
There was a problem hiding this comment.
Pull request overview
This PR introduces a new authentication subsystem (JWT cookie sessions + Google OAuth), wires it into the backend router/middleware chain, and updates the chat domain to be user-scoped (ownership, listing, deletion, and title support) as part of merging auth and chat functionality.
Changes:
- Add auth domain (DB schema/queries, service, middleware, handlers) and integrate into
cmd/backend/main.go. - Update chat to require authenticated user context, add chat ownership fields + pagination, and improve streaming behavior/testing.
- Strengthen configuration/env defaults & validation, expand CORS behavior, and update deployment/env examples.
Reviewed changes
Copilot reviewed 47 out of 51 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| Makefile | Adds test target and makes build depend on tests. |
| internal/question/models.go | sqlc-generated model updates to include new auth-related types/fields. |
| internal/middleware/usercontext.go | Adds mock user context middleware utilities (test/dev scaffolding). |
| internal/database/migrations/9_chatHistory.up.sql | Adds user_id, title, updated_at columns to chats. |
| internal/database/migrations/9_chatHistory.down.sql | Drops chat history columns and adjusts message FK (rollback). |
| internal/database/migrations/10_seed_mock_user.up.sql | Seeds a mock user row for local/dev usage. |
| internal/database/migrations/10_seed_mock_user.down.sql | Removes the seeded mock user row. |
| internal/cors/middleware.go | Enables Access-Control-Allow-Credentials: true for allowed origins. |
| internal/cors/middleware_test.go | Expands CORS origin tests and asserts credentials header behavior. |
| internal/content/models.go | sqlc-generated model updates to include new auth-related types/fields. |
| internal/config/config.go | Adds auth/OAuth config fields and validation (secret + localhost constraints). |
| internal/config/config_test.go | Adds unit tests for env normalization and config validation rules. |
| internal/chat/type.go | Adds paginated chat response type + pagination constants. |
| internal/chat/streamHub.go | Changes stream subscription/publish model and adds error propagation helpers. |
| internal/chat/streamHub_test.go | Adds tests for stream error publishing and rune-based delta publishing. |
| internal/chat/service.go | Scopes chat/message access to user, adds list/delete, updates title workflow, stream logic changes. |
| internal/chat/schema.sql | Updates chat schema for new chat ownership/title/timestamps (sqlc schema). |
| internal/chat/queries.sql | Adds user-scoped chat/message queries, chat listing/count, and delete chat query. |
| internal/chat/provider.go | Adds GetTitle and improves SSE parsing/EOF error behavior. |
| internal/chat/provider_test.go | Adds tests validating SSE parsing behavior and EOF-before-finish handling. |
| internal/chat/models.go | sqlc-generated model updates for chat fields + auth-related types. |
| internal/chat/handler.go | Adds authenticated routing, chat list/delete endpoints, pagination parsing, SSE error handling. |
| internal/auth/types.go | Defines auth domain types/constants (sessions, OAuth types, refresh token types). |
| internal/auth/store.go | Implements auth repository operations (refresh token family, OAuth state, OAuth user). |
| internal/auth/service.go | Implements auth business logic (issue/refresh/session/logout and OAuth flow). |
| internal/auth/service_test.go | Adds table-driven tests for refresh/session/logout/OAuth flow and provider URL behavior. |
| internal/auth/schema.sql | Defines auth tables/types for sqlc schema input. |
| internal/auth/queries.sql | Adds sqlc queries for auth tables (tokens, OAuth state, users/accounts). |
| internal/auth/oauth.go | Adds Google OAuth provider implementation (PKCE + ID token exchange/verify). |
| internal/auth/oauth_credentials.go | Adds loader for Google OAuth client secret JSON. |
| internal/auth/oauth_credentials_test.go | Adds tests for credentials JSON parsing. |
| internal/auth/models.go | sqlc-generated models for auth package. |
| internal/auth/middleware.go | Adds request auth middleware reading access token cookie and injecting user context. |
| internal/auth/middleware_test.go | Tests middleware authentication behavior and context injection. |
| internal/auth/handler.go | Adds auth HTTP endpoints (session/refresh/logout + OAuth login/callback) and cookie handling. |
| internal/auth/handler_test.go | Adds tests for auth handler endpoints and cookie attribute behavior. |
| internal/auth/google_id_token.go | Implements Google ID token verification via JWKS caching + JWT validation. |
| internal/auth/google_id_token_test.go | Tests Google ID token verifier against a fake JWKS server and various claim failures. |
| internal/auth/db.go | sqlc-generated DBTX/Queries boilerplate for auth package. |
| go.mod | Adds JWT + oauth2 deps and promotes testify to direct dependency. |
| go.sum | Updates module sums for new dependencies. |
| docs/AUTH_DESIGN.md | Updates auth spec URL reference. |
| cmd/backend/main.go | Integrates config validation, auth wiring (service/middleware/handlers), and protects routes. |
| cmd/backend/main_test.go | Adds tests for parseAllowOrigins trimming behavior. |
| .gitignore | Ignores OAuth client secret/credentials JSON patterns. |
| .env.example | Adds ENVIRONMENT/SECRET/OAuth config examples and expands origin allowlist examples. |
| .deploy/stage/compose.yaml | Adds ENVIRONMENT/PORT and OAuth env vars; updates LLM URL. |
| .deploy/snapshot/compose.yaml | Adds ENVIRONMENT/PORT and OAuth env vars; expands origins and redirect allowlist. |
| .deploy/local/compose.yaml | Moves to ENVIRONMENT=dev and adds OAuth env vars + expanded allowlists. |
| .deploy/dev/compose.yaml | Adds ENVIRONMENT/PORT and OAuth env vars; expands allowlists. |
Files not reviewed (2)
- internal/auth/db.go: Generated file
- internal/auth/models.go: Generated file
Comment on lines
+412
to
+421
| for _, allowed := range allowlist { | ||
| allowed = strings.TrimSpace(allowed) | ||
| if allowed == "" { | ||
| continue | ||
| } | ||
| if raw == allowed || strings.HasPrefix(raw, strings.TrimRight(allowed, "/")+"/") { | ||
| return true | ||
| } | ||
| } | ||
| return false |
Comment on lines
+114
to
118
| for _, sub := range subs { | ||
| select { | ||
| case ch <- stream: | ||
| default: //avoid blocking | ||
| case sub.chunks <- stream: | ||
| case <-sub.done: | ||
| } |
Comment on lines
+127
to
+133
| handlerutil.WriteJSONResponse(w, status, map[string]interface{}{ | ||
| "id": chat.ID, | ||
| "title": chat.Title, | ||
| "createdAt": chat.CreatedAt, | ||
| "updatedAt": chat.UpdatedAt, | ||
| "messages": messages, | ||
| }) |
Comment on lines
+1
to
+4
| ALTER TABLE chats | ||
| ADD COLUMN user_id UUID NOT NULL REFERENCES users(id), | ||
| ADD COLUMN title VARCHAR(255) NOT NULL DEFAULT '', | ||
| ADD COLUMN updated_at TIMESTAMPTZ NOT NULL DEFAULT now(); |
Comment on lines
+185
to
+201
| func (s *ChatService) DeleteChat(ctx context.Context, chatID uuid.UUID, userID uuid.UUID) error { | ||
| chat, err := s.querier.GetChat(ctx, chatID) | ||
| if err != nil { | ||
| return databaseutil.WrapDBErrorWithKeyValue(err, "chat", "chat_id", chatID.String(), s.logger, "get chat for delete") | ||
| } | ||
| if chat.ID == uuid.Nil { | ||
| return handlerutil.NewNotFoundError("chat", "chat_id", chatID.String(), "") | ||
| } | ||
| if chat.UserID != userID { | ||
| return handlerutil.NewNotFoundError("chat", "chat_id", chatID.String(), "chat does not belong to the user") | ||
| } | ||
|
|
||
| err = s.querier.DeleteChat(ctx, chatID) | ||
| if err != nil { | ||
| return databaseutil.WrapDBErrorWithKeyValue(err, "chat", "chat_id", chatID.String(), s.logger, "delete chat") | ||
| } | ||
| return nil |
Comment on lines
+265
to
+268
| if newTitle == "" { | ||
| newTitle = content | ||
| createTitle = true | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Type of changes
Purpose
Additional Information