mirror of
https://github.com/Termix-SSH/Termix.git
synced 2026-10-29 22:55:24 +00:00
feat: move session sharing and collab rooms into a plugin (B12)
This commit is contained in:
1 parent
791d8656a1
commit
a276f6898c
207 files changed
+35771
-11072
No files matched your search
@@ -761,70 +761,6 @@ export const sessionRecordings = mysqlTable(
|
||||
],
|
||||
);
|
||||
|
||||
export const sessionShares = mysqlTable(
|
||||
"session_shares",
|
||||
{
|
||||
id: varchar("id", { length: 255 }).primaryKey(),
|
||||
|
||||
hostId: int("host_id")
|
||||
.notNull()
|
||||
.references(() => hosts.id, { onDelete: "cascade" }),
|
||||
ownerUserId: varchar("owner_user_id", { length: 255 })
|
||||
.notNull()
|
||||
.references(() => users.id, { onDelete: "cascade" }),
|
||||
|
||||
protocol: varchar("protocol", { length: 255 }).notNull(),
|
||||
|
||||
// Live-session binding: TerminalSessionManager's session.id for SSH, or
|
||||
// guacd's own guacamoleConnectionId for rdp/vnc/telnet. Neither is a DB
|
||||
// row (process-local, in-memory) so this intentionally has no FK.
|
||||
sessionId: varchar("session_id", { length: 255 }).notNull(),
|
||||
tabInstanceId: text("tab_instance_id"),
|
||||
|
||||
shareType: text("share_type").notNull(), // "link" | "user"
|
||||
targetUserId: varchar("target_user_id", { length: 255 }).references(() => users.id, {
|
||||
onDelete: "cascade",
|
||||
}),
|
||||
linkToken: varchar("link_token", { length: 255 }).unique(),
|
||||
|
||||
permissionLevel: text("permission_level").notNull().default("read-only"),
|
||||
|
||||
createdAt: varchar("created_at", { length: 255 })
|
||||
.notNull()
|
||||
.default(sql`(CURRENT_TIMESTAMP)`),
|
||||
expiresAt: varchar("expires_at", { length: 255 }).notNull(),
|
||||
revokedAt: text("revoked_at"),
|
||||
|
||||
lastJoinedAt: text("last_joined_at"),
|
||||
joinCount: int("join_count").notNull().default(0),
|
||||
},
|
||||
// Resolved from the live session on join, and listed per host.
|
||||
(table) => [
|
||||
index("idx_session_shares_session_id").on(table.sessionId),
|
||||
index("idx_session_shares_host_id").on(table.hostId),
|
||||
],
|
||||
);
|
||||
|
||||
export const sessionShareParticipants = mysqlTable(
|
||||
"session_share_participants",
|
||||
{
|
||||
id: int("id").autoincrement().primaryKey(),
|
||||
shareId: varchar("share_id", { length: 255 })
|
||||
.notNull()
|
||||
.references(() => sessionShares.id, { onDelete: "cascade" }),
|
||||
|
||||
userId: varchar("user_id", { length: 255 }).references(() => users.id, {
|
||||
onDelete: "cascade",
|
||||
}),
|
||||
guestLabel: text("guest_label"),
|
||||
|
||||
joinedAt: text("joined_at")
|
||||
.notNull()
|
||||
.default(sql`(CURRENT_TIMESTAMP)`),
|
||||
leftAt: text("left_at"),
|
||||
},
|
||||
);
|
||||
|
||||
export const opksshTokens = mysqlTable(
|
||||
"opkssh_tokens",
|
||||
{
|
||||
@@ -1569,81 +1505,6 @@ export const aiProposals = mysqlTable(
|
||||
|
||||
// --- collab rooms ---
|
||||
|
||||
/**
|
||||
* A collaboration room: a group of users watching one "stage" - the live
|
||||
* session the current presenter is showing. The stage points at a
|
||||
* shareType="room" row in session_shares, so transport, gating, recording and
|
||||
* expiry all reuse the session-sharing machinery.
|
||||
*/
|
||||
export const collabRooms = mysqlTable(
|
||||
"collab_rooms",
|
||||
{
|
||||
id: varchar("id", { length: 255 }).primaryKey(),
|
||||
name: varchar("name", { length: 255 }).notNull(),
|
||||
ownerUserId: varchar("owner_user_id", { length: 255 })
|
||||
.notNull()
|
||||
.references(() => users.id, { onDelete: "cascade" }),
|
||||
|
||||
// Persistent rooms survive being emptied and can be re-used; one-off
|
||||
// rooms are ended explicitly and never listed again.
|
||||
persistent: boolean("persistent")
|
||||
.notNull()
|
||||
.default(false),
|
||||
|
||||
presenterUserId: varchar("presenter_user_id", { length: 255 }).references(() => users.id, {
|
||||
onDelete: "set null",
|
||||
}),
|
||||
stageProtocol: text("stage_protocol"),
|
||||
stageHostId: int("stage_host_id").references(() => hosts.id, {
|
||||
onDelete: "set null",
|
||||
}),
|
||||
stageShareId: varchar("stage_share_id", { length: 255 }).references(() => sessionShares.id, {
|
||||
onDelete: "set null",
|
||||
}),
|
||||
|
||||
// Set = anonymous guests may watch the stage through this token.
|
||||
guestLinkToken: varchar("guest_link_token", { length: 255 }),
|
||||
|
||||
createdAt: varchar("created_at", { length: 255 })
|
||||
.notNull()
|
||||
.default(sql`(CURRENT_TIMESTAMP)`),
|
||||
endedAt: text("ended_at"),
|
||||
},
|
||||
(table) => [
|
||||
index("idx_collab_rooms_owner").on(table.ownerUserId),
|
||||
uniqueIndex("idx_collab_rooms_guest_token").on(table.guestLinkToken),
|
||||
],
|
||||
);
|
||||
|
||||
export const collabRoomMembers = mysqlTable(
|
||||
"collab_room_members",
|
||||
{
|
||||
id: int("id").autoincrement().primaryKey(),
|
||||
roomId: varchar("room_id", { length: 255 })
|
||||
.notNull()
|
||||
.references(() => collabRooms.id, { onDelete: "cascade" }),
|
||||
userId: varchar("user_id", { length: 255 })
|
||||
.notNull()
|
||||
.references(() => users.id, { onDelete: "cascade" }),
|
||||
|
||||
// "host" runs the room: invites, force-switches the presenter, ends it.
|
||||
roomRole: text("room_role").notNull().default("member"),
|
||||
addedBy: varchar("added_by", { length: 255 }).references(() => users.id, {
|
||||
onDelete: "set null",
|
||||
}),
|
||||
createdAt: varchar("created_at", { length: 255 })
|
||||
.notNull()
|
||||
.default(sql`(CURRENT_TIMESTAMP)`),
|
||||
},
|
||||
(table) => [
|
||||
uniqueIndex("idx_collab_room_members_room_user").on(
|
||||
table.roomId,
|
||||
table.userId,
|
||||
),
|
||||
index("idx_collab_room_members_user").on(table.userId),
|
||||
],
|
||||
);
|
||||
|
||||
// --- secret sources ---
|
||||
|
||||
/**
|
||||
|
||||
Reference in new issue
Block a user