Files
harheimertc/server/api/personen/[filename].get.js

109 lines
2.9 KiB
JavaScript

import fs from 'fs/promises'
import path from 'path'
import sharp from 'sharp'
// Handle both dev and production paths
const getDataPath = (filename) => {
const cwd = process.cwd()
if (cwd.endsWith('.output')) {
return path.join(cwd, '../server/data', filename)
}
return path.join(cwd, 'server/data', filename)
}
const PERSONEN_DIR = getDataPath('personen')
export default defineEventHandler(async (event) => {
try {
const filename = getRouterParam(event, 'filename')
if (!filename) {
throw createError({
statusCode: 400,
statusMessage: 'Dateiname erforderlich'
})
}
// Sicherheitsprüfung: Nur erlaubte Dateinamen (UUID-Format)
if (!/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\.(jpg|jpeg|png|gif|webp)$/i.test(filename)) {
throw createError({
statusCode: 400,
statusMessage: 'Ungültiger Dateiname'
})
}
const filePath = path.join(PERSONEN_DIR, filename)
// Prüfe ob Datei existiert
try {
await fs.access(filePath)
} catch {
throw createError({
statusCode: 404,
statusMessage: 'Bild nicht gefunden'
})
}
// MIME-Type bestimmen
const ext = path.extname(filename).toLowerCase()
const mimeTypes = {
'.jpg': 'image/jpeg',
'.jpeg': 'image/jpeg',
'.png': 'image/png',
'.gif': 'image/gif',
'.webp': 'image/webp'
}
const contentType = mimeTypes[ext] || 'application/octet-stream'
// Optional: Query-Parameter für Größe
const query = getQuery(event)
const width = query.width ? parseInt(query.width) : null
const height = query.height ? parseInt(query.height) : null
let imageBuffer = await fs.readFile(filePath)
// Bild verarbeiten falls Größe angegeben
if (width || height) {
const resizeOptions = {}
if (width && height) {
resizeOptions.width = width
resizeOptions.height = height
resizeOptions.fit = 'cover'
} else if (width) {
resizeOptions.width = width
resizeOptions.fit = 'inside'
resizeOptions.withoutEnlargement = true
} else if (height) {
resizeOptions.height = height
resizeOptions.fit = 'inside'
resizeOptions.withoutEnlargement = true
}
imageBuffer = await sharp(imageBuffer)
.rotate() // EXIF-Orientierung korrigieren
.resize(resizeOptions)
.toBuffer()
} else {
// Nur EXIF-Orientierung korrigieren
imageBuffer = await sharp(imageBuffer).rotate().toBuffer()
}
setHeader(event, 'Content-Type', contentType)
setHeader(event, 'Cache-Control', 'public, max-age=31536000')
return imageBuffer
} catch (error) {
console.error('Fehler beim Laden des Personenfotos:', error)
if (error.statusCode) {
throw error
}
throw createError({
statusCode: 500,
statusMessage: 'Fehler beim Laden des Bildes'
})
}
})