68 lines
2.9 KiB
Markdown
68 lines
2.9 KiB
Markdown
# Authentication
|
|
|
|
Session-token authentication for the signaling server and product client.
|
|
|
|
## Trust boundaries
|
|
|
|
| Surface | Identity proof | Notes |
|
|
|---|---|---|
|
|
| Signaling server REST (mutations) | `Authorization: Bearer <token>` | Actor user IDs in request bodies are ignored; server derives `authUserId` from the token |
|
|
| Signaling server REST (discovery) | None | `GET /api/servers`, featured/trending/search remain public |
|
|
| Signaling server WebSocket | `identify.token` | Connections must identify before any other message type |
|
|
| Electron Local API | Separate in-memory bearer tokens | Proxies login to allowed signaling servers only |
|
|
| Product client local DB | OS user account | SQLite and attachments are plaintext at rest |
|
|
|
|
## Login / register response
|
|
|
|
```json
|
|
{
|
|
"id": "<uuid>",
|
|
"username": "alice",
|
|
"displayName": "Alice",
|
|
"token": "<opaque-hex>",
|
|
"expiresAt": 1710000000000
|
|
}
|
|
```
|
|
|
|
- Tokens are opaque 64-character hex strings stored in server SQLite (`session_tokens`).
|
|
- Default TTL: 24 hours (`SESSION_TOKEN_TTL_MS` env override supported).
|
|
- Passwords are stored with bcrypt; legacy SHA-256 hashes are upgraded transparently on successful login.
|
|
|
|
## Protected REST routes
|
|
|
|
Require `Authorization: Bearer`:
|
|
|
|
- `PUT/POST/DELETE` under `/api/servers/*` (except public `GET`)
|
|
- `PUT /api/requests/:id`
|
|
- Plugin-support mutations under `/api/servers/:serverId/plugins/*`
|
|
- `/api/users/device-tokens/*`
|
|
- `POST /api/users/logout`
|
|
|
|
## WebSocket identify contract
|
|
|
|
```json
|
|
{
|
|
"type": "identify",
|
|
"token": "<session-token>",
|
|
"oderId": "<user-id>",
|
|
"displayName": "Alice",
|
|
"connectionScope": "ws://host:3001"
|
|
}
|
|
```
|
|
|
|
- `oderId` must match the token's user id when provided.
|
|
- Server responds with `auth_error` or `auth_required` when authentication fails.
|
|
|
|
## Client storage
|
|
|
|
The product client stores tokens per signaling-server base URL in `localStorage` (`metoyou.authTokens`). An HTTP interceptor attaches the bearer token to `/api/*` requests targeting that server.
|
|
|
|
Persisted local user state (`metoyou_currentUserId` + IndexedDB/SQLite profile) is **not** sufficient to use chat or presence. On startup, `loadCurrentUser$` requires a non-expired session token for the user's home/active signaling server (or any stored token as a fallback). Missing or rejected tokens dispatch `SESSION_EXPIRED` and redirect to `/login`. WebSocket `auth_required` / `auth_error` responses trigger the same path.
|
|
|
|
## Security considerations
|
|
|
|
- Rate limits: login/register (100 / 15 min), server join (30 / min).
|
|
- CORS allowlist: optional `corsAllowlist` in `server/data/variables.json` or `CORS_ALLOWLIST` env (comma-separated). Empty allowlist keeps permissive CORS for local development.
|
|
- Push-token routes require bearer auth and user-id match.
|
|
- RTC relay: direct-message/direct-call types always relay; server-icon types require shared server membership; WebRTC offer/answer/ice remain open for cross-server DM WebRTC.
|