fix(presence): drop status='online' from registration insert
Mirrors the REST-login change in f17c46c on the registration insert path.
A successful POST /api/auth/register does not by itself imply a live
WebSocket — the client may never connect (transient network, mobile
background, error path between the 201 and /ws), leaving a permanently
stuck-online row that no disconnect timer can clean up. The schema
default 'offline' is correct; ws/handler.ts flips it to 'online' on real
WS auth.
The federated-stub upgrade path in the same handler is unaffected: it
only updates passwordHash/username/homeUserId/displayName/avatarColor,
leaving the stub's pre-existing 'offline' status (set when the stub was
created via replication) untouched.
Updates docs/systems/auth.md step 7 to reflect the new behavior.
This commit is contained in:
@@ -149,7 +149,7 @@ If `requestedAvatarColor` is provided and is in `AVATAR_COLORS`, use it. Otherwi
|
|||||||
4. Check username uniqueness (exact match on lowercased username)
|
4. Check username uniqueness (exact match on lowercased username)
|
||||||
5. Hash password (bcrypt, 12 rounds)
|
5. Hash password (bcrypt, 12 rounds)
|
||||||
6. Generate Snowflake ID
|
6. Generate Snowflake ID
|
||||||
7. Insert user row with `status: 'online'`, admin flag if first user
|
7. Insert user row (status defaults to `'offline'` at the schema level; it is set to `'online'` only when the client establishes a WebSocket via the WS auth path in `ws/handler.ts`). Admin flag set if first user.
|
||||||
8. Sign JWT with `{ userId, username }`
|
8. Sign JWT with `{ userId, username }`
|
||||||
9. Return `{ token, user }` (user sanitized via `sanitizeUser(user, true)`)
|
9. Return `{ token, user }` (user sanitized via `sanitizeUser(user, true)`)
|
||||||
|
|
||||||
|
|||||||
@@ -166,12 +166,19 @@ export async function authRoutes(app: FastifyInstance): Promise<void> {
|
|||||||
? requestedAvatarColor
|
? requestedAvatarColor
|
||||||
: AVATAR_COLORS[Math.floor(Math.random() * AVATAR_COLORS.length)];
|
: AVATAR_COLORS[Math.floor(Math.random() * AVATAR_COLORS.length)];
|
||||||
|
|
||||||
|
// Note: status is left at the schema default ('offline') and is set to
|
||||||
|
// 'online' exclusively by the WebSocket auth path (ws/handler.ts). A
|
||||||
|
// successful REST /register does not by itself imply a live connection —
|
||||||
|
// the client may never establish a WS (transient network failure, mobile
|
||||||
|
// background, error path between this 201 response and /ws connect),
|
||||||
|
// which would otherwise produce a permanently stuck-online row that no
|
||||||
|
// disconnect timer can clean up. The WS handshake will flip it to
|
||||||
|
// 'online' once a real socket attaches.
|
||||||
db.insert(schema.users).values({
|
db.insert(schema.users).values({
|
||||||
id: userId,
|
id: userId,
|
||||||
username: trimmedUsername,
|
username: trimmedUsername,
|
||||||
displayName: displayName?.trim() || null,
|
displayName: displayName?.trim() || null,
|
||||||
passwordHash,
|
passwordHash,
|
||||||
status: 'online',
|
|
||||||
isAdmin: isFirstUser ? 1 : 0,
|
isAdmin: isFirstUser ? 1 : 0,
|
||||||
homeInstance: homeInstance || null,
|
homeInstance: homeInstance || null,
|
||||||
homeUserId: (homeInstance && homeUserId && typeof homeUserId === 'string') ? homeUserId : null,
|
homeUserId: (homeInstance && homeUserId && typeof homeUserId === 'string') ? homeUserId : null,
|
||||||
|
|||||||
Reference in New Issue
Block a user