From ece75cf2dff2cc194e6b4e900b20dfe0451f1197 Mon Sep 17 00:00:00 2001 From: Decobus Date: Sun, 20 Jul 2025 16:11:11 -0400 Subject: [PATCH] Auto-generate OBS source names and improve stream list UI MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Remove manual OBS source name input from Add Stream form - Auto-generate OBS source names using pattern: streamName_twitch - Update security validation to exclude obs_source_name requirement - Increase stream avatar size from 32px to 64px for better visibility - Fix spacing issues between UI elements using explicit margins 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- app/api/addStream/route.ts | 12 ++++++++-- app/streams/page.tsx | 45 ++++++++++++-------------------------- lib/security.ts | 7 ------ 3 files changed, 24 insertions(+), 40 deletions(-) diff --git a/app/api/addStream/route.ts b/app/api/addStream/route.ts index 750962e..20961df 100644 --- a/app/api/addStream/route.ts +++ b/app/api/addStream/route.ts @@ -63,8 +63,13 @@ async function fetchTeamInfo(teamId: number) { import { validateStreamInput } from '../../../lib/security'; +// Generate OBS source name from stream name +function generateOBSSourceName(streamName: string): string { + return streamName.toLowerCase().replace(/\s+/g, '_') + '_twitch'; +} + export async function POST(request: NextRequest) { - let name: string, obs_source_name: string, url: string, team_id: number; + let name: string, url: string, team_id: number, obs_source_name: string; // Parse and validate request body try { @@ -78,7 +83,10 @@ export async function POST(request: NextRequest) { }, { status: 400 }); } - ({ name, obs_source_name, url, team_id } = validation.data!); + ({ name, url, team_id } = validation.data!); + + // Auto-generate OBS source name from stream name + obs_source_name = generateOBSSourceName(name); } catch { return NextResponse.json({ error: 'Invalid JSON in request body' }, { status: 400 }); diff --git a/app/streams/page.tsx b/app/streams/page.tsx index 75aa281..d24851b 100644 --- a/app/streams/page.tsx +++ b/app/streams/page.tsx @@ -17,7 +17,6 @@ interface Stream { export default function AddStream() { const [formData, setFormData] = useState({ name: '', - obs_source_name: '', twitch_username: '', team_id: null, }); @@ -125,9 +124,6 @@ export default function AddStream() { errors.name = 'Stream name must be at least 2 characters'; } - if (!formData.obs_source_name.trim()) { - errors.obs_source_name = 'OBS source name is required'; - } if (!formData.twitch_username.trim()) { errors.twitch_username = 'Twitch username is required'; @@ -162,7 +158,7 @@ export default function AddStream() { const data = await response.json(); if (response.ok) { showSuccess('Stream Added', `"${formData.name}" has been added successfully`); - setFormData({ name: '', obs_source_name: '', twitch_username: '', team_id: null }); + setFormData({ name: '', twitch_username: '', team_id: null }); setValidationErrors({}); fetchData(); } else { @@ -214,28 +210,6 @@ export default function AddStream() { )} - {/* OBS Source Name */} -
- - - {validationErrors.obs_source_name && ( -
- {validationErrors.obs_source_name} -
- )} -
{/* Twitch Username */}
@@ -317,11 +291,19 @@ export default function AddStream() { return (
-
-
+
+
{stream.name.charAt(0).toUpperCase()}
-
+
{stream.name}
OBS: {stream.obs_source_name}
Team: {team?.name || 'Unknown'}
@@ -329,12 +311,13 @@ export default function AddStream() {
ID: {stream.id}
-
+
diff --git a/lib/security.ts b/lib/security.ts index e38cecf..d5bc705 100644 --- a/lib/security.ts +++ b/lib/security.ts @@ -38,7 +38,6 @@ export function sanitizeString(input: string, maxLength: number = 100): string { // Validation schemas export interface StreamInput { name: string; - obs_source_name: string; url: string; team_id: number; } @@ -58,11 +57,6 @@ export function validateStreamInput(input: unknown): { valid: boolean; errors: s errors.push('Name must be 100 characters or less'); } - if (!data.obs_source_name || typeof data.obs_source_name !== 'string') { - errors.push('OBS source name is required and must be a string'); - } else if (data.obs_source_name.length > 100) { - errors.push('OBS source name must be 100 characters or less'); - } if (!data.url || typeof data.url !== 'string') { errors.push('URL is required and must be a string'); @@ -83,7 +77,6 @@ export function validateStreamInput(input: unknown): { valid: boolean; errors: s errors: [], data: { name: sanitizeString(data.name as string), - obs_source_name: sanitizeString(data.obs_source_name as string), url: data.url as string, team_id: data.team_id as number, },