Galerie: proxy + previews; uploads internal; membership PDF storage hardened; migration/preview scripts
Some checks failed
Code Analysis (JS/Vue) / analyze (push) Failing after 48s
Some checks failed
Code Analysis (JS/Vue) / analyze (push) Failing after 48s
This commit is contained in:
@@ -13,12 +13,12 @@ export default defineEventHandler(async (event) => {
|
||||
})
|
||||
}
|
||||
|
||||
// Upload-Verzeichnis finden
|
||||
const uploadDir = path.join(process.cwd(), 'public', 'uploads')
|
||||
console.log('Upload-Verzeichnis:', uploadDir)
|
||||
// Upload-Verzeichnis finden (intern)
|
||||
const uploadDir = path.join(process.cwd(), '..', 'server', 'data', 'uploads')
|
||||
console.log('Upload-Verzeichnis:', uploadDir)
|
||||
|
||||
// Alle Dateien im Upload-Verzeichnis durchsuchen
|
||||
const files = await fs.readdir(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)
|
||||
|
||||
@@ -71,7 +71,7 @@ export default defineEventHandler(async (event) => {
|
||||
})
|
||||
}
|
||||
|
||||
const filePath = path.join(uploadDir, matchingFile)
|
||||
const filePath = path.join(uploadDir, matchingFile)
|
||||
|
||||
// Datei lesen
|
||||
const fileBuffer = await fs.readFile(filePath)
|
||||
|
||||
@@ -299,7 +299,7 @@ Volljährig: ${data.isVolljaehrig ? 'Ja' : 'Nein'}
|
||||
Das ausgefüllte Formular ist als Anhang verfügbar.`
|
||||
|
||||
// nosemgrep: javascript.lang.security.audit.path-traversal.path-join-resolve-traversal.path-join-resolve-traversal
|
||||
const textPath = path.join(process.cwd(), 'public', 'uploads', `${filename}.txt`)
|
||||
const textPath = path.join(getDataPath('uploads'), `${filename}.txt`)
|
||||
await fs.writeFile(textPath, textContent, 'utf8')
|
||||
|
||||
return `${filename}.txt`
|
||||
@@ -659,28 +659,17 @@ export default defineEventHandler(async (event) => {
|
||||
return Buffer.from(pdfBytes)
|
||||
}
|
||||
|
||||
let usedTemplate = false
|
||||
const uploadsDir = path.join(process.cwd(), 'public', 'uploads')
|
||||
await fs.mkdir(uploadsDir, { recursive: true })
|
||||
let usedTemplate = false
|
||||
const uploadsDir = getDataPath('uploads')
|
||||
await fs.mkdir(uploadsDir, { recursive: true })
|
||||
try {
|
||||
const filled = await fillPdfTemplate(data)
|
||||
// nosemgrep: javascript.lang.security.audit.path-traversal.path-join-resolve-traversal.path-join-resolve-traversal
|
||||
// filename is generated from timestamp, not user input, path traversal prevented
|
||||
// nosemgrep: javascript.lang.security.audit.path-traversal.path-join-resolve-traversal.path-join-resolve-traversal
|
||||
const finalPdfPath = path.join(uploadsDir, `${filename}.pdf`)
|
||||
await fs.writeFile(finalPdfPath, filled)
|
||||
// Zusätzlich: Kopie ins repo-root public/uploads legen, falls Nitro cwd anders ist
|
||||
try {
|
||||
const repoRoot = path.resolve(process.cwd(), '..')
|
||||
const repoUploads = path.join(repoRoot, 'public', 'uploads')
|
||||
await fs.mkdir(repoUploads, { recursive: true })
|
||||
// nosemgrep: javascript.lang.security.audit.path-traversal.path-join-resolve-traversal.path-join-resolve-traversal
|
||||
// filename is generated from timestamp, not user input, path traversal prevented
|
||||
// nosemgrep: javascript.lang.security.audit.path-traversal.path-join-resolve-traversal.path-join-resolve-traversal
|
||||
await fs.copyFile(finalPdfPath, path.join(repoUploads, `${filename}.pdf`))
|
||||
} catch (_e) {
|
||||
console.warn('Kopie in repo public/uploads fehlgeschlagen:', e.message)
|
||||
}
|
||||
const finalPdfPath = path.join(uploadsDir, `${filename}.pdf`)
|
||||
await fs.writeFile(finalPdfPath, filled)
|
||||
// Do NOT copy filled PDFs into public repo uploads to avoid accidental exposure.
|
||||
usedTemplate = true
|
||||
} catch (templateError) {
|
||||
// Template konnte nicht verwendet werden -> weiter zum LaTeX-Fallback
|
||||
@@ -720,7 +709,7 @@ export default defineEventHandler(async (event) => {
|
||||
// LaTeX-Inhalt generieren
|
||||
const latexContent = generateLaTeXContent(data)
|
||||
|
||||
// LaTeX-Datei schreiben
|
||||
// LaTeX-Datei schreiben
|
||||
// nosemgrep: javascript.lang.security.audit.path-traversal.path-join-resolve-traversal.path-join-resolve-traversal
|
||||
// filename is generated from timestamp, not user input, path traversal prevented
|
||||
// nosemgrep: javascript.lang.security.audit.path-traversal.path-join-resolve-traversal.path-join-resolve-traversal
|
||||
@@ -733,30 +722,14 @@ export default defineEventHandler(async (event) => {
|
||||
const command = `cd "${tempDir}" && pdflatex -interaction=nonstopmode "${filename}.tex"`
|
||||
await execAsync(command)
|
||||
|
||||
// PDF-Datei in Uploads-Verzeichnis kopieren
|
||||
// PDF-Datei in Uploads-Verzeichnis kopieren
|
||||
// nosemgrep: javascript.lang.security.audit.path-traversal.path-join-resolve-traversal.path-join-resolve-traversal
|
||||
// filename is generated from timestamp, not user input, path traversal prevented
|
||||
// nosemgrep: javascript.lang.security.audit.path-traversal.path-join-resolve-traversal.path-join-resolve-traversal
|
||||
const pdfPath = path.join(tempDir, `${filename}.pdf`)
|
||||
await fs.mkdir(uploadsDir, { recursive: true })
|
||||
|
||||
// nosemgrep: javascript.lang.security.audit.path-traversal.path-join-resolve-traversal.path-join-resolve-traversal
|
||||
// filename is generated from timestamp, not user input, path traversal prevented
|
||||
// nosemgrep: javascript.lang.security.audit.path-traversal.path-join-resolve-traversal.path-join-resolve-traversal
|
||||
const finalPdfPath = path.join(uploadsDir, `${filename}.pdf`)
|
||||
await fs.copyFile(pdfPath, finalPdfPath)
|
||||
// Kopie ins repo-root public/uploads für bessere Auffindbarkeit
|
||||
try {
|
||||
const repoRoot = path.resolve(process.cwd(), '..')
|
||||
const repoUploads = path.join(repoRoot, 'public', 'uploads')
|
||||
await fs.mkdir(repoUploads, { recursive: true })
|
||||
// nosemgrep: javascript.lang.security.audit.path-traversal.path-join-resolve-traversal.path-join-resolve-traversal
|
||||
// filename is generated from timestamp, not user input, path traversal prevented
|
||||
// nosemgrep: javascript.lang.security.audit.path-traversal.path-join-resolve-traversal.path-join-resolve-traversal
|
||||
await fs.copyFile(finalPdfPath, path.join(repoUploads, `${filename}.pdf`))
|
||||
} catch (e) {
|
||||
console.warn('Kopie in repo public/uploads fehlgeschlagen:', e.message)
|
||||
}
|
||||
await fs.mkdir(uploadsDir, { recursive: true })
|
||||
const finalPdfPath = path.join(uploadsDir, `${filename}.pdf`)
|
||||
await fs.copyFile(pdfPath, finalPdfPath)
|
||||
|
||||
// E-Mail senden
|
||||
emailResult = await sendMembershipEmail(data, filename, event)
|
||||
@@ -793,14 +766,14 @@ export default defineEventHandler(async (event) => {
|
||||
// E-Mail senden (Fallback)
|
||||
const emailResult = await sendMembershipEmail(data, filename, event)
|
||||
|
||||
console.log('LaTeX nicht verfügbar, verwende Fallback-Lösung')
|
||||
console.log('E-Mail würde gesendet werden an:', emailResult.recipients || [])
|
||||
console.log('Betreff:', emailResult.subject || '')
|
||||
console.log('Nachricht:', emailResult.message || '')
|
||||
console.log('Upload-Verzeichnis:', path.join(process.cwd(), 'public', 'uploads'))
|
||||
console.log('LaTeX nicht verfügbar, verwende Fallback-Lösung')
|
||||
console.log('E-Mail würde gesendet werden an:', emailResult.recipients || [])
|
||||
console.log('Betreff:', emailResult.subject || '')
|
||||
console.log('Nachricht:', emailResult.message || '')
|
||||
console.log('Upload-Verzeichnis:', getDataPath('uploads'))
|
||||
|
||||
// Verfügbare Dateien auflisten
|
||||
const uploadsDir = path.join(process.cwd(), 'public', 'uploads')
|
||||
const uploadsDir = getDataPath('uploads')
|
||||
try {
|
||||
const files = await fs.readdir(uploadsDir)
|
||||
console.log('Verfügbare Dateien:', files)
|
||||
|
||||
Reference in New Issue
Block a user