package adminauth import ( "context" "net/http" "net/http/httptest" "path/filepath" "strings" "testing" "time" adminapp "github.com/chenyme/grok2api/backend/internal/application/adminauth" "github.com/chenyme/grok2api/backend/internal/infra/persistence/relational" "github.com/chenyme/grok2api/backend/internal/infra/security" "github.com/gin-gonic/gin" ) func TestRefreshUsesHTTPOnlyCookieAndDoesNotExposeToken(t *testing.T) { gin.SetMode(gin.TestMode) ctx := context.Background() database, err := relational.OpenSQLite(ctx, filepath.Join(t.TempDir(), "auth.db")) if err != nil { t.Fatal(err) } defer database.Close() if err := database.InitializeSchema(ctx); err != nil { t.Fatal(err) } service := adminapp.NewService( relational.NewAdminRepository(database), relational.NewAdminSessionRepository(database), security.NewTokenService("12345678901234567890123456789012"), 15*time.Minute, 30*24*time.Hour, ) if err := service.Bootstrap(ctx, "admin", "password123"); err != nil { t.Fatal(err) } router := gin.New() NewHandler(service, true).RegisterPublic(router.Group("/api/admin/v1")) login := httptest.NewRecorder() loginRequest := httptest.NewRequest(http.MethodPost, "/api/admin/v1/auth/login", strings.NewReader(`{"username":"admin","password":"password123"}`)) loginRequest.Header.Set("Content-Type", "application/json") router.ServeHTTP(login, loginRequest) if login.Code != http.StatusOK { t.Fatalf("login status = %d, body = %s", login.Code, login.Body.String()) } if strings.Contains(login.Body.String(), `"refreshToken":`) { t.Fatalf("login response exposed refresh token: %s", login.Body.String()) } cookies := login.Result().Cookies() if len(cookies) != 1 || cookies[0].Name != refreshCookieName || !cookies[0].HttpOnly || !cookies[0].Secure { t.Fatalf("unexpected refresh cookie: %#v", cookies) } refresh := httptest.NewRecorder() refreshRequest := httptest.NewRequest(http.MethodPost, "/api/admin/v1/auth/refresh", strings.NewReader(`{}`)) refreshRequest.Header.Set("Content-Type", "application/json") refreshRequest.AddCookie(cookies[0]) router.ServeHTTP(refresh, refreshRequest) if refresh.Code != http.StatusOK { t.Fatalf("refresh status = %d, body = %s", refresh.Code, refresh.Body.String()) } if strings.Contains(refresh.Body.String(), `"refreshToken":`) { t.Fatalf("refresh response exposed refresh token: %s", refresh.Body.String()) } }