130 lines
2.9 KiB
Markdown
130 lines
2.9 KiB
Markdown
# Auth API
|
|
|
|
Base path: `/api/v1/auth`
|
|
|
|
All endpoints require `Authorization: Bearer <jwt>` unless noted otherwise.
|
|
|
|
Related: [[02 - Authentication]], [[09 - Teams API]]
|
|
|
|
---
|
|
|
|
## Endpoints
|
|
|
|
### GET /auth/google
|
|
|
|
Initiates the Google OAuth flow. Redirects the browser to the Google consent screen.
|
|
|
|
> No authentication required.
|
|
|
|
---
|
|
|
|
### GET /auth/google/callback
|
|
|
|
OAuth callback handler. Called by Google after the user grants consent. Sets JWT tokens and redirects to the frontend.
|
|
|
|
> No authentication required. Handled entirely by the backend.
|
|
|
|
---
|
|
|
|
### POST /auth/refresh
|
|
|
|
Refreshes the access token using a valid refresh token.
|
|
|
|
**Request body:**
|
|
|
|
```json
|
|
{ "refreshToken": "string" }
|
|
```
|
|
|
|
**Response:**
|
|
|
|
```json
|
|
{
|
|
"accessToken": "string",
|
|
"refreshToken": "string"
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
### POST /auth/logout
|
|
|
|
Invalidates the current refresh token. Requires authentication.
|
|
|
|
**Response:**
|
|
|
|
```json
|
|
{ "message": "Logged out" }
|
|
```
|
|
|
|
---
|
|
|
|
### GET /auth/me
|
|
|
|
Returns the currently authenticated user.
|
|
|
|
**Response:**
|
|
|
|
```json
|
|
{
|
|
"id": "cuid",
|
|
"email": "user@example.com",
|
|
"name": "User Name",
|
|
"teamId": "cuid",
|
|
"teamRole": "EDITOR"
|
|
}
|
|
```
|
|
|
|
**Possible `teamRole` values:** `OWNER`, `ADMIN`, `EDITOR`, `REVIEWER`, `READONLY`
|
|
|
|
---
|
|
|
|
### POST /auth/switch-team
|
|
|
|
Switch the active team context. Returns a new access token scoped to the requested team. The caller must be a member of the target team.
|
|
|
|
**Request body:**
|
|
|
|
```json
|
|
{ "teamId": "cuid" }
|
|
```
|
|
|
|
**Response:**
|
|
|
|
```json
|
|
{ "accessToken": "string" }
|
|
```
|
|
|
|
Replace the stored access token with the returned one. All subsequent requests will be scoped to the new team. The refresh token is unchanged.
|
|
|
|
> **Note:** The response does not include `teamRole`. The new role is encoded inside the JWT payload (`teamRole` claim). Clients that need the role without decoding the JWT must call `GET /users/me` after switching teams. See the backlog for a possible improvement.
|
|
|
|
> **Frontend status:** No UI exists for team switching. This endpoint is only reachable via direct API call. Use `GET /teams/mine` to enumerate the teams available to switch to.
|
|
|
|
---
|
|
|
|
### GET /users/me/preferences
|
|
|
|
Returns the current user's preferences as a freeform JSON object.
|
|
|
|
**Response:** `Record<string, unknown>`
|
|
|
|
---
|
|
|
|
### PATCH /users/me/preferences
|
|
|
|
Merges new key/value pairs into the user's stored preferences. Existing keys not present in the request body are preserved.
|
|
|
|
**Request body:** `Record<string, unknown>`
|
|
|
|
**Response:** Updated preferences object
|
|
|
|
---
|
|
|
|
## Notes
|
|
|
|
- Access tokens are short-lived JWTs signed with `JWT_SECRET`.
|
|
- Refresh tokens are stored encrypted and are invalidated on logout.
|
|
- YouTube OAuth tokens (for channel connections) are separate from user auth tokens and are AES-256 encrypted in the database using `TOKEN_ENCRYPTION_KEY`. If that key changes, all channel connections must be re-authenticated.
|
|
- See [[06 - Authentication]] for the full auth flow and guard usage.
|