11package org .bugzkit .api .auth .controller ;
22
3+ import io .swagger .v3 .oas .annotations .Operation ;
4+ import io .swagger .v3 .oas .annotations .media .Content ;
5+ import io .swagger .v3 .oas .annotations .media .Schema ;
6+ import io .swagger .v3 .oas .annotations .responses .ApiResponse ;
7+ import io .swagger .v3 .oas .annotations .responses .ApiResponses ;
38import io .swagger .v3 .oas .annotations .security .SecurityRequirement ;
49import io .swagger .v3 .oas .annotations .tags .Tag ;
510import jakarta .servlet .http .HttpServletRequest ;
1823import org .bugzkit .api .auth .util .AuthUtil ;
1924import org .bugzkit .api .auth .util .JwtUtil ;
2025import org .bugzkit .api .shared .constants .Path ;
26+ import org .bugzkit .api .shared .error .ErrorMessage ;
2127import org .bugzkit .api .shared .interceptor .RateLimit ;
2228import org .bugzkit .api .user .payload .dto .UserDTO ;
2329import org .springframework .beans .factory .annotation .Value ;
@@ -53,13 +59,39 @@ public AuthController(AuthService authService, DeviceService deviceService) {
5359 this .deviceService = deviceService ;
5460 }
5561
62+ @ Operation (summary = "Register a new user account" )
63+ @ ApiResponses ({
64+ @ ApiResponse (responseCode = "201" , description = "Registered" ),
65+ @ ApiResponse (
66+ responseCode = "400" ,
67+ description = "Validation error" ,
68+ content = @ Content (schema = @ Schema (implementation = ErrorMessage .class ))),
69+ @ ApiResponse (
70+ responseCode = "409" ,
71+ description = "Username or email already exists" ,
72+ content = @ Content (schema = @ Schema (implementation = ErrorMessage .class ))),
73+ @ ApiResponse (responseCode = "429" , description = "Too many requests" , content = @ Content )
74+ })
5675 @ RateLimit (requests = 5 , duration = 60 )
5776 @ PostMapping ("/register" )
5877 public ResponseEntity <UserDTO > register (
5978 @ Valid @ RequestBody RegisterUserRequest registerUserRequest ) {
6079 return new ResponseEntity <>(authService .register (registerUserRequest ), HttpStatus .CREATED );
6180 }
6281
82+ @ Operation (summary = "Sign in and receive access and refresh token cookies" )
83+ @ ApiResponses ({
84+ @ ApiResponse (responseCode = "204" , description = "Authenticated — cookies set" ),
85+ @ ApiResponse (
86+ responseCode = "400" ,
87+ description = "Validation error" ,
88+ content = @ Content (schema = @ Schema (implementation = ErrorMessage .class ))),
89+ @ ApiResponse (
90+ responseCode = "401" ,
91+ description = "Invalid credentials or account inactive/locked" ,
92+ content = @ Content (schema = @ Schema (implementation = ErrorMessage .class ))),
93+ @ ApiResponse (responseCode = "429" , description = "Too many requests" , content = @ Content )
94+ })
6395 @ RateLimit (requests = 10 , duration = 60 )
6496 @ PostMapping ("/tokens" )
6597 public ResponseEntity <Void > authenticate (
@@ -70,13 +102,23 @@ public ResponseEntity<Void> authenticate(
70102 return setAuthCookies (authTokens );
71103 }
72104
105+ @ Operation (summary = "Sign out and clear auth cookies for the current device" )
106+ @ ApiResponse (responseCode = "204" , description = "Signed out — cookies cleared" )
73107 @ DeleteMapping ("/tokens" )
74108 public ResponseEntity <Void > deleteTokens (HttpServletRequest request ) {
75109 final var accessToken = AuthUtil .getValueFromCookie ("accessToken" , request );
76110 authService .deleteTokens (accessToken );
77111 return removeAuthCookies ();
78112 }
79113
114+ @ Operation (summary = "List all active devices for the current user" )
115+ @ ApiResponses ({
116+ @ ApiResponse (responseCode = "200" , description = "OK" ),
117+ @ ApiResponse (
118+ responseCode = "401" ,
119+ description = "Unauthorized" ,
120+ content = @ Content (schema = @ Schema (implementation = ErrorMessage .class )))
121+ })
80122 @ SecurityRequirement (name = "cookieAuth" )
81123 @ GetMapping ("/tokens/devices" )
82124 public ResponseEntity <List <DeviceDTO >> findAllDevices (HttpServletRequest request ) {
@@ -85,19 +127,38 @@ public ResponseEntity<List<DeviceDTO>> findAllDevices(HttpServletRequest request
85127 return ResponseEntity .ok (deviceService .findAll (deviceId ));
86128 }
87129
130+ @ Operation (summary = "Sign out from all devices and clear auth cookies" )
131+ @ ApiResponse (responseCode = "204" , description = "Signed out from all devices" )
88132 @ DeleteMapping ("/tokens/devices" )
89133 public ResponseEntity <Void > deleteTokensOnAllDevices () {
90134 authService .deleteTokensOnAllDevices ();
91135 return removeAuthCookies ();
92136 }
93137
138+ @ Operation (summary = "Revoke a specific device and invalidate all access tokens" )
139+ @ ApiResponses ({
140+ @ ApiResponse (responseCode = "204" , description = "Device revoked" ),
141+ @ ApiResponse (
142+ responseCode = "401" ,
143+ description = "Unauthorized" ,
144+ content = @ Content (schema = @ Schema (implementation = ErrorMessage .class )))
145+ })
94146 @ SecurityRequirement (name = "cookieAuth" )
95147 @ DeleteMapping ("/tokens/devices/{deviceId}" )
96148 public ResponseEntity <Void > revokeDevice (@ PathVariable String deviceId ) {
97149 deviceService .revoke (deviceId );
98150 return ResponseEntity .noContent ().build ();
99151 }
100152
153+ @ Operation (summary = "Refresh access and refresh token cookies using the refresh token" )
154+ @ ApiResponses ({
155+ @ ApiResponse (responseCode = "204" , description = "Tokens refreshed — cookies updated" ),
156+ @ ApiResponse (
157+ responseCode = "400" ,
158+ description = "Invalid or expired refresh token" ,
159+ content = @ Content (schema = @ Schema (implementation = ErrorMessage .class ))),
160+ @ ApiResponse (responseCode = "429" , description = "Too many requests" , content = @ Content )
161+ })
101162 @ RateLimit (requests = 10 , duration = 60 )
102163 @ PostMapping ("/tokens/refresh" )
103164 public ResponseEntity <Void > refreshTokens (HttpServletRequest request ) {
@@ -107,6 +168,15 @@ public ResponseEntity<Void> refreshTokens(HttpServletRequest request) {
107168 return setAuthCookies (authTokens );
108169 }
109170
171+ @ Operation (summary = "Send a password reset email" )
172+ @ ApiResponses ({
173+ @ ApiResponse (responseCode = "204" , description = "Email sent if account exists" ),
174+ @ ApiResponse (
175+ responseCode = "400" ,
176+ description = "Validation error" ,
177+ content = @ Content (schema = @ Schema (implementation = ErrorMessage .class ))),
178+ @ ApiResponse (responseCode = "429" , description = "Too many requests" , content = @ Content )
179+ })
110180 @ RateLimit (requests = 3 , duration = 60 )
111181 @ PostMapping ("/password/forgot" )
112182 public ResponseEntity <Void > forgotPassword (
@@ -115,6 +185,15 @@ public ResponseEntity<Void> forgotPassword(
115185 return ResponseEntity .noContent ().build ();
116186 }
117187
188+ @ Operation (summary = "Reset password using a token from the reset email" )
189+ @ ApiResponses ({
190+ @ ApiResponse (responseCode = "204" , description = "Password reset" ),
191+ @ ApiResponse (
192+ responseCode = "400" ,
193+ description = "Invalid or expired token, or validation error" ,
194+ content = @ Content (schema = @ Schema (implementation = ErrorMessage .class ))),
195+ @ ApiResponse (responseCode = "429" , description = "Too many requests" , content = @ Content )
196+ })
118197 @ RateLimit (requests = 5 , duration = 60 )
119198 @ PostMapping ("/password/reset" )
120199 public ResponseEntity <Void > resetPassword (
@@ -123,6 +202,17 @@ public ResponseEntity<Void> resetPassword(
123202 return ResponseEntity .noContent ().build ();
124203 }
125204
205+ @ Operation (summary = "Resend the email verification link" )
206+ @ ApiResponses ({
207+ @ ApiResponse (
208+ responseCode = "204" ,
209+ description = "Email sent if account exists and is inactive" ),
210+ @ ApiResponse (
211+ responseCode = "400" ,
212+ description = "Validation error" ,
213+ content = @ Content (schema = @ Schema (implementation = ErrorMessage .class ))),
214+ @ ApiResponse (responseCode = "429" , description = "Too many requests" , content = @ Content )
215+ })
126216 @ RateLimit (requests = 3 , duration = 60 )
127217 @ PostMapping ("/verification-email" )
128218 public ResponseEntity <Void > sendVerificationMail (
@@ -131,6 +221,15 @@ public ResponseEntity<Void> sendVerificationMail(
131221 return ResponseEntity .noContent ().build ();
132222 }
133223
224+ @ Operation (summary = "Verify email address using a token from the verification email" )
225+ @ ApiResponses ({
226+ @ ApiResponse (responseCode = "204" , description = "Email verified" ),
227+ @ ApiResponse (
228+ responseCode = "400" ,
229+ description = "Invalid or expired token" ,
230+ content = @ Content (schema = @ Schema (implementation = ErrorMessage .class ))),
231+ @ ApiResponse (responseCode = "429" , description = "Too many requests" , content = @ Content )
232+ })
134233 @ RateLimit (requests = 5 , duration = 60 )
135234 @ PostMapping ("/verify-email" )
136235 public ResponseEntity <Void > verifyEmail (
0 commit comments