base commit
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
/** Минимальное экранирование для безопасного HTML из пользовательского ввода. */
|
||||
export function escapeHtml(input) {
|
||||
return String(input ?? '')
|
||||
.replace(/&/g, '&')
|
||||
.replace(/</g, '<')
|
||||
.replace(/>/g, '>')
|
||||
.replace(/"/g, '"')
|
||||
}
|
||||
@@ -42,3 +42,19 @@ export async function persistMultipartImages(request, { maxFiles = 10 } = {}) {
|
||||
|
||||
return urls
|
||||
}
|
||||
|
||||
/** Сохранить один буфер изображения в uploads/, вернуть путь `/uploads/...`. */
|
||||
export async function saveImageBufferToUploads(originalFilename, buffer) {
|
||||
const ext = safeImageExt(originalFilename)
|
||||
if (!ext) {
|
||||
throw uploadError('Разрешены только файлы: png, jpg, jpeg, webp')
|
||||
}
|
||||
|
||||
const uploadsDir = path.join(process.cwd(), 'uploads')
|
||||
await fs.promises.mkdir(uploadsDir, { recursive: true })
|
||||
|
||||
const fileName = `${crypto.randomUUID()}${ext}`
|
||||
const fullPath = path.join(uploadsDir, fileName)
|
||||
await fs.promises.writeFile(fullPath, buffer)
|
||||
return `/uploads/${fileName}`
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user