All checks were successful
Docker Deploy / build-and-push (push) Successful in 5m9s
85 lines
2.1 KiB
TypeScript
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, "&")
|
|
.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;
|
|
};
|