feat: polling API, HMAC webhook signing, session-only keys, prod audio fix
- Add polling API (GET/POST /api/fights/poll) so bots don't need public URLs - Add HMAC-SHA256 webhook signing (X-Botfights-Signature header) - Stop auto-persisting nsec keys — session-only by default with opt-in "Remember on this device" - Fix production TTS: add wav/mp3/ogg MIME types, /audio/* route, SPA blocklist - Overhaul docs: mode selector (poll vs webhook), AI-first bot examples, security tab - Fix duplicate sign-in buttons, login flow bugs Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
150ce7447d
commit
95ed80335a
+6
-1
@@ -122,6 +122,9 @@ if (process.env.NODE_ENV === 'production' && existsSync(publicDir)) {
|
||||
woff2: 'font/woff2',
|
||||
webp: 'image/webp',
|
||||
webmanifest: 'application/manifest+json',
|
||||
wav: 'audio/wav',
|
||||
mp3: 'audio/mpeg',
|
||||
ogg: 'audio/ogg',
|
||||
}
|
||||
|
||||
function serveFile(c: Context, reqPath: string, cacheControl: string) {
|
||||
@@ -160,12 +163,14 @@ if (process.env.NODE_ENV === 'production' && existsSync(publicDir)) {
|
||||
app.get('/icon.svg', (c) => serveFile(c, '/icon.svg', 'public, max-age=86400'))
|
||||
app.get('/apple-touch-icon.png', (c) => serveFile(c, '/apple-touch-icon.png', 'public, max-age=86400'))
|
||||
|
||||
// Audio files (pre-generated TTS, SFX)
|
||||
app.get('/audio/*', (c) => serveFile(c, c.req.path, 'public, max-age=86400'))
|
||||
// SPA fallback: only for navigation requests (not JS/CSS/asset files)
|
||||
app.get('*', (c) => {
|
||||
if (c.req.path.startsWith('/api/')) return c.notFound()
|
||||
// Don't serve index.html for asset requests — return 404 so the browser gets a proper error
|
||||
const ext = c.req.path.split('.').pop()
|
||||
if (ext && ext !== c.req.path && ['js', 'css', 'map', 'json', 'png', 'jpg', 'svg', 'woff', 'woff2', 'webp', 'ico'].includes(ext)) {
|
||||
if (ext && ext !== c.req.path && ['js', 'css', 'map', 'json', 'png', 'jpg', 'svg', 'woff', 'woff2', 'webp', 'ico', 'wav', 'mp3', 'ogg'].includes(ext)) {
|
||||
return c.notFound()
|
||||
}
|
||||
const indexPath = join(publicDir, 'index.html')
|
||||
|
||||
Reference in New Issue
Block a user