Skip to content
This repository was archived by the owner on May 21, 2026. It is now read-only.

Commit 086066a

Browse files
Merge branch 'dev'
2 parents 64a3ef8 + 78c708d commit 086066a

46 files changed

Lines changed: 2122 additions & 670 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 75 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -1,73 +1,75 @@
1-
HELP.md
2-
target/
3-
!.mvn/wrapper/maven-wrapper.jar
4-
!**/src/main/**/target/
5-
!**/src/test/**/target/
6-
7-
### STS ###
8-
.apt_generated
9-
.classpath
10-
.factorypath
11-
.project
12-
.settings
13-
.springBeans
14-
.sts4-cache
15-
16-
### IntelliJ IDEA ###
17-
.idea
18-
*.iws
19-
*.iml
20-
*.ipr
21-
22-
### NetBeans ###
23-
/nbproject/private/
24-
/nbbuild/
25-
/dist/
26-
/nbdist/
27-
/.nb-gradle/
28-
build/
29-
!**/src/main/**/build/
30-
!**/src/test/**/build/
31-
32-
### VS Code ###
33-
.vscode/
34-
35-
# dependencies
36-
frontend/node_modules
37-
frontend/.pnp
38-
frontend/.pnp.js
39-
40-
# testing
41-
frontend/coverage
42-
43-
# production
44-
frontend/build
45-
46-
# misc
47-
frontend/.DS_Store
48-
frontend/.env.local
49-
frontend/.env.development.local
50-
frontend/.env.test.local
51-
frontend/.env.production.local
52-
53-
frontend/npm-debug.log*
54-
frontend/yarn-debug.log*
55-
frontend/yarn-error.log*
56-
57-
### Others ###
58-
59-
backend/src/main/resources/application.properties
60-
/imageDB
61-
/frontend
62-
frontend/build.zip
63-
64-
.console.sql
65-
66-
# Ignore Gradle project-specific cache directory
67-
.gradle
68-
69-
# Ignore Gradle build output directory
70-
build
71-
72-
docker\.env
73-
\.env
1+
HELP.md
2+
target/
3+
!.mvn/wrapper/maven-wrapper.jar
4+
!**/src/main/**/target/
5+
!**/src/test/**/target/
6+
7+
### STS ###
8+
.apt_generated
9+
.classpath
10+
.factorypath
11+
.project
12+
.settings
13+
.springBeans
14+
.sts4-cache
15+
16+
### IntelliJ IDEA ###
17+
.idea
18+
*.iws
19+
*.iml
20+
*.ipr
21+
22+
### NetBeans ###
23+
/nbproject/private/
24+
/nbbuild/
25+
/dist/
26+
/nbdist/
27+
/.nb-gradle/
28+
build/
29+
!**/src/main/**/build/
30+
!**/src/test/**/build/
31+
32+
### VS Code ###
33+
.vscode/
34+
35+
# dependencies
36+
frontend/node_modules
37+
frontend/.pnp
38+
frontend/.pnp.js
39+
40+
# testing
41+
frontend/coverage
42+
43+
# production
44+
frontend/build
45+
46+
# misc
47+
frontend/.DS_Store
48+
frontend/.env.local
49+
frontend/.env.development.local
50+
frontend/.env.test.local
51+
frontend/.env.production.local
52+
53+
frontend/npm-debug.log*
54+
frontend/yarn-debug.log*
55+
frontend/yarn-error.log*
56+
57+
### Others ###
58+
59+
backend/src/main/resources/application.properties
60+
/imageDB
61+
/frontend
62+
frontend/build.zip
63+
64+
.console.sql
65+
66+
# Ignore Gradle project-specific cache directory
67+
.gradle
68+
69+
# Ignore Gradle build output directory
70+
build
71+
72+
docker\.env
73+
\.env
74+
bin/
75+

