Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 31 additions & 5 deletions packages/workflow-renderer/src/note/note-block-view.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,34 @@ function getTwitchParent(): string {
return typeof window !== 'undefined' ? window.location.hostname : 'localhost'
}

/** Parse a URL, tolerating scheme-less inputs (https is assumed). Returns null if unparseable. */
function parseUrl(url: string): URL | null {
for (const candidate of [url, `https://${url}`]) {
try {
return new URL(candidate)
} catch {}
}
return null
}

/**
* Resolve a Dropbox share link to a direct, embeddable video URL. Accepts only URLs
* whose host is `dropbox.com` or a `*.dropbox.com` subdomain (so attacker-controlled
* hosts like `dropbox.com.evil.com` are rejected), then rewrites the host to
* `dl.dropboxusercontent.com` so the file streams as media. Returns null for any
* non-Dropbox host or non-video path.
*/
function getDropboxDirectVideoUrl(url: string): string | null {
const parsed = parseUrl(url)
if (!parsed) return null
const host = parsed.hostname.toLowerCase()
if (host !== 'dropbox.com' && !host.endsWith('.dropbox.com')) return null
if (!/\.(mp4|mov|webm)$/i.test(parsed.pathname)) return null
parsed.hostname = 'dl.dropboxusercontent.com'
parsed.searchParams.delete('dl')
return parsed.toString()
}

/**
* Get embed info for supported media platforms
*/
Expand Down Expand Up @@ -250,11 +278,9 @@ function getEmbedInfo(url: string): EmbedInfo | null {
return { url: `https://drive.google.com/file/d/${googleDriveMatch[1]}/preview`, type: 'iframe' }
}

if (url.includes('dropbox.com') && /\.(mp4|mov|webm)/.test(url)) {
const directUrl = url
.replace('www.dropbox.com', 'dl.dropboxusercontent.com')
.replace('?dl=0', '')
return { url: directUrl, type: 'video' }
const dropboxDirectVideoUrl = getDropboxDirectVideoUrl(url)
if (dropboxDirectVideoUrl) {
return { url: dropboxDirectVideoUrl, type: 'video' }
}

const tenorMatch = url.match(/tenor\.com\/view\/[^/]+-(\d+)/)
Expand Down
Loading