From de881ae4fb268efe63453bc916d67b68755939e2 Mon Sep 17 00:00:00 2001 From: Alex Kern Date: Mon, 30 Dec 2024 21:34:53 -0800 Subject: [PATCH] format --- src/app/api/ice/route.ts | 47 +++++++++++++---------------- src/components/WebRTCProvider.tsx | 6 ++-- src/coturn.ts | 38 ++++++++++++----------- src/hooks/useDownloader.ts | 5 ++- src/hooks/useUploaderChannel.ts | 23 +++++++++++--- src/hooks/useUploaderConnections.ts | 38 ++++++++++++++++++----- src/redisClient.ts | 10 +++--- 7 files changed, 103 insertions(+), 64 deletions(-) diff --git a/src/app/api/ice/route.ts b/src/app/api/ice/route.ts index 41e9e99..8dedc1c 100644 --- a/src/app/api/ice/route.ts +++ b/src/app/api/ice/route.ts @@ -5,33 +5,28 @@ import { setTurnCredentials } from '../../../coturn' const turnHost = process.env.TURN_HOST || '127.0.0.1' export async function POST(): Promise { - if (!process.env.COTURN_ENABLED) { - return NextResponse.json({ - iceServers: [ - { urls: 'stun:stun.l.google.com:19302' } - ] - }) - } + if (!process.env.COTURN_ENABLED) { + return NextResponse.json({ + iceServers: [{ urls: 'stun:stun.l.google.com:19302' }], + }) + } - // Generate ephemeral credentials - const username = crypto.randomBytes(8).toString('hex') - const password = crypto.randomBytes(8).toString('hex') - const ttl = 86400 // 24 hours + // Generate ephemeral credentials + const username = crypto.randomBytes(8).toString('hex') + const password = crypto.randomBytes(8).toString('hex') + const ttl = 86400 // 24 hours - // Store credentials in Redis - await setTurnCredentials(username, password, ttl) + // Store credentials in Redis + await setTurnCredentials(username, password, ttl) - return NextResponse.json({ - iceServers: [ - { urls: 'stun:stun.l.google.com:19302' }, - { - urls: [ - `turn:${turnHost}:3478`, - `turns:${turnHost}:5349` - ], - username, - credential: password - } - ] - }) + return NextResponse.json({ + iceServers: [ + { urls: 'stun:stun.l.google.com:19302' }, + { + urls: [`turn:${turnHost}:3478`, `turns:${turnHost}:5349`], + username, + credential: password, + }, + ], + }) } diff --git a/src/components/WebRTCProvider.tsx b/src/components/WebRTCProvider.tsx index 64b8637..7a52bf8 100644 --- a/src/components/WebRTCProvider.tsx +++ b/src/components/WebRTCProvider.tsx @@ -32,7 +32,7 @@ let globalPeer: Peer | null = null async function getOrCreateGlobalPeer(): Promise { if (!globalPeer) { const response = await fetch('/api/ice', { - method: 'POST' + method: 'POST', }) const { iceServers } = await response.json() console.log('[WebRTCProvider] ICE servers:', iceServers) @@ -40,8 +40,8 @@ async function getOrCreateGlobalPeer(): Promise { globalPeer = new Peer({ debug: 3, config: { - iceServers - } + iceServers, + }, }) } diff --git a/src/coturn.ts b/src/coturn.ts index 3b89452..7b56e4b 100644 --- a/src/coturn.ts +++ b/src/coturn.ts @@ -1,30 +1,34 @@ import crypto from 'crypto' import { getRedisClient } from './redisClient' -function generateHMACKey(username: string, realm: string, password: string): string { - const str = `${username}:${realm}:${password}` - return crypto.createHash('md5').update(str).digest('hex') +function generateHMACKey( + username: string, + realm: string, + password: string, +): string { + const str = `${username}:${realm}:${password}` + return crypto.createHash('md5').update(str).digest('hex') } export async function setTurnCredentials( - username: string, - password: string, - ttl: number + username: string, + password: string, + ttl: number, ): Promise { - if (!process.env.COTURN_ENABLED) { - return - } + if (!process.env.COTURN_ENABLED) { + return + } - const realm = process.env.TURN_REALM || 'file.pizza' + const realm = process.env.TURN_REALM || 'file.pizza' - if (!realm) { - throw new Error('TURN_REALM environment variable not set') - } + if (!realm) { + throw new Error('TURN_REALM environment variable not set') + } - const redis = getRedisClient() + const redis = getRedisClient() - const hmacKey = generateHMACKey(username, realm, password) - const key = `turn/realm/${realm}/user/${username}/key` + const hmacKey = generateHMACKey(username, realm, password) + const key = `turn/realm/${realm}/user/${username}/key` - await redis.setex(key, ttl, hmacKey) + await redis.setex(key, ttl, hmacKey) } diff --git a/src/hooks/useDownloader.ts b/src/hooks/useDownloader.ts index 6deae44..900447c 100644 --- a/src/hooks/useDownloader.ts +++ b/src/hooks/useDownloader.ts @@ -188,7 +188,10 @@ export function useDownloader(uploaderPeerID: string): { let nextFileIndex = 0 const startNextFileOrFinish = () => { if (nextFileIndex >= filesInfo.length) return - console.log('[Downloader] starting next file:', filesInfo[nextFileIndex].fileName) + console.log( + '[Downloader] starting next file:', + filesInfo[nextFileIndex].fileName, + ) dataConnection.send({ type: MessageType.Start, fileName: filesInfo[nextFileIndex].fileName, diff --git a/src/hooks/useUploaderChannel.ts b/src/hooks/useUploaderChannel.ts index 85603f4..dba7092 100644 --- a/src/hooks/useUploaderChannel.ts +++ b/src/hooks/useUploaderChannel.ts @@ -24,20 +24,26 @@ export function useUploaderChannel( const { isLoading, error, data } = useQuery({ queryKey: ['uploaderChannel', uploaderPeerID], queryFn: async () => { - console.log('[UploaderChannel] creating new channel for peer', uploaderPeerID) + console.log( + '[UploaderChannel] creating new channel for peer', + uploaderPeerID, + ) const response = await fetch('/api/create', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ uploaderPeerID }), }) if (!response.ok) { - console.error('[UploaderChannel] failed to create channel:', response.status) + console.error( + '[UploaderChannel] failed to create channel:', + response.status, + ) throw new Error('Network response was not ok') } const data = await response.json() console.log('[UploaderChannel] channel created successfully:', { longSlug: data.longSlug, - shortSlug: data.shortSlug + shortSlug: data.shortSlug, }) return data }, @@ -62,7 +68,10 @@ export function useUploaderChannel( body: JSON.stringify({ slug: shortSlug, secret: s }), }) if (!response.ok) { - console.error('[UploaderChannel] failed to renew channel', response.status) + console.error( + '[UploaderChannel] failed to renew channel', + response.status, + ) throw new Error('Network response was not ok') } const data = await response.json() @@ -78,7 +87,11 @@ export function useUploaderChannel( const run = (): void => { timeout = setTimeout(() => { - console.log('[UploaderChannel] scheduling channel renewal in', renewInterval, 'ms') + console.log( + '[UploaderChannel] scheduling channel renewal in', + renewInterval, + 'ms', + ) renewMutation.mutate({ secret }) run() }, renewInterval) diff --git a/src/hooks/useUploaderConnections.ts b/src/hooks/useUploaderConnections.ts index 0f1c8bc..f23d7ed 100644 --- a/src/hooks/useUploaderConnections.ts +++ b/src/hooks/useUploaderConnections.ts @@ -34,14 +34,20 @@ export function useUploaderConnections( const [connections, setConnections] = useState>([]) useEffect(() => { - console.log('[UploaderConnections] initializing with', files.length, 'files') + console.log( + '[UploaderConnections] initializing with', + files.length, + 'files', + ) const cleanupHandlers: Array<() => void> = [] const listener = (conn: DataConnection) => { console.log('[UploaderConnections] new connection from peer', conn.peer) // If the connection is a report, we need to hard-redirect the uploader to the reported page to prevent them from uploading more files. if (conn.metadata?.type === 'report') { - console.log('[UploaderConnections] received report connection, redirecting') + console.log( + '[UploaderConnections] received report connection, redirecting', + ) // Broadcast report message to all connections connections.forEach((c) => { c.dataConnection.send({ @@ -85,7 +91,9 @@ export function useUploaderConnections( console.log('[UploaderConnections] client info:', { browser: `${message.browserName} ${message.browserVersion}`, os: `${message.osName} ${message.osVersion}`, - mobile: message.mobileVendor ? `${message.mobileVendor} ${message.mobileModel}` : 'N/A' + mobile: message.mobileVendor + ? `${message.mobileVendor} ${message.mobileModel}` + : 'N/A', }) const newConnectionState = { browserName: message.browserName, @@ -97,7 +105,9 @@ export function useUploaderConnections( } if (password) { - console.log('[UploaderConnections] password required, requesting authentication') + console.log( + '[UploaderConnections] password required, requesting authentication', + ) const request: Message = { type: MessageType.PasswordRequired, } @@ -206,7 +216,12 @@ export function useUploaderConnections( case MessageType.Start: { const fileName = message.fileName let offset = message.offset - console.log('[UploaderConnections] starting transfer of', fileName, 'from offset', offset) + console.log( + '[UploaderConnections] starting transfer of', + fileName, + 'from offset', + offset, + ) const file = validateOffset(files, fileName, offset) const sendNextChunkAsync = () => { @@ -226,7 +241,14 @@ export function useUploaderConnections( updateConnection((draft) => { offset = end if (final) { - console.log('[UploaderConnections] completed file', fileName, '- file', draft.completedFiles + 1, 'of', draft.totalFiles) + console.log( + '[UploaderConnections] completed file', + fileName, + '- file', + draft.completedFiles + 1, + 'of', + draft.totalFiles, + ) return { ...draft, status: UploaderConnectionStatus.Ready, @@ -288,7 +310,9 @@ export function useUploaderConnections( } case MessageType.Done: { - console.log('[UploaderConnections] transfer completed successfully') + console.log( + '[UploaderConnections] transfer completed successfully', + ) updateConnection((draft) => { if (draft.status !== UploaderConnectionStatus.Ready) { return draft diff --git a/src/redisClient.ts b/src/redisClient.ts index ee7afcd..6bf3aaa 100644 --- a/src/redisClient.ts +++ b/src/redisClient.ts @@ -5,8 +5,8 @@ export { Redis } let redisClient: Redis.Redis | null = null export function getRedisClient(): Redis.Redis { - if (!redisClient) { - redisClient = new Redis(process.env.REDIS_URL) - } - return redisClient -} \ No newline at end of file + if (!redisClient) { + redisClient = new Redis(process.env.REDIS_URL) + } + return redisClient +}