Sanitize URLs to compare just apex domain
This commit is contained in:
@@ -26,7 +26,7 @@ import {useTickEveryMinute} from '#/state/shell'
|
|||||||
import * as Toast from '#/view/com/util/Toast'
|
import * as Toast from '#/view/com/util/Toast'
|
||||||
import {useDialogContext} from '#/components/Dialog'
|
import {useDialogContext} from '#/components/Dialog'
|
||||||
import {useAnalytics} from '#/analytics'
|
import {useAnalytics} from '#/analytics'
|
||||||
import {getLiveServiceNames} from '#/features/liveNow/utils'
|
import {getLiveNowHost, getLiveServiceNames} from '#/features/liveNow/utils'
|
||||||
import type * as bsky from '#/types/bsky'
|
import type * as bsky from '#/types/bsky'
|
||||||
|
|
||||||
export * from '#/features/liveNow/utils'
|
export * from '#/features/liveNow/utils'
|
||||||
@@ -35,10 +35,6 @@ export const DEFAULT_ALLOWED_DOMAINS = [
|
|||||||
'twitch.tv',
|
'twitch.tv',
|
||||||
'stream.place',
|
'stream.place',
|
||||||
'bluecast.app',
|
'bluecast.app',
|
||||||
|
|
||||||
// TODO remove need for subdomains
|
|
||||||
'www.twitch.tv',
|
|
||||||
'www.bluecast.app',
|
|
||||||
]
|
]
|
||||||
|
|
||||||
export type LiveNowConfig = {
|
export type LiveNowConfig = {
|
||||||
@@ -153,10 +149,10 @@ export function isStatusValidForViewers(
|
|||||||
try {
|
try {
|
||||||
const {host: liveDid} = new AtUri(status.uri)
|
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 host = getLiveNowHost(status.embed.external.uri)
|
||||||
const exception = config.allowedHostsExceptionsByDid.get(liveDid)
|
const exception = config.allowedHostsExceptionsByDid.get(liveDid)
|
||||||
const isValidException = exception ? exception.has(url.hostname) : false
|
const isValidException = exception ? exception.has(host) : false
|
||||||
const isValidForAnyone = config.defaultAllowedHosts.has(url.hostname)
|
const isValidForAnyone = config.defaultAllowedHosts.has(host)
|
||||||
return isValidException || isValidForAnyone
|
return isValidException || isValidForAnyone
|
||||||
} else {
|
} else {
|
||||||
return false
|
return false
|
||||||
@@ -176,8 +172,8 @@ export function useLiveLinkMetaQuery(url: string | null) {
|
|||||||
queryKey: ['link-meta', url],
|
queryKey: ['link-meta', url],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
if (!url) return undefined
|
if (!url) return undefined
|
||||||
const urlp = new URL(url)
|
const host = getLiveNowHost(url)
|
||||||
if (!liveNowConfig.currentAccountAllowedHosts.has(urlp.hostname)) {
|
if (!liveNowConfig.currentAccountAllowedHosts.has(host)) {
|
||||||
const {formatted} = getLiveServiceNames(
|
const {formatted} = getLiveServiceNames(
|
||||||
liveNowConfig.currentAccountAllowedHosts,
|
liveNowConfig.currentAccountAllowedHosts,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import {type I18n} from '@lingui/core'
|
import {type I18n} from '@lingui/core'
|
||||||
import {plural} from '@lingui/macro'
|
import {plural} from '@lingui/macro'
|
||||||
|
import psl from 'psl'
|
||||||
|
|
||||||
export function displayDuration(i18n: I18n, durationInMinutes: number) {
|
export function displayDuration(i18n: I18n, durationInMinutes: number) {
|
||||||
const roundedDurationInMinutes = Math.round(durationInMinutes)
|
const roundedDurationInMinutes = Math.round(durationInMinutes)
|
||||||
@@ -25,27 +26,48 @@ export function displayDuration(i18n: I18n, durationInMinutes: number) {
|
|||||||
|
|
||||||
const serviceUrlToNameMap: Record<string, string> = {
|
const serviceUrlToNameMap: Record<string, string> = {
|
||||||
'twitch.tv': 'Twitch',
|
'twitch.tv': 'Twitch',
|
||||||
'www.twitch.tv': 'Twitch',
|
|
||||||
'youtube.com': 'YouTube',
|
'youtube.com': 'YouTube',
|
||||||
'www.youtube.com': 'YouTube',
|
|
||||||
'youtu.be': 'YouTube',
|
|
||||||
'nba.com': 'NBA',
|
'nba.com': 'NBA',
|
||||||
'www.nba.com': 'NBA',
|
|
||||||
'nba.smart.link': 'nba.smart.link',
|
'nba.smart.link': 'nba.smart.link',
|
||||||
'espn.com': 'ESPN',
|
'espn.com': 'ESPN',
|
||||||
'www.espn.com': 'ESPN',
|
|
||||||
'stream.place': 'Streamplace',
|
'stream.place': 'Streamplace',
|
||||||
'skylight.social': 'Skylight',
|
'skylight.social': 'Skylight',
|
||||||
'bluecast.app': 'Bluecast',
|
'bluecast.app': 'Bluecast',
|
||||||
'www.bluecast.app': 'Bluecast',
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getLiveServiceNames(domains: Set<string>) {
|
export function getLiveServiceNames(domains: Set<string>) {
|
||||||
|
console.log(domains)
|
||||||
const names = Array.from(
|
const names = Array.from(
|
||||||
new Set(Array.from(domains.values()).map(d => serviceUrlToNameMap[d] || d)),
|
new Set(
|
||||||
|
Array.from(domains.values())
|
||||||
|
.map(d => sanitizeLiveNowHost(d))
|
||||||
|
.map(d => serviceUrlToNameMap[d] || d),
|
||||||
|
),
|
||||||
)
|
)
|
||||||
return {
|
return {
|
||||||
names,
|
names,
|
||||||
formatted: names.join(', '),
|
formatted: names.join(', '),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function sanitizeLiveNowHost(hostname: string) {
|
||||||
|
// special case this one
|
||||||
|
if (hostname === 'nba.smart.link') {
|
||||||
|
return hostname
|
||||||
|
}
|
||||||
|
const parsed = psl.parse(hostname)
|
||||||
|
if (parsed.error || !parsed.listed || !parsed.domain) {
|
||||||
|
// fall back to dumb version
|
||||||
|
return hostname.replace(/^www\./, '')
|
||||||
|
}
|
||||||
|
return parsed.domain
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extracts the apex domain from a given URL, for use when matching allowed
|
||||||
|
* Live Now hosts.
|
||||||
|
*/
|
||||||
|
export function getLiveNowHost(url: string) {
|
||||||
|
const {hostname} = new URL(url)
|
||||||
|
return sanitizeLiveNowHost(hostname)
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user