Files
us.proxy.sune.chat/index.js

70 lines
2.0 KiB
JavaScript

import { addSocket, removeSocket, handleMessage, handlePoll } from './run.js'
const PORT = +(process.env.PORT || 8080)
const ALLOWED_ORIGINS = ['sune.planetrenox.com', 'sune.chat']
const isAllowed = origin => {
if (!origin) return false
try {
const h = new URL(origin).hostname
return ALLOWED_ORIGINS.some(a => h === a || h.endsWith('.github.io'))
} catch { return false }
}
const CORS = {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'GET, OPTIONS',
'Access-Control-Allow-Headers': 'Content-Type, Authorization',
'Access-Control-Max-Age': '86400',
}
const json = (data, status = 200) => new Response(JSON.stringify(data), {
status,
headers: { 'Content-Type': 'application/json', 'Cache-Control': 'no-store', ...CORS },
})
Bun.serve({
port: PORT,
fetch(req, server) {
const url = new URL(req.url)
const method = req.method.toUpperCase()
if (method === 'OPTIONS') return new Response(null, { status: 204, headers: CORS })
const origin = req.headers.get('Origin')
if (origin && !isAllowed(origin)) return json({ error: 'Forbidden' }, 403)
if (url.pathname !== '/ws') return json({ error: 'not found' }, 404)
const uid = (url.searchParams.get('uid') || '').slice(0, 64).replace(/[^a-zA-Z0-9_-]/g, '')
if (!uid) return json({ error: 'uid is required' }, 400)
if (server.upgrade(req, { data: { uid } })) return
if (method === 'GET') return json(handlePoll(uid))
return json({ error: 'method not allowed' }, 405)
},
websocket: {
open(ws) {
const { uid } = ws.data
addSocket(uid, ws)
},
message(ws, raw) {
const { uid } = ws.data
let msg
try { msg = JSON.parse(String(raw)) }
catch { try { ws.send(JSON.stringify({ type: 'err', message: 'bad_json' })) } catch {}; return }
handleMessage(uid, ws, msg)
},
close(ws) {
const { uid } = ws.data
removeSocket(uid, ws)
},
},
})
console.log(`🟢 us.proxy.sune.chat running on :${PORT}`)