AUTH_COOKIE_FIX.md

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
# Authentication Cookie Fix
2+
3+
## Problem
4+
The login GraphQL query was returning the JWT in the response body but not setting the `Set-Cookie` header, causing the browser to never store an auth cookie. This resulted in subsequent `isLogged` queries returning UNAUTHORIZED.
5+
6+
## Root Cause
7+
- Spring Boot 3.3 with virtual threads enabled (`spring.threads.virtual.enabled=true`)
8+
- GraphQL operations execute on virtual threads via Spring GraphQL's reactive execution model
9+
- `RequestContextHolder.getRequestAttributes()` returns `null` in virtual thread context
10+
- The code in `UserController.login` that attempted to set cookies via `HttpServletResponse` was never executed
11+
12+
## Solution
13+
Removed the `RequestContextHolder` usage from `UserController.login` and `UserController.doLogoutUser`.
14+
15+
The application now relies solely on `GraphQlCookieInterceptor` which:
16+
- Operates at the web layer (not within virtual thread context)
17+
- Intercepts all GraphQL responses
18+
- For `login` operations: extracts the JWT token from response data and adds `Set-Cookie` header
19+
- For `logout` operations: adds a clear cookie header
20+
- Properly handles cross-origin requests with correct `SameSite` and `Secure` attributes
21+
22+
## Changes Made
23+
- **src/main/java/com/espacogeek/geek/controllers/UserController.java**
24+
- Removed `RequestContextHolder` usage from `doLoginUser` method (GraphQL operation: `login`)
25+
- Removed `RequestContextHolder` usage from `doLogoutUser` method (GraphQL operation: `logout`)
26+
- Removed unused imports: `HttpHeaders`, `ResponseCookie`, `RequestContextHolder`, `ServletRequestAttributes`, `HttpServletRequest`, `HttpServletResponse`
27+
28+
## How It Works Now
29+
1. User calls `login` GraphQL query with credentials
30+
2. `UserController.doLoginUser` authenticates and returns JWT token in response data
31+
3. `GraphQlCookieInterceptor` intercepts the response
32+
4. Interceptor extracts token from `response.getData().get("login")`
33+
5. Interceptor adds `Set-Cookie` header to `response.getResponseHeaders()`
34+
6. Browser receives both token in body and Set-Cookie header
35+
36+
## Testing
37+
All existing tests pass, including:
38+
- `LoginQueryTest` - validates login functionality
39+
- All user-related tests
40+
41+
## Configuration
42+
Cookie behavior is configured in `application.properties`:
43+
```properties
44+
security.jwt.cookie-name=EG_AUTH
45+
security.jwt.cookie-path=/
46+
security.jwt.same-site-when-same-site=Lax
47+
security.jwt.expiration-ms=604800000
48+
```
49+
50+
CORS must allow credentials:
51+
```properties
52+
spring.mvc.cors.allowed-origins=http://localhost:3000
53+
```
54+
55+
Frontend must use `credentials: 'include'` in fetch requests.

