atri.dad/routes/api/chat.ts
Atridad Lahiji 871000c333
All checks were successful
Docker Deploy / build-and-push (push) Successful in 5m9s
Added a weird little chat for shits and giggles
2025-04-26 01:34:49 -06:00

85 lines
2.1 KiB
TypeScript

import { FreshContext } from "$fresh/server.ts";
const chatConnections = new Set<WebSocket>();
// HTML sanitization
function sanitizeText(text: string): string {
return text
.replace(/&/g, "&amp;")
.replace(/</g, "&lt;")
.replace(/>/g, "&gt;")
.replace(/"/g, "&quot;")
.replace(/'/g, "&#039;");
}
// Process and sanitize message object
function processChatMessage(message: string): string {
try {
const parsed = JSON.parse(message);
if (typeof parsed.text === "string") {
parsed.text = sanitizeText(parsed.text.trim().slice(0, 2000));
}
if (typeof parsed.sender === "string") {
parsed.sender = sanitizeText(parsed.sender.trim().slice(0, 50));
}
if (!parsed.timestamp) {
parsed.timestamp = new Date().toISOString();
}
return JSON.stringify(parsed);
} catch (error) {
console.error("Invalid message format:", error);
return JSON.stringify({
text: "Error: Invalid message format",
sender: "System",
timestamp: new Date().toISOString(),
});
}
}
// Broadcast current user count to all clients
function broadcastUserCount() {
const count = chatConnections.size;
const message = JSON.stringify({
type: "user_count",
count: count,
});
for (const client of chatConnections) {
if (client.readyState === WebSocket.OPEN) {
client.send(message);
}
}
}
export const handler = (req: Request, _ctx: FreshContext): Response => {
const { socket, response } = Deno.upgradeWebSocket(req);
socket.onopen = () => {
chatConnections.add(socket);
console.log(`New connection: ${chatConnections.size} users connected`);
broadcastUserCount();
};
// Handle messages
socket.onmessage = (event) => {
const sanitizedMessage = processChatMessage(event.data);
for (const client of chatConnections) {
if (client.readyState === WebSocket.OPEN) {
client.send(sanitizedMessage);
}
}
};
socket.onclose = () => {
chatConnections.delete(socket);
console.log(`Connection closed: ${chatConnections.size} users connected`);
broadcastUserCount();
};
return response;
};