Repository: MennatAllahhxx/xBank
Pull request #8: added auth middleware for logged in user
Author: login: MennatAllahhxx
Created: 2025-03-14T20:55:13Z | Merged: 2025-03-14T21:16:27Z



<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

- **New Features**
  - Introduced a secure endpoint that allows users to view their profile information.
  - Enhanced authentication now requires valid tokens, ensuring that only authenticated users can access protected features.
  - Added a new configuration option for automatic review processes.
  
- **Bug Fixes**
  - Improved error handling for user retrieval and authentication processes.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->


Diff:
diff --git a/.coderabbit.yaml b/.coderabbit.yaml
new file mode 100644
index 0000000..d1709eb
--- /dev/null
+++ b/.coderabbit.yaml
@@ -0,0 +1,4 @@
+reviews:
+  auto_review:
+    base_branches:
+      - dev
\ No newline at end of file
diff --git a/src/presentation/controllers/user.controller.ts b/src/presentation/controllers/user.controller.ts
index 67e45cb..d6971e2 100644
--- a/src/presentation/controllers/user.controller.ts
+++ b/src/presentation/controllers/user.controller.ts
@@ -1,6 +1,7 @@
 import { Request, Response } from "express";
 import { UserService } from "../../application/services/user.service.js";
 import { User } from "../../core/entities/user.entity.js";
