Files
infohliadka/lib/validate-input.ts

79 lines
2.0 KiB
TypeScript

import { sanitizeHtml, validateDomain } from './security'
export function sanitizeUrl(url: string): string {
return sanitizeHtml(url.trim().substring(0, 2048))
}
export function validateEmail(email: string): boolean {
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/
return emailRegex.test(email) && email.length <= 254
}
export function validateUrl(url: string): boolean {
try {
const sanitized = sanitizeUrl(url)
if (!sanitized) return false
// Add protocol if missing
let testUrl = sanitized
if (!testUrl.startsWith('http://') && !testUrl.startsWith('https://')) {
testUrl = 'https://' + testUrl
}
const urlObj = new URL(testUrl)
// Check for suspicious patterns
const suspiciousPatterns = [
/javascript:/i,
/data:/i,
/vbscript:/i,
/file:/i,
/about:/i
]
return !suspiciousPatterns.some(pattern => pattern.test(testUrl))
} catch {
return false
}
}
export function validateRiskLevel(level: any): boolean {
const num = parseInt(level)
return !isNaN(num) && num >= 1 && num <= 5
}
export function escapeSql(input: string): string {
return input.replace(/'/g, "''")
}
export interface ValidationResult {
valid: boolean
errors: string[]
}
export function validateReportData(data: any): ValidationResult {
const errors: string[] = []
if (!data.source_url || typeof data.source_url !== 'string') {
errors.push('Source URL is required')
} else if (!validateUrl(data.source_url)) {
errors.push('Invalid URL format')
}
if (data.reporter_email && !validateEmail(data.reporter_email)) {
errors.push('Invalid email format')
}
if (!data.categories || !Array.isArray(data.categories) || data.categories.length === 0) {
errors.push('At least one category is required')
}
if (data.description && typeof data.description === 'string' && data.description.length > 1000) {
errors.push('Description too long (max 1000 characters)')
}
return {
valid: errors.length === 0,
errors
}
}