feat: instance-level streaming limits with admin settings panel

Add a server-side instance_settings table (single-row, CHECK(id=1))
that stores admin-configurable streaming bounds: bitrate min/max/step,
allowed resolutions, and allowed framerates.

Backend:
- New instance_settings schema + migrations (is_admin on users, default
  settings row, first-registered-user promoted to admin)
- GET/PATCH /api/settings/streaming endpoints with admin-only writes
  and full input validation including cross-field checks

Frontend:
- settingsStore fetches limits on WebSocket ready, exposes isAdmin flag
- ScreenShareSettingsPopover reads bounds from store instead of
  hardcoded constants, auto-clamps stale localStorage values
- buildScreenShareOptions() clamps bitrate to server limits at build
  time as enforcement backstop
- ServerSettings modal gains a "Streaming" tab (admin-only) with
  bitrate range sliders, resolution/framerate toggles, and save/reset
This commit is contained in:
Jannis Braun
2026-02-26 03:33:29 +01:00
parent 2184ded2c1
commit 773a03b1aa
22 changed files with 541 additions and 9 deletions
+6
View File
@@ -14,6 +14,7 @@ function sanitizeUser(row: typeof schema.users.$inferSelect): User {
avatar: row.avatar,
status: (row.status ?? 'offline') as User['status'],
customStatus: row.customStatus,
isAdmin: row.isAdmin === 1,
createdAt: row.createdAt,
};
}
@@ -67,12 +68,17 @@ export async function authRoutes(app: FastifyInstance): Promise<void> {
const userId = generateSnowflake();
const now = Date.now();
// First registered user becomes instance admin
const userCount = db.select().from(schema.users).all().length;
const isFirstUser = userCount === 0;
db.insert(schema.users).values({
id: userId,
username: trimmedUsername,
displayName: displayName?.trim() || null,
passwordHash,
status: 'online',
isAdmin: isFirstUser ? 1 : 0,
createdAt: now,
}).run();