diff --git a/src/lib/strings/embed-player.ts b/src/lib/strings/embed-player.ts index f5e99a656..98272c6a3 100644 --- a/src/lib/strings/embed-player.ts +++ b/src/lib/strings/embed-player.ts @@ -1,5 +1,7 @@ import {Dimensions} from 'react-native' +import {isDid} from '@atproto/api' +import {isValidHandle} from '#/lib/strings/handles' import {IS_WEB, IS_WEB_SAFARI} from '#/env' const {height: SCREEN_HEIGHT} = Dimensions.get('window') @@ -11,7 +13,7 @@ const IFRAME_HOST = IS_WEB : 'https://witchsky.app' : __DEV__ && !process.env.JEST_WORKER_ID ? 'http://localhost:8100' - : 'https://witchsky.app' + : 'https://bsky.app' export const embedPlayerSources = [ 'youtube', @@ -464,14 +466,28 @@ export function parseEmbedPlayerFromUrl( } if (urlp.hostname === 'stream.place') { - return { - type: 'streamplace_stream', - source: 'streamplace', - playerUri: `https://stream.place/embed${urlp.pathname}`, + if (isValidStreamPlaceUrl(urlp)) { + return { + type: 'streamplace_stream', + source: 'streamplace', + playerUri: `https://stream.place/embed${urlp.pathname}`, + } } } } +function isValidStreamPlaceUrl(urlp: URL): boolean { + // stream.place URLs should have a path like /did:plc:xxx/... or /handle.bsky.social/... + const pathParts = urlp.pathname.split('/').filter(Boolean) + if (pathParts.length === 0) { + return false + } + + // The first part of the path should be either a valid DID or a valid handle + const identifier = pathParts[0] + return isDid(identifier) || isValidHandle(identifier) +} + export function getPlayerAspect({ type, hasThumb, diff --git a/src/lib/strings/handles.ts b/src/lib/strings/handles.ts index bdac50a56..ebe049e41 100644 --- a/src/lib/strings/handles.ts +++ b/src/lib/strings/handles.ts @@ -7,6 +7,10 @@ const VALIDATE_REGEX = export const MAX_SERVICE_HANDLE_LENGTH = 18 +export function isValidHandle(handle: string): boolean { + return VALIDATE_REGEX.test(handle) +} + export function makeValidHandle(str: string): string { if (str.length > 20) { str = str.slice(0, 20)