| 331 | ) |
| 332 | |
| 333 | const generateSocketToken = async (): Promise<string> => { |
| 334 | // boundary-raw-fetch: pre-bootstrap one-time socket token mint — Better Auth's |
| 335 | // generateOneTimeToken handler (in INDIRECT_ZOD_ROUTES baseline) has no client |
| 336 | // contract; called from Socket.IO auth callback before any contract-bound client. |
| 337 | const res = await fetch('/api/auth/socket-token', { |
| 338 | method: 'POST', |
| 339 | credentials: 'include', |
| 340 | headers: { 'cache-control': 'no-store' }, |
| 341 | }) |
| 342 | if (!res.ok) { |
| 343 | if (res.status === 401) { |
| 344 | throw new Error('Authentication required') |
| 345 | } |
| 346 | throw new Error('Failed to generate socket token') |
| 347 | } |
| 348 | const body = await res.json().catch(() => ({})) |
| 349 | const token = body?.token |
| 350 | if (!token || typeof token !== 'string') throw new Error('Invalid socket token') |
| 351 | return token |
| 352 | } |
| 353 | |
| 354 | useEffect(() => { |
| 355 | if (!user?.id) return |