+import { AuthRequest } from "../types/auth.types.js";
 
 export class UserController {
     constructor(private userService: UserService) {
@@ -100,6 +101,22 @@ export class UserController {
         }
     }
 
+    getUserProfile = async (req: AuthRequest, res: Response) => {
+        try {            
+            const user: User | null = await this.userService.getUserById(req.user?.id as string);
+            
+            if (!user) {
+                res.status(404).json({ message: "User not found" });
+            } else {
+                const {password:_, ...userWithoutPassword} = user;
+                res.status(200).json(userWithoutPassword);
+            }
+        }
+        catch (err: any) {
+            res.status(500).json({ message: 'Internal server error' });
+        }
+    }
+
     getUserByEmail = async (req:Request, res: Response) => {
         try {
             const user: User | null = await this.userService.getUserByEmail(req.params.email);
diff --git a/src/presentation/middleware/auth.middleware.ts b/src/presentation/middleware/auth.middleware.ts
new file mode 100644
index 0000000..9b2f1b8
--- /dev/null
+++ b/src/presentation/middleware/auth.middleware.ts
@@ -0,0 +1,47 @@
+import { Response, NextFunction } from "express";
+import jwt from 'jsonwebtoken'
+import { AuthRequest } from "../types/auth.types.js";
+
+interface JwtPayload {
+    id: string;
+    email: string;
+    iat: number;
+}
+
+export const authMiddleware = (
+    req: AuthRequest, 
+    res: Response, 
+    next: NextFunction
+) => {
+    try {
+        if (!process.env.JWT_SECRET) {
+            throw new Error('JWT_SECRET not defined');
+        }
+
+        const token = req.header('Authorization')?.replace('Bearer ', '');
+
+        if (!token) {
+            res.status(401).json({ message: 'Unauthorized' });
+            return;
+        }
+
+        const decoded = jwt.verify(token, process.env.JWT_SECRET as string) as JwtPayload;
+        
+        if (!decoded) {
+            res.status(401).json({ message: 'Unauthorized' });
+            return;
+        }
+
+        req.user = { id: decoded.id, email: decoded.email };
+        next();
+    } catch (err: any) {
+        if (err.message === 'jwt expired' || err.message === 'invalid token') {
+            res.status(401).json({ message: 'Unauthorized' });
+            return;
+        } else {
+            res.status(500).json({ message: 'Internal server error' });
+            return;
+        }
+    }
+    
+}
diff --git a/src/presentation/routes/user.route.ts b/src/presentation/routes/user.route.ts
index f7c7a8b..a035500 100644
--- a/src/presentation/routes/user.route.ts
+++ b/src/presentation/routes/user.route.ts
@@ -3,6 +3,7 @@ import { container } from "tsyringe";
 import { UserController } from "../controllers/user.controller.js";
 import { UserService } from "../../application/services/user.service.js";
 import { UserRepository } from "../../core/interfaces/user.repo.interface.js";
+import { authMiddleware } from "../middleware/auth.middleware.js";
 ;
 
 const UserRouter = express.Router();
@@ -14,6 +15,7 @@ const userController = new UserController(userService);
 UserRouter.post('/auth/register', userController.createUser.bind(userController));
 UserRouter.post('/auth/login', userController.login.bind(userController));
 UserRouter.put('/user/:id', userController.updateUser.bind(userController));
+UserRouter.get('/users/me', authMiddleware, userController.getUserProfile.bind(userController));
 UserRouter.get('/user/email/:email', userController.getUserByEmail.bind(userController));
 UserRouter.get('/user/:id', userController.getUserById.bind(userController));
 UserRouter.get('/users', userController.getAllUsers.bind(userController));
diff --git a/src/presentation/types/auth.types.ts b/src/presentation/types/auth.types.ts
new file mode 100644
index 0000000..c14189d
--- /dev/null
+++ b/src/presentation/types/auth.types.ts
@@ -0,0 +1,5 @@
+import { Request } from 'express';
+
+export interface AuthRequest extends Request {
+    user?: { id: string; email: string };
+}
\ No newline at end of file


Reviews:
user: login: coderabbitai[bot]
body: **Actionable comments posted: 2**

<details>
<summary>🧹 Nitpick comments (1)</summary><blockquote>

<details>
<summary>.coderabbit.yaml (1)</summary><blockquote>

`1-4`: **Add a newline at the end of the file.**

According to the YAMLlint hint, this file does not have a newline at the end, which can trigger lint warnings or errors. Consider adding a newline for compatibility with most style guidelines.


```diff
 reviews:
   auto_review:
     base_branches:
       - dev
+ 
```

<details>
<summary>🧰 Tools</summary>

<details>
<summary>🪛 YAMLlint (1.35.1)</summary>

[error] 4-4: no new line character at the end of file

(new-line-at-end-of-file)

</details>

</details>

</blockquote></details>

</blockquote></details>

<details>
<summary>📜 Review details</summary>

**Configuration used: .coderabbit.yaml**
**Review profile: CHILL**
**Plan: Pro**

<details>
<summary>📥 Commits</summary>

Reviewing files that changed from the base of the PR and between d8c1e68f77583987a262c50dfb5bef76bcf9a008 and ee3905ec08d971f8599e5328d7d1ece096e7c45c.

</details>

<details>
<summary>📒 Files selected for processing (4)</summary>

* `.coderabbit.yaml` (1 hunks)
* `src/presentation/controllers/user.controller.ts` (2 hunks)
* `src/presentation/middleware/auth.middleware.ts` (1 hunks)
* `src/presentation/routes/user.route.ts` (2 hunks)

</details>

<details>
<summary>🧰 Additional context used</summary>

<details>
<summary>🪛 YAMLlint (1.35.1)</summary>

<details>
<summary>.coderabbit.yaml</summary>

[error] 4-4: no new line character at the end of file

(new-line-at-end-of-file)

</details>

</details>

</details>

<details>
<summary>🔇 Additional comments (3)</summary><blockquote>

<details>
<summary>src/presentation/routes/user.route.ts (2)</summary>

`6-6`: **Import looks correct.**

The introduction of `authMiddleware` import is aligned with your new authentication flow. No issues here.

---

`18-18`: **New route provides a secure endpoint.**

The new route `/users/me` correctly applies `authMiddleware` to ensure an authenticated user context. The use of `bind(userController)` also ensures this method retains its `this` context. Great job.

</details>
<details>
<summary>src/presentation/controllers/user.controller.ts (1)</summary>

`107-121`: **Method logic is sound.**

The new `getUserProfile` method is straightforward and properly checks if `user` is found. Good handling of the case where `req.user?.id` could be undefined. Code is clear and consistent with the rest of the controller.

</details>

</blockquote></details>

</details>

<!-- This is an auto-generated comment by CodeRabbit for review status -->
state: COMMENTED
author_association: NONE
submitted_at: 2025-03-14T21:05:48Z
user: login: MennatAllahhxx
state: COMMENTED
author_association: OWNER
submitted_at: 2025-03-14T21:06:48Z
user: login: coderabbitai[bot]
state: COMMENTED
author_association: NONE
submitted_at: 2025-03-14T21:07:54Z
user: login: coderabbitai[bot]
body: **Actionable comments posted: 0**

<details>
<summary>🧹 Nitpick comments (4)</summary><blockquote>

<details>
<summary>src/presentation/controllers/user.controller.ts (2)</summary><blockquote>

`104-118`: **Add null check for req.user before accessing id property**

While using the optional chaining operator (`?.`) is good, the type assertion (`as string`) bypasses TypeScript's null check. If the middleware fails to set `req.user` for any reason, this could lead to passing `undefined` as an ID to the service.

Consider adding an explicit check:

```diff
    getUserProfile = async (req: AuthRequest, res: Response) => {
        try {            
+           if (!req.user || !req.user.id) {
+               return res.status(401).json({ message: "User not authenticated" });
+           }
-           const user: User | null = await this.userService.getUserById(req.user?.id as string);
+           const user: User | null = await this.userService.getUserById(req.user.id);
            
            if (!user) {
                res.status(404).json({ message: "User not found" });
            } else {
                const {password:_, ...userWithoutPassword} = user;
                res.status(200).json(userWithoutPassword);
            }
        }
        catch (err: any) {
            res.status(500).json({ message: 'Internal server error' });
        }
    }
```

---

`104-118`: **Consider refactoring to reduce code duplication with getUserById**

The `getUserProfile` method shares almost identical code with the existing `getUserById` method. This creates maintenance challenges where changes to one method might need to be replicated in the other.

Consider refactoring to reuse the common logic:

```diff
    getUserProfile = async (req: AuthRequest, res: Response) => {
        try {            
            if (!req.user || !req.user.id) {
                return res.status(401).json({ message: "User not authenticated" });
            }
-           const user: User | null = await this.userService.getUserById(req.user.id);
-            
-           if (!user) {
-               res.status(404).json({ message: "User not found" });
-           } else {
-               const {password:_, ...userWithoutPassword} = user;
-               res.status(200).json(userWithoutPassword);
-           }
+           // Reuse the getUserById logic with the authenticated user's ID
+           return this.getUserById({...req, params: { id: req.user.id }}, res);
        }
        catch (err: any) {
            res.status(500).json({ message: 'Internal server error' });
        }
    }
```

</blockquote></details>
<details>
<summary>src/presentation/middleware/auth.middleware.ts (2)</summary><blockquote>

`30-33`: **Remove redundant check after token verification**

The check for `!decoded` is redundant since `jwt.verify()` will throw an error if the token is invalid, which would be caught by your catch block. The execution will never reach this condition if the token is invalid.

```diff
        const decoded = jwt.verify(token, process.env.JWT_SECRET as string) as JwtPayload;
        
-        if (!decoded) {
-            res.status(401).json({ message: 'Unauthorized' });
-            return;
-        }

        req.user = { id: decoded.id, email: decoded.email };
```

---

`37-45`: **Simplify error handling in catch block**

The `return` statements at the end of each condition in the catch block are unnecessary since the function would end there anyway.

```diff
    } catch (err: any) {
        if (err.message === 'jwt expired' || err.message === 'invalid token') {
            res.status(401).json({ message: 'Unauthorized' });
-            return;
        } else {
            res.status(500).json({ message: 'Internal server error' });
-            return;
        }
    }
```

</blockquote></details>

</blockquote></details>

<details>
<summary>📜 Review details</summary>

**Configuration used: .coderabbit.yaml**
**Review profile: CHILL**
**Plan: Pro**

<details>
<summary>📥 Commits</summary>

Reviewing files that changed from the base of the PR and between ee3905ec08d971f8599e5328d7d1ece096e7c45c and 743162dfae3a6641bfd51f3c604c4df8d186b471.

</details>

<details>
<summary>📒 Files selected for processing (3)</summary>

* `src/presentation/controllers/user.controller.ts` (2 hunks)
* `src/presentation/middleware/auth.middleware.ts` (1 hunks)
* `src/presentation/types/auth.types.ts` (1 hunks)

</details>

<details>
<summary>🔇 Additional comments (2)</summary><blockquote>

<details>
<summary>src/presentation/types/auth.types.ts (1)</summary>

`1-5`: **Well-structured auth type implementation**

Good job on creating a separate type file for the `AuthRequest` interface. This follows the recommendation from the previous review and helps maintain a clean architecture by centralizing type definitions. The interface is properly typed with optional user property, which is appropriate for authentication purposes.

</details>
<details>
<summary>src/presentation/middleware/auth.middleware.ts (1)</summary>

`11-47`: **Well-implemented authentication middleware**

The middleware effectively handles JWT authentication with proper error handling for various scenarios. Good practices implemented:
- Checking for JWT_SECRET environment variable
- Properly extracting and verifying tokens
- Specific error messages for auth failures
- Attaching user data to the request for downstream handlers

This implementation provides a strong foundation for protecting routes that require authentication.

</details>

</blockquote></details>

</details>

<!-- This is an auto-generated comment by CodeRabbit for review status -->
state: COMMENTED
author_association: NONE
submitted_at: 2025-03-14T21:15:51Z

Review comments:
diff_hunk: @@ -2,6 +2,10 @@ import { Request, Response } from "express";
 import { UserService } from "../../application/services/user.service.js";
 import { User } from "../../core/entities/user.entity.js";
 
+interface AuthRequest extends Request {
+    user?: { id: string; email: string };
+}
path: src/presentation/controllers/user.controller.ts
user: login: coderabbitai[bot]
body: _🛠️ Refactor suggestion_

**Avoid duplicating the `AuthRequest` interface in multiple files.**

The `AuthRequest` interface appears here and also in `auth.middleware.ts`. Maintaining a single definition (e.g., in a shared types file) can reduce the risk of mismatch or confusion.


```diff
- interface AuthRequest extends Request {
-     user?: { id: string; email: string };
- }
```

*Consider moving this interface definition to a shared file and importing it everywhere it’s needed.*


> Committable suggestion skipped: line range outside the PR's diff.

<!-- This is an auto-generated reply by CodeRabbit -->

✅ Addressed in commit 743162d

<!-- This is an auto-generated comment by CodeRabbit -->
created_at: 2025-03-14T21:05:48Z
author_association: NONE
diff_hunk: @@ -0,0 +1,50 @@
+import { Request, Response, NextFunction } from "express";
+import jwt from 'jsonwebtoken'
+
+interface JwtPayload {
+    id: string;
+    email: string;
+    iat: number;
+}
+
+interface AuthRequest extends Request {
+    user?: { id: string; email: string };
+}
+
+export const authMiddleware = (
+    req: AuthRequest, 
+    res: Response, 
+    next: NextFunction
+) => {
+    try {
+        if (!process.env.JWT_SECRET) {
+            throw new Error('JWT_SECRET not defined');
+        }
+
+        const token = req.header('Authorization')?.replace('Bearer ', '');
+
+        if (!token) {
+            res.status(401).json({ message: 'Unauthorized' });
+            return;
+        }
+
+        const decoded = jwt.verify(token, process.env.JWT_SECRET as string) as JwtPayload;
+        
+        if (!decoded) {
+            res.status(401).json({ message: 'Unauthorized' });
+            return;
+        }
+
+        req.user = { id: decoded.id, email: decoded.email };
+        next();
+    } catch (err: any) {
+        if (err.message === 'jwt expired' || err.message === 'invalid token') {
+            res.status(401).json({ message: 'Unauthorized' });
+            return;
+        } else {
+            res.status(500).json({ message: 'Internal server error' });
+            return;
+        }
+    }
+    
+}
path: src/presentation/middleware/auth.middleware.ts
user: login: coderabbitai[bot]
body: _🛠️ Refactor suggestion_

**Consider centralizing the AuthRequest interface and verify environment setup.**

1. **Repeated Interface**: The `AuthRequest` interface is defined here, but a similar interface exists in `user.controller.ts`. Consolidating it in a shared file avoids potential drift if changes are made in one place but not the other.
2. **Environment Variable**: Throwing an error when `JWT_SECRET` is not defined is a valid approach, but ensure the environment is set up correctly in all deployments to prevent unexpected runtime failures.
3. **Security & Error Handling**: The overall middleware logic is secure and properly responds with `401` on invalid or missing tokens. Nicely done.

<!-- This is an auto-generated comment by CodeRabbit -->
created_at: 2025-03-14T21:05:48Z
author_association: NONE
diff_hunk: @@ -2,6 +2,10 @@ import { Request, Response } from "express";
 import { UserService } from "../../application/services/user.service.js";
 import { User } from "../../core/entities/user.entity.js";
 
+interface AuthRequest extends Request {
+    user?: { id: string; email: string };
+}
path: src/presentation/controllers/user.controller.ts
user: login: MennatAllahhxx
body: where do you suggest to add that shared file

created_at: 2025-03-14T21:06:48Z
author_association: OWNER
diff_hunk: @@ -2,6 +2,10 @@ import { Request, Response } from "express";
 import { UserService } from "../../application/services/user.service.js";
 import { User } from "../../core/entities/user.entity.js";
 
+interface AuthRequest extends Request {
+    user?: { id: string; email: string };
+}
path: src/presentation/controllers/user.controller.ts
user: login: coderabbitai[bot]
body: <details>
<summary>🧩 Analysis chain</summary>

@MennatAllahhxx Based on the project structure, I recommend creating a new directory for shared types. Here are some options:

1. Create a `src/presentation/types` directory and add an `auth.types.ts` file there:
   ```typescript
   import { Request } from "express";
   
   export interface AuthRequest extends Request {
       user?: { id: string; email: string };
   }
   ```

2. Create a `src/core/types` directory if you want these types to be available across the entire application.

3. If you prefer a single file rather than a directory, you could create `src/presentation/shared.types.ts`.

Then import it in both files where needed:
```typescript
import { AuthRequest } from "../../presentation/types/auth.types.js";
// or
import { AuthRequest } from "../../core/types/auth.types.js";
```

The first option (presentation/types) is most suitable if these types are only used within the presentation layer. The second option (core/types) is better if they might be used across different layers of your application.

---

🏁 Script executed:
```
#!/bin/bash
# Examine the project directory structure to understand the organization
find src -type d | sort
```

Length of output: 349

---



</details>

@MennatAllahhxx After examining your project structure, I see you're following a clean architecture pattern with distinct layers. Based on this, I recommend:

1. Create a new directory `src/presentation/types` and add a file like `auth.types.ts`:
   ```typescript
   import { Request } from "express";
   
   export interface AuthRequest extends Request {
       user?: { id: string; email: string };
   }
   ```

2. Alternative option: Place it in `src/core/interfaces` if this interface might be used across multiple layers of your application.

Since `AuthRequest` extends Express's `Request` and is specifically used in the presentation layer (controllers and middleware), option #1 is more aligned with your architecture. This keeps presentation-specific types within that layer while providing a single definition to import where needed.

<!-- This is an auto-generated reply by CodeRabbit -->
created_at: 2025-03-14T21:07:54Z
author_association: NONE

PR comments:
user: login: coderabbitai[bot]
created_at: 2025-03-14T20:55:20Z
body: <!-- This is an auto-generated comment: summarize by coderabbit.ai -->
<!-- walkthrough_start -->

## Walkthrough

This pull request introduces a new configuration in the `.coderabbit.yaml` file for automatic reviews on the `dev` branch. It also adds a user authentication feature by extending the Express `Request` interface, creating an `AuthRequest` interface, implementing `authMiddleware` for JWT validation, and adding a secured route that allows an authenticated user to retrieve their profile via the new `getUserProfile` method.

## Changes

| File(s)                                                                                                   | Summary                                                                                                                                                                                                            |
| --------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `.coderabbit.yaml`                                                                                        | Added new `reviews.auto_review.base_branches` configuration with an entry for the `dev` branch.                                                                                                                    |
| `src/.../user.controller.ts`                                                                              | Added method `getUserProfile(req: AuthRequest, res: Response)` to retrieve user profile based on `id` from `req.user`.                                                                                         |
| `src/.../auth.middleware.ts`                                                                              | Introduced `authMiddleware(req: AuthRequest, res: Response, next: NextFunction)` for JWT authentication, and added interface `JwtPayload`.                                                                        |
| `src/.../user.route.ts`                                                                                  | Added route `UserRouter.get('/users/me', authMiddleware, userController.getUserProfile.bind(userController));` for retrieving the authenticated user's profile.                                                  |
| `src/.../auth.types.ts`                                                                                  | Created new interface `AuthRequest` extending `Request` with an optional `user` property containing `id` and `email`.                                                                                           |

## Sequence Diagram(s)

```mermaid
sequenceDiagram
    participant C as Client
    participant R as Router
    participant AM as AuthMiddleware
    participant UC as UserController
    participant US as UserService

    C ->> R: GET /users/me (with JWT)
    R ->> AM: Validate JWT from header
    alt Token valid
        AM -->> R: Attach user info
        R ->> UC: getUserProfile(req)
        UC ->> US: getUserById(userId)
        alt User exists
            US -->> UC: User details
            UC -->> R: 200 OK with user data (without password)
            R -->> C: 200 OK
        else User not found
            US -->> UC: Not found
            UC -->> R: 404 Not Found
            R -->> C: 404 response
        end
    else Token invalid/absent
        AM -->> C: 401 Unauthorized
    end
```

## Possibly related PRs

- **MennatAllahhxx/xBank#5**: Involved changes to the `base_branch` configuration in `.coderabbit.yaml`, aligning with the updates made in this PR.

## Poem

> I’m a rabbit in the code field, hopping with glee,  
> New routes and configs set my spirit free.  
> JWT tokens twirl like a playful dance,  
> Securing profiles with a swift, bold advance.  
> Bugs get nibbled away in this festive spree! 🐰  
> Code and carrots—a match made perfectly!

<!-- walkthrough_end -->
<!-- internal state start -->


<!-- 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= -->

<!-- internal state end -->
<!-- finishing_touch_checkbox_start -->

<details>
<summary>✨ Finishing Touches</summary>

- [ ] <!-- {"checkboxId": "7962f53c-55bc-4827-bfbf-6a18da830691"} --> 📝 Generate Docstrings

</details>

<!-- finishing_touch_checkbox_end -->
<!-- tips_start -->

---



<details>
<summary>🪧 Tips</summary>

### Chat

There are 3 ways to chat with [CodeRabbit](https://coderabbit.ai?utm_source=oss&utm_medium=github&utm_campaign=MennatAllahhxx/xBank&utm_content=8):

- Review comments: Directly reply to a review comment made by CodeRabbit. Example:
  - `I pushed a fix in commit <commit_id>, please review it.`
  - `Generate unit testing code for this file.`
  - `Open a follow-up GitHub issue for this discussion.`
- Files and specific lines of code (under the "Files changed" tab): Tag `@coderabbitai` in a new review comment at the desired location with your query. Examples:
  - `@coderabbitai generate unit testing code for this file.`
  -	`@coderabbitai modularize this function.`
- PR comments: Tag `@coderabbitai` in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
  - `@coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.`
  - `@coderabbitai read src/utils.ts and generate unit testing code.`
  - `@coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.`
  - `@coderabbitai help me debug CodeRabbit configuration file.`

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

### CodeRabbit Commands (Invoked using PR comments)

- `@coderabbitai pause` to pause the reviews on a PR.
- `@coderabbitai resume` to resume the paused reviews.
- `@coderabbitai review` to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
- `@coderabbitai full review` to do a full review from scratch and review all the files again.
- `@coderabbitai summary` to regenerate the summary of the PR.
- `@coderabbitai generate docstrings` to [generate docstrings](https://docs.coderabbit.ai/finishing-touches/docstrings) for this PR.
- `@coderabbitai resolve` resolve all the CodeRabbit review comments.
- `@coderabbitai configuration` to show the current CodeRabbit configuration for the repository.
- `@coderabbitai help` to get help.

### Other keywords and placeholders

- Add `@coderabbitai ignore` anywhere in the PR description to prevent this PR from being reviewed.
- Add `@coderabbitai summary` to generate the high-level summary at a specific location in the PR description.
- Add `@coderabbitai` anywhere in the PR title to generate the title automatically.

### Documentation and Community

- Visit our [Documentation](https://docs.coderabbit.ai) for detailed information on how to use CodeRabbit.
- Join our [Discord Community](http://discord.gg/coderabbit) to get help, request features, and share feedback.
- Follow us on [X/Twitter](https://twitter.com/coderabbitai) for updates and announcements.

</details>

<!-- tips_end -->
author_association: NONE
user: login: MennatAllahhxx
created_at: 2025-03-14T20:56:13Z
body: @coderabbitai why is review skipped
author_association: OWNER
user: login: coderabbitai[bot]
created_at: 2025-03-14T20:57:16Z
body: <!-- This is an auto-generated reply by CodeRabbit -->
> [!TIP]
> For best results, initiate chat on the files or code changes.

<details>
<summary>🧩 Analysis chain</summary>

@MennatAllahhxx I'll investigate why the review was skipped for this PR. Let me gather some information about your current configuration and PR details to provide you with a proper explanation.

---

🏁 Script executed:
```
#!/bin/bash
# Get PR details
gh pr view 8 --json files,title,body,state,additions,deletions

# Check if there's a CodeRabbit config file in the repo
find . -name "coderabbit.yaml" -o -name ".coderabbit.yaml"
```

Length of output: 490

---

> Debug Information Gathered

---

@MennatAllahhxx Based on my investigation, I don't see any configuration settings that would cause your review to be skipped. Your PR has 72 lines of code changes across 3 files and your CodeRabbit configuration has auto-review enabled.

Let me gather more information about your PR to determine why it might have been skipped:

---

🏁 Script executed:
```
#!/bin/bash
# Check if the PR is a draft
gh pr view 8 --json isDraft

# Check when the PR was created and updated
gh pr view 8 --json createdAt,updatedAt

# Check GitHub checks status
gh pr checks 8
```

Length of output: 285

---

@MennatAllahhxx It appears that CodeRabbit did actually process your PR (the check shows "Review completed"), but it may not have created any comments. Let me check the PR commits and any CodeRabbit activities to understand what happened:

---

🏁 Script executed:
```
#!/bin/bash
# Check the PR commits
gh pr view 8 --json commits

# Look for any comments from CodeRabbit
gh pr view 8 --json comments | jq '.comments[] | select(.author.login == "coderabbitai") | {body: .body, createdAt: .createdAt}'

# Check the files more closely
cat src/presentation/middleware/auth.middleware.ts
```

Length of output: 6316

---

@MennatAllahhxx I found the reason why your review was skipped! According to CodeRabbit's auto-generated comment on your PR:

> Auto reviews are disabled on base/target branches other than the default branch.

This means your PR is targeting a branch that is not the default branch of the repository. CodeRabbit by default only reviews PRs that target the default branch (usually `main` or `master`).

Let me check which branch your PR is targeting:

---

🏁 Script executed:
```
#!/bin/bash
# Check the base and head branches of the PR
gh pr view 8 --json baseRefName,headRefName
```

Length of output: 106

---



</details>

@MennatAllahhxx Now I can explain exactly why your review was skipped! Your pull request #8 is targeting the `dev` branch (not the default branch of your repository). 

By default, CodeRabbit only automatically reviews PRs that target the repository's default branch (usually `main` or `master`). This is why you received the message "Auto reviews are disabled on base/target branches other than the default branch."

You have two options:

1. **Trigger a manual review** for this PR using the command `@coderabbitai review` in a comment
2. **Update your CodeRabbit configuration** to include `dev` in the list of base branches that should be automatically reviewed:

```yaml
reviews:
  auto_review:
    base_branches:
      - dev
```

Would you like me to help you with either of these options?

(•ᴗ•)
author_association: NONE
user: login: MennatAllahhxx
created_at: 2025-03-14T20:59:01Z
body: @coderabbitai help me with the 2nd option, how to do so

author_association: OWNER
user: login: coderabbitai[bot]
created_at: 2025-03-14T20:59:34Z
body: <!-- This is an auto-generated reply by CodeRabbit -->
> [!TIP]
> For best results, initiate chat on the files or code changes.

<details>
<summary>🧩 Analysis chain</summary>

@MennatAllahhxx I'll help you set up the CodeRabbit configuration to automatically review PRs targeting your `dev` branch. First, let me check if you already have a configuration file in your repository, then I'll guide you through the necessary changes.

---

🏁 Script executed:
```
#!/bin/bash
# Check if a CodeRabbit configuration file already exists
find . -name "coderabbit.yaml" -o -name ".coderabbit.yaml"
```

Length of output: 56

---

> Debug Information Gathered

---



</details>

@MennatAllahhxx I'll guide you through setting up CodeRabbit to automatically review PRs targeting your `dev` branch.

You need to create a configuration file at the root of your repository. Let me walk you through the process:

1. Create a new file named `.coderabbit.yaml` (or `coderabbit.yaml` without the dot) in the root directory of your repository

2. Add the following content to the file:

```yaml
reviews:
  auto_review:
    base_branches:
      - dev
```

3. Commit and push this file to your repository

This configuration tells CodeRabbit to automatically review PRs that target the `dev` branch, in addition to the default branch. Once you've added this file, your future PRs targeting the `dev` branch will be automatically reviewed.

For this current PR, you can trigger a manual review by commenting with `@coderabbitai review` once you've set up the configuration.

Would you like me to help you with anything else regarding the CodeRabbit configuration?
author_association: NONE
user: login: MennatAllahhxx
created_at: 2025-03-14T21:01:27Z
body: @coderabbitai what if i dont want the default branch to be included

author_association: OWNER
user: login: coderabbitai[bot]
created_at: 2025-03-14T21:02:02Z
body: <!-- This is an auto-generated reply by CodeRabbit -->
> [!TIP]
> For best results, initiate chat on the files or code changes.

<details>
<summary>🧩 Analysis chain</summary>

@MennatAllahhxx If you only want CodeRabbit to auto-review PRs targeting the `dev` branch and not include the default branch, you can use the following configuration in your `.coderabbit.yaml` file:

```yaml
reviews:
  auto_review:
    enabled: true
    ignore_default_branch: true
    base_branches:
      - dev
```

The `ignore_default_branch: true` setting tells CodeRabbit to exclude the default branch from automatic reviews, while the `base_branches` list specifies which branches should receive auto-reviews.

After adding this configuration, only PRs targeting the `dev` branch will be automatically reviewed, and PRs targeting your default branch will be skipped.

---



---

> Debug Information Gathered

---



</details>

@MennatAllahhxx I apologize for my previous incorrect information. After reviewing the complete CodeRabbit configuration schema, I can see that there's no direct `ignore_default_branch` option available.

The configuration schema shows that the `base_branches` property is for specifying branches *in addition to* the default branch, not for replacing it.

If you want CodeRabbit to only review PRs targeting the `dev` branch and not the default branch, you would need to:

1. Consider disabling auto-review completely in the configuration
2. Manually trigger reviews on the PRs targeting the `dev` branch using the `@coderabbitai review` command

Your configuration would look like:

```yaml
reviews:
  auto_review:
    enabled: false  # Disable automatic reviews completely
```

Then manually trigger reviews on PRs targeting the `dev` branch as needed.

Would you like me to help you set up this configuration or explore other options?
author_association: NONE