111 lines
3.4 KiB
JavaScript
111 lines
3.4 KiB
JavaScript
import fs from 'fs/promises'
|
|
import path from 'path'
|
|
import { getUserFromToken } from '../../../utils/auth.js'
|
|
|
|
export default defineEventHandler(async (event) => {
|
|
try {
|
|
// Datei-ID aus der URL extrahieren
|
|
const fileId = decodeURIComponent(getRouterParam(event, 'id'))
|
|
if (!fileId) {
|
|
throw createError({
|
|
statusCode: 400,
|
|
statusMessage: 'Datei-ID fehlt'
|
|
})
|
|
}
|
|
|
|
// Upload-Verzeichnis finden
|
|
const uploadDir = path.join(process.cwd(), 'public', 'uploads')
|
|
console.log('Upload-Verzeichnis:', uploadDir)
|
|
|
|
// Alle Dateien im Upload-Verzeichnis durchsuchen
|
|
const files = await fs.readdir(uploadDir)
|
|
console.log('Verfügbare Dateien:', files)
|
|
console.log('Gesuchte Datei-ID:', fileId)
|
|
|
|
const matchingFile = files.find(file => file.includes(fileId))
|
|
console.log('Gefundene Datei:', matchingFile)
|
|
|
|
if (!matchingFile) {
|
|
throw createError({
|
|
statusCode: 404,
|
|
statusMessage: 'Datei nicht gefunden'
|
|
})
|
|
}
|
|
|
|
// Prüfen ob der Benutzer berechtigt ist, diese Datei herunterzuladen
|
|
const token = getCookie(event, 'auth_token')
|
|
let isAuthorized = false
|
|
|
|
if (token) {
|
|
// Authentifizierte Benutzer prüfen
|
|
const user = await getUserFromToken(token)
|
|
const roles = Array.isArray(user.roles) ? user.roles : (user.role ? [user.role] : [])
|
|
if (user && (roles.includes('admin') || roles.includes('vorstand'))) {
|
|
// Admin/Vorstand kann alle Dateien herunterladen
|
|
isAuthorized = true
|
|
}
|
|
}
|
|
|
|
// Prüfen ob es sich um eine aktuelle Session handelt (innerhalb der letzten 24 Stunden)
|
|
const downloadToken = getCookie(event, 'download_token')
|
|
|
|
if (downloadToken) {
|
|
try {
|
|
const decoded = Buffer.from(downloadToken, 'base64').toString('utf8')
|
|
const [tokenFilename, timestamp] = decoded.split(':')
|
|
|
|
// Prüfen ob der Token für diese Datei ist und nicht älter als 24 Stunden
|
|
if (tokenFilename === fileId.replace('.pdf', '') &&
|
|
Date.now() - parseInt(timestamp) < 24 * 60 * 60 * 1000) {
|
|
isAuthorized = true
|
|
}
|
|
} catch (e) {
|
|
console.warn('Ungültiger Download-Token:', e.message)
|
|
}
|
|
}
|
|
|
|
if (!isAuthorized) {
|
|
throw createError({
|
|
statusCode: 403,
|
|
statusMessage: 'Keine Berechtigung für diesen Download'
|
|
})
|
|
}
|
|
|
|
const filePath = path.join(uploadDir, matchingFile)
|
|
|
|
// Datei lesen
|
|
const fileBuffer = await fs.readFile(filePath)
|
|
|
|
// MIME-Type basierend auf Dateiendung bestimmen
|
|
const ext = path.extname(matchingFile).toLowerCase()
|
|
let mimeType = 'application/octet-stream'
|
|
let filename = matchingFile
|
|
|
|
if (ext === '.pdf') {
|
|
mimeType = 'application/pdf'
|
|
} else if (ext === '.txt') {
|
|
mimeType = 'text/plain'
|
|
filename = matchingFile.replace('.txt', '.pdf') // Für Download als PDF benennen
|
|
}
|
|
|
|
// Datei als Download senden
|
|
setHeader(event, 'Content-Type', mimeType)
|
|
setHeader(event, 'Content-Disposition', `attachment; filename="${filename}"`)
|
|
setHeader(event, 'Content-Length', fileBuffer.length.toString())
|
|
|
|
return fileBuffer
|
|
|
|
} catch (error) {
|
|
console.error('Download-Fehler:', error)
|
|
|
|
if (error.statusCode) {
|
|
throw error
|
|
}
|
|
|
|
throw createError({
|
|
statusCode: 500,
|
|
statusMessage: 'Interner Serverfehler'
|
|
})
|
|
}
|
|
})
|