moon cricket
This commit is contained in:
+31
-8
@@ -66,6 +66,7 @@ const siteGateEnabled = siteGateSetting == null
|
||||
const staticDataBase = (import.meta.env.VITE_STATIC_DATA_BASE || '/data').replace(/\/+$/, '')
|
||||
const staticDataEnabled = String(import.meta.env.VITE_STATIC_DATA || 'false').toLowerCase() === 'true'
|
||||
const missingStaticDataPaths = new Set()
|
||||
const turnstileRequiredEvent = 'tssbot:turnstile-required'
|
||||
|
||||
const BLOCKED_PLAYER_UIDS = new Set(['165569402', '86157459', '33536334', '41808996', '3651161'])
|
||||
const BLOCKED_TEAM_NAMES = new Set(['TPC'])
|
||||
@@ -135,6 +136,15 @@ function dataSource(apiPath, staticPath = null) {
|
||||
return { apiPath, staticPath }
|
||||
}
|
||||
|
||||
function turnstileSessionRequiredMessage(error) {
|
||||
return error === 'Turnstile session required' || error === 'Site session required'
|
||||
}
|
||||
|
||||
function promptTurnstileSession(detail) {
|
||||
if (typeof window === 'undefined' || !turnstileSiteKey) return
|
||||
window.dispatchEvent(new CustomEvent(turnstileRequiredEvent, { detail }))
|
||||
}
|
||||
|
||||
const publicDataSources = {
|
||||
teams: dataSource(apiEndpoints.teams, staticDataPath('leaderboard-teams.json')),
|
||||
players: dataSource(apiEndpoints.players, staticDataPath('leaderboard-players.json')),
|
||||
@@ -161,6 +171,10 @@ async function fetchJson(path, signal) {
|
||||
const error = new Error(body?.error || `Request failed with ${response.status}`)
|
||||
error.status = response.status
|
||||
error.path = path
|
||||
error.detail = body?.detail
|
||||
if (response.status === 403 && turnstileSessionRequiredMessage(body?.error)) {
|
||||
promptTurnstileSession({ path, error: body?.error, detail: body?.detail })
|
||||
}
|
||||
throw error
|
||||
}
|
||||
|
||||
@@ -1307,10 +1321,10 @@ function SiteGate({ onVerified }) {
|
||||
>
|
||||
<div className="flex w-full max-w-sm flex-col items-center gap-4 rounded-md border border-border bg-fury-white p-6 text-center text-text shadow-[0_24px_70px_rgba(0,0,0,0.24)]">
|
||||
<h1 id="site-gate-title" className="text-lg font-semibold">
|
||||
Verifying you are human
|
||||
Start a protected session
|
||||
</h1>
|
||||
<p className="text-sm text-text-soft">
|
||||
This quick check protects the site from automated abuse. It usually clears itself.
|
||||
Complete this Turnstile check to continue using protected site data.
|
||||
</p>
|
||||
<TurnstileWidget
|
||||
siteKey={turnstileSiteKey}
|
||||
@@ -1330,15 +1344,15 @@ function SiteGate({ onVerified }) {
|
||||
}
|
||||
|
||||
function App() {
|
||||
if (!siteGateEnabled) return <AppContent />
|
||||
return <GatedAppContent />
|
||||
if (!turnstileSiteKey) return <AppContent />
|
||||
return <GatedAppContent enforceInitialGate={siteGateEnabled} />
|
||||
}
|
||||
|
||||
function GatedAppContent() {
|
||||
function GatedAppContent({ enforceInitialGate }) {
|
||||
const embeddedGateState = document
|
||||
.querySelector('meta[name="tss-turnstile-session"]')
|
||||
?.getAttribute('content')
|
||||
const initialGateState = turnstileSiteKey
|
||||
const initialGateState = enforceInitialGate
|
||||
? ['verified', 'required'].includes(embeddedGateState)
|
||||
? embeddedGateState
|
||||
: 'checking'
|
||||
@@ -1346,7 +1360,7 @@ function GatedAppContent() {
|
||||
const [gateState, setGateState] = useState(initialGateState)
|
||||
|
||||
useEffect(() => {
|
||||
if (!turnstileSiteKey || gateState !== 'checking') return undefined
|
||||
if (!enforceInitialGate || gateState !== 'checking') return undefined
|
||||
let cancelled = false
|
||||
fetch('/api/turnstile/session', { headers: { Accept: 'application/json' } })
|
||||
.then((response) => (response.ok ? response.json() : { verified: false }))
|
||||
@@ -1360,7 +1374,16 @@ function GatedAppContent() {
|
||||
return () => {
|
||||
cancelled = true
|
||||
}
|
||||
}, [gateState])
|
||||
}, [enforceInitialGate, gateState])
|
||||
|
||||
useEffect(() => {
|
||||
function handleTurnstileRequired() {
|
||||
setGateState('required')
|
||||
}
|
||||
|
||||
window.addEventListener(turnstileRequiredEvent, handleTurnstileRequired)
|
||||
return () => window.removeEventListener(turnstileRequiredEvent, handleTurnstileRequired)
|
||||
}, [])
|
||||
|
||||
if (gateState === 'checking') {
|
||||
return <div className="fixed inset-0 bg-bg" aria-hidden="true" />
|
||||
|
||||
Reference in New Issue
Block a user