openvibers/openvibe.chat Commits
Calls: a socket that signs in after its welcome is named in the voice-channel list (the list is pushed again; Live's sidebar kept showing the anon number) (#121)
Changes
@@@ -601,6 +601,7 @@ class CallServer {const a = callRoom ? await rooms.access(callRoom, user) : null;if (!a || !a.read || !a.join) { if (c.ws.readyState === WebSocket.OPEN) { c.ws.send(JSON.stringify({ type: 'error', message: 'You cannot join this call' })); c.ws.close(); } break; }}++ const signedIn = (c.user ? c.user.id : null) !== (user ? user.id : null);c.user = user; c.anonId = user ? null : chatServer.getAnonIdForConnection(c.ip, channelId);c.isChannelCreator = !!(user && ch?.createdBy === user.id);c.isStreamer = ch?.streamId ? !!(user && (await ctx.getStreamById(ch.streamId))?.user_id === user.id) : false;@@@ -615,6 +616,9 @@ class CallServer {}));const u = JSON.stringify({ type: 'peer-updated', ...pInfo });for (const [pid, info] of room) { if (pid !== peerId && info.ws.readyState === WebSocket.OPEN) info.ws.send(u); }++ // The voice-channel list (Live's sidebar) names people from these records too: without this push it++ // kept showing a socket that signed in after its welcome as its anon number (Maticus, 2026-10-20).++ if (signedIn) this._notifyChannelsChanged();return acceptedToken;}case 'force-mute': {@@@ -213,12 +213,19 @@ t('the pre-admission buffer is capped: 201 early messages close the socket (1008} finally { h.ctx.warm = warm; }});--t('a cookie does not sign a call socket in: its auth-update does', async () => {++t('a cookie does not sign a call socket in: its auth-update does, and the voice-channel list then names them', async () => {++ const chat = await h.ws({ token: dan.token });const s = await callWs({ channelId: 'public', cookie: `ov_token=${cat.token}`, ip: '198.51.100.5' });const welcome = await s.next((m) => m.type === 'welcome');assert.notStrictEqual(welcome.participants.find((p) => p.peerId === welcome.peerId).username, 'cat', 'anonymous on the cookie alone');++ // The join's own (debounced) push lists them anonymous; the sign-in comes after it.++ await chat.next((m) => m.type === 'voice-channels' && m.channels.some((c) => c.id === 'public' && c.participants.some((p) => p.peerId === welcome.peerId && !p.username)));s.sendJson({ type: 'auth-update', token: cat.token });assert.strictEqual((await s.next((m) => m.type === 'self-updated')).participant.username, 'cat');++ // Live's sidebar showed the anon number until something else changed the list (Maticus, 2026-10-20).++ const named = (m) => m.type === 'voice-channels' && m.channels.some((c) => c.id === 'public' && c.participants.some((p) => p.peerId === welcome.peerId && p.username === 'cat'));++ assert.ok(await chat.next(named), 'the list is pushed again with their name');++ chat.close();await bye(s);});
@@ -601,6 +601,7 @@ class CallServer {
@@ -601,6 +601,7 @@ class CallServer {
const a = callRoom ? await rooms.access(callRoom, user) : null;
const a = callRoom ? await rooms.access(callRoom, user) : null;
if (!a || !a.read || !a.join) { if (c.ws.readyState === WebSocket.OPEN) { c.ws.send(JSON.stringify({ type: 'error', message: 'You cannot join this call' })); c.ws.close(); } break; }
if (!a || !a.read || !a.join) { if (c.ws.readyState === WebSocket.OPEN) { c.ws.send(JSON.stringify({ type: 'error', message: 'You cannot join this call' })); c.ws.close(); } break; }
}
}
+ const signedIn = (c.user ? c.user.id : null) !== (user ? user.id : null);
c.user = user; c.anonId = user ? null : chatServer.getAnonIdForConnection(c.ip, channelId);
c.user = user; c.anonId = user ? null : chatServer.getAnonIdForConnection(c.ip, channelId);
c.isChannelCreator = !!(user && ch?.createdBy === user.id);
c.isChannelCreator = !!(user && ch?.createdBy === user.id);
c.isStreamer = ch?.streamId ? !!(user && (await ctx.getStreamById(ch.streamId))?.user_id === user.id) : false;
c.isStreamer = ch?.streamId ? !!(user && (await ctx.getStreamById(ch.streamId))?.user_id === user.id) : false;
@@ -615,6 +616,9 @@ class CallServer {
@@ -615,6 +616,9 @@ class CallServer {
}));
}));
const u = JSON.stringify({ type: 'peer-updated', ...pInfo });
const u = JSON.stringify({ type: 'peer-updated', ...pInfo });
for (const [pid, info] of room) { if (pid !== peerId && info.ws.readyState === WebSocket.OPEN) info.ws.send(u); }
for (const [pid, info] of room) { if (pid !== peerId && info.ws.readyState === WebSocket.OPEN) info.ws.send(u); }
+ // The voice-channel list (Live's sidebar) names people from these records too: without this push it
+ // kept showing a socket that signed in after its welcome as its anon number (Maticus, 2026-10-20).
+ if (signedIn) this._notifyChannelsChanged();
return acceptedToken;
return acceptedToken;
}
}
case 'force-mute': {
case 'force-mute': {
@@ -213,12 +213,19 @@ t('the pre-admission buffer is capped: 201 early messages close the socket (1008
@@ -213,12 +213,19 @@ t('the pre-admission buffer is capped: 201 early messages close the socket (1008
} finally { h.ctx.warm = warm; }
} finally { h.ctx.warm = warm; }
});
});
-t('a cookie does not sign a call socket in: its auth-update does', async () => {
+t('a cookie does not sign a call socket in: its auth-update does, and the voice-channel list then names them', async () => {
+ const chat = await h.ws({ token: dan.token });
const s = await callWs({ channelId: 'public', cookie: `ov_token=${cat.token}`, ip: '198.51.100.5' });
const s = await callWs({ channelId: 'public', cookie: `ov_token=${cat.token}`, ip: '198.51.100.5' });
const welcome = await s.next((m) => m.type === 'welcome');
const welcome = await s.next((m) => m.type === 'welcome');
assert.notStrictEqual(welcome.participants.find((p) => p.peerId === welcome.peerId).username, 'cat', 'anonymous on the cookie alone');
assert.notStrictEqual(welcome.participants.find((p) => p.peerId === welcome.peerId).username, 'cat', 'anonymous on the cookie alone');
+ // The join's own (debounced) push lists them anonymous; the sign-in comes after it.
+ await chat.next((m) => m.type === 'voice-channels' && m.channels.some((c) => c.id === 'public' && c.participants.some((p) => p.peerId === welcome.peerId && !p.username)));
s.sendJson({ type: 'auth-update', token: cat.token });
s.sendJson({ type: 'auth-update', token: cat.token });
assert.strictEqual((await s.next((m) => m.type === 'self-updated')).participant.username, 'cat');
assert.strictEqual((await s.next((m) => m.type === 'self-updated')).participant.username, 'cat');
+ // Live's sidebar showed the anon number until something else changed the list (Maticus, 2026-10-20).
+ const named = (m) => m.type === 'voice-channels' && m.channels.some((c) => c.id === 'public' && c.participants.some((p) => p.peerId === welcome.peerId && p.username === 'cat'));
+ assert.ok(await chat.next(named), 'the list is pushed again with their name');
+ chat.close();
await bye(s);
await bye(s);
});
});