Files

71 lines
2.4 KiB
TypeScript

import { env } from 'cloudflare:workers';
import { requestOrigin } from '@/lib/request-origin';
import { RoomEntryError } from '@/db/rooms';
import { authenticateSelectedSeat } from '@/lib/selected-seat';
import { readTableTalk, sendTableTalk, TableTalkError } from '@/db/table-talk';
import { RuleError } from '@/game/engine';
const noStore = { 'Cache-Control': 'no-store' };
async function handle(req: Request, write: boolean) {
try {
const url = new URL(req.url);
if (
write &&
req.headers.get('origin') &&
req.headers.get('origin') !== requestOrigin(req, env.DUNE_PUBLIC_ORIGIN)
)
throw new TableTalkError('Invalid request origin.', 403);
const code = url.pathname.split('/').at(-2)!.toUpperCase();
if (!/^[A-Z2-9]{8}$/.test(code))
throw new TableTalkError('Invalid room code.', 400);
const auth = await authenticateSelectedSeat(req, code);
if (write) {
const raw = await req.text();
if (raw.length > 6500)
throw new TableTalkError('Request too large.', 413);
return Response.json(await sendTableTalk(code, auth, JSON.parse(raw)), {
headers: noStore,
});
}
if (
[...url.searchParams.keys()].some(
(key) => !['recipient', 'before'].includes(key),
)
)
throw new TableTalkError('Invalid conversation request.', 400);
return Response.json(
await readTableTalk(
code,
auth,
url.searchParams.get('recipient'),
url.searchParams.get('before'),
),
{ headers: noStore },
);
} catch (error) {
return Response.json(
{
...((error instanceof TableTalkError || error instanceof RoomEntryError) && error.code ? { code: error.code } : {}),
error:
error instanceof TableTalkError || error instanceof RuleError
? error.message
: error instanceof SyntaxError
? 'Invalid JSON.'
: 'Table discussion is temporarily unavailable.',
},
{
status:
(error instanceof TableTalkError || error instanceof RoomEntryError)
? error.status
: error instanceof RuleError
? 409
: error instanceof SyntaxError
? 400
: 500,
headers: noStore,
},
);
}
}
export const GET = (req: Request) => handle(req, false);
export const POST = (req: Request) => handle(req, true);