# Auth & Session (`src/common/middleware/auth.middleware.ts`)

The `AuthMiddleware` runs globally (see `app.module.ts`). It authenticates requests via HTTP-only cookies and attaches the current user to the request. Protected routes get `user` (serialized) and `sessionId` on the request object.

## Public routes (no auth required)

These paths bypass the middleware:

| Path | Purpose |
| --- | --- |
| `POST /user/register` | Create account |
| `POST /user/login` | Sign in |
| `POST /user/verify-login-otp` | Confirm OTP sign-in |
| `POST /user/forgot-password` | Request reset OTP |
| `POST /user/reset-password` | Reset password |
| `GET /user/google-callback` | OAuth callback |
| `GET /user/init-google-auth` | Build OAuth URL |
| `POST /user/resend-otp` | Resend OTP |

Everything else requires authentication.

## Cookies

| Cookie | Type | Lifespan | Notes |
| --- | --- | --- | --- |
| `happydada` | access token (JWT) | 15 min | Sent on every request; enables auth |
| `hayyya` | refresh token (JWT) | 7 days | Used to re-issue the access token when it expires |

Names are configurable via `ACCESS_COOKIE_NAME` / `REFRESH_COOKIE_NAME` (defaults `happydada` / `hayyya`). In production both are `Secure`; both are `HttpOnly` and `SameSite=Lax`.

## Request flow

1. If the path is public → `next()`.
2. **Access token valid** → load user from DB, attach `req.user` + `req.sessionId`, `next()`.
3. **Access token invalid/expired but refresh token valid** → re-sign a new access token, set the `happydada` cookie, attach user, `next()`.
4. **Neither valid** → throw `401 Unauthorized`.

## Attached request fields

| Field | Type | Description |
| --- | --- | --- |
| `req.user` | `SafeUser` | Serialized user (no password) — see `serialize-user.util.ts` |
| `req.sessionId` | string | Session id from the token payload |

## Errors

| Code | Description |
| --- | --- |
| 401 | `Authentication required` — no valid access or refresh token |
