Api doc#26
Conversation
|
@CodeRabbit review |
✅ Actions performedReview triggered.
|
WalkthroughAdds two new API documentation files for Auth and User endpoints. Changes AuthController.RefreshToken from GET to POST. Adjusts UserController.UpdateUserAsync to return only the inner data payload on success. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant C as Client
participant A as AuthController
participant S as AuthService
Note over C,A: Refresh Token (changed to POST)
C->>A: POST /api/Auth/refresh-token/{id}<br/>Cookie: refresh_token
A->>S: Validate & refresh(token, userId)
alt success
S-->>A: New JWT + refresh token
A-->>C: 200 { success, data: { isAuthenticated, token, refreshToken, user } }
else error
S-->>A: Error
A-->>C: 200 { success:false, errors:[...] }
end
sequenceDiagram
autonumber
participant C as Client
participant U as UserController
participant US as UserService
Note over C,U: Update User (response shape adjusted)
C->>U: POST /api/User/profile/update/{userId}<br/>{ name, bio, avatarPath }
U->>US: UpdateUser(userId, payload)
alt success
U->>US: GetUserById(userId)
US-->>U: { success, data: User }
U-->>C: 200 data: User <!-- returns inner data only -->
else error
U-->>C: 200 { success:false, errors:[...] }
end
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10–15 minutes Possibly related PRs
Poem
✨ Finishing Touches
🧪 Generate unit tests
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: 6
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
AskFm/AskFm.API/Controllers/UserController.cs (1)
141-146: UpdatePassword authorization check is inverted (blocks the rightful user).This currently forbids the current user from updating their own password.
- if (await _checkCurrentUser(userId)) - { - - return StatusCode(StatusCodes.Status403Forbidden, "Invalid Operation"); - } + if (!await _checkCurrentUser(userId)) + { + return StatusCode(StatusCodes.Status403Forbidden, "Cannot update this user"); + }AskFm/AskFm.API/Controllers/AuthController.cs (1)
100-108: Strengthen refresh-token cookie security flags.Set Secure and SameSite to reduce CSRF/exfiltration risk; prefer UTC for expiry.
- private void setRefreshToken(string refreshToken,DateTime expires) + private void setRefreshToken(string refreshToken, DateTime expires) { var cookieOption = new CookieOptions() { HttpOnly = true, - Expires = expires.ToLocalTime() + Expires = expires.ToUniversalTime(), + Secure = true, + SameSite = SameSite.Strict, + Path = "/" }; Response.Cookies.Append("refreshToken", refreshToken, cookieOption); }
🧹 Nitpick comments (6)
AskFm/AskFm.API/Controllers/UserController.cs (1)
159-163: Harden _checkCurrentUser against null/failed reads.Avoid potential NREs and treat failed lookups as “not current user”.
- var current_user = await _userService.GetCurrentUserAsync(); - return current_user.Data.Id == userId; + var current = await _userService.GetCurrentUserAsync(); + if (!current.success || current.Data is null) return false; + return current.Data.Id == userId;AskFm/AskFm.API/Controllers/AuthController.cs (1)
8-8: Remove unused using.
using Sprache;appears unused.-using Sprache;APIs/Auth.md (1)
20-21: Document error responses (400/401/403) for all endpoints.Right now only 200 is shown; controllers also return 400/401/403.
Would you like me to add concise error response examples for each endpoint?
Also applies to: 65-66, 103-104, 140-141
APIs/User.md (3)
21-24: Tighten heading and wording.-### Get User By +### Get User By Id GET: `/api/User/profile/{userId}` -Description: Get user by id +Description: Get user by ID
42-46: HTTP verb casing and clarity.-### Delete current user -Delete: `/api/User/profile/{userId}` +### Delete Current User +DELETE: `/api/User/profile/{userId}`
5-18: Note non-200 outcomes and consistent payload shape.Controllers can return 400/403; add brief error examples. Also call out that User endpoints return a bare User object (not the Auth envelope), which is intentional.
Happy to push a patch to add minimal error samples and a short “Common Responses” section.
Also applies to: 25-38, 60-73
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
APIs/Auth.md(1 hunks)APIs/User.md(1 hunks)AskFm/AskFm.API/Controllers/AuthController.cs(1 hunks)AskFm/AskFm.API/Controllers/UserController.cs(1 hunks)
🧰 Additional context used
🪛 LanguageTool
APIs/Auth.md
[grammar] ~3-~3: There might be a mistake here.
Context: ...dpoints for Authentication ### Register POST: /api/Auth/register Request ...
(QB_NEW_EN)
[grammar] ~52-~52: There might be a mistake here.
Context: ...unt": 0 } } } ----- ### Login POST: `/api/Auth/login` **Request**...
(QB_NEW_EN)
[grammar] ~97-~97: There might be a mistake here.
Context: ... } } } ``` ------ ### Refresh Token POST: /api/Auth/refresh-token/{id} Des...
(QB_NEW_EN)
[grammar] ~98-~98: There might be a mistake here.
Context: ...ken POST: /api/Auth/refresh-token/{id} Description: refersh token when jwt toke...
(QB_NEW_EN)
[grammar] ~99-~99: Ensure spelling is correct
Context: ...i/Auth/refresh-token/{id}` Description: refersh token when jwt token is expired **Resp...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
[grammar] ~134-~134: There might be a mistake here.
Context: ... 0 } } } ``` --------- ### Logout POST: /api/Auth/logout/{id} Descriptio...
(QB_NEW_EN)
[grammar] ~135-~135: There might be a mistake here.
Context: ...### Logout POST: /api/Auth/logout/{id} Description: refersh token when jwt toke...
(QB_NEW_EN)
[grammar] ~136-~136: Ensure spelling is correct
Context: ...T: /api/Auth/logout/{id} Description: refersh token when jwt token is expired **Resp...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
APIs/User.md
[grammar] ~1-~1: There might be a mistake here.
Context: # Endpoints for User ### Get current user Profile GET: `/api/User...
(QB_NEW_EN)
[grammar] ~21-~21: There might be a mistake here.
Context: ...unt": 0 } ``` --------- ### Get User By GET: /api/User/profile/{userId} Descri...
(QB_NEW_EN)
[grammar] ~22-~22: There might be a mistake here.
Context: ...er By GET: /api/User/profile/{userId} Description: Get user by id *Response...
(QB_NEW_EN)
[grammar] ~44-~44: There might be a mistake here.
Context: ...api/User/profile/{userId}` Response Status Code: 200 --------- ### Update U...
(QB_NEW_EN)
[grammar] ~48-~48: There might be a mistake here.
Context: ...tus Code: 200 --------- ### Update User POST: `/api/User/profile/update/{userId}...
(QB_NEW_EN)
[grammar] ~76-~76: There might be a mistake here.
Context: ...werCount": 0 } ``` --------- ### Follow POST: `/api/User/profile/{followerId}/fo...
(QB_NEW_EN)
[grammar] ~92-~92: There might be a mistake here.
Context: ...Code: 200 --------- ### Update Password GET: `/api/User/profile/update/pass/{use...
(QB_NEW_EN)
🪛 markdownlint-cli2 (0.17.2)
APIs/User.md
3-3: Heading levels should only increment by one level at a time
Expected: h2; Actual: h3
(MD001, heading-increment)
6-6: Emphasis used instead of a heading
(MD036, no-emphasis-as-heading)
18-18: Emphasis used instead of a heading
(MD036, no-emphasis-as-heading)
55-55: Emphasis used instead of a heading
(MD036, no-emphasis-as-heading)
63-63: Emphasis used instead of a heading
(MD036, no-emphasis-as-heading)
96-96: Horizontal rule style
Expected: -----; Actual: ------
(MD035, hr-style)
101-101: Emphasis used instead of a heading
(MD036, no-emphasis-as-heading)
| "passwrod": "string", | ||
| "lastSeen": "2025-09-06T22:27:00.026Z" |
There was a problem hiding this comment.
Fix “passwrod” typo in request body.
User-facing docs.
- "passwrod": "string",
+ "password": "string",📝 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.
| "passwrod": "string", | |
| "lastSeen": "2025-09-06T22:27:00.026Z" | |
| "password": "string", | |
| "lastSeen": "2025-09-06T22:27:00.026Z" |
🤖 Prompt for AI Agents
In APIs/Auth.md around lines 14 to 15, the request body contains a typo
"passwrod": change the key to the correct "password" in the JSON example; update
any other occurrences of "passwrod" in this file (and related docs) to
"password" to keep examples consistent and user-facing documentation accurate.
| ------ | ||
| ### Refresh Token | ||
| POST: `/api/Auth/refresh-token/{id}` | ||
| Description: refersh token when jwt token is expired | ||
|
|
||
| **Response** |
There was a problem hiding this comment.
Clarify refresh-token description and fix spelling. Align with controller behavior.
If you accept making the action anonymous (suggested in code), reflect that here and note cookie requirement.
-### Refresh Token
-POST: `/api/Auth/refresh-token/{id}`
-Description: refersh token when jwt token is expired
+### Refresh Token
+POST: `/api/Auth/refresh-token/{id}`
+Description: Refresh the access token using the HTTP-only `refreshToken` cookie.
+Auth: No Authorization header required (endpoint validates the refresh token).If you keep [Authorize] on the action instead, change “Auth” to “Requires valid Bearer token” and note the access token must still be valid.
📝 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.
| ------ | |
| ### Refresh Token | |
| POST: `/api/Auth/refresh-token/{id}` | |
| Description: refersh token when jwt token is expired | |
| **Response** | |
| ------ | |
| ### Refresh Token | |
| POST: `/api/Auth/refresh-token/{id}` | |
| Description: Refresh the access token using the HTTP-only `refreshToken` cookie. | |
| Auth: No Authorization header required (endpoint validates the refresh token). | |
| **Response** |
🧰 Tools
🪛 LanguageTool
[grammar] ~97-~97: There might be a mistake here.
Context: ... } } } ``` ------ ### Refresh Token POST: /api/Auth/refresh-token/{id} Des...
(QB_NEW_EN)
[grammar] ~98-~98: There might be a mistake here.
Context: ...ken POST: /api/Auth/refresh-token/{id} Description: refersh token when jwt toke...
(QB_NEW_EN)
[grammar] ~99-~99: Ensure spelling is correct
Context: ...i/Auth/refresh-token/{id}` Description: refersh token when jwt token is expired **Resp...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
🤖 Prompt for AI Agents
In APIs/Auth.md around lines 96 to 101, the Refresh Token section has a typo
("refersh") and an inaccurate description that doesn't reflect controller
behavior; update the heading and description to "Refresh Token", fix spelling,
and then either (A) if the controller action is made anonymous, state "Anonymous
access" and note that the request requires the refresh token cookie to be
present (and include the POST path `/api/Auth/refresh-token/{id}`), or (B) if
the action remains protected with [Authorize], change the descriptor to
"Requires valid Bearer token" and explicitly state that the access token must
still be valid while describing that the endpoint exchanges the refresh token
(from cookie) for a new access token; ensure the docs clearly state the cookie
requirement in both cases.
| ### Logout | ||
| POST: `/api/Auth/logout/{id}` | ||
| Description: refersh token when jwt token is expired | ||
|
|
||
| **Response** | ||
|
|
There was a problem hiding this comment.
Fix Logout description and spelling.
-### Logout
-POST: `/api/Auth/logout/{id}`
-Description: refersh token when jwt token is expired
+### Logout
+POST: `/api/Auth/logout/{id}`
+Description: Revoke the refresh token and clear the cookie.📝 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.
| ### Logout | |
| POST: `/api/Auth/logout/{id}` | |
| Description: refersh token when jwt token is expired | |
| **Response** | |
| ### Logout | |
| POST: `/api/Auth/logout/{id}` | |
| Description: Revoke the refresh token and clear the cookie. | |
| **Response** |
🧰 Tools
🪛 LanguageTool
[grammar] ~134-~134: There might be a mistake here.
Context: ... 0 } } } ``` --------- ### Logout POST: /api/Auth/logout/{id} Descriptio...
(QB_NEW_EN)
[grammar] ~135-~135: There might be a mistake here.
Context: ...### Logout POST: /api/Auth/logout/{id} Description: refersh token when jwt toke...
(QB_NEW_EN)
[grammar] ~136-~136: Ensure spelling is correct
Context: ...T: /api/Auth/logout/{id} Description: refersh token when jwt token is expired **Resp...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
🤖 Prompt for AI Agents
In APIs/Auth.md around lines 134 to 139, the Logout endpoint description is
incorrect and misspelled: change "refersh token when jwt token is expired" to a
clear, correct description such as "Invalidates the user's refresh token and
logs out the user" (or "Revokes the refresh token and ends the session"),
correct the spelling of "refresh", and optionally add a brief Response summary
(e.g., 200 on success, 401/404 on errors) to replace the empty **Response**
section.
| GET: `/api/User/profile/update/pass/{userId}` | ||
|
|
||
| **Request** | ||
| ```json | ||
| { | ||
| "currentPassword": "string", | ||
| "updatedPassword": "string" | ||
| } | ||
| ``` |
There was a problem hiding this comment.
Method mismatch: docs show GET but code uses POST for Update Password.
Align with controller.
-### Update Password
-GET: `/api/User/profile/update/pass/{userId}`
+### Update Password
+POST: `/api/User/profile/update/pass/{userId}`📝 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.
| GET: `/api/User/profile/update/pass/{userId}` | |
| **Request** | |
| ```json | |
| { | |
| "currentPassword": "string", | |
| "updatedPassword": "string" | |
| } | |
| ``` | |
| ### Update Password | |
| POST: `/api/User/profile/update/pass/{userId}` | |
| **Request** |
🧰 Tools
🪛 markdownlint-cli2 (0.17.2)
96-96: Horizontal rule style
Expected: -----; Actual: ------
(MD035, hr-style)
101-101: Emphasis used instead of a heading
(MD036, no-emphasis-as-heading)
🤖 Prompt for AI Agents
In APIs/User.md around lines 93 to 101 the HTTP method for the Update Password
endpoint is listed as GET but the controller uses POST; update the documentation
to use POST for the endpoint (e.g., POST
`/api/User/profile/update/pass/{userId}`), ensure the Request example stays
under the POST method, and adjust any related sample requests or headers in this
section to match the controller's POST behavior.
| [HttpPost] | ||
| [Route("refresh-token/{id}")] | ||
| [Authorize(AuthenticationSchemes = "Bearer")] | ||
| public async Task<IActionResult> RefreshToken(int id) |
There was a problem hiding this comment.
Refresh endpoint requires [Authorize], defeating refresh when access token is expired.
Either make this action anonymous (recommended) or document that an unexpired access token is required (which undermines refresh UX).
- [HttpPost]
- [Route("refresh-token/{id}")]
- [Authorize(AuthenticationSchemes = "Bearer")]
+ [HttpPost]
+ [Route("refresh-token/{id}")]
+ [AllowAnonymous]
public async Task<IActionResult> RefreshToken(int id)📝 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.
| [HttpPost] | |
| [Route("refresh-token/{id}")] | |
| [Authorize(AuthenticationSchemes = "Bearer")] | |
| public async Task<IActionResult> RefreshToken(int id) | |
| [HttpPost] | |
| [Route("refresh-token/{id}")] | |
| [AllowAnonymous] | |
| public async Task<IActionResult> RefreshToken(int id) |
🤖 Prompt for AI Agents
In AskFm/AskFm.API/Controllers/AuthController.cs around lines 59-62, the
RefreshToken endpoint is decorated with [Authorize] which forces a valid access
token and prevents token refresh when the access token is expired; remove or
replace [Authorize(AuthenticationSchemes = "Bearer")] with [AllowAnonymous] (or
remove the attribute) so the endpoint can be called without a valid access
token, then ensure the method explicitly validates the provided refresh token
(from body/cookie) and the user id, handles invalid/expired refresh tokens with
proper 401/400 responses, and keeps other security checks (e.g.,
rotating/storing refresh tokens, revocation) intact.
| var userRead = await _userService.GetUserByIdAsync(userId); | ||
| return Ok(userRead); | ||
| return Ok(userRead.Data); | ||
| } |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Return only the inner payload — also handle post-update read failures.
Good switch to returning userRead.Data. Add a guard so a failed read doesn’t return 200 with null (or mask an error).
- var userRead = await _userService.GetUserByIdAsync(userId);
- return Ok(userRead.Data);
+ var userRead = await _userService.GetUserByIdAsync(userId);
+ if (!userRead.success || userRead.Data is null)
+ {
+ return StatusCode(StatusCodes.Status500InternalServerError, "Failed to load updated user.");
+ }
+ return Ok(userRead.Data);📝 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.
| var userRead = await _userService.GetUserByIdAsync(userId); | |
| return Ok(userRead); | |
| return Ok(userRead.Data); | |
| } | |
| var userRead = await _userService.GetUserByIdAsync(userId); | |
| if (!userRead.success || userRead.Data is null) | |
| { | |
| return StatusCode(StatusCodes.Status500InternalServerError, "Failed to load updated user."); | |
| } | |
| return Ok(userRead.Data); | |
| } |
#9
In This PR I add documentation for User & Authentication APIs
Summary by CodeRabbit
New Features
Documentation
Refactor
Chores