feat: add UI authentication with cookie-based JWT support - #18
Conversation
📝 WalkthroughWalkthroughAdds browser-facing login/signup views and controller, permits those endpoints in security config, updates JWT filter to accept tokens from Authorization header or a Changes
Sequence Diagram(s)sequenceDiagram
participant Browser
participant AuthViewController
participant AuthService
participant JwtService
participant HttpResponse
Browser->>AuthViewController: POST /login-form (username,password)
AuthViewController->>AuthService: login(credentials)
AuthService-->>AuthViewController: User
AuthViewController->>JwtService: generateToken(user)
JwtService-->>AuthViewController: JWT
AuthViewController->>HttpResponse: addCookie(name="JWT", HttpOnly, maxAge=86400, path="/")
AuthViewController-->>Browser: Redirect /api/hello
sequenceDiagram
participant Browser
participant JwtAuthenticationFilter
participant AuthService
participant SecurityContext
Browser->>JwtAuthenticationFilter: Request (maybe Authorization header / maybe JWT cookie)
JwtAuthenticationFilter->>JwtAuthenticationFilter: Try header "Bearer ..."
alt header absent/blank
JwtAuthenticationFilter->>JwtAuthenticationFilter: Try cookie "JWT"
end
JwtAuthenticationFilter->>AuthService: loadUserByUsername(subject)
AuthService-->>JwtAuthenticationFilter: UserDetails
JwtAuthenticationFilter->>JwtAuthenticationFilter: validate token
JwtAuthenticationFilter->>SecurityContext: setAuthentication(authToken)
JwtAuthenticationFilter-->>Browser: Proceed with request
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 5
🧹 Nitpick comments (1)
src/main/java/org/example/alfs/controllers/AuthController.java (1)
59-64: Remove unnecessary JWT cookie from REST API endpoint.At lines 59–64, the JWT token is already returned in the JSON response body (
LoginResponseDTO). Setting a cookie here is redundant for API clients like Postman. The/loginendpoint's comment (line 47) confirms it is "mainly used for API testing", not browser-based login. Browser-based cookie handling already has a dedicated controller:AuthViewController.Either remove the cookie-setting code, or if cookies must be set here for compatibility, add
SecureandSameSiteattributes.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/main/java/org/example/alfs/controllers/AuthController.java` around lines 59 - 64, Remove the redundant JWT cookie being added in AuthController's login handler: eliminate creation and adding of the Cookie object (jwtCookie and response.addCookie(...)) since the token is already returned in LoginResponseDTO and browser cookie handling is done by AuthViewController; if you need to preserve cookie behavior for compatibility instead, ensure you set Secure and SameSite attributes on the Cookie before adding it (and keep HttpOnly/Path/MaxAge as appropriate) and document that choice.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/main/java/org/example/alfs/controllers/AuthViewController.java`:
- Line 70: Replace the ambiguous post-login redirect in AuthViewController (the
line returning "redirect:/api/hello") with a definitive target: either a UI
route like "redirect:/" or "redirect:/home" or a configurable property (e.g.,
app.ui.postLoginRedirect) accessed from the controller; remove the inline
comment. If you want to restore prior saved-request behavior instead, wire in a
SavedRequestAwareAuthenticationSuccessHandler or read the saved redirect URL and
return it from the same controller method. Update AuthViewController accordingly
so the redirect target is explicit and comment-free.
- Around line 39-48: The signup form handler currently builds SignupRequestDTO
manually from `@RequestParam` (method signupForm) which bypasses bean validation;
change the method signature to accept the form DTO directly as `@Valid`
`@ModelAttribute` org.example.alfs.dto.auth.SignupRequestDTO request (and add a
BindingResult bindingResult parameter) so Spring will validate `@NotBlank`
constraints, check bindingResult for errors and return the form view on
validation failure, otherwise call authService.signup(request) and continue
normal flow; ensure imports for javax/jakarta.validation.Valid and
org.springframework.web.bind.annotation.ModelAttribute and handle validation
errors consistently with your view logic.
In `@src/main/java/org/example/alfs/security/JwtAuthenticationFilter.java`:
- Around line 44-56: The Bearer branch in JwtAuthenticationFilter currently sets
jwt = authHeader.substring(7) even when the header is "Bearer " which yields an
empty string and prevents the cookie fallback; update the logic in the
authHeader handling (authHeader, jwt) to trim the extracted token and treat
empty strings as missing (set jwt back to null or skip assigning) so the
subsequent request.getCookies() loop (cookie name "JWT") will run when the token
is blank.
In `@src/main/jte/login.jte`:
- Around line 5-11: The labels for the username and password fields are not
associated with their inputs; update the Username label and its corresponding
<input name="username"> to include a matching id (e.g., id="username") and add
for="username" on the <label>, and do the same for the Password label/input pair
(e.g., id="password" and for="password") so assistive technologies can correctly
bind the labels to the inputs.
In `@src/main/jte/signup.jte`:
- Around line 5-11: The labels in signup.jte are not bound to their inputs; add
id attributes to the username and password inputs (e.g., id="username" and
id="password") and set the corresponding label for attributes (for="username"
and for="password") so the <label> elements are associated with the <input
name="username"> and <input name="password"> respectively to improve
accessibility.
---
Nitpick comments:
In `@src/main/java/org/example/alfs/controllers/AuthController.java`:
- Around line 59-64: Remove the redundant JWT cookie being added in
AuthController's login handler: eliminate creation and adding of the Cookie
object (jwtCookie and response.addCookie(...)) since the token is already
returned in LoginResponseDTO and browser cookie handling is done by
AuthViewController; if you need to preserve cookie behavior for compatibility
instead, ensure you set Secure and SameSite attributes on the Cookie before
adding it (and keep HttpOnly/Path/MaxAge as appropriate) and document that
choice.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 2ca1a260-c1de-430f-bb1b-9f6ac8d1a5fe
📒 Files selected for processing (6)
src/main/java/org/example/alfs/config/SecurityConfig.javasrc/main/java/org/example/alfs/controllers/AuthController.javasrc/main/java/org/example/alfs/controllers/AuthViewController.javasrc/main/java/org/example/alfs/security/JwtAuthenticationFilter.javasrc/main/jte/login.jtesrc/main/jte/signup.jte
|
|
||
| response.addCookie(cookie); | ||
|
|
||
| return "redirect:/api/hello"; // should redirect to home? |
There was a problem hiding this comment.
Resolve the post-login redirect target before merge.
Line 70 contains an unresolved “should redirect to home?” note in behavior code. Please decide a final target (UI landing page vs API endpoint) and remove ambiguity.
I can draft a small follow-up patch that redirects to a configurable UI route (or to a saved-request URL) if you want.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/main/java/org/example/alfs/controllers/AuthViewController.java` at line
70, Replace the ambiguous post-login redirect in AuthViewController (the line
returning "redirect:/api/hello") with a definitive target: either a UI route
like "redirect:/" or "redirect:/home" or a configurable property (e.g.,
app.ui.postLoginRedirect) accessed from the controller; remove the inline
comment. If you want to restore prior saved-request behavior instead, wire in a
SavedRequestAwareAuthenticationSuccessHandler or read the saved redirect URL and
return it from the same controller method. Update AuthViewController accordingly
so the redirect target is explicit and comment-free.
There was a problem hiding this comment.
we keep this for development. Will change this later when UI is done.
There was a problem hiding this comment.
@addee1, understood — keeping it as-is during development is reasonable. Would you like me to open a follow-up GitHub issue to track the redirect target cleanup once the UI is finalized, so it doesn't get lost?
🧠 Learnings used
Learnt from: addee1
Repo: ithsjava25/project-backend-alfs PR: 9
File: src/main/java/org/example/alfs/config/SecurityConfig.java:27-29
Timestamp: 2026-04-09T09:49:11.596Z
Learning: In the project `ithsjava25/project-backend-alfs`, the Spring Security configuration (`src/main/java/org/example/alfs/config/SecurityConfig.java`) intentionally disables CSRF and frame options, and permits the H2 console without authentication. This is by design for development-only use — the project is a stateless JWT-based REST API not targeting production deployment. Do not flag these settings as security issues.
Learnt from: FionaSprinkles
Repo: ithsjava25/project-backend-alfs PR: 11
File: src/main/java/org/example/alfs/services/TicketService.java:50-54
Timestamp: 2026-04-09T13:26:48.849Z
Learning: In `ithsjava25/project-backend-alfs`, the IDOR vulnerability in `TicketService.getTicketById()` (and the `GET /view/id/{id}` endpoint in `TicketController`) is a known, intentionally deferred issue. Authorization/ownership checks will be added in a future PR when authentication and authorization are implemented. Do not re-flag this as a new issue.
| User user = authService.login(username, password); | ||
|
|
||
| String token = jwtService.generateToken(user); | ||
|
|
||
| Cookie cookie = new Cookie("JWT", token); | ||
| cookie.setHttpOnly(true); | ||
| cookie.setPath("/"); | ||
| cookie.setMaxAge(60 * 60 * 24); | ||
|
|
||
| response.addCookie(cookie); | ||
|
|
||
| return "redirect:/api/hello"; // should redirect to home? |
There was a problem hiding this comment.
Should we add error handling if the login fails? Or is that maybe a later concern?
There was a problem hiding this comment.
We should probably align with @FionaSprinkles on how we want to handle this in the UI.
For example, if we want an error page, or just show an error message directly in the login form.
But we should definately have error handling for the UI also.
There was a problem hiding this comment.
Let's discuss this on discord :)
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/main/java/org/example/alfs/controllers/AuthViewController.java`:
- Around line 71-76: The JWT cookie creation in AuthViewController currently
uses java.servlet.Cookie (see the code that constructs Cookie cookie = new
Cookie("JWT", token) and the matching clear path) and must be hardened: replace
these with org.springframework.http.ResponseCookie builders so you can set
secure=true and sameSite (e.g., "Lax" or "Strict"), keep httpOnly(true),
path("/"), and maxAge as before; do the same for the cookie-clear branch (build
a ResponseCookie with maxAge(0) or maxAge(0) and the same
secure/httpOnly/sameSite/path attributes) and add the cookie to the response via
ResponseCookie.toString() in the Set-Cookie header or
response.addHeader("Set-Cookie", responseCookie.toString()) so attributes are
applied consistently.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: d3007a31-90e1-4345-b127-04410a75a233
📒 Files selected for processing (5)
src/main/java/org/example/alfs/controllers/AuthController.javasrc/main/java/org/example/alfs/controllers/AuthViewController.javasrc/main/java/org/example/alfs/security/JwtAuthenticationFilter.javasrc/main/jte/login.jtesrc/main/jte/signup.jte
✅ Files skipped from review due to trivial changes (4)
- src/main/jte/login.jte
- src/main/java/org/example/alfs/controllers/AuthController.java
- src/main/jte/signup.jte
- src/main/java/org/example/alfs/security/JwtAuthenticationFilter.java
| Cookie cookie = new Cookie("JWT", token); | ||
| cookie.setHttpOnly(true); | ||
| cookie.setPath("/"); | ||
| cookie.setMaxAge(60 * 60 * 24); | ||
|
|
||
| response.addCookie(cookie); |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
find . -type f -name "AuthViewController.java"Repository: ithsjava25/project-backend-alfs
Length of output: 143
🏁 Script executed:
cat -n ./src/main/java/org/example/alfs/controllers/AuthViewController.java | sed -n '60,110p'Repository: ithsjava25/project-backend-alfs
Length of output: 1622
🏁 Script executed:
head -20 ./src/main/java/org/example/alfs/controllers/AuthViewController.javaRepository: ithsjava25/project-backend-alfs
Length of output: 801
🏁 Script executed:
ls -la | grep -E "pom.xml|build.gradle"Repository: ithsjava25/project-backend-alfs
Length of output: 132
🏁 Script executed:
cat pom.xml | grep -A 5 -B 5 "spring-boot"Repository: ithsjava25/project-backend-alfs
Length of output: 3101
Add Secure and SameSite attributes to JWT cookies on set/clear paths.
Lines 71–76 and 95–100 create JWT cookies without Secure and SameSite attributes. While this project is development-focused, proper cookie hardening remains a best practice. Use ResponseCookie with explicit security flags:
Suggested implementation
+import java.time.Duration;
+import org.springframework.http.ResponseCookie;
@@
- Cookie cookie = new Cookie("JWT", token);
- cookie.setHttpOnly(true);
- cookie.setPath("/");
- cookie.setMaxAge(60 * 60 * 24);
-
- response.addCookie(cookie);
+ ResponseCookie cookie = ResponseCookie.from("JWT", token)
+ .httpOnly(true)
+ .secure(true) // if local HTTP is required, gate by profile/env
+ .sameSite("Lax")
+ .path("/")
+ .maxAge(Duration.ofHours(24))
+ .build();
+ response.addHeader("Set-Cookie", cookie.toString());
@@
- Cookie cookie = new Cookie("JWT", null);
- cookie.setHttpOnly(true);
- cookie.setPath("/");
- cookie.setMaxAge(0);
-
- response.addCookie(cookie);
+ ResponseCookie cookie = ResponseCookie.from("JWT", "")
+ .httpOnly(true)
+ .secure(true)
+ .sameSite("Lax")
+ .path("/")
+ .maxAge(Duration.ZERO)
+ .build();
+ response.addHeader("Set-Cookie", cookie.toString());📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| Cookie cookie = new Cookie("JWT", token); | |
| cookie.setHttpOnly(true); | |
| cookie.setPath("/"); | |
| cookie.setMaxAge(60 * 60 * 24); | |
| response.addCookie(cookie); | |
| import java.time.Duration; | |
| import org.springframework.http.ResponseCookie; | |
| // ... other code ... | |
| ResponseCookie cookie = ResponseCookie.from("JWT", token) | |
| .httpOnly(true) | |
| .secure(true) // if local HTTP is required, gate by profile/env | |
| .sameSite("Lax") | |
| .path("/") | |
| .maxAge(Duration.ofHours(24)) | |
| .build(); | |
| response.addHeader("Set-Cookie", cookie.toString()); | |
| // ... in logout/clear section (around line 95-100) ... | |
| ResponseCookie cookie = ResponseCookie.from("JWT", "") | |
| .httpOnly(true) | |
| .secure(true) | |
| .sameSite("Lax") | |
| .path("/") | |
| .maxAge(Duration.ZERO) | |
| .build(); | |
| response.addHeader("Set-Cookie", cookie.toString()); |
🧰 Tools
🪛 ast-grep (0.42.1)
[warning] 75-75: The application does not appear to verify inbound requests which can lead to a Cross-site request forgery (CSRF) vulnerability. If the application uses cookie-based authentication, an attacker can trick users into sending authenticated HTTP requests without their knowledge from any arbitrary domain they visit. To prevent this vulnerability start by identifying if the framework or library leveraged has built-in features or offers plugins for CSRF protection. CSRF tokens should be unique and securely random. The Synchronizer Token or Double Submit Cookie patterns with defense-in-depth mechanisms such as the sameSite cookie flag can help prevent CSRF. For more information, see: [Cross-site request forgery prevention](https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Req\ uest_Forgery_Prevention_Cheat_Sheet.html).
Context: response.addCookie(cookie);
Note: [CWE-352] Cross-Site Request Forgery (CSRF). [REFERENCES]
- https://stackoverflow.com/questions/42717210/samesite-cookie-in-java-application
(cookie-missing-samesite-java)
[warning] 75-75: A cookie was detected without setting the 'secure' flag. The 'secure' flag for cookies prevents the client from transmitting the cookie over insecure channels such as HTTP. Set the 'secure' flag by calling '.setSecure(true);'.
Context: response.addCookie(cookie);
Note: [CWE-614] Sensitive Cookie in HTTPS Session Without 'Secure' Attribute. [REFERENCES]
- https://owasp.org/www-community/controls/SecureCookieAttribute
(cookie-missing-secure-flag-java)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/main/java/org/example/alfs/controllers/AuthViewController.java` around
lines 71 - 76, The JWT cookie creation in AuthViewController currently uses
java.servlet.Cookie (see the code that constructs Cookie cookie = new
Cookie("JWT", token) and the matching clear path) and must be hardened: replace
these with org.springframework.http.ResponseCookie builders so you can set
secure=true and sameSite (e.g., "Lax" or "Strict"), keep httpOnly(true),
path("/"), and maxAge as before; do the same for the cookie-clear branch (build
a ResponseCookie with maxAge(0) or maxAge(0) and the same
secure/httpOnly/sameSite/path attributes) and add the cookie to the response via
ResponseCookie.toString() in the Set-Cookie header or
response.addHeader("Set-Cookie", responseCookie.toString()) so attributes are
applied consistently.
There was a problem hiding this comment.
Will fix this later! Thanks for input
There was a problem hiding this comment.
@addee1, sounds good! Would you like me to open a GitHub issue to track this cookie hardening improvement (adding Secure and SameSite attributes via ResponseCookie) so it doesn't get lost?
🧠 Learnings used
Learnt from: addee1
Repo: ithsjava25/project-backend-alfs PR: 9
File: src/main/java/org/example/alfs/config/SecurityConfig.java:27-29
Timestamp: 2026-04-09T09:49:11.596Z
Learning: In the project `ithsjava25/project-backend-alfs`, the Spring Security configuration (`src/main/java/org/example/alfs/config/SecurityConfig.java`) intentionally disables CSRF and frame options, and permits the H2 console without authentication. This is by design for development-only use — the project is a stateless JWT-based REST API not targeting production deployment. Do not flag these settings as security issues.
Learnt from: addee1
Repo: ithsjava25/project-backend-alfs PR: 9
File: src/main/resources/application.properties:19-20
Timestamp: 2026-04-09T10:02:51.794Z
Learning: In the project `ithsjava25/project-backend-alfs`, the JWT secret is intentionally hardcoded in `src/main/resources/application.properties` (`jwt.secret=bXlTdXBlclNlY3JldEtleU15U3VwZXJTZWNyZXRLZXk=`). This is by design for development/demo purposes only — the team is aware it should be externalized via environment variables or a secrets manager in a production setup. Do not flag this as a security issue.
Learnt from: FionaSprinkles
Repo: ithsjava25/project-backend-alfs PR: 11
File: src/main/java/org/example/alfs/services/TicketService.java:50-54
Timestamp: 2026-04-09T13:26:48.849Z
Learning: In `ithsjava25/project-backend-alfs`, the IDOR vulnerability in `TicketService.getTicketById()` (and the `GET /view/id/{id}` endpoint in `TicketController`) is a known, intentionally deferred issue. Authorization/ownership checks will be added in a future PR when authentication and authorization are implemented. Do not re-flag this as a new issue.
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
gh issue create \
--repo ithsjava25/project-backend-alfs \
--title "Harden JWT cookies: add Secure and SameSite attributes via ResponseCookie" \
--body "## Summary
The JWT cookie set in \`AuthViewController\` (and its logout/clear path) currently uses \`jakarta.servlet.http.Cookie\` without \`Secure\` or \`SameSite\` attributes. This should be hardened by replacing both cookie creation and cookie-clear paths with \`org.springframework.http.ResponseCookie\` builders.
## Changes needed
Replace the \`jakarta.servlet.http.Cookie\` usage in \`src/main/java/org/example/alfs/controllers/AuthViewController.java\` with \`ResponseCookie\`:
\`\`\`java
import java.time.Duration;
import org.springframework.http.ResponseCookie;
// Set cookie on login:
ResponseCookie cookie = ResponseCookie.from(\"JWT\", token)
.httpOnly(true)
.secure(true)
.sameSite(\"Lax\")
.path(\"/\")
.maxAge(Duration.ofHours(24))
.build();
response.addHeader(\"Set-Cookie\", cookie.toString());
// Clear cookie on logout:
ResponseCookie cookie = ResponseCookie.from(\"JWT\", \"\")
.httpOnly(true)
.secure(true)
.sameSite(\"Lax\")
.path(\"/\")
.maxAge(Duration.ZERO)
.build();
response.addHeader(\"Set-Cookie\", cookie.toString());
\`\`\`
> Note: If local HTTP development (non-HTTPS) is needed, consider gating the \`secure(true)\` flag by Spring profile or environment variable.
## References
- Flagged in PR `#18`: https://github.com/ithsjava25/project-backend-alfs/pull/18#discussion_r3080199509
- Requested by `@addee1`
## Why this matters
- Missing \`Secure\` flag: cookie can be transmitted over HTTP, exposing the JWT (CWE-614).
- Missing \`SameSite\` flag: leaves the app open to CSRF via cookie-based auth (CWE-352).
" \
--assignee addee1
Length of output: 60
@addee1, done! I've opened issue #20 — "Harden JWT cookies: add Secure and SameSite attributes via ResponseCookie" — assigned to you, with full details and the suggested ResponseCookie implementation for both the login (set) and logout (clear) paths. 🐇
🧠 Learnings used
Learnt from: addee1
Repo: ithsjava25/project-backend-alfs PR: 9
File: src/main/java/org/example/alfs/config/SecurityConfig.java:27-29
Timestamp: 2026-04-09T09:49:11.596Z
Learning: In the project `ithsjava25/project-backend-alfs`, the Spring Security configuration (`src/main/java/org/example/alfs/config/SecurityConfig.java`) intentionally disables CSRF and frame options, and permits the H2 console without authentication. This is by design for development-only use — the project is a stateless JWT-based REST API not targeting production deployment. Do not flag these settings as security issues.
Learnt from: FionaSprinkles
Repo: ithsjava25/project-backend-alfs PR: 11
File: src/main/java/org/example/alfs/services/TicketService.java:50-54
Timestamp: 2026-04-09T13:26:48.849Z
Learning: In `ithsjava25/project-backend-alfs`, the IDOR vulnerability in `TicketService.getTicketById()` (and the `GET /view/id/{id}` endpoint in `TicketController`) is a known, intentionally deferred issue. Authorization/ownership checks will be added in a future PR when authentication and authorization are implemented. Do not re-flag this as a new issue.
Learnt from: addee1
Repo: ithsjava25/project-backend-alfs PR: 9
File: src/main/resources/application.properties:19-20
Timestamp: 2026-04-09T10:02:51.794Z
Learning: In the project `ithsjava25/project-backend-alfs`, the JWT secret is intentionally hardcoded in `src/main/resources/application.properties` (`jwt.secret=bXlTdXBlclNlY3JldEtleU15U3VwZXJTZWNyZXRLZXk=`). This is by design for development/demo purposes only — the team is aware it should be externalized via environment variables or a secrets manager in a production setup. Do not flag this as a security issue.
Learnt from: addee1
Repo: ithsjava25/project-backend-alfs PR: 8
File: src/main/resources/application.properties:5-7
Timestamp: 2026-04-11T16:56:55.483Z
Learning: In the project `ithsjava25/project-backend-alfs`, the MinIO credentials (`storage.s3.accessKey=minioadmin` and `storage.s3.secretKey=minioadmin`) are intentionally hardcoded in `src/main/resources/application.properties`. This is by design for development/demo purposes only — the team is aware these should be externalized via environment variables or a secrets manager in a production setup. Do not flag these as security issues.
This PR introduces browser-based authentication using cookies alongside the existing API-based authentication.
✨ Features added
🧠 Design decisions
🧪 Testing
📌 Notes
This does not change existing authorization logic.
It only adds a UI layer for authentication.
Summary by CodeRabbit
New Features
Security