| import DOMPurify from "isomorphic-dompurify"; |
|
|
| export function sanitizeHTML(input: string | null | undefined): string { |
| return sanitizeString(input, false); |
| } |
|
|
| export function sanitizeInput(input: string | null | undefined): string { |
| return sanitizeString(input, true); |
| } |
|
|
| export function sanitizeUrl(input: string | null | undefined): string { |
| if (!input || typeof input !== "string") { |
| return ""; |
| } |
| try { |
| |
| const parsed = new URL(input); |
| |
| if (!["http:", "https:"].includes(parsed.protocol)) { |
| return ""; |
| } |
| return input; |
| } catch (error) { |
| |
| |
| if (input.startsWith("javascript:") || input.startsWith("data:")) { |
| return ""; |
| } |
| return input; |
| } |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| export function sanitizeString( |
| input: string | null | undefined, |
| strict: boolean = false |
| ): string { |
| if (!input || typeof input !== "string") { |
| return ""; |
| } |
|
|
| try { |
|
|
| if (strict) { |
| |
| return DOMPurify.sanitize(input, { ALLOWED_TAGS: [] }); |
| } |
|
|
| |
| return DOMPurify.sanitize(input, { |
| ALLOWED_TAGS: [ |
| "b", |
| "i", |
| "em", |
| "strong", |
| "u", |
| "br", |
| "p", |
| "ul", |
| "ol", |
| "li", |
| "a", |
| ], |
| ALLOWED_ATTR: ["href", "target", "rel"], |
| }); |
| } catch (error) { |
| |
| return encodeHtmlEntities(input); |
| } |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| export function sanitizeObject<T extends Record<string, unknown>>( |
| obj: T | null | undefined, |
| strict: boolean = false |
| ): T { |
| if (!obj || typeof obj !== "object") { |
| return {} as T; |
| } |
|
|
| const sanitized: Record<string, unknown> = { ...obj }; |
|
|
| for (const key in sanitized) { |
| const value = sanitized[key]; |
|
|
| if (typeof value === "string") { |
| sanitized[key] = sanitizeString(value, strict); |
| } else if (Array.isArray(value)) { |
| sanitized[key] = value.map((item) => |
| typeof item === "string" ? sanitizeString(item, strict) : item |
| ); |
| } else if ( |
| value !== null && |
| typeof value === "object" && |
| !Array.isArray(value) |
| ) { |
| sanitized[key] = sanitizeObject( |
| value as Record<string, unknown>, |
| strict |
| ); |
| } |
| } |
|
|
| return sanitized as T; |
| } |
|
|
| |
| |
| |
| |
| |
| export function sanitizeEmail(email: string | null | undefined): string { |
| if (!email || typeof email !== "string") { |
| return ""; |
| } |
|
|
| const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; |
| const sanitized = email.trim().toLowerCase(); |
|
|
| return emailRegex.test(sanitized) ? sanitized : ""; |
| } |
|
|
| |
| |
| |
| |
| |
| export function sanitizeFilename( |
| filename: string | null | undefined |
| ): string { |
| if (!filename || typeof filename !== "string") { |
| return "file"; |
| } |
|
|
| |
| return filename |
| .replace(/[/\\]/g, "") |
| .replace(/\.\./g, "") |
| .replace(/[^\w\s.-]/g, "") |
| .trim() |
| .substring(0, 255) |
| .replace(/^\.+/, ""); |
| } |
|
|
| |
| |
| |
| |
| |
| export function sanitizeSearchInput( |
| input: string | null | undefined |
| ): string { |
| if (!input || typeof input !== "string") { |
| return ""; |
| } |
|
|
| |
| return input |
| .trim() |
| .replace(/['"`]/g, "") |
| .replace(/[\r\n]/g, " ") |
| .substring(0, 200); |
| } |
|
|
| |
| |
| |
| |
| |
| export function sanitizeJsonField( |
| input: string | null | undefined |
| ): string { |
| if (!input || typeof input !== "string") { |
| return ""; |
| } |
|
|
| return input |
| .replace(/\\/g, "\\\\") |
| .replace(/"/g, '\\"') |
| .replace(/\n/g, "\\n") |
| .replace(/\r/g, "\\r") |
| .replace(/\t/g, "\\t"); |
| } |
|
|
| |
| |
| |
| |
| |
| export function sanitizePhoneNumber( |
| phone: string | null | undefined |
| ): string { |
| if (!phone || typeof phone !== "string") { |
| return ""; |
| } |
|
|
| |
| const sanitized = phone.replace(/[^\d+\-().\s]/g, "").trim(); |
|
|
| |
| const digitCount = (sanitized.match(/\d/g) || []).length; |
| return digitCount >= 7 ? sanitized : ""; |
| } |
|
|
| |
| |
| |
| |
| |
| function encodeHtmlEntities(str: string): string { |
| return str |
| .replace(/&/g, "&") |
| .replace(/</g, "<") |
| .replace(/>/g, ">") |
| .replace(/"/g, """) |
| .replace(/'/g, "'"); |
| } |
|
|