52 lines
1.4 KiB
TypeScript
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, "<")
|
|
.replace(/>/g, ">")
|
|
.replace(/"/g, """)
|
|
.replace(/'/g, "'")
|
|
.replace(/\//g, "/");
|
|
}
|
|
|
|
/**
|
|
* 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`,
|
|
});
|
|
}
|
|
}
|