From fb5b007861a5111c572e223a97f278d6dbabb4f5 Mon Sep 17 00:00:00 2001 From: Chneemann Date: Sat, 5 Sep 2026 11:00:15 +0200 Subject: [PATCH] refactor(utils): export uuid regex and isValidUuid helper --- app/(app)/dm/[conversationId]/page.tsx | 11 ++--------- .../[serverId]/channels/[channelId]/page.tsx | 11 ++--------- app/api/dm/[conversationId]/route.ts | 7 ++----- app/api/dm/messages/[messageId]/route.ts | 13 +++---------- app/api/dm/route.ts | 11 ++--------- lib/utils.ts | 18 +++++++++++++++++- 6 files changed, 28 insertions(+), 43 deletions(-) diff --git a/app/(app)/dm/[conversationId]/page.tsx b/app/(app)/dm/[conversationId]/page.tsx index 4f740e3..59f36bb 100644 --- a/app/(app)/dm/[conversationId]/page.tsx +++ b/app/(app)/dm/[conversationId]/page.tsx @@ -12,14 +12,7 @@ import { AppHeader } from "@/components/layout/AppHeader"; import { ChatInput } from "@/components/chat/ChatInput"; import { ChatMessages } from "@/components/chat/ChatMessages"; import type { MessageWithMember } from "@/components/chat/ChatItem"; - -/** - * Regular expression to validate standard UUID v1-v5 formats. - * - * @type {RegExp} - */ -const UUID_REGEX = - /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i; +import { isValidUuid } from "@/lib/utils"; /** * Renders the direct message conversation page with header, message history, and input field. @@ -38,7 +31,7 @@ export default async function DirectMessagePage({ const { conversationId } = await params; // 1. Validation - if (!UUID_REGEX.test(conversationId)) { + if (!isValidUuid(conversationId)) { redirect("/"); } diff --git a/app/(app)/servers/[serverId]/channels/[channelId]/page.tsx b/app/(app)/servers/[serverId]/channels/[channelId]/page.tsx index 38b7569..8590c8b 100644 --- a/app/(app)/servers/[serverId]/channels/[channelId]/page.tsx +++ b/app/(app)/servers/[serverId]/channels/[channelId]/page.tsx @@ -11,14 +11,7 @@ import { ChatMessages } from "@/components/chat/ChatMessages"; import { getChannelById } from "@/lib/services/channel.service"; import { getChannelMessages } from "@/lib/services/message.service"; import { getServerById } from "@/lib/services/server.service"; - -/** - * Regular expression for validating UUID string formats. - * - * @type {RegExp} - */ -const UUID_REGEX = - /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i; +import { isValidUuid } from "@/lib/utils"; /** * Renders the channel chat view by validating parameters, checking user session, fetching channel data, and displaying headers, messages, and input controls. @@ -37,7 +30,7 @@ export default async function ChannelPage({ const { serverId, channelId } = await params; // 1. Check the UUID format for BOTH parameters - if (!UUID_REGEX.test(serverId) || !UUID_REGEX.test(channelId)) { + if (!isValidUuid(serverId) || !isValidUuid(channelId)) { redirect("/"); } diff --git a/app/api/dm/[conversationId]/route.ts b/app/api/dm/[conversationId]/route.ts index 30d8ed9..cf56145 100644 --- a/app/api/dm/[conversationId]/route.ts +++ b/app/api/dm/[conversationId]/route.ts @@ -6,13 +6,10 @@ import { auth } from "@/auth"; import { db } from "@/db"; import { conversations, directMessages } from "@/db/schema"; +import { isValidUuid } from "@/lib/utils"; import { and, eq, or } from "drizzle-orm"; import { NextResponse } from "next/server"; -/** Regular expression to validate UUID format for conversation IDs. */ -const UUID_REGEX = - /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i; - /** * Handles POST requests to send a new direct message in a conversation. * @@ -30,7 +27,7 @@ export async function POST( try { const { conversationId } = await params; - if (!UUID_REGEX.test(conversationId)) { + if (!isValidUuid(conversationId)) { return NextResponse.json( { error: "Invalid Conversation ID" }, { status: 400 }, diff --git a/app/api/dm/messages/[messageId]/route.ts b/app/api/dm/messages/[messageId]/route.ts index 8412303..64d8138 100644 --- a/app/api/dm/messages/[messageId]/route.ts +++ b/app/api/dm/messages/[messageId]/route.ts @@ -6,17 +6,10 @@ import { auth } from "@/auth"; import { db } from "@/db"; import { directMessages } from "@/db/schema"; +import { isValidUuid } from "@/lib/utils"; import { eq } from "drizzle-orm"; import { NextResponse } from "next/server"; -/** - * Regular expression for validating UUID version 1-5 strings. - * - * @constant {RegExp} - */ -const UUID_REGEX = - /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i; - /** * Handles PATCH requests to update the content of an existing direct message. * @@ -34,7 +27,7 @@ export async function PATCH( try { const { messageId } = await params; - if (!UUID_REGEX.test(messageId)) { + if (!isValidUuid(messageId)) { return NextResponse.json( { error: "Invalid Message ID" }, { status: 400 }, @@ -104,7 +97,7 @@ export async function DELETE( try { const { messageId } = await params; - if (!UUID_REGEX.test(messageId)) { + if (!isValidUuid(messageId)) { return NextResponse.json( { error: "Invalid Message ID" }, { status: 400 }, diff --git a/app/api/dm/route.ts b/app/api/dm/route.ts index aa385d9..8e271de 100644 --- a/app/api/dm/route.ts +++ b/app/api/dm/route.ts @@ -6,17 +6,10 @@ import { auth } from "@/auth"; import { db } from "@/db"; import { conversations } from "@/db/schema"; +import { isValidUuid } from "@/lib/utils"; import { and, eq, or } from "drizzle-orm"; import { NextResponse } from "next/server"; -/** - * Regular expression pattern for validating UUID format. - * - * @type {RegExp} - */ -const UUID_REGEX = - /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i; - /** * Handles HTTP POST requests to initiate or fetch a direct message conversation with a specified recipient. * @@ -36,7 +29,7 @@ export async function POST(req: Request) { if ( !recipientId || - !UUID_REGEX.test(recipientId) || + !isValidUuid(recipientId) || recipientId === session.user.id ) { return NextResponse.json( diff --git a/lib/utils.ts b/lib/utils.ts index bf91959..d8750a3 100644 --- a/lib/utils.ts +++ b/lib/utils.ts @@ -1,11 +1,27 @@ /** * @file lib/utils.ts - * @description Utility module providing helper functions for conditionally merging and combining Tailwind CSS classes. + * @description Utility module providing helper functions for classes and data validation. */ import { type ClassValue, clsx } from "clsx"; import { twMerge } from "tailwind-merge"; +/** + * Regex pattern to validate standard v1-v5 UUIDs. + */ +export const UUID_REGEX = + /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i; + +/** + * Checks whether a given string is a valid UUID. + * + * @param {string} id - The string to validate. + * @returns {boolean} True if valid UUID, false otherwise. + */ +export function isValidUuid(id: string): boolean { + return UUID_REGEX.test(id); +} + /** * Merges multiple class names or conditional class objects into a single string using clsx and tailwind-merge. * Resolves Tailwind CSS class conflicts intelligently.