GRAPHQL_GUIDE.md

Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
# GraphQL API Guide
2+
3+
## Accessing GraphiQL
4+
5+
GraphiQL is an interactive GraphQL IDE that allows you to explore and test the API.
6+
7+
### Local Development
8+
Once the application is running, access GraphiQL at:
9+
```
10+
http://localhost:8080/graphiql
11+
```
12+
13+
### GraphQL Endpoint
14+
The GraphQL API endpoint is:
15+
```
16+
http://localhost:8080/api
17+
```
18+
19+
## Using GraphiQL
20+
21+
### 1. Exploring the Schema
22+
- Click the "Docs" button on the right side of GraphiQL to browse all available queries and mutations
23+
- The schema includes detailed descriptions and examples for each operation
24+
- Use auto-complete (Ctrl+Space) to discover fields and operations
25+
26+
### 2. Example Queries
27+
28+
#### Search for TV Series
29+
```graphql
30+
query {
31+
tvserie(name: "Breaking Bad") {
32+
content {
33+
id
34+
name
35+
about
36+
cover
37+
genre {
38+
name
39+
}
40+
}
41+
totalElements
42+
}
43+
}
44+
```
45+
46+
#### Search for Games
47+
```graphql
48+
query {
49+
game(name: "The Last of Us", page: 0, size: 10) {
50+
content {
51+
id
52+
name
53+
about
54+
cover
55+
genre {
56+
name
57+
}
58+
}
59+
totalPages
60+
totalElements
61+
}
62+
}
63+
```
64+
65+
#### Get Daily Quote Artwork
66+
```graphql
67+
query {
68+
dailyQuoteArtwork {
69+
quote
70+
author
71+
urlArtwork
72+
}
73+
}
74+
```
75+
76+
### 3. Authentication
77+
78+
Most mutations require authentication. First, login to get a JWT token:
79+
80+
```graphql
81+
query {
82+
login(email: "user@example.com", password: "yourpassword")
83+
}
84+
```
85+
86+
Then, add the token to the HTTP Headers in GraphiQL:
87+
```json
88+
{
89+
"Authorization": "Bearer YOUR_JWT_TOKEN_HERE"
90+
}
91+
```
92+
93+
### 4. Example Mutations
94+
95+
#### Create a New User (No authentication required)
96+
```graphql
97+
mutation {
98+
createUser(credentials: {
99+
username: "johndoe"
100+
email: "john@example.com"
101+
password: "securepassword123"
102+
})
103+
}
104+
```
105+
106+
#### Change Password (Requires authentication)
107+
```graphql
108+
mutation {
109+
editPassword(
110+
actualPassword: "currentpassword"
111+
newPassword: "newsecurepassword"
112+
)
113+
}
114+
```
115+
116+
#### Update Username (Requires authentication)
117+
```graphql
118+
mutation {
119+
editUsername(
120+
password: "yourpassword"
121+
newUsername: "newusername"
122+
)
123+
}
124+
```
125+
126+
## Tips
127+
128+
1. **Use Variables**: For cleaner queries, use GraphQL variables:
129+
```graphql
130+
query SearchGame($name: String!, $page: Int, $size: Int) {
131+
game(name: $name, page: $page, size: $size) {
132+
content {
133+
id
134+
name
135+
}
136+
}
137+
}
138+
```
139+
Variables panel:
140+
```json
141+
{
142+
"name": "The Last of Us",
143+
"page": 0,
144+
"size": 10
145+
}
146+
```
147+
148+
2. **Request Only What You Need**: GraphQL allows you to specify exactly which fields you want, reducing data transfer.
149+
150+
3. **Explore Nested Fields**: Use the Docs panel to discover all available nested fields in types like Media, Genre, etc.
151+
152+
4. **Format Your Queries**: Use the "Prettify" button to auto-format your GraphQL queries.
153+
154+
## Troubleshooting
155+
156+
### GraphiQL is not accessible
157+
- Ensure the application is running
158+
- Check that you're accessing the correct URL: `http://localhost:8080/graphiql`
159+
- Verify the port number matches your configuration
160+
161+
### Authentication errors
162+
- Make sure you've included the JWT token in the Authorization header
163+
- Verify the token is still valid (tokens may expire)
164+
- Check that you're using the format: `Bearer YOUR_TOKEN`
165+
166+
### Database errors
167+
- Ensure MySQL database is running and accessible
168+
- Verify environment variables are set correctly:
169+
- `SPRING_DATASOURCE_URL`
170+
- `SPRING_DATASOURCE_USERNAME`
171+
- `SPRING_DATASOURCE_PASSWORD`
172+
173+
## Additional Resources
174+
175+
- [GraphQL Official Documentation](https://graphql.org/learn/)
176+
- [Spring for GraphQL Documentation](https://docs.spring.io/spring-graphql/reference/)

0 commit comments

Comments
 (0)