Files
Kordant/web/src/server/api/validation.ts
2026-05-27 10:30:23 -04:00

52 lines
1.4 KiB
TypeScript

import { TRPCError } from "@trpc/server";
/**
* Sanitizes string inputs to prevent XSS.
* Escapes HTML entities and strips dangerous attributes.
*/
export function sanitizeHtml(input: string): string {
return input
.replace(/&/g, "&")
.replace(/</g, "&lt;")
.replace(/>/g, "&gt;")
.replace(/"/g, "&quot;")
.replace(/'/g, "&#x27;")
.replace(/\//g, "&#x2F;");
}
/**
* Validates that a string doesn't contain HTML or script tags.
* Throws TRPCError if malicious content is detected.
*/
export function validateNoHtml(input: string, fieldName: string): void {
const htmlPattern = /<[^>]*>/;
if (htmlPattern.test(input)) {
throw new TRPCError({
code: "BAD_REQUEST",
message: `${fieldName} contains invalid characters`,
});
}
}
/**
* Validates string length with meaningful error messages.
*/
export function validateStringLength(
input: string,
fieldName: string,
options: { min?: number; max?: number },
): void {
if (options.min !== undefined && input.length < options.min) {
throw new TRPCError({
code: "BAD_REQUEST",
message: `${fieldName} must be at least ${options.min} characters`,
});
}
if (options.max !== undefined && input.length > options.max) {
throw new TRPCError({
code: "BAD_REQUEST",
message: `${fieldName} must be at most ${options.max} characters`,
});
}
}