diff --git a/README.md b/README.md index fc18bcd..444fe07 100644 --- a/README.md +++ b/README.md @@ -115,7 +115,7 @@ Everything else is IRC. `PRIVMSG`, `JOIN`, `PART`, `NICK`, `TOPIC`, `MODE`, Joining a nonexistent channel creates it. Channels disappear when empty. Nicks are unique per server. Identity starts with a key — a nick is a display name. Accounts are optional: you can create an anonymous session instantly, or -register with a password to persist your identity across sessions. +register with a password for multi-client access to a single session. ### On the resemblance to JSON-RPC @@ -152,7 +152,7 @@ need to change. ### Identity & Sessions — Dual Authentication Model The server supports two authentication paths: **anonymous sessions** for -instant access, and **optional account registration** for persistent identity. +instant access, and **optional account registration** for multi-client access. #### Anonymous Sessions (No Account Required) @@ -168,7 +168,7 @@ The simplest entry point. No registration, no passwords. #### Registered Accounts (Optional) -For users who want persistent identity across sessions: +For users who want multi-client access (multiple devices sharing one session): - **Registration**: client sends `POST /api/v1/register` with a nick and password (minimum 8 characters) → server creates a session with the @@ -178,7 +178,9 @@ For users who want persistent identity across sessions: new client token for the existing session. This enables multi-client access: logging in from a new device adds a client to the existing session rather than creating a new one, so channel memberships and message queues - are shared. + are shared. Note: login only works while the session still exists — if all + clients have logged out or the user has sent QUIT, the session is deleted + and the registration is lost. - Registered accounts cannot be logged into via `POST /api/v1/session` — that endpoint is for anonymous sessions only. - Anonymous sessions (created via `/session`) cannot be logged into via @@ -195,10 +197,12 @@ For users who want persistent identity across sessions: **Rationale:** IRC has no accounts. You connect, pick a nick, and talk. Anonymous sessions preserve that simplicity — instant access, zero friction. -But some users want to keep their nick across sessions without relying on a -bouncer or nick reservation system. Optional registration with password -solves this without adding friction for casual users: if you don't want an -account, don't create one. Identity verification at the message layer via +But some users want to access the same session from multiple devices without +a bouncer. Optional registration with password enables multi-client login +without adding friction for casual users: if you don't want an account, +don't create one. Note: in the current implementation, both anonymous and +registered sessions are deleted when the last client disconnects (QUIT or +logout); registration does not make a session survive all-client removal. Identity verification at the message layer via cryptographic signatures (see [Security Model](#security-model)) remains independent of account registration. @@ -430,13 +434,14 @@ The entire read/write loop for a client is two endpoints. Everything else │ │ │ ... use the API normally (JOIN, PRIVMSG, poll, etc.) ... │ │ │ -│ (Later, from a new device or after token expiry) │ +│ (From another device, while session is still active) │ │ │ │ 2. POST /api/v1/login │ │ {"nick":"alice", "password":"s3cret!!"} │ │ → {"id":1, "nick":"alice", "token":"d4e5f6..."} │ │ (New client added to existing session — channels │ -│ and message queues are preserved) │ +│ and message queues are preserved. If all clients │ +│ have logged out, session no longer exists.) │ │ │ └────────────────────────────────────────────────────────────┘ ``` @@ -1977,14 +1982,19 @@ skew issues) and simpler than UUIDs (integer comparison vs. string comparison). - **Client output queue entries**: Pruned automatically when older than `QUEUE_MAX_AGE` (default 30 days). - **Channels**: Deleted when the last member leaves (ephemeral). -- **Sessions**: Anonymous sessions are deleted on `QUIT` or when all clients - have logged out. Registered sessions persist across logouts — the session - remains so the user can log in again later. Idle sessions (both anonymous - and registered) are automatically expired after `SESSION_IDLE_TIMEOUT` +- **Sessions**: Both anonymous and registered sessions are deleted on `QUIT` + or when the last client logs out (`POST /api/v1/logout` with no remaining + clients triggers session cleanup). There is no distinction between session + types in the cleanup path — `handleQuit` and `cleanupUser` both call + `DeleteSession` unconditionally. Idle sessions are automatically expired + after `SESSION_IDLE_TIMEOUT` (default 30 days) — the server runs a background cleanup loop that parts idle users from all channels, broadcasts QUIT, and releases their nicks. - **Clients**: Individual client tokens are deleted on `POST /api/v1/logout`. A session can have multiple clients; removing one doesn't affect others. + However, when the last client is removed (via logout), the entire session + is deleted — the user is parted from all channels, QUIT is broadcast, and + the nick is released. --- @@ -2138,7 +2148,7 @@ export TOKEN=$(curl -s -X POST http://localhost:8080/api/v1/session \ -H 'Content-Type: application/json' \ -d '{"nick":"testuser"}' | jq -r .token) -# 1b. Or register an account (persistent identity) +# 1b. Or register an account (multi-client support) export TOKEN=$(curl -s -X POST http://localhost:8080/api/v1/register \ -H 'Content-Type: application/json' \ -d '{"nick":"testuser","password":"mypassword"}' | jq -r .token) @@ -2577,9 +2587,9 @@ neoirc/ 2. **Accounts optional** — anonymous sessions are instant: pick a nick and talk. No registration, no email verification. The cost of entry is a - hashcash proof, not bureaucracy. For users who want persistent identity, - optional account registration with password is available — but never - required. Identity verification at the message layer uses cryptographic + hashcash proof, not bureaucracy. For users who want multi-client access + (multiple devices sharing one session), optional account registration + with password is available — but never required. Identity verification at the message layer uses cryptographic signing, independent of account status. 3. **IRC semantics over HTTP** — command names and numeric codes from