about summary refs log tree commit diff
path: root/src/lib
diff options
context:
space:
mode:
authorSamuel Newman <mozzius@protonmail.com>2025-05-17 01:38:34 +0300
committerGitHub <noreply@github.com>2025-05-16 15:38:34 -0700
commit1cdbfc709235ed1933ba51403d941762f384690b (patch)
treef55aa9a16f05645bcc5c2d63839113725b1ca308 /src/lib
parent75ffb3d243a5415d173f2bca8a5334b70451a1f4 (diff)
downloadvoidsky-1cdbfc709235ed1933ba51403d941762f384690b.tar.zst
Live via service config (#8378)
* add config (with temp config)

* only allow whitelisted domains in form

* move config to generic config

* use array-based config

* update deps

* rm expect-error
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/actor-status.ts33
1 files changed, 28 insertions, 5 deletions
diff --git a/src/lib/actor-status.ts b/src/lib/actor-status.ts
index 30921a88a..7e023be44 100644
--- a/src/lib/actor-status.ts
+++ b/src/lib/actor-status.ts
@@ -2,27 +2,28 @@ import {useMemo} from 'react'
 import {
   type $Typed,
   type AppBskyActorDefs,
-  type AppBskyEmbedExternal,
+  AppBskyEmbedExternal,
 } from '@atproto/api'
 import {isAfter, parseISO} from 'date-fns'
 
 import {useMaybeProfileShadow} from '#/state/cache/profile-shadow'
+import {useLiveNowConfig} from '#/state/service-config'
 import {useTickEveryMinute} from '#/state/shell'
-import {temp__canBeLive, temp__isStatusValid} from '#/components/live/temp'
 import type * as bsky from '#/types/bsky'
 
 export function useActorStatus(actor?: bsky.profile.AnyProfileView) {
   const shadowed = useMaybeProfileShadow(actor)
   const tick = useTickEveryMinute()
+  const config = useLiveNowConfig()
+
   return useMemo(() => {
     tick! // revalidate every minute
 
     if (
       shadowed &&
-      temp__canBeLive(shadowed) &&
       'status' in shadowed &&
       shadowed.status &&
-      temp__isStatusValid(shadowed.status) &&
+      validateStatus(shadowed.did, shadowed.status, config) &&
       isStatusStillActive(shadowed.status.expiresAt)
     ) {
       return {
@@ -39,7 +40,7 @@ export function useActorStatus(actor?: bsky.profile.AnyProfileView) {
         record: {},
       } satisfies AppBskyActorDefs.StatusView
     }
-  }, [shadowed, tick])
+  }, [shadowed, config, tick])
 }
 
 export function isStatusStillActive(timeStr: string | undefined) {
@@ -49,3 +50,25 @@ export function isStatusStillActive(timeStr: string | undefined) {
 
   return isAfter(expiry, now)
 }
+
+export function validateStatus(
+  did: string,
+  status: AppBskyActorDefs.StatusView,
+  config: {did: string; domains: string[]}[],
+) {
+  if (status.status !== 'app.bsky.actor.status#live') return false
+  const sources = config.find(cfg => cfg.did === did)
+  if (!sources) {
+    return false
+  }
+  try {
+    if (AppBskyEmbedExternal.isView(status.embed)) {
+      const url = new URL(status.embed.external.uri)
+      return sources.domains.includes(url.hostname)
+    } else {
+      return false
+    }
+  } catch {
+    return false
+  }
+}