Chat: clientId-Based Identity
Replace IP-based identity with clientId throughout the chat system. This makes flag, block, delete-by-user, and rename all operate per-browser rather than per-IP, so users on the same network are independent.
Data Model
ChatMessage
Add clientId: string. Stored on every message so flag/delete/rename can trace back to the originating browser.
ConnectionInfo
Remove ip. The clientId field (already optional) becomes required.
BlockedEntry
Change from { ip, username, blockedAt } to { clientId, username, blockedAt }.
Server (chat-room.ts)
Removals
ipBySocketmapCF-Connecting-IPheader readsConnectionInfo.ip
blockedEntries
Rekey from IP to clientId. On load, discard any old IP-keyed entries (no migration path).
handleJoin
- Block check:
blockedEntries.has(clientId)instead of IP lookup. - Rename detection: if a connection already exists with the same
clientIdbut different username, treat this as a rename:- Update
msg.usernameon allthis.messageswheremsg.clientId === clientId - Broadcast
{ type: "rename", oldUsername, newUsername }to all clients - Continue normal join flow
- Update
handleFlag
- Get
clientIdfrom the flagged message (message.clientId) - Add
clientIdtoblockedEntries - Find all connections with that
clientId, send BLOCKED
handleDeleteByUser
Match msg.clientId instead of msg.username. Client sends clientId (from message data attribute) instead of username.
handleUnblock
Unblock by clientId instead of IP.
addWarning
Auto-block by clientId instead of IP.
buildStatusMessage
Dedup by clientId directly (remove ip:username fallback).
Types (types.ts)
ChatMessage: addclientId: stringConnectionInfo: removeip, makeclientIdrequiredBlockedEntry:ip→clientIdClientDeleteByUserData:{ username }→{ clientId }ClientUnblockData:{ ip }→{ clientId }- Add
RENAME: "rename"toSERVER_MESSAGE_TYPE - Add
ServerRenameMessage { type: "rename", oldUsername: string, newUsername: string } ServerFlaggedMessage:ip→clientIdServerUnblockedMessage:ip→clientId- Add
ServerRenameMessagetoServerMessageunion
Client (chat-client.ts)
- Store
clientIdfrom received messages asdata-client-idon message DOM elements - Handle
"rename": query[data-chat="username"]spans, update text where it matchesoldUsername - Flag callback: send
clientIdfrom element’s data attribute - Delete-by-user: send
clientIdinstead of username - Unblock: send
clientIdinstead of IP - Blocked list display: show truncated clientId instead of IP