docs: fix false session persistence claim for registered accounts
All checks were successful
check / check (push) Successful in 1m4s
All checks were successful
check / check (push) Successful in 1m4s
The README incorrectly claimed that registered sessions persist across logouts. The actual code (handleQuit and cleanupUser in api.go) deletes ALL sessions unconditionally when the last client disconnects — no check for password_hash. Updated Data Lifecycle, Registered Accounts, Identity & Sessions rationale, flow diagram, and Design Principles to accurately state that both anonymous and registered sessions are deleted on QUIT or last-client-logout. Registration enables multi-client access (login from another device while session is active), not session persistence across all-client removal.
This commit is contained in:
46
README.md
46
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
|
||||
|
||||
Reference in New Issue
Block a user