> ## Documentation Index
> Fetch the complete documentation index at: https://docs.pyqdeck.in/llms.txt
> Use this file to discover all available pages before exploring further.

# Authentication & Authorization

> Deep-dive into PyqDeck authentication flow with Clerk

## Overview

PyqDeck uses **Clerk** for authentication. We leverage Clerk's managed UI for sign-in/up and their Express middleware for backend session validation.

## JWT Flow

1. **Frontend**: Obtains a short-lived JWT (Session Token) from Clerk.
2. **Request**: The token is sent in the `Authorization: Bearer <token>` header.
3. **Backend Middleware**: `clerkMiddleware()` (from `@clerk/express`) validates the JWT using the `CLERK_PUBLISHABLE_KEY` and `CLERK_SECRET_KEY`.
4. **Session Object**: If valid, `req.auth` is populated with the user's Clerk ID and metadata.

## User Provisioning (syncUser)

We use a "lazy provisioning" strategy. Users are only created in our MongoDB when they make their first authenticated API request.

### `syncUser.middleware.js`

This middleware runs after the Clerk middleware:

1. **Check Cache**: It first checks if a user with the given `clerkId` exists in our database.
2. **Fetch Clerk Profile**: If not found, it performs a server-side fetch to the Clerk API (`api.clerk.com/v1/users/{id}`) to get the user's full profile (email, name, avatar).
3. **Upsert**: It creates or updates the user record in MongoDB.
4. **Attach to Request**: The database user object is attached to `req.dbUser`.

**Note**: We use a manual `https` request for the Clerk API fetch to avoid IPv6 resolution issues common in some Node.js environments.

## Role-Based Access Control (RBAC)

We define three primary roles in the `User` model:

| Role     | Permissions                                                                |
| -------- | -------------------------------------------------------------------------- |
| `normal` | View papers, search questions, add bookmarks, submit solutions.            |
| `editor` | All `normal` permissions + Create/Edit universities, subjects, and papers. |
| `admin`  | Full system access, including user management and platform configuration.  |

### Authorization Middleware

We use the `authorize` higher-order function in `backend/src/middlewares/auth.middleware.js`:

* `requireAuthentication`: Ensures the user is logged in (has a valid Clerk session).
* `isEditor`: Restricts access to users with `editor` or `admin` roles.
* `isAdmin`: Restricts access to users with the `admin` role only.

```javascript theme={null}
// Example usage in routes
router.post("/", requireAuthentication, isAdmin, universityController.create);
```

## Role Management

Roles can be managed in two ways:

1. **Clerk Public Metadata**: If a `role` is set in the user's `public_metadata` in Clerk, it will be synced to our database during the `syncUser` flow.
2. **Direct DB Edit**: Admins can update roles directly in the database or via the Studio (Admin Panel).
