Added a weird little chat for shits and giggles
This commit is contained in:
85
routes/api/chat.ts
Normal file
85
routes/api/chat.ts
Normal file
@ -0,0 +1,85 @@
|
||||
import { FreshContext } from "$fresh/server.ts";
|
||||
|
||||
const chatConnections = new Set<WebSocket>();
|
||||
|
||||
// HTML sanitization
|
||||
function sanitizeText(text: string): string {
|
||||
return text
|
||||
.replace(/&/g, "&")
|
||||
.replace(/</g, "<")
|
||||
.replace(/>/g, ">")
|
||||
.replace(/"/g, """)
|
||||
.replace(/'/g, "'");
|
||||
}
|
||||
|
||||
// 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;
|
||||
};
|
Reference in New Issue
Block a user