[APP-1784] Proper fix for Live Now status not showing (#9779)
* Be sure to validate if actor is allowed to be live on certain domain * Rename for clarity * Memoize
This commit is contained in:
@@ -55,7 +55,7 @@ function DialogInner({profile}: {profile: bsky.profile.AnyProfileView}) {
|
|||||||
const tick = useTickEveryMinute()
|
const tick = useTickEveryMinute()
|
||||||
const liveNowConfig = useLiveNowConfig()
|
const liveNowConfig = useLiveNowConfig()
|
||||||
const {formatted: allowedServices} = getLiveServiceNames(
|
const {formatted: allowedServices} = getLiveServiceNames(
|
||||||
liveNowConfig.allowedDomains,
|
liveNowConfig.currentAccountAllowedHosts,
|
||||||
)
|
)
|
||||||
|
|
||||||
const time = useCallback(
|
const time = useCallback(
|
||||||
|
|||||||
@@ -31,8 +31,10 @@ export function useLiveLinkMetaQuery(url: string | null) {
|
|||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
if (!url) return undefined
|
if (!url) return undefined
|
||||||
const urlp = new URL(url)
|
const urlp = new URL(url)
|
||||||
if (!liveNowConfig.allowedDomains.has(urlp.hostname)) {
|
if (!liveNowConfig.currentAccountAllowedHosts.has(urlp.hostname)) {
|
||||||
const {formatted} = getLiveServiceNames(liveNowConfig.allowedDomains)
|
const {formatted} = getLiveServiceNames(
|
||||||
|
liveNowConfig.currentAccountAllowedHosts,
|
||||||
|
)
|
||||||
throw new Error(
|
throw new Error(
|
||||||
_(
|
_(
|
||||||
msg`This service is not supported while the Live feature is in beta. Allowed services: ${formatted}.`,
|
msg`This service is not supported while the Live feature is in beta. Allowed services: ${formatted}.`,
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import {
|
|||||||
type $Typed,
|
type $Typed,
|
||||||
type AppBskyActorDefs,
|
type AppBskyActorDefs,
|
||||||
AppBskyEmbedExternal,
|
AppBskyEmbedExternal,
|
||||||
|
AtUri,
|
||||||
} from '@atproto/api'
|
} from '@atproto/api'
|
||||||
import {isAfter, parseISO} from 'date-fns'
|
import {isAfter, parseISO} from 'date-fns'
|
||||||
|
|
||||||
@@ -73,10 +74,15 @@ export function isStatusValidForViewers(
|
|||||||
config: LiveNowConfig,
|
config: LiveNowConfig,
|
||||||
) {
|
) {
|
||||||
if (status.status !== 'app.bsky.actor.status#live') return false
|
if (status.status !== 'app.bsky.actor.status#live') return false
|
||||||
|
if (!status.uri) return false // should not happen, just backwards compat
|
||||||
try {
|
try {
|
||||||
|
const {host: liveDid} = new AtUri(status.uri)
|
||||||
if (AppBskyEmbedExternal.isView(status.embed)) {
|
if (AppBskyEmbedExternal.isView(status.embed)) {
|
||||||
const url = new URL(status.embed.external.uri)
|
const url = new URL(status.embed.external.uri)
|
||||||
return config.allSupportedDomains.has(url.hostname)
|
const exception = config.allowedHostsExceptionsByDid.get(liveDid)
|
||||||
|
const isValidException = exception ? exception.has(url.hostname) : false
|
||||||
|
const isValidForAnyone = config.defaultAllowedHosts.has(url.hostname)
|
||||||
|
return isValidException || isValidForAnyone
|
||||||
} else {
|
} else {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -89,29 +89,38 @@ const DEFAULT_LIVE_ALLOWED_DOMAINS = [
|
|||||||
'www.bluecast.app',
|
'www.bluecast.app',
|
||||||
]
|
]
|
||||||
export type LiveNowConfig = {
|
export type LiveNowConfig = {
|
||||||
allowedDomains: Set<string>
|
currentAccountAllowedHosts: Set<string>
|
||||||
allSupportedDomains: Set<string>
|
defaultAllowedHosts: Set<string>
|
||||||
|
allowedHostsExceptionsByDid: Map<string, Set<string>>
|
||||||
}
|
}
|
||||||
export function useLiveNowConfig(): LiveNowConfig {
|
export function useLiveNowConfig(): LiveNowConfig {
|
||||||
const ctx = useContext(LiveNowContext)
|
const ctx = useContext(LiveNowContext)
|
||||||
const canGoLive = useCanGoLive()
|
const canGoLive = useCanGoLive()
|
||||||
const {currentAccount} = useSession()
|
const {currentAccount} = useSession()
|
||||||
const allVipDomains = new Set(ctx.flatMap(live => live.domains))
|
return useMemo(() => {
|
||||||
const allSupportedDomains = new Set(
|
const defaultAllowedHosts = new Set(DEFAULT_LIVE_ALLOWED_DOMAINS)
|
||||||
DEFAULT_LIVE_ALLOWED_DOMAINS.concat(Array.from(allVipDomains)),
|
const allowedHostsExceptionsByDid = new Map<string, Set<string>>()
|
||||||
)
|
for (const live of ctx) {
|
||||||
if (!currentAccount?.did || !canGoLive)
|
allowedHostsExceptionsByDid.set(
|
||||||
return {
|
live.did,
|
||||||
allowedDomains: new Set(),
|
new Set(DEFAULT_LIVE_ALLOWED_DOMAINS.concat(live.domains)),
|
||||||
allSupportedDomains,
|
)
|
||||||
}
|
}
|
||||||
const vip = ctx.find(live => live.did === currentAccount.did)
|
if (!currentAccount?.did || !canGoLive)
|
||||||
return {
|
return {
|
||||||
allowedDomains: new Set(
|
currentAccountAllowedHosts: new Set(),
|
||||||
DEFAULT_LIVE_ALLOWED_DOMAINS.concat(vip ? vip.domains : []),
|
defaultAllowedHosts,
|
||||||
),
|
allowedHostsExceptionsByDid,
|
||||||
allSupportedDomains,
|
}
|
||||||
}
|
const vip = ctx.find(live => live.did === currentAccount.did)
|
||||||
|
return {
|
||||||
|
currentAccountAllowedHosts: new Set(
|
||||||
|
DEFAULT_LIVE_ALLOWED_DOMAINS.concat(vip ? vip.domains : []),
|
||||||
|
),
|
||||||
|
defaultAllowedHosts,
|
||||||
|
allowedHostsExceptionsByDid,
|
||||||
|
}
|
||||||
|
}, [ctx, currentAccount, canGoLive])
|
||||||
}
|
}
|
||||||
|
|
||||||
export function useCanGoLive() {
|
export function useCanGoLive() {
|
||||||
|
|||||||
Reference in New Issue
Block a user