Enhance security and error handling in various components by refining error catch blocks to ignore specific errors, improving code clarity and consistency across the application.
Some checks failed
Code Analysis (JS/Vue) / analyze (push) Failing after 4m10s

This commit is contained in:
Torsten Schulz (local)
2025-12-20 15:05:49 +01:00
parent c9037fec45
commit 6fda6ebad0
42 changed files with 117 additions and 113 deletions

View File

@@ -31,3 +31,18 @@ jobs:
- name: Semgrep (SAST)
run: semgrep --config p/default --error .
- name: npm audit (high+)
run: npm audit --audit-level=high || true
- name: OSV-Scanner (SCA)
run: |
curl -L -o osv-scanner https://github.com/google/osv-scanner/releases/latest/download/osv-scanner_linux_amd64
chmod +x osv-scanner
./osv-scanner --lockfile package-lock.json
- name: gitleaks (Secrets Scanning)
run: |
curl -sSL https://github.com/gitleaks/gitleaks/releases/latest/download/gitleaks_linux_x64.tar.gz \
| tar -xz gitleaks
./gitleaks detect --source . --no-git --redact --exit-code 1

View File

@@ -100,7 +100,7 @@ const isMemberMenuOpen = ref(false)
// Reactive auth state from store
const isLoggedIn = computed(() => authStore.isLoggedIn)
const isAdmin = computed(() => authStore.isAdmin)
// const isAdmin = computed(() => authStore.isAdmin)
const toggleMemberMenu = () => {
isMemberMenuOpen.value = !isMemberMenuOpen.value

View File

@@ -103,7 +103,7 @@
<script setup>
import { ref, onMounted } from 'vue'
import { Calendar, Users, BarChart } from 'lucide-vue-next'
import { Users } from 'lucide-vue-next'
const mannschaften = ref([])
@@ -124,7 +124,7 @@ const loadMannschaften = async () => {
return
}
mannschaften.value = lines.slice(1).map((line, index) => {
mannschaften.value = lines.slice(1).map((line, _index) => {
// Besserer CSV-Parser: Respektiert Anführungszeichen
const values = []
let current = ''

View File

@@ -280,7 +280,7 @@ const upcomingGames = computed(() => {
// Nur Spiele der nächsten 7 Tage
return gameDate >= today && gameDate <= in7Days
} catch (error) {
} catch (_error) {
return false
}
})

View File

@@ -1,4 +1,4 @@
export default defineNuxtRouteMiddleware(async (to, from) => {
export default defineNuxtRouteMiddleware(async (to, _from) => {
// Only run on client-side
if (process.server) return

View File

@@ -1,4 +1,4 @@
export default defineNuxtRouteMiddleware(async (to, from) => {
export default defineNuxtRouteMiddleware(async (to, _from) => {
// Check if route requires auth
const protectedRoutes = ['/mitgliederbereich', '/cms']
const requiresAuth = protectedRoutes.some(route => to.path.startsWith(route))
@@ -33,7 +33,7 @@ export default defineNuxtRouteMiddleware(async (to, from) => {
}
}
}
} catch (error) {
} catch (_error) {
return navigateTo('/login?redirect=' + to.path)
}
})

View File

@@ -362,7 +362,7 @@ const approveUser = async (user) => {
setTimeout(() => successMessage.value = '', 3000)
await loadUsers()
} catch (error) {
} catch (_error) {
errorMessage.value = 'Fehler beim Freischalten des Benutzers'
setTimeout(() => errorMessage.value = '', 3000)
}
@@ -397,7 +397,7 @@ async function saveUserRoles() {
closeRoleModal()
await loadUsers()
} catch (error) {
} catch (_error) {
errorMessage.value = 'Fehler beim Aktualisieren der Rollen'
setTimeout(() => errorMessage.value = '', 3000)
}

View File

@@ -566,8 +566,6 @@
import { ref, onMounted } from 'vue'
import { Settings, Calendar, Users as UsersIcon, CreditCard, Plus, Trash2, X, Loader2, AlertCircle, Check } from 'lucide-vue-next'
const authStore = useAuthStore()
const isLoading = ref(true)
const isSaving = ref(false)
const errorMessage = ref('')
@@ -596,7 +594,7 @@ const loadConfig = async () => {
try {
const response = await $fetch('/api/config')
config.value = response
} catch (error) {
} catch {
errorMessage.value = 'Fehler beim Laden der Konfiguration.'
} finally {
isLoading.value = false
@@ -615,7 +613,7 @@ const saveConfig = async () => {
})
successMessage.value = 'Konfiguration erfolgreich gespeichert!'
try { window.showSuccessModal && window.showSuccessModal('Erfolg', 'Konfiguration erfolgreich gespeichert!') } catch (_e) {
try { window.showSuccessModal && window.showSuccessModal('Erfolg', 'Konfiguration erfolgreich gespeichert!') } catch {
// Modal nicht verfügbar, ignorieren
}
setTimeout(() => {
@@ -623,7 +621,7 @@ const saveConfig = async () => {
}, 3000)
} catch (error) {
errorMessage.value = error.data?.message || 'Fehler beim Speichern der Konfiguration.'
try { window.showErrorModal && window.showErrorModal('Fehler', errorMessage.value) } catch (_e) {
try { window.showErrorModal && window.showErrorModal('Fehler', errorMessage.value) } catch {
// Modal nicht verfügbar, ignorieren
}
} finally {

View File

@@ -168,11 +168,11 @@ async function save() {
const updated = { ...current, seiten: { ...(current.seiten || {}), geschichte: html } }
try {
await $fetch('/api/config', { method: 'PUT', body: updated })
try { window.showSuccessModal && window.showSuccessModal('Erfolg', 'Inhalt erfolgreich gespeichert!') } catch (_e) {
try { window.showSuccessModal && window.showSuccessModal('Erfolg', 'Inhalt erfolgreich gespeichert!') } catch {
// Modal nicht verfügbar, ignorieren
}
} catch (error) {
try { window.showErrorModal && window.showErrorModal('Fehler', error?.data?.message || 'Speichern fehlgeschlagen') } catch (_e) {
try { window.showErrorModal && window.showErrorModal('Fehler', error?.data?.message || 'Speichern fehlgeschlagen') } catch {
// Modal nicht verfügbar, ignorieren
}
}

View File

@@ -621,11 +621,11 @@ const closeUploadModal = () => {
}
// Drag and Drop Events
const handleDragEnter = () => {
const _handleDragEnter = () => {
isDragOver.value = true
}
const handleDragLeave = () => {
const _handleDragLeave = () => {
isDragOver.value = false
}
@@ -675,7 +675,7 @@ const loadExistingData = async () => {
}
}
}
} catch (_error) {
} catch {
// Fehler beim Laden der Datei, ignorieren
}
}

View File

@@ -247,9 +247,7 @@
<script setup>
import { ref, onMounted } from 'vue'
import { Calendar, Plus, Trash2, Loader2, AlertCircle, Pencil } from 'lucide-vue-next'
const authStore = useAuthStore()
import { Plus, Trash2, Loader2, AlertCircle, Pencil } from 'lucide-vue-next'
const isLoading = ref(true)
const isSaving = ref(false)

View File

@@ -193,11 +193,11 @@ async function save() {
const updated = { ...current, seiten: { ...(current.seiten || {}), ttRegeln: html } }
try {
await $fetch('/api/config', { method: 'PUT', body: updated })
try { window.showSuccessModal && window.showSuccessModal('Erfolg', 'Regeln erfolgreich gespeichert!') } catch (_e) {
try { window.showSuccessModal && window.showSuccessModal('Erfolg', 'Regeln erfolgreich gespeichert!') } catch {
// Modal nicht verfügbar, ignorieren
}
} catch (error) {
try { window.showErrorModal && window.showErrorModal('Fehler', error?.data?.message || 'Speichern fehlgeschlagen') } catch (_e) {
try { window.showErrorModal && window.showErrorModal('Fehler', error?.data?.message || 'Speichern fehlgeschlagen') } catch {
// Modal nicht verfügbar, ignorieren
}
}
@@ -254,7 +254,7 @@ function insertRuleTemplate(type) {
<p class="text-gray-600 text-sm"><strong>Verstoß:</strong> [Was ist der Verstoß?]<br><strong>Strafe:</strong> [Welche Strafe wird verhängt?]<br><strong>Häufigkeit:</strong> [Bei wiederholten Verstößen?]</p>
</div>
`
bgColor = 'bg-green-50'
// bgColor = 'bg-green-50' // Nicht verwendet
break
case 'service':
template = `
@@ -263,7 +263,7 @@ function insertRuleTemplate(type) {
<p class="text-gray-600 text-sm"><strong>Regel:</strong> [Aufschlagregel hier eingeben]<br><strong>Technik:</strong> [Wie muss der Aufschlag ausgeführt werden?]<br><strong>Fehler:</strong> [Was gilt als Fehler?]</p>
</div>
`
bgColor = 'bg-yellow-50'
// bgColor = 'bg-yellow-50'
break
}

View File

@@ -120,11 +120,11 @@ async function save() {
const updated = { ...current, seiten: { ...(current.seiten || {}), ueberUns: html } }
try {
await $fetch('/api/config', { method: 'PUT', body: updated })
try { window.showSuccessModal && window.showSuccessModal('Erfolg', 'Inhalt erfolgreich gespeichert!') } catch (_e) {
try { window.showSuccessModal && window.showSuccessModal('Erfolg', 'Inhalt erfolgreich gespeichert!') } catch {
// Modal nicht verfügbar, ignorieren
}
} catch (error) {
try { window.showErrorModal && window.showErrorModal('Fehler', error?.data?.message || 'Speichern fehlgeschlagen') } catch (_e) {
try { window.showErrorModal && window.showErrorModal('Fehler', error?.data?.message || 'Speichern fehlgeschlagen') } catch {
// Modal nicht verfügbar, ignorieren
}
}

View File

@@ -135,7 +135,7 @@
<script setup>
import { ref, onMounted } from 'vue'
import { Calendar, Users, BarChart } from 'lucide-vue-next'
import { Users } from 'lucide-vue-next'
const route = useRoute()
const mannschaft = ref(null)

View File

@@ -283,7 +283,7 @@
</template>
<script setup>
import { ref, onMounted, computed } from 'vue'
import { ref, onMounted } from 'vue'
useHead({
title: 'Spielpläne - Mannschaften - Harheimer TC'
@@ -398,8 +398,6 @@ const filterData = () => {
}
// Zuerst nach aktueller Saison filtern (immer aktiv)
const currentDate = new Date()
const currentYear = currentDate.getFullYear()
// Da die Spiele bis 2026 gehen, nehmen wir die Saison 2025/26
// Saison läuft vom 01.07. bis 30.06. des Folgejahres
@@ -434,7 +432,7 @@ const filterData = () => {
const inSaison = spielDatum >= saisonStart && spielDatum <= saisonEnd
return inSaison
} catch (error) {
} catch (_error) {
console.error('Fehler beim Parsen von Termin:', termin, error)
return false
}
@@ -738,7 +736,7 @@ const getRowClass = (row) => {
// Standard: Weiß
return 'bg-white'
} catch (error) {
} catch {
return 'bg-white'
}
}

View File

@@ -771,7 +771,7 @@
<script setup>
import { ref, computed, onMounted } from 'vue'
import { Users, UserPlus, Mail, Phone, MapPin, FileText, Clock, Edit, Trash2, Loader2, AlertCircle, Table2, Grid3x3 } from 'lucide-vue-next'
import { UserPlus, Mail, Phone, MapPin, FileText, Clock, Edit, Trash2, Loader2, AlertCircle, Table2, Grid3x3 } from 'lucide-vue-next'
const authStore = useAuthStore()
@@ -1003,7 +1003,7 @@ const processBulkCSV = async (file) => {
}
// Parse data rows
bulkPreviewData.value = lines.slice(1).map((line, index) => {
bulkPreviewData.value = lines.slice(1).map((line, _index) => {
const values = parseCSVLine(line)
return {
firstName: values[firstNameIdx] || '',

View File

@@ -221,7 +221,7 @@ const loadProfile = async () => {
email: response.user.email,
phone: response.user.phone || ''
}
} catch (error) {
} catch {
errorMessage.value = 'Fehler beim Laden des Profils.'
} finally {
isLoading.value = false

View File

@@ -175,7 +175,7 @@ async function checkSubscription() {
}
})
alreadySubscribed.value = response.subscribed || false
} catch (err) {
} catch (_err) {
// Fehler ignorieren - könnte bedeuten, dass nicht abonniert ist
alreadySubscribed.value = false
} finally {

View File

@@ -206,7 +206,7 @@
</template>
<script setup>
import { ref, onMounted, computed } from 'vue'
import { ref, onMounted } from 'vue'
useHead({
title: 'Spielplan - Harheimer TC'

View File

@@ -243,7 +243,7 @@
</template>
<script setup>
import { Globe, FileText, Download, ExternalLink, Target, Circle, Zap, Play, Trophy, Users, BookOpen } from 'lucide-vue-next'
import { Globe, FileText, Target, Circle, Zap, Play, Trophy, Users, BookOpen } from 'lucide-vue-next'
useHead({
title: 'TT-Regeln - Harheimer TC',

View File

@@ -29,7 +29,7 @@ async function loadConfig() {
try {
const data = await $fetch('/api/config')
rawContent.value = data?.seiten?.geschichte || ''
} catch (_e) {
} catch {
rawContent.value = ''
}
}

View File

@@ -29,7 +29,7 @@ async function loadConfig() {
try {
const data = await $fetch('/api/config')
rawContent.value = data?.seiten?.ttRegeln || ''
} catch (_e) {
} catch {
rawContent.value = ''
}
}

View File

@@ -29,7 +29,7 @@ async function loadConfig() {
try {
const data = await $fetch('/api/config')
rawContent.value = data?.seiten?.ueberUns || ''
} catch (_e) {
} catch {
rawContent.value = ''
}
}

View File

@@ -97,7 +97,7 @@ export default defineEventHandler(async (event) => {
// Versuche pdftotext zu verwenden (falls auf dem System installiert)
const { stdout } = await execAsync(`pdftotext "${file.path}" -`)
extractedText = stdout
} catch (error) {
} catch (_error) {
console.log('pdftotext nicht verfügbar, verwende Fallback-Text')
// Fallback: Verwende den bekannten Satzungsinhalt
extractedText = `Vereinssatzung

View File

@@ -13,7 +13,7 @@ const getDataPath = (filename) => {
return path.join(cwd, 'server/data', filename)
}
export default defineEventHandler(async (event) => {
export default defineEventHandler(async (_event) => {
try {
const configFile = getDataPath('config.json')
const data = await fs.readFile(configFile, 'utf-8')

View File

@@ -1,5 +1,5 @@
import { verifyToken, getUserById, hasAnyRole, readUsers, writeUsers } from '../../utils/auth.js'
import { readMembers, writeMembers, getMemberById } from '../../utils/members.js'
import { readMembers, writeMembers } from '../../utils/members.js'
export default defineEventHandler(async (event) => {
try {

View File

@@ -3,10 +3,9 @@ import { exec } from 'child_process'
import { promisify } from 'util'
import fs from 'fs/promises'
import path from 'path'
import { encrypt } from '../../utils/encryption.js'
import { PDFDocument, rgb, StandardFonts } from 'pdf-lib'
import { StandardFonts } from 'pdf-lib'
const require = createRequire(import.meta.url)
// const require = createRequire(import.meta.url) // Nicht verwendet
const execAsync = promisify(exec)
function mapFieldValue(data, name) {
@@ -39,7 +38,7 @@ function setTextFieldIfEmpty(field, val) {
const cur = field.getText()
if (cur && String(cur).trim() !== '') return
}
} catch (_e) {
} catch {
// Feld nicht lesbar, ignorieren
}
if (val != null && String(val).trim() !== '') field.setText(val)
@@ -60,11 +59,11 @@ function setCheckboxIfNeeded(field, name, data) {
if (mapped === 'true' || mapped === 'ja' || mapped === 'checked') {
try {
if (!(typeof field.isChecked === 'function' && field.isChecked())) field.check && field.check()
} catch (_e) {
} catch {
field.check && field.check()
}
}
} catch (_e) {
} catch {
// Feld nicht verarbeitbar, ignorieren
}
}
@@ -87,7 +86,7 @@ async function fillFormFields(pdfDoc, form, data) {
try {
const helv2 = await pdfDoc.embedFont(StandardFonts.Helvetica)
form.updateFieldAppearances(helv2)
} catch (_e) {
} catch {
// Schriftart nicht einbettbar, ignorieren
}
}
@@ -285,7 +284,7 @@ Unterschrift ${data.isVolljaehrig ? '' : '(bei Minderjährigen Unterschrift eine
return result
}
async function generateSimplePDF(data, filename, event) {
async function generateSimplePDF(data, filename, _event) {
// Fallback: HTML zu PDF mit puppeteer oder ähnlich
// Für jetzt: Einfache Textdatei
const textContent = `
@@ -317,7 +316,7 @@ function getDataPath(filename) {
return path.join(projectRoot, 'server', 'data', filename)
}
async function sendMembershipEmail(data, filename, event) {
async function sendMembershipEmail(data, _filename, _event) {
try {
const configPath = getDataPath('config.json')
const configData = await fs.readFile(configPath, 'utf8')
@@ -425,7 +424,7 @@ export default defineEventHandler(async (event) => {
if (!res.ok) throw new Error(`Template konnte nicht geladen werden: ${res.status}`)
arrayBuffer = await res.arrayBuffer()
}
} catch (e) {
} catch (_e) {
throw new Error('Template-Laden fehlgeschlagen: ' + e.message)
}
@@ -433,7 +432,7 @@ export default defineEventHandler(async (event) => {
let form
try {
form = pdfDoc.getForm()
} catch (e) {
} catch (_e) {
form = null
}
@@ -442,7 +441,7 @@ export default defineEventHandler(async (event) => {
// Koordinaten (in PDF-Punkten) müssen ggf. feinjustiert werden.
const pages = pdfDoc.getPages()
const firstPage = pages[0]
const { width, height } = firstPage.getSize()
firstPage.getSize()
// Schätzwerte: (x, y) in Punkten von linker unteren Ecke
// Diese Werte müssen nach Sichtprüfung justiert werden.
@@ -522,7 +521,7 @@ export default defineEventHandler(async (event) => {
} else if (data.mitgliedschaftsart === 'passiv') {
firstPage.drawText('X', { x: coords.mitglied_checkbox_passiv.x, y: coords.mitglied_checkbox_passiv.y, size: 12, font: helveticaFont })
}
} catch (e) {
} catch (_e) {
console.warn('Fehler beim Zeichnen der Checkbox:', e.message)
}
// Debug overlay: zeichne Marker an allen Koordinaten, wenn data.debug === true
@@ -542,11 +541,11 @@ export default defineEventHandler(async (event) => {
// small label a bit to the right
firstPage.drawText(key, { x: c.x + 8, y: c.y - 1, size: 7, color: rgb(0.6, 0, 0), font: helveticaFont })
}
} catch (e) {
} catch (_e) {
console.warn('Debug overlay fehlgeschlagen:', e.message)
}
}
} catch (e) {
} catch (_e) {
console.warn('Fehler beim positional drawing:', e.message)
}
@@ -601,7 +600,7 @@ export default defineEventHandler(async (event) => {
continue
}
}
} catch (e) {
} catch (_e) {
// ignore getter errors and proceed to set
}
const val = mapValue(lower)
@@ -626,7 +625,7 @@ export default defineEventHandler(async (event) => {
if (lower.includes('passiv') && data.mitgliedschaftsart === 'passiv') field.check && field.check()
}
}
} catch (e) {
} catch (_e) {
// ignore isChecked errors
}
continue
@@ -637,12 +636,12 @@ export default defineEventHandler(async (event) => {
if (!(typeof field.isChecked === 'function' && field.isChecked())) {
field.check && field.check()
}
} catch (e) {
} catch (_e) {
field.check && field.check()
}
}
}
} catch (e) {
} catch (_e) {
console.warn('Fehler beim Befüllen Feld', fname, e.message)
}
}
@@ -651,7 +650,7 @@ export default defineEventHandler(async (event) => {
try {
const helv2 = await pdfDoc.embedFont(StandardFonts.Helvetica)
form.updateFieldAppearances(helv2)
} catch (e) {
} catch (_e) {
console.warn('Warning: could not update field appearances after mapping fields:', e.message)
}
@@ -678,7 +677,7 @@ export default defineEventHandler(async (event) => {
// 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) {
} catch (_e) {
console.warn('Kopie in repo public/uploads fehlgeschlagen:', e.message)
}
usedTemplate = true

View File

@@ -1,6 +1,6 @@
import fs from 'fs/promises'
import path from 'path'
import { decryptObject, encryptObject } from '../../utils/encryption.js'
import { decryptObject } from '../../utils/encryption.js'
import { saveMember } from '../../utils/members.js'
export default defineEventHandler(async (event) => {

View File

@@ -3,7 +3,6 @@ import path from 'path'
import { getUserFromToken, hasAnyRole } from '../../../../../utils/auth.js'
import { randomUUID } from 'crypto'
import { getRecipientsByGroup, getNewsletterSubscribers, generateUnsubscribeToken } from '../../../../../utils/newsletter.js'
import { encryptObject, decryptObject } from '../../../../../utils/encryption.js'
import nodemailer from 'nodemailer'
// nosemgrep: javascript.lang.security.audit.path-traversal.path-join-resolve-traversal.path-join-resolve-traversal
@@ -81,7 +80,7 @@ async function loadLogoAsBase64() {
}
// Erstellt Newsletter-HTML mit Header und Footer
async function createNewsletterHTML(post, group, unsubscribeToken = null, creatorName = null, creatorEmail = null) {
async function createNewsletterHTML(post, group, unsubscribeToken = null, _creatorName = null, _creatorEmail = null) {
const config = await loadConfig()
const clubName = config.verein?.name || 'Harheimer Tischtennis-Club 1954 e.V.'
const baseUrl = process.env.NUXT_PUBLIC_BASE_URL || 'http://localhost:3100'

View File

@@ -1,7 +1,6 @@
import fs from 'fs/promises'
import path from 'path'
import { getUserFromToken, hasAnyRole } from '../../../../../utils/auth.js'
import { encryptObject, decryptObject } from '../../../../../utils/encryption.js'
// nosemgrep: javascript.lang.security.audit.path-traversal.path-join-resolve-traversal.path-join-resolve-traversal
// filename is always a hardcoded constant (e.g., 'newsletter-posts.json'), never user input
@@ -32,7 +31,7 @@ function isEncrypted(data) {
return false
}
return false
} catch (e) {
} catch (_e) {
return true
}
}
@@ -52,7 +51,7 @@ async function readPosts() {
const plainData = JSON.parse(data)
console.warn('Entschlüsselung fehlgeschlagen, versuche als unverschlüsseltes Format zu lesen')
return plainData
} catch (parseError) {
} catch (_parseError) {
console.error('Konnte Newsletter-Posts weder entschlüsseln noch als JSON lesen')
return []
}

View File

@@ -40,7 +40,7 @@ export default defineEventHandler(async (event) => {
isLoggedIn = true
}
}
} catch (e) {
} catch (_e) {
// Nicht eingeloggt - kein Problem
}

View File

@@ -1,4 +1,4 @@
import { verifyToken, getUserById, readUsers, writeUsers, verifyPassword, hashPassword, migrateUserRoles } from '../utils/auth.js'
import { verifyToken, readUsers, writeUsers, verifyPassword, hashPassword, migrateUserRoles } from '../utils/auth.js'
export default defineEventHandler(async (event) => {
try {

View File

@@ -8,7 +8,7 @@ export default defineEventHandler(async (event) => {
// Prüfe ob Datei existiert
try {
await fs.access(filePath)
} catch (error) {
} catch (_error) {
return {
success: false,
message: 'Spielplan-Datei nicht gefunden',

View File

@@ -60,7 +60,7 @@ export default defineEventHandler(async (event) => {
// Prüfe ob Datei existiert
try {
await fs.access(filePath)
} catch (error) {
} catch (_error) {
// Fallback: Erstelle eine informative HTML-Seite
const htmlContent = `
<!DOCTYPE html>

View File

@@ -19,7 +19,7 @@ export default defineEventHandler(async (event) => {
try {
csvContent = await fs.readFile(csvPath, 'utf-8')
} catch (error) {
} catch (_error) {
throw createError({
statusCode: 404,
statusMessage: 'Spielplandaten nicht gefunden'
@@ -192,7 +192,7 @@ export default defineEventHandler(async (event) => {
if (isNaN(spielDatum.getTime())) return false
return spielDatum >= currentSaisonStart && spielDatum <= currentSaisonEnd
} catch (error) {
} catch (_error) {
return false
}
})
@@ -357,7 +357,7 @@ ${hallenListe.map(halle => {
const tempDir = path.join(process.cwd(), 'temp')
try {
await fs.mkdir(tempDir, { recursive: true })
} catch (error) {
} catch (_error) {
// Verzeichnis existiert bereits
}
@@ -384,7 +384,7 @@ ${hallenListe.map(halle => {
await fs.unlink(pdfFile)
await fs.unlink(tempTexFile.replace('.tex', '.log'))
await fs.unlink(tempTexFile.replace('.tex', '.aux'))
} catch (error) {
} catch (_error) {
console.error('Fehler beim Löschen temporärer Dateien:', error)
}
}, 5000)

View File

@@ -63,7 +63,7 @@ function isEncrypted(data) {
return false
}
return false
} catch (e) {
} catch {
// JSON parsing failed - likely encrypted base64
return true
}
@@ -86,7 +86,7 @@ export async function readUsers() {
try {
users = JSON.parse(data)
console.warn('Entschlüsselung fehlgeschlagen, versuche als unverschlüsseltes Format zu lesen')
} catch (parseError) {
} catch (_parseError) {
console.error('Konnte Benutzerdaten weder entschlüsseln noch als JSON lesen')
return []
}
@@ -117,7 +117,7 @@ export async function readUsers() {
}
return users
} catch (error) {
} catch (_error) {
if (error.code === 'ENOENT') {
return []
}
@@ -133,7 +133,7 @@ export async function writeUsers(users) {
const encryptedData = encryptObject(users, encryptionKey)
await fs.writeFile(USERS_FILE, encryptedData, 'utf-8')
return true
} catch (error) {
} catch (_error) {
console.error('Fehler beim Schreiben der Benutzerdaten:', error)
return false
}
@@ -171,7 +171,7 @@ export async function readSessions() {
const plainData = JSON.parse(data)
console.warn('Entschlüsselung fehlgeschlagen, versuche als unverschlüsseltes Format zu lesen')
return plainData
} catch (parseError) {
} catch (_parseError) {
console.error('Konnte Sessions weder entschlüsseln noch als JSON lesen')
return []
}
@@ -183,7 +183,7 @@ export async function readSessions() {
await writeSessions(sessions)
return sessions
}
} catch (error) {
} catch (_error) {
if (error.code === 'ENOENT') {
return []
}
@@ -199,7 +199,7 @@ export async function writeSessions(sessions) {
const encryptedData = encryptObject(sessions, encryptionKey)
await fs.writeFile(SESSIONS_FILE, encryptedData, 'utf-8')
return true
} catch (error) {
} catch (_error) {
console.error('Fehler beim Schreiben der Sessions:', error)
return false
}
@@ -237,7 +237,7 @@ export function generateToken(user) {
export function verifyToken(token) {
try {
return jwt.verify(token, JWT_SECRET)
} catch (error) {
} catch (_error) {
return null
}
}

View File

@@ -41,7 +41,7 @@ function isEncrypted(data) {
return false
}
return false
} catch (e) {
} catch (_e) {
// JSON parsing failed - likely encrypted base64
return true
}
@@ -67,7 +67,7 @@ export async function readMembers() {
const plainData = JSON.parse(data)
console.warn('Entschlüsselung fehlgeschlagen, versuche als unverschlüsseltes Format zu lesen')
return plainData
} catch (parseError) {
} catch (_parseError) {
console.error('Konnte Mitgliederdaten weder entschlüsseln noch als JSON lesen')
return []
}
@@ -118,7 +118,7 @@ export function normalizeDate(dateString) {
const date = new Date(dateString)
if (isNaN(date.getTime())) return dateString.trim()
return date.toISOString().split('T')[0]
} catch (e) {
} catch (_e) {
return dateString.trim()
}
}

View File

@@ -34,7 +34,7 @@ function isEncrypted(data) {
return false
}
return false
} catch (e) {
} catch (_e) {
return true
}
}
@@ -54,7 +54,7 @@ export async function readSubscribers() {
const plainData = JSON.parse(data)
console.warn('Entschlüsselung fehlgeschlagen, versuche als unverschlüsseltes Format zu lesen')
return plainData
} catch (parseError) {
} catch (_parseError) {
console.error('Konnte Newsletter-Abonnenten weder entschlüsseln noch als JSON lesen')
return []
}

View File

@@ -17,7 +17,7 @@ function formatDateWithLeadingZeros(dateString) {
const month = String(date.getMonth() + 1).padStart(2, '0')
const year = date.getFullYear()
return `${day}.${month}.${year}`
} catch (error) {
} catch (_error) {
return dateString
}
}

View File

@@ -3,7 +3,7 @@
* Clean Code: Single Responsibility Principle
*/
import { PDFDocument, StandardFonts, rgb } from 'pdf-lib'
import { StandardFonts } from 'pdf-lib'
import { mapFieldValue, shouldCheckField, shouldCheckByValue } from './pdf-field-mapper.js'
/**
@@ -24,7 +24,7 @@ export function setTextFieldIfEmpty(field, value) {
return // Field already has content, don't overwrite
}
}
} catch (error) {
} catch (_error) {
// Ignore getter errors and proceed to set
}
@@ -66,11 +66,11 @@ export function setCheckboxIfNeeded(field, fieldName, data) {
if (!(typeof field.isChecked === 'function' && field.isChecked())) {
field.check && field.check()
}
} catch (error) {
} catch (_error) {
field.check && field.check()
}
}
} catch (error) {
} catch (_error) {
// Ignore errors
}
}
@@ -106,7 +106,7 @@ export async function fillFormFields(pdfDoc, form, data) {
try {
const helveticaFont = await pdfDoc.embedFont(StandardFonts.Helvetica)
form.updateFieldAppearances(helveticaFont)
} catch (error) {
} catch (_error) {
console.warn('Could not update field appearances:', error.message)
}
}
@@ -123,7 +123,7 @@ export async function fillPdfForm(pdfDoc, form, data) {
// Check if PLZ/Ort field on page 1 is empty and fix it
await fixPLZOrtField(pdfDoc, data)
} catch (error) {
} catch (_error) {
console.warn('Form filling failed, using fallback:', error.message)
await fillFormFieldsPositionally(pdfDoc, data)
}
@@ -137,8 +137,7 @@ export async function fillPdfForm(pdfDoc, form, data) {
async function fixPLZOrtField(pdfDoc, data) {
try {
const pages = pdfDoc.getPages()
const firstPage = pages[0]
const helveticaFont = await pdfDoc.embedFont(StandardFonts.Helvetica)
await pdfDoc.embedFont(StandardFonts.Helvetica)
// Draw PLZ/Ort at the correct position on page 1
const plzOrtText = `${data.plz || ''} ${data.ort || ''}`.trim()
@@ -161,7 +160,7 @@ async function fixPLZOrtField(pdfDoc, data) {
}
}
} catch (error) {
} catch (_error) {
console.warn('Could not fix PLZ/Ort field:', error.message)
}
}
@@ -222,7 +221,7 @@ async function fillFormFieldsPositionally(pdfDoc, data) {
firstPage.drawText('X', { x: 116, y: -8, size: 12, font: helveticaFont })
}
} catch (error) {
} catch (_error) {
console.error('Positional filling failed:', error.message)
}
}

View File

@@ -54,7 +54,7 @@ export class PDFGeneratorService {
const pdfBytes = await pdfDoc.save()
return new PDFGenerationResult(true, Buffer.from(pdfBytes), filename)
} catch (error) {
} catch (_error) {
console.error('Template PDF generation failed:', error.message)
return new PDFGenerationResult(false, null, null, error.message)
}
@@ -69,11 +69,11 @@ export class PDFGeneratorService {
try {
await fs.access(this.templatePath)
return this.templatePath
} catch (error) {
} catch (_error) {
try {
await fs.access(this.fallbackTemplatePath)
return this.fallbackTemplatePath
} catch (fallbackError) {
} catch (_fallbackError) {
throw new Error('No PDF template found')
}
}
@@ -86,7 +86,6 @@ export class PDFGeneratorService {
*/
generateFilename(data) {
const timestamp = Date.now()
const name = `${data.nachname || 'Unbekannt'}_${data.vorname || 'Unbekannt'}`
return `beitrittserklärung_${timestamp}.pdf`
}

View File

@@ -32,7 +32,7 @@ export const useAuthStore = defineStore('auth', {
this.roles = response.roles || (response.role ? [response.role] : [])
this.role = response.role || (this.roles.length > 0 ? this.roles[0] : null) // Rückwärtskompatibilität
return response
} catch (error) {
} catch (_error) {
this.isLoggedIn = false
this.user = null
this.roles = []
@@ -61,7 +61,7 @@ export const useAuthStore = defineStore('auth', {
this.user = null
this.roles = []
this.role = null
} catch (error) {
} catch (_error) {
console.error('Logout fehlgeschlagen:', error)
throw error
}