From de681414c34e32464e046dbd609aa179049fe944 Mon Sep 17 00:00:00 2001 From: The-Best-Codes Date: Sat, 23 Nov 2024 19:49:39 -0600 Subject: [PATCH] Add message, username, and password max lengths --- index.ts | 36 ++++++++++++++++++++++++++---------- src/constants.ts | 15 +++++++++++++++ src/db/database.ts | 15 ++++++++++++++- 3 files changed, 55 insertions(+), 11 deletions(-) create mode 100644 src/constants.ts diff --git a/index.ts b/index.ts index d0315d0..5bb92a1 100644 --- a/index.ts +++ b/index.ts @@ -5,6 +5,7 @@ import { getRecentMessages, type User, } from "./src/db/database"; +import { LIMITS, validateInput } from "./src/constants"; import crypto from "crypto"; const port = process.env.PORT || 5177; @@ -205,16 +206,31 @@ const server: any = Bun.serve({ switch (data.type) { case "message": - const msg = await createMessage(user.id, data.content); - server.publish( - "chat", - JSON.stringify({ - type: "message", - username: user.username, - content: data.content, - timestamp: new Date().toISOString(), - }) - ); + try { + // Validate message content + const validatedContent = validateInput( + data.content, + LIMITS.MESSAGE_MAX_LENGTH + ); + const msg = await createMessage(user.id, validatedContent); + server.publish( + "chat", + JSON.stringify({ + type: "message", + username: user.username, + content: validatedContent, + timestamp: new Date().toISOString(), + }) + ); + } catch (error) { + // Send error back to the client + ws.send( + JSON.stringify({ + type: "error", + message: (error as Error)?.message || "Failed to send message", + }) + ); + } break; case "typing": diff --git a/src/constants.ts b/src/constants.ts new file mode 100644 index 0000000..726623c --- /dev/null +++ b/src/constants.ts @@ -0,0 +1,15 @@ +export const LIMITS = { + USERNAME_MAX_LENGTH: 50, + PASSWORD_MAX_LENGTH: 128, + MESSAGE_MAX_LENGTH: 2000, +} as const; + +export function validateInput(input: string, maxLength: number): string { + if (!input || typeof input !== "string") { + throw new Error("Invalid input"); + } + if (input.length > maxLength) { + throw new Error(`Input exceeds maximum length of ${maxLength} characters`); + } + return input.trim(); +} diff --git a/src/db/database.ts b/src/db/database.ts index b4bc067..217e686 100644 --- a/src/db/database.ts +++ b/src/db/database.ts @@ -1,8 +1,10 @@ import { Database } from "bun:sqlite"; import * as bcrypt from "bcryptjs"; +import { LIMITS, validateInput } from "../constants"; const DB_PATH = process.env.DB_PATH || `${process.cwd()}/chat.db`; -const SCHEMA_PATH = process.env.SCHEMA_PATH || `${process.cwd()}/src/db/schema.sql`; +const SCHEMA_PATH = + process.env.SCHEMA_PATH || `${process.cwd()}/src/db/schema.sql`; // Create database with proper path const db = new Database(DB_PATH); @@ -34,6 +36,10 @@ export const createUser = async ( username: string, password: string ): Promise => { + // Validate input lengths + username = validateInput(username, LIMITS.USERNAME_MAX_LENGTH); + password = validateInput(password, LIMITS.PASSWORD_MAX_LENGTH); + const hashedPassword = await bcrypt.hash(password, 10); try { const stmt = db.prepare( @@ -61,6 +67,10 @@ export const verifyUser = async ( username: string, password: string ): Promise => { + // Validate input lengths + username = validateInput(username, LIMITS.USERNAME_MAX_LENGTH); + password = validateInput(password, LIMITS.PASSWORD_MAX_LENGTH); + const stmt = db.prepare("SELECT * FROM users WHERE username = ?"); const row = stmt.get(username) as any; @@ -84,6 +94,9 @@ export const createMessage = async ( userId: number, content: string ): Promise => { + // Validate message length + content = validateInput(content, LIMITS.MESSAGE_MAX_LENGTH); + const stmt = db.prepare( "INSERT INTO messages (user_id, content) VALUES (?, ?)" );