38 lines
1.5 KiB
TypeScript
38 lines
1.5 KiB
TypeScript
import { NextRequest, NextResponse } from "next/server";
|
|
import config from "@payload-config";
|
|
import { getPayload } from "payload";
|
|
import { removePresence, touchPresence } from "@/lib/realtime/presence";
|
|
|
|
export const dynamic = "force-dynamic";
|
|
export const runtime = "nodejs";
|
|
|
|
async function authenticate(req: NextRequest) {
|
|
const payload = await getPayload({ config: await config });
|
|
return payload.auth({ headers: req.headers, canSetHeaders: false });
|
|
}
|
|
|
|
function channelFrom(req: NextRequest): string | null {
|
|
const channel = req.nextUrl.searchParams.get("channel")?.trim();
|
|
return channel && /^[a-z0-9:_-]{1,80}$/i.test(channel) ? channel : null;
|
|
}
|
|
|
|
export async function POST(req: NextRequest) {
|
|
const channel = channelFrom(req);
|
|
if (!channel) return NextResponse.json({ ok: false, error: "Invalid channel." }, { status: 400 });
|
|
const { user } = await authenticate(req);
|
|
if (!user) return NextResponse.json({ ok: false }, { status: 401 });
|
|
touchPresence(channel, {
|
|
id: user.id as number,
|
|
name: user.payloadDisplayName || user.username || `Pilot #${user.id}`,
|
|
});
|
|
return NextResponse.json({ ok: true });
|
|
}
|
|
|
|
export async function DELETE(req: NextRequest) {
|
|
const channel = channelFrom(req);
|
|
if (!channel) return NextResponse.json({ ok: false, error: "Invalid channel." }, { status: 400 });
|
|
const { user } = await authenticate(req);
|
|
if (!user) return NextResponse.json({ ok: false }, { status: 401 });
|
|
removePresence(channel, user.id as number);
|
|
return NextResponse.json({ ok: true });
|
|
}
|