gohorsejobs/docs/API_SECURITY.md

107 lines
4.2 KiB
Markdown

# 🔐 API Security & Access Levels
This document details the security layers, authentication methods, and role-based access control (RBAC) for the GoHorse Jobs API. Use this guide to verify and test route protection.
## 🛡️ Authentication Methods
1. **Bearer Token (JWT)**
* Header: `Authorization: Bearer <token>`
* Used by: Mobile apps, external integrations, simple API tests.
2. **HttpOnly Cookie**
* Cookie Name: `jwt`
* Used by: Web Frontend (Next.js), Backoffice.
* Properties: `HttpOnly`, `Secure` (in prod), `SameSite=Lax`.
## 🚦 Access Levels
| Level | Description | Middleware |
| :--- | :--- | :--- |
| **Public** | Open to everyone (Guests). No check performed. | None |
| **Authenticated** | Requires a valid JWT (Header or Cookie). | `HeaderAuthGuard` |
| **Role-Restricted** | Requires valid JWT + Specific Role claim. | `HeaderAuthGuard` + `RequireRoles(...)` |
## 🗺️ Route Permission Matrix
### 🟢 Public Routes
| Method | Route | Description | Notes |
| :--- | :--- | :--- | :--- |
| `POST` | `/api/v1/auth/login` | User Login | Returns JWT + Cookie |
| `POST` | `/api/v1/auth/register` | Candidate Register | Creates `jobSeeker` user |
| `POST` | `/api/v1/companies` | Company Register | Creates company + `companyAdmin` |
| `GET` | `/api/v1/jobs` | List Jobs | Public search/list |
| `GET` | `/api/v1/jobs/{id}` | Get Job | Public details |
| `GET` | `/docs/*` | Swagger UI | API Documentation |
### 🟡 Authenticated Routes (Any Logged User)
**Requirement**: Valid JWT.
| Method | Route | Description |
| :--- | :--- | :--- |
| `GET` | `/api/v1/users/me` | Get Own Profile |
| `PATCH` | `/api/v1/users/{id}` | Update Own Profile (Self-check in handler) |
| `GET` | `/api/v1/notifications` | Get Own Notifications |
| `POST` | `/api/v1/applications` | Apply for Job (Candidate) |
| `POST` | `/api/v1/storage/upload-url` | Get S3 Upload URL |
| `POST` | `/api/v1/storage/download-url` | Get S3 Download URL |
| `DELETE` | `/api/v1/storage/files` | Delete S3 File |
### 🟠 Recruiter / CompanyAdmin Routes
**Requirement**: Role `companyAdmin` OR `recruiter`.
| Method | Route | Description |
| :--- | :--- | :--- |
| `POST` | `/api/v1/jobs` | Create Job |
| `PUT` | `/api/v1/jobs/{id}` | Update Job |
| `DELETE` | `/api/v1/jobs/{id}` | Delete Job |
| `GET` | `/api/v1/applications` | List Applications (for own jobs) |
| `PUT` | `/api/v1/applications/{id}/status` | Update Application Status |
### 🔴 Admin / SuperAdmin Routes (Backoffice)
**Requirement**: Role `superadmin` OR `admin`.
| Method | Route | Description | Middleware Check |
| :--- | :--- | :--- | :--- |
| `GET` | `/api/v1/users` | List All Users | `adminOnly` |
| `POST` | `/api/v1/users` | Create User (Staff) | `adminOnly` |
| `DELETE` | `/api/v1/users/{id}` | Delete User | `adminOnly` |
| `GET` | `/api/v1/users/roles` | List System Roles | `adminOnly` |
| `GET` | `/api/v1/companies` | List Companies (Full) | `adminOnly` |
| `PATCH` | `/api/v1/companies/{id}/status` | Activate/Ban Company | `adminOnly` |
| `GET` | `/api/v1/jobs/moderation` | Moderate Jobs | `adminOnly` |
| `PATCH` | `/api/v1/jobs/{id}/status` | Approve/Reject Job | `adminOnly` |
| `POST` | `/api/v1/jobs/{id}/duplicate` | Admin Duplicate Job | `adminOnly` |
| `GET` | `/api/v1/tags` | List Tags | `adminOnly` |
| `POST` | `/api/v1/tags` | Create Tag | `adminOnly` |
| `PATCH` | `/api/v1/tags/{id}` | Update Tag | `adminOnly` |
| `GET` | `/api/v1/candidates` | List All Candidates | `adminOnly` |
| `GET` | `/api/v1/audit/logins` | View Audit Logs | `adminOnly` |
## 🧪 Testing Security
**1. Test Public Access (Should Succeed)**
```bash
curl http://localhost:8521/api/v1/jobs
```
**2. Test Protected Route without Token (Should Fail 401)**
```bash
curl http://localhost:8521/api/v1/users/me
# Expected: 401 Unauthorized
```
**3. Test Admin Route as Candidate (Should Fail 403)**
1. Login as Candidate -> Get Token A
2. Call Admin Route:
```bash
curl -H "Authorization: Bearer <TOKEN_A>" http://localhost:8521/api/v1/audit/logins
# Expected: 403 Forbidden
```
**4. Test Admin Route as Admin (Should Succeed)**
1. Login as SuperAdmin -> Get Token B
2. Call Admin Route:
```bash
curl -H "Authorization: Bearer <TOKEN_B>" http://localhost:8521/api/v1/audit/logins
# Expected: 200 OK
```