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

@@ -34,6 +34,10 @@ export interface LiveSessionProvider {
shareId: string,
controllerUserId: string | null,
) => void;
listGuests?: (
sessionId: string,
shareId: string,
) => { label: string | null }[];
createViewerToken?: (sessionId: string, readOnly: boolean) => string;
}
@@ -104,6 +108,24 @@ export function createLiveSessions(ctx: PluginContext) {
return !!session && session.isConnected && session.userId === userId;
},
/** Anonymous link guests on one share; empty when the type cannot tell. */
async listGuests(
protocol: string,
sessionId: string,
shareId: string,
asUser?: string,
): Promise<{ label: string | null }[]> {
const live = provider(protocol);
if (!live || !("listGuests" in live)) return [];
try {
return (
(await run(asUser, () => live.listGuests(sessionId, shareId))) ?? []
);
} catch {
return [];
}
},
/** Ends the session for every guest. Best effort, like before. */
async ownerEndSession(
protocol: string,
@@ -364,6 +364,16 @@ export function registerRoomRoutes(
}
const members = await rooms.listMembers(roomId);
const stageShare = await liveStageShare(access.room);
const guests =
stageShare && access.room.stageProtocol
? await live.listGuests(
access.room.stageProtocol,
stageShare.sessionId,
stageShare.id,
stageShare.ownerUserId,
)
: [];
const mayReview = access.isHost || access.room.presenterUserId === userId;
const controlRequests = await store.listRequests(roomId);
res.json({
@@ -373,6 +383,7 @@ export function registerRoomRoutes(
members,
online: await hub.onlineUsers(roomId),
stage: stagePayload(access.room),
guests,
controllerUserId: await store.getController(roomId),
controlRequests: mayReview
? controlRequests
@@ -1124,6 +1135,65 @@ export function registerRoomRoutes(
},
);
/**
* @openapi
* /plugin-api/session-sharing/rooms/{id}/guests/remove:
* post:
* summary: Disconnect every anonymous guest watching the stage (host only)
* description: The guest link stays valid, so a guest may open it again.
* tags:
* - Collab
* security:
* - bearerAuth: []
* parameters:
* - in: path
* name: id
* required: true
* schema:
* type: string
* responses:
* 200:
* description: Guests disconnected
* 403:
* description: Not the host
* 404:
* description: Not a member, or no such room
*/
router.post(
"/rooms/:id/guests/remove",
requireUse,
async (req: Request, res: Response) => {
const userId = actorOf(ctx);
const roomId = String(req.params.id);
try {
const access = await requireRoomMember(roomId, userId);
if (!access) return res.status(404).json({ error: "Room not found" });
if (!access.isHost) {
return res
.status(403)
.json({ error: "Only the host can remove guests" });
}
const share = await liveStageShare(access.room);
if (share && access.room.stageProtocol) {
await live.disconnectParticipants(
access.room.stageProtocol,
share.sessionId,
share.id,
{ userId: null, reason: "The host removed the guests" },
share.ownerUserId,
);
}
res.json({ success: true });
} catch (error) {
fail(
res,
"collab_guests_remove_error",
"Failed to remove guests",
)(error);
}
},
);
/**
* @openapi
* /plugin-api/session-sharing/rooms/{id}/guest-link: