fix: show meeting guests to members and hide the roster from guests (#1353)

This commit is contained in:
LukeGus committed 2026-09-30 12:09:05 -05:00
1 parent ab43563247
commit f896e121e2
14 files changed
+254 -19

No files matched your search

@@ -142,6 +142,8 @@ export async function activate(ctx: PluginContext) {
sessionManager.ownerEndSession(sessionId, reason),
disconnectParticipants: (sessionId, shareId, options) =>
sessionManager.disconnectShareParticipants(sessionId, shareId, options),
listGuests: (sessionId, shareId) =>
sessionManager.listShareGuests(sessionId, shareId),
setRoomShareControl: (sessionId, shareId, controllerUserId) =>
sessionManager.setRoomShareControl(sessionId, shareId, controllerUserId),
subscribe: (sessionId, onData) => {
@@ -36,6 +36,11 @@ export interface LiveSessionsV1 {
shareId: string,
options: { reason: string; userId?: string | null },
) => number;
/** The anonymous link guests watching through one share. */
listGuests: (
sessionId: string,
shareId: string,
) => { label: string | null }[];
/** Hands input control of a room share to one member, or back to the owner. */
setRoomShareControl: (
sessionId: string,
@@ -486,7 +486,28 @@ export class TerminalSessionManager {
participants.every((participant) => participant.isOwner)
)
return;
this.broadcast(sessionId, { type: "participants", participants });
// Link guests are anonymous viewers; they do not get the roster.
this.broadcast(
sessionId,
{ type: "participants", participants },
(participant) => participant.userId !== null,
);
}
/** The anonymous link guests watching through one share. */
listShareGuests(
sessionId: string,
shareId: string,
): { label: string | null }[] {
const session = this.sessions.get(sessionId);
if (!session) return [];
return Array.from(session.participants.values())
.filter(
(participant) =>
participant.userId === null &&
participant.joinedViaShareId === shareId,
)
.map((participant) => ({ label: participant.guestLabel ?? null }));
}
/**
@@ -554,12 +575,17 @@ export class TerminalSessionManager {
}
/** Fans out a message to every OPEN participant socket; skips closed ones and send failures. */
broadcast(sessionId: string, message: object): void {
broadcast(
sessionId: string,
message: object,
include?: (participant: SessionParticipant) => boolean,
): void {
const session = this.sessions.get(sessionId);
if (!session) return;
const payload = JSON.stringify(message);
for (const participant of session.participants.values()) {
if (participant.ws.readyState !== WebSocket.OPEN) continue;
if (include && !include(participant)) continue;
try {
participant.ws.send(payload);
} catch {