Skip to content

Commit

Permalink
format
Browse files Browse the repository at this point in the history
  • Loading branch information
kern committed Dec 31, 2024
1 parent 9e7d78c commit de881ae
Show file tree
Hide file tree
Showing 7 changed files with 103 additions and 64 deletions.
47 changes: 21 additions & 26 deletions src/app/api/ice/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,33 +5,28 @@ import { setTurnCredentials } from '../../../coturn'
const turnHost = process.env.TURN_HOST || '127.0.0.1'

export async function POST(): Promise<NextResponse> {
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,
},
],
})
}
6 changes: 3 additions & 3 deletions src/components/WebRTCProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,16 +32,16 @@ let globalPeer: Peer | null = null
async function getOrCreateGlobalPeer(): Promise<Peer> {
if (!globalPeer) {
const response = await fetch('/api/ice', {
method: 'POST'
method: 'POST',
})
const { iceServers } = await response.json()
console.log('[WebRTCProvider] ICE servers:', iceServers)

globalPeer = new Peer({
debug: 3,
config: {
iceServers
}
iceServers,
},
})
}

Expand Down
38 changes: 21 additions & 17 deletions src/coturn.ts
Original file line number Diff line number Diff line change
@@ -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<void> {
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)
}
5 changes: 4 additions & 1 deletion src/hooks/useDownloader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
23 changes: 18 additions & 5 deletions src/hooks/useUploaderChannel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
},
Expand All @@ -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()
Expand All @@ -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)
Expand Down
38 changes: 31 additions & 7 deletions src/hooks/useUploaderConnections.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,20 @@ export function useUploaderConnections(
const [connections, setConnections] = useState<Array<UploaderConnection>>([])

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({
Expand Down Expand Up @@ -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,
Expand All @@ -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,
}
Expand Down Expand Up @@ -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 = () => {
Expand All @@ -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,
Expand Down Expand Up @@ -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
Expand Down
10 changes: 5 additions & 5 deletions src/redisClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
if (!redisClient) {
redisClient = new Redis(process.env.REDIS_URL)
}
return redisClient
}

0 comments on commit de881ae

Please sign in to comment.