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
Some checks failed
Code Analysis (JS/Vue) / analyze (push) Failing after 4m10s
This commit is contained in:
@@ -31,3 +31,18 @@ jobs:
|
|||||||
|
|
||||||
- name: Semgrep (SAST)
|
- name: Semgrep (SAST)
|
||||||
run: semgrep --config p/default --error .
|
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
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ const isMemberMenuOpen = ref(false)
|
|||||||
|
|
||||||
// Reactive auth state from store
|
// Reactive auth state from store
|
||||||
const isLoggedIn = computed(() => authStore.isLoggedIn)
|
const isLoggedIn = computed(() => authStore.isLoggedIn)
|
||||||
const isAdmin = computed(() => authStore.isAdmin)
|
// const isAdmin = computed(() => authStore.isAdmin)
|
||||||
|
|
||||||
const toggleMemberMenu = () => {
|
const toggleMemberMenu = () => {
|
||||||
isMemberMenuOpen.value = !isMemberMenuOpen.value
|
isMemberMenuOpen.value = !isMemberMenuOpen.value
|
||||||
|
|||||||
@@ -103,7 +103,7 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, onMounted } from 'vue'
|
import { ref, onMounted } from 'vue'
|
||||||
import { Calendar, Users, BarChart } from 'lucide-vue-next'
|
import { Users } from 'lucide-vue-next'
|
||||||
|
|
||||||
const mannschaften = ref([])
|
const mannschaften = ref([])
|
||||||
|
|
||||||
@@ -124,7 +124,7 @@ const loadMannschaften = async () => {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
mannschaften.value = lines.slice(1).map((line, index) => {
|
mannschaften.value = lines.slice(1).map((line, _index) => {
|
||||||
// Besserer CSV-Parser: Respektiert Anführungszeichen
|
// Besserer CSV-Parser: Respektiert Anführungszeichen
|
||||||
const values = []
|
const values = []
|
||||||
let current = ''
|
let current = ''
|
||||||
|
|||||||
@@ -280,7 +280,7 @@ const upcomingGames = computed(() => {
|
|||||||
|
|
||||||
// Nur Spiele der nächsten 7 Tage
|
// Nur Spiele der nächsten 7 Tage
|
||||||
return gameDate >= today && gameDate <= in7Days
|
return gameDate >= today && gameDate <= in7Days
|
||||||
} catch (error) {
|
} catch (_error) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
export default defineNuxtRouteMiddleware(async (to, from) => {
|
export default defineNuxtRouteMiddleware(async (to, _from) => {
|
||||||
// Only run on client-side
|
// Only run on client-side
|
||||||
if (process.server) return
|
if (process.server) return
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
export default defineNuxtRouteMiddleware(async (to, from) => {
|
export default defineNuxtRouteMiddleware(async (to, _from) => {
|
||||||
// Check if route requires auth
|
// Check if route requires auth
|
||||||
const protectedRoutes = ['/mitgliederbereich', '/cms']
|
const protectedRoutes = ['/mitgliederbereich', '/cms']
|
||||||
const requiresAuth = protectedRoutes.some(route => to.path.startsWith(route))
|
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)
|
return navigateTo('/login?redirect=' + to.path)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -362,7 +362,7 @@ const approveUser = async (user) => {
|
|||||||
setTimeout(() => successMessage.value = '', 3000)
|
setTimeout(() => successMessage.value = '', 3000)
|
||||||
|
|
||||||
await loadUsers()
|
await loadUsers()
|
||||||
} catch (error) {
|
} catch (_error) {
|
||||||
errorMessage.value = 'Fehler beim Freischalten des Benutzers'
|
errorMessage.value = 'Fehler beim Freischalten des Benutzers'
|
||||||
setTimeout(() => errorMessage.value = '', 3000)
|
setTimeout(() => errorMessage.value = '', 3000)
|
||||||
}
|
}
|
||||||
@@ -397,14 +397,14 @@ async function saveUserRoles() {
|
|||||||
|
|
||||||
closeRoleModal()
|
closeRoleModal()
|
||||||
await loadUsers()
|
await loadUsers()
|
||||||
} catch (error) {
|
} catch (_error) {
|
||||||
errorMessage.value = 'Fehler beim Aktualisieren der Rollen'
|
errorMessage.value = 'Fehler beim Aktualisieren der Rollen'
|
||||||
setTimeout(() => errorMessage.value = '', 3000)
|
setTimeout(() => errorMessage.value = '', 3000)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const rejectUser = async (user) => {
|
const rejectUser = async (user) => {
|
||||||
window.showConfirmModal('Registrierung ablehnen', `Möchten Sie die Registrierung von ${user.name} wirklich ablehnen?`, async () => {
|
window.showConfirmModal('Registrierung ablehnen', `Möchten Sie die Registrierung von ${user.name} wirklich ablehnen?`, async () => {
|
||||||
try {
|
try {
|
||||||
await $fetch('/api/cms/users/reject', {
|
await $fetch('/api/cms/users/reject', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
@@ -422,7 +422,7 @@ const rejectUser = async (user) => {
|
|||||||
|
|
||||||
|
|
||||||
const deactivateUser = async (user) => {
|
const deactivateUser = async (user) => {
|
||||||
window.showConfirmModal('Benutzer deaktivieren', `Möchten Sie ${user.name} wirklich deaktivieren?`, async () => {
|
window.showConfirmModal('Benutzer deaktivieren', `Möchten Sie ${user.name} wirklich deaktivieren?`, async () => {
|
||||||
try {
|
try {
|
||||||
await $fetch('/api/cms/users/deactivate', {
|
await $fetch('/api/cms/users/deactivate', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
|
|||||||
@@ -566,8 +566,6 @@
|
|||||||
import { ref, onMounted } from 'vue'
|
import { ref, onMounted } from 'vue'
|
||||||
import { Settings, Calendar, Users as UsersIcon, CreditCard, Plus, Trash2, X, Loader2, AlertCircle, Check } from 'lucide-vue-next'
|
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 isLoading = ref(true)
|
||||||
const isSaving = ref(false)
|
const isSaving = ref(false)
|
||||||
const errorMessage = ref('')
|
const errorMessage = ref('')
|
||||||
@@ -596,7 +594,7 @@ const loadConfig = async () => {
|
|||||||
try {
|
try {
|
||||||
const response = await $fetch('/api/config')
|
const response = await $fetch('/api/config')
|
||||||
config.value = response
|
config.value = response
|
||||||
} catch (error) {
|
} catch {
|
||||||
errorMessage.value = 'Fehler beim Laden der Konfiguration.'
|
errorMessage.value = 'Fehler beim Laden der Konfiguration.'
|
||||||
} finally {
|
} finally {
|
||||||
isLoading.value = false
|
isLoading.value = false
|
||||||
@@ -615,7 +613,7 @@ const saveConfig = async () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
successMessage.value = 'Konfiguration erfolgreich gespeichert!'
|
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
|
// Modal nicht verfügbar, ignorieren
|
||||||
}
|
}
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
@@ -623,7 +621,7 @@ const saveConfig = async () => {
|
|||||||
}, 3000)
|
}, 3000)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
errorMessage.value = error.data?.message || 'Fehler beim Speichern der Konfiguration.'
|
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
|
// Modal nicht verfügbar, ignorieren
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
|
|||||||
@@ -168,11 +168,11 @@ async function save() {
|
|||||||
const updated = { ...current, seiten: { ...(current.seiten || {}), geschichte: html } }
|
const updated = { ...current, seiten: { ...(current.seiten || {}), geschichte: html } }
|
||||||
try {
|
try {
|
||||||
await $fetch('/api/config', { method: 'PUT', body: updated })
|
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
|
// Modal nicht verfügbar, ignorieren
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} 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
|
// Modal nicht verfügbar, ignorieren
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -621,11 +621,11 @@ const closeUploadModal = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Drag and Drop Events
|
// Drag and Drop Events
|
||||||
const handleDragEnter = () => {
|
const _handleDragEnter = () => {
|
||||||
isDragOver.value = true
|
isDragOver.value = true
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleDragLeave = () => {
|
const _handleDragLeave = () => {
|
||||||
isDragOver.value = false
|
isDragOver.value = false
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -675,7 +675,7 @@ const loadExistingData = async () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (_error) {
|
} catch {
|
||||||
// Fehler beim Laden der Datei, ignorieren
|
// Fehler beim Laden der Datei, ignorieren
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -247,9 +247,7 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, onMounted } from 'vue'
|
import { ref, onMounted } from 'vue'
|
||||||
import { Calendar, Plus, Trash2, Loader2, AlertCircle, Pencil } from 'lucide-vue-next'
|
import { Plus, Trash2, Loader2, AlertCircle, Pencil } from 'lucide-vue-next'
|
||||||
|
|
||||||
const authStore = useAuthStore()
|
|
||||||
|
|
||||||
const isLoading = ref(true)
|
const isLoading = ref(true)
|
||||||
const isSaving = ref(false)
|
const isSaving = ref(false)
|
||||||
|
|||||||
@@ -193,11 +193,11 @@ async function save() {
|
|||||||
const updated = { ...current, seiten: { ...(current.seiten || {}), ttRegeln: html } }
|
const updated = { ...current, seiten: { ...(current.seiten || {}), ttRegeln: html } }
|
||||||
try {
|
try {
|
||||||
await $fetch('/api/config', { method: 'PUT', body: updated })
|
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
|
// Modal nicht verfügbar, ignorieren
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} 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
|
// 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>
|
<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>
|
</div>
|
||||||
`
|
`
|
||||||
bgColor = 'bg-green-50'
|
// bgColor = 'bg-green-50' // Nicht verwendet
|
||||||
break
|
break
|
||||||
case 'service':
|
case 'service':
|
||||||
template = `
|
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>
|
<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>
|
</div>
|
||||||
`
|
`
|
||||||
bgColor = 'bg-yellow-50'
|
// bgColor = 'bg-yellow-50'
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -120,11 +120,11 @@ async function save() {
|
|||||||
const updated = { ...current, seiten: { ...(current.seiten || {}), ueberUns: html } }
|
const updated = { ...current, seiten: { ...(current.seiten || {}), ueberUns: html } }
|
||||||
try {
|
try {
|
||||||
await $fetch('/api/config', { method: 'PUT', body: updated })
|
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
|
// Modal nicht verfügbar, ignorieren
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} 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
|
// Modal nicht verfügbar, ignorieren
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -135,7 +135,7 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, onMounted } from 'vue'
|
import { ref, onMounted } from 'vue'
|
||||||
import { Calendar, Users, BarChart } from 'lucide-vue-next'
|
import { Users } from 'lucide-vue-next'
|
||||||
|
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const mannschaft = ref(null)
|
const mannschaft = ref(null)
|
||||||
|
|||||||
@@ -283,7 +283,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, onMounted, computed } from 'vue'
|
import { ref, onMounted } from 'vue'
|
||||||
|
|
||||||
useHead({
|
useHead({
|
||||||
title: 'Spielpläne - Mannschaften - Harheimer TC'
|
title: 'Spielpläne - Mannschaften - Harheimer TC'
|
||||||
@@ -398,8 +398,6 @@ const filterData = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Zuerst nach aktueller Saison filtern (immer aktiv)
|
// 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
|
// Da die Spiele bis 2026 gehen, nehmen wir die Saison 2025/26
|
||||||
// Saison läuft vom 01.07. bis 30.06. des Folgejahres
|
// Saison läuft vom 01.07. bis 30.06. des Folgejahres
|
||||||
@@ -434,7 +432,7 @@ const filterData = () => {
|
|||||||
const inSaison = spielDatum >= saisonStart && spielDatum <= saisonEnd
|
const inSaison = spielDatum >= saisonStart && spielDatum <= saisonEnd
|
||||||
|
|
||||||
return inSaison
|
return inSaison
|
||||||
} catch (error) {
|
} catch (_error) {
|
||||||
console.error('Fehler beim Parsen von Termin:', termin, error)
|
console.error('Fehler beim Parsen von Termin:', termin, error)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@@ -738,7 +736,7 @@ const getRowClass = (row) => {
|
|||||||
|
|
||||||
// Standard: Weiß
|
// Standard: Weiß
|
||||||
return 'bg-white'
|
return 'bg-white'
|
||||||
} catch (error) {
|
} catch {
|
||||||
return 'bg-white'
|
return 'bg-white'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -771,7 +771,7 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, computed, onMounted } from 'vue'
|
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()
|
const authStore = useAuthStore()
|
||||||
|
|
||||||
@@ -1003,7 +1003,7 @@ const processBulkCSV = async (file) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Parse data rows
|
// Parse data rows
|
||||||
bulkPreviewData.value = lines.slice(1).map((line, index) => {
|
bulkPreviewData.value = lines.slice(1).map((line, _index) => {
|
||||||
const values = parseCSVLine(line)
|
const values = parseCSVLine(line)
|
||||||
return {
|
return {
|
||||||
firstName: values[firstNameIdx] || '',
|
firstName: values[firstNameIdx] || '',
|
||||||
|
|||||||
@@ -221,7 +221,7 @@ const loadProfile = async () => {
|
|||||||
email: response.user.email,
|
email: response.user.email,
|
||||||
phone: response.user.phone || ''
|
phone: response.user.phone || ''
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch {
|
||||||
errorMessage.value = 'Fehler beim Laden des Profils.'
|
errorMessage.value = 'Fehler beim Laden des Profils.'
|
||||||
} finally {
|
} finally {
|
||||||
isLoading.value = false
|
isLoading.value = false
|
||||||
|
|||||||
@@ -175,7 +175,7 @@ async function checkSubscription() {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
alreadySubscribed.value = response.subscribed || false
|
alreadySubscribed.value = response.subscribed || false
|
||||||
} catch (err) {
|
} catch (_err) {
|
||||||
// Fehler ignorieren - könnte bedeuten, dass nicht abonniert ist
|
// Fehler ignorieren - könnte bedeuten, dass nicht abonniert ist
|
||||||
alreadySubscribed.value = false
|
alreadySubscribed.value = false
|
||||||
} finally {
|
} finally {
|
||||||
|
|||||||
@@ -206,7 +206,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, onMounted, computed } from 'vue'
|
import { ref, onMounted } from 'vue'
|
||||||
|
|
||||||
useHead({
|
useHead({
|
||||||
title: 'Spielplan - Harheimer TC'
|
title: 'Spielplan - Harheimer TC'
|
||||||
|
|||||||
@@ -243,7 +243,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<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({
|
useHead({
|
||||||
title: 'TT-Regeln - Harheimer TC',
|
title: 'TT-Regeln - Harheimer TC',
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ async function loadConfig() {
|
|||||||
try {
|
try {
|
||||||
const data = await $fetch('/api/config')
|
const data = await $fetch('/api/config')
|
||||||
rawContent.value = data?.seiten?.geschichte || ''
|
rawContent.value = data?.seiten?.geschichte || ''
|
||||||
} catch (_e) {
|
} catch {
|
||||||
rawContent.value = ''
|
rawContent.value = ''
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ async function loadConfig() {
|
|||||||
try {
|
try {
|
||||||
const data = await $fetch('/api/config')
|
const data = await $fetch('/api/config')
|
||||||
rawContent.value = data?.seiten?.ttRegeln || ''
|
rawContent.value = data?.seiten?.ttRegeln || ''
|
||||||
} catch (_e) {
|
} catch {
|
||||||
rawContent.value = ''
|
rawContent.value = ''
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ async function loadConfig() {
|
|||||||
try {
|
try {
|
||||||
const data = await $fetch('/api/config')
|
const data = await $fetch('/api/config')
|
||||||
rawContent.value = data?.seiten?.ueberUns || ''
|
rawContent.value = data?.seiten?.ueberUns || ''
|
||||||
} catch (_e) {
|
} catch {
|
||||||
rawContent.value = ''
|
rawContent.value = ''
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -97,7 +97,7 @@ export default defineEventHandler(async (event) => {
|
|||||||
// Versuche pdftotext zu verwenden (falls auf dem System installiert)
|
// Versuche pdftotext zu verwenden (falls auf dem System installiert)
|
||||||
const { stdout } = await execAsync(`pdftotext "${file.path}" -`)
|
const { stdout } = await execAsync(`pdftotext "${file.path}" -`)
|
||||||
extractedText = stdout
|
extractedText = stdout
|
||||||
} catch (error) {
|
} catch (_error) {
|
||||||
console.log('pdftotext nicht verfügbar, verwende Fallback-Text')
|
console.log('pdftotext nicht verfügbar, verwende Fallback-Text')
|
||||||
// Fallback: Verwende den bekannten Satzungsinhalt
|
// Fallback: Verwende den bekannten Satzungsinhalt
|
||||||
extractedText = `Vereinssatzung
|
extractedText = `Vereinssatzung
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ const getDataPath = (filename) => {
|
|||||||
return path.join(cwd, 'server/data', filename)
|
return path.join(cwd, 'server/data', filename)
|
||||||
}
|
}
|
||||||
|
|
||||||
export default defineEventHandler(async (event) => {
|
export default defineEventHandler(async (_event) => {
|
||||||
try {
|
try {
|
||||||
const configFile = getDataPath('config.json')
|
const configFile = getDataPath('config.json')
|
||||||
const data = await fs.readFile(configFile, 'utf-8')
|
const data = await fs.readFile(configFile, 'utf-8')
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { verifyToken, getUserById, hasAnyRole, readUsers, writeUsers } from '../../utils/auth.js'
|
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) => {
|
export default defineEventHandler(async (event) => {
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -3,10 +3,9 @@ import { exec } from 'child_process'
|
|||||||
import { promisify } from 'util'
|
import { promisify } from 'util'
|
||||||
import fs from 'fs/promises'
|
import fs from 'fs/promises'
|
||||||
import path from 'path'
|
import path from 'path'
|
||||||
import { encrypt } from '../../utils/encryption.js'
|
import { StandardFonts } from 'pdf-lib'
|
||||||
import { PDFDocument, rgb, StandardFonts } from 'pdf-lib'
|
|
||||||
|
|
||||||
const require = createRequire(import.meta.url)
|
// const require = createRequire(import.meta.url) // Nicht verwendet
|
||||||
const execAsync = promisify(exec)
|
const execAsync = promisify(exec)
|
||||||
|
|
||||||
function mapFieldValue(data, name) {
|
function mapFieldValue(data, name) {
|
||||||
@@ -39,7 +38,7 @@ function setTextFieldIfEmpty(field, val) {
|
|||||||
const cur = field.getText()
|
const cur = field.getText()
|
||||||
if (cur && String(cur).trim() !== '') return
|
if (cur && String(cur).trim() !== '') return
|
||||||
}
|
}
|
||||||
} catch (_e) {
|
} catch {
|
||||||
// Feld nicht lesbar, ignorieren
|
// Feld nicht lesbar, ignorieren
|
||||||
}
|
}
|
||||||
if (val != null && String(val).trim() !== '') field.setText(val)
|
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') {
|
if (mapped === 'true' || mapped === 'ja' || mapped === 'checked') {
|
||||||
try {
|
try {
|
||||||
if (!(typeof field.isChecked === 'function' && field.isChecked())) field.check && field.check()
|
if (!(typeof field.isChecked === 'function' && field.isChecked())) field.check && field.check()
|
||||||
} catch (_e) {
|
} catch {
|
||||||
field.check && field.check()
|
field.check && field.check()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (_e) {
|
} catch {
|
||||||
// Feld nicht verarbeitbar, ignorieren
|
// Feld nicht verarbeitbar, ignorieren
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -87,7 +86,7 @@ async function fillFormFields(pdfDoc, form, data) {
|
|||||||
try {
|
try {
|
||||||
const helv2 = await pdfDoc.embedFont(StandardFonts.Helvetica)
|
const helv2 = await pdfDoc.embedFont(StandardFonts.Helvetica)
|
||||||
form.updateFieldAppearances(helv2)
|
form.updateFieldAppearances(helv2)
|
||||||
} catch (_e) {
|
} catch {
|
||||||
// Schriftart nicht einbettbar, ignorieren
|
// Schriftart nicht einbettbar, ignorieren
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -285,7 +284,7 @@ Unterschrift ${data.isVolljaehrig ? '' : '(bei Minderjährigen Unterschrift eine
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
async function generateSimplePDF(data, filename, event) {
|
async function generateSimplePDF(data, filename, _event) {
|
||||||
// Fallback: HTML zu PDF mit puppeteer oder ähnlich
|
// Fallback: HTML zu PDF mit puppeteer oder ähnlich
|
||||||
// Für jetzt: Einfache Textdatei
|
// Für jetzt: Einfache Textdatei
|
||||||
const textContent = `
|
const textContent = `
|
||||||
@@ -317,7 +316,7 @@ function getDataPath(filename) {
|
|||||||
return path.join(projectRoot, 'server', 'data', filename)
|
return path.join(projectRoot, 'server', 'data', filename)
|
||||||
}
|
}
|
||||||
|
|
||||||
async function sendMembershipEmail(data, filename, event) {
|
async function sendMembershipEmail(data, _filename, _event) {
|
||||||
try {
|
try {
|
||||||
const configPath = getDataPath('config.json')
|
const configPath = getDataPath('config.json')
|
||||||
const configData = await fs.readFile(configPath, 'utf8')
|
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}`)
|
if (!res.ok) throw new Error(`Template konnte nicht geladen werden: ${res.status}`)
|
||||||
arrayBuffer = await res.arrayBuffer()
|
arrayBuffer = await res.arrayBuffer()
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (_e) {
|
||||||
throw new Error('Template-Laden fehlgeschlagen: ' + e.message)
|
throw new Error('Template-Laden fehlgeschlagen: ' + e.message)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -433,7 +432,7 @@ export default defineEventHandler(async (event) => {
|
|||||||
let form
|
let form
|
||||||
try {
|
try {
|
||||||
form = pdfDoc.getForm()
|
form = pdfDoc.getForm()
|
||||||
} catch (e) {
|
} catch (_e) {
|
||||||
form = null
|
form = null
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -442,7 +441,7 @@ export default defineEventHandler(async (event) => {
|
|||||||
// Koordinaten (in PDF-Punkten) müssen ggf. feinjustiert werden.
|
// Koordinaten (in PDF-Punkten) müssen ggf. feinjustiert werden.
|
||||||
const pages = pdfDoc.getPages()
|
const pages = pdfDoc.getPages()
|
||||||
const firstPage = pages[0]
|
const firstPage = pages[0]
|
||||||
const { width, height } = firstPage.getSize()
|
firstPage.getSize()
|
||||||
|
|
||||||
// Schätzwerte: (x, y) in Punkten von linker unteren Ecke
|
// Schätzwerte: (x, y) in Punkten von linker unteren Ecke
|
||||||
// Diese Werte müssen nach Sichtprüfung justiert werden.
|
// Diese Werte müssen nach Sichtprüfung justiert werden.
|
||||||
@@ -522,7 +521,7 @@ export default defineEventHandler(async (event) => {
|
|||||||
} else if (data.mitgliedschaftsart === 'passiv') {
|
} else if (data.mitgliedschaftsart === 'passiv') {
|
||||||
firstPage.drawText('X', { x: coords.mitglied_checkbox_passiv.x, y: coords.mitglied_checkbox_passiv.y, size: 12, font: helveticaFont })
|
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)
|
console.warn('Fehler beim Zeichnen der Checkbox:', e.message)
|
||||||
}
|
}
|
||||||
// Debug overlay: zeichne Marker an allen Koordinaten, wenn data.debug === true
|
// 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
|
// 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 })
|
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)
|
console.warn('Debug overlay fehlgeschlagen:', e.message)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (_e) {
|
||||||
console.warn('Fehler beim positional drawing:', e.message)
|
console.warn('Fehler beim positional drawing:', e.message)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -601,7 +600,7 @@ export default defineEventHandler(async (event) => {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (_e) {
|
||||||
// ignore getter errors and proceed to set
|
// ignore getter errors and proceed to set
|
||||||
}
|
}
|
||||||
const val = mapValue(lower)
|
const val = mapValue(lower)
|
||||||
@@ -626,7 +625,7 @@ export default defineEventHandler(async (event) => {
|
|||||||
if (lower.includes('passiv') && data.mitgliedschaftsart === 'passiv') field.check && field.check()
|
if (lower.includes('passiv') && data.mitgliedschaftsart === 'passiv') field.check && field.check()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (_e) {
|
||||||
// ignore isChecked errors
|
// ignore isChecked errors
|
||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
@@ -637,12 +636,12 @@ export default defineEventHandler(async (event) => {
|
|||||||
if (!(typeof field.isChecked === 'function' && field.isChecked())) {
|
if (!(typeof field.isChecked === 'function' && field.isChecked())) {
|
||||||
field.check && field.check()
|
field.check && field.check()
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (_e) {
|
||||||
field.check && field.check()
|
field.check && field.check()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (_e) {
|
||||||
console.warn('Fehler beim Befüllen Feld', fname, e.message)
|
console.warn('Fehler beim Befüllen Feld', fname, e.message)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -651,7 +650,7 @@ export default defineEventHandler(async (event) => {
|
|||||||
try {
|
try {
|
||||||
const helv2 = await pdfDoc.embedFont(StandardFonts.Helvetica)
|
const helv2 = await pdfDoc.embedFont(StandardFonts.Helvetica)
|
||||||
form.updateFieldAppearances(helv2)
|
form.updateFieldAppearances(helv2)
|
||||||
} catch (e) {
|
} catch (_e) {
|
||||||
console.warn('Warning: could not update field appearances after mapping fields:', e.message)
|
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
|
// 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
|
// nosemgrep: javascript.lang.security.audit.path-traversal.path-join-resolve-traversal.path-join-resolve-traversal
|
||||||
await fs.copyFile(finalPdfPath, path.join(repoUploads, `${filename}.pdf`))
|
await fs.copyFile(finalPdfPath, path.join(repoUploads, `${filename}.pdf`))
|
||||||
} catch (e) {
|
} catch (_e) {
|
||||||
console.warn('Kopie in repo public/uploads fehlgeschlagen:', e.message)
|
console.warn('Kopie in repo public/uploads fehlgeschlagen:', e.message)
|
||||||
}
|
}
|
||||||
usedTemplate = true
|
usedTemplate = true
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import fs from 'fs/promises'
|
import fs from 'fs/promises'
|
||||||
import path from 'path'
|
import path from 'path'
|
||||||
import { decryptObject, encryptObject } from '../../utils/encryption.js'
|
import { decryptObject } from '../../utils/encryption.js'
|
||||||
import { saveMember } from '../../utils/members.js'
|
import { saveMember } from '../../utils/members.js'
|
||||||
|
|
||||||
export default defineEventHandler(async (event) => {
|
export default defineEventHandler(async (event) => {
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ import path from 'path'
|
|||||||
import { getUserFromToken, hasAnyRole } from '../../../../../utils/auth.js'
|
import { getUserFromToken, hasAnyRole } from '../../../../../utils/auth.js'
|
||||||
import { randomUUID } from 'crypto'
|
import { randomUUID } from 'crypto'
|
||||||
import { getRecipientsByGroup, getNewsletterSubscribers, generateUnsubscribeToken } from '../../../../../utils/newsletter.js'
|
import { getRecipientsByGroup, getNewsletterSubscribers, generateUnsubscribeToken } from '../../../../../utils/newsletter.js'
|
||||||
import { encryptObject, decryptObject } from '../../../../../utils/encryption.js'
|
|
||||||
import nodemailer from 'nodemailer'
|
import nodemailer from 'nodemailer'
|
||||||
|
|
||||||
// nosemgrep: javascript.lang.security.audit.path-traversal.path-join-resolve-traversal.path-join-resolve-traversal
|
// 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
|
// 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 config = await loadConfig()
|
||||||
const clubName = config.verein?.name || 'Harheimer Tischtennis-Club 1954 e.V.'
|
const clubName = config.verein?.name || 'Harheimer Tischtennis-Club 1954 e.V.'
|
||||||
const baseUrl = process.env.NUXT_PUBLIC_BASE_URL || 'http://localhost:3100'
|
const baseUrl = process.env.NUXT_PUBLIC_BASE_URL || 'http://localhost:3100'
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import fs from 'fs/promises'
|
import fs from 'fs/promises'
|
||||||
import path from 'path'
|
import path from 'path'
|
||||||
import { getUserFromToken, hasAnyRole } from '../../../../../utils/auth.js'
|
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
|
// 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
|
// 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
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
} catch (e) {
|
} catch (_e) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -52,7 +51,7 @@ async function readPosts() {
|
|||||||
const plainData = JSON.parse(data)
|
const plainData = JSON.parse(data)
|
||||||
console.warn('Entschlüsselung fehlgeschlagen, versuche als unverschlüsseltes Format zu lesen')
|
console.warn('Entschlüsselung fehlgeschlagen, versuche als unverschlüsseltes Format zu lesen')
|
||||||
return plainData
|
return plainData
|
||||||
} catch (parseError) {
|
} catch (_parseError) {
|
||||||
console.error('Konnte Newsletter-Posts weder entschlüsseln noch als JSON lesen')
|
console.error('Konnte Newsletter-Posts weder entschlüsseln noch als JSON lesen')
|
||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ export default defineEventHandler(async (event) => {
|
|||||||
isLoggedIn = true
|
isLoggedIn = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (_e) {
|
||||||
// Nicht eingeloggt - kein Problem
|
// Nicht eingeloggt - kein Problem
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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) => {
|
export default defineEventHandler(async (event) => {
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ export default defineEventHandler(async (event) => {
|
|||||||
// Prüfe ob Datei existiert
|
// Prüfe ob Datei existiert
|
||||||
try {
|
try {
|
||||||
await fs.access(filePath)
|
await fs.access(filePath)
|
||||||
} catch (error) {
|
} catch (_error) {
|
||||||
return {
|
return {
|
||||||
success: false,
|
success: false,
|
||||||
message: 'Spielplan-Datei nicht gefunden',
|
message: 'Spielplan-Datei nicht gefunden',
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ export default defineEventHandler(async (event) => {
|
|||||||
// Prüfe ob Datei existiert
|
// Prüfe ob Datei existiert
|
||||||
try {
|
try {
|
||||||
await fs.access(filePath)
|
await fs.access(filePath)
|
||||||
} catch (error) {
|
} catch (_error) {
|
||||||
// Fallback: Erstelle eine informative HTML-Seite
|
// Fallback: Erstelle eine informative HTML-Seite
|
||||||
const htmlContent = `
|
const htmlContent = `
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ export default defineEventHandler(async (event) => {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
csvContent = await fs.readFile(csvPath, 'utf-8')
|
csvContent = await fs.readFile(csvPath, 'utf-8')
|
||||||
} catch (error) {
|
} catch (_error) {
|
||||||
throw createError({
|
throw createError({
|
||||||
statusCode: 404,
|
statusCode: 404,
|
||||||
statusMessage: 'Spielplandaten nicht gefunden'
|
statusMessage: 'Spielplandaten nicht gefunden'
|
||||||
@@ -192,7 +192,7 @@ export default defineEventHandler(async (event) => {
|
|||||||
if (isNaN(spielDatum.getTime())) return false
|
if (isNaN(spielDatum.getTime())) return false
|
||||||
|
|
||||||
return spielDatum >= currentSaisonStart && spielDatum <= currentSaisonEnd
|
return spielDatum >= currentSaisonStart && spielDatum <= currentSaisonEnd
|
||||||
} catch (error) {
|
} catch (_error) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -357,7 +357,7 @@ ${hallenListe.map(halle => {
|
|||||||
const tempDir = path.join(process.cwd(), 'temp')
|
const tempDir = path.join(process.cwd(), 'temp')
|
||||||
try {
|
try {
|
||||||
await fs.mkdir(tempDir, { recursive: true })
|
await fs.mkdir(tempDir, { recursive: true })
|
||||||
} catch (error) {
|
} catch (_error) {
|
||||||
// Verzeichnis existiert bereits
|
// Verzeichnis existiert bereits
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -384,7 +384,7 @@ ${hallenListe.map(halle => {
|
|||||||
await fs.unlink(pdfFile)
|
await fs.unlink(pdfFile)
|
||||||
await fs.unlink(tempTexFile.replace('.tex', '.log'))
|
await fs.unlink(tempTexFile.replace('.tex', '.log'))
|
||||||
await fs.unlink(tempTexFile.replace('.tex', '.aux'))
|
await fs.unlink(tempTexFile.replace('.tex', '.aux'))
|
||||||
} catch (error) {
|
} catch (_error) {
|
||||||
console.error('Fehler beim Löschen temporärer Dateien:', error)
|
console.error('Fehler beim Löschen temporärer Dateien:', error)
|
||||||
}
|
}
|
||||||
}, 5000)
|
}, 5000)
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ function isEncrypted(data) {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
} catch (e) {
|
} catch {
|
||||||
// JSON parsing failed - likely encrypted base64
|
// JSON parsing failed - likely encrypted base64
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@@ -86,7 +86,7 @@ export async function readUsers() {
|
|||||||
try {
|
try {
|
||||||
users = JSON.parse(data)
|
users = JSON.parse(data)
|
||||||
console.warn('Entschlüsselung fehlgeschlagen, versuche als unverschlüsseltes Format zu lesen')
|
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')
|
console.error('Konnte Benutzerdaten weder entschlüsseln noch als JSON lesen')
|
||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
@@ -117,7 +117,7 @@ export async function readUsers() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return users
|
return users
|
||||||
} catch (error) {
|
} catch (_error) {
|
||||||
if (error.code === 'ENOENT') {
|
if (error.code === 'ENOENT') {
|
||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
@@ -133,7 +133,7 @@ export async function writeUsers(users) {
|
|||||||
const encryptedData = encryptObject(users, encryptionKey)
|
const encryptedData = encryptObject(users, encryptionKey)
|
||||||
await fs.writeFile(USERS_FILE, encryptedData, 'utf-8')
|
await fs.writeFile(USERS_FILE, encryptedData, 'utf-8')
|
||||||
return true
|
return true
|
||||||
} catch (error) {
|
} catch (_error) {
|
||||||
console.error('Fehler beim Schreiben der Benutzerdaten:', error)
|
console.error('Fehler beim Schreiben der Benutzerdaten:', error)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@@ -171,7 +171,7 @@ export async function readSessions() {
|
|||||||
const plainData = JSON.parse(data)
|
const plainData = JSON.parse(data)
|
||||||
console.warn('Entschlüsselung fehlgeschlagen, versuche als unverschlüsseltes Format zu lesen')
|
console.warn('Entschlüsselung fehlgeschlagen, versuche als unverschlüsseltes Format zu lesen')
|
||||||
return plainData
|
return plainData
|
||||||
} catch (parseError) {
|
} catch (_parseError) {
|
||||||
console.error('Konnte Sessions weder entschlüsseln noch als JSON lesen')
|
console.error('Konnte Sessions weder entschlüsseln noch als JSON lesen')
|
||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
@@ -183,7 +183,7 @@ export async function readSessions() {
|
|||||||
await writeSessions(sessions)
|
await writeSessions(sessions)
|
||||||
return sessions
|
return sessions
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (_error) {
|
||||||
if (error.code === 'ENOENT') {
|
if (error.code === 'ENOENT') {
|
||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
@@ -199,7 +199,7 @@ export async function writeSessions(sessions) {
|
|||||||
const encryptedData = encryptObject(sessions, encryptionKey)
|
const encryptedData = encryptObject(sessions, encryptionKey)
|
||||||
await fs.writeFile(SESSIONS_FILE, encryptedData, 'utf-8')
|
await fs.writeFile(SESSIONS_FILE, encryptedData, 'utf-8')
|
||||||
return true
|
return true
|
||||||
} catch (error) {
|
} catch (_error) {
|
||||||
console.error('Fehler beim Schreiben der Sessions:', error)
|
console.error('Fehler beim Schreiben der Sessions:', error)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@@ -237,7 +237,7 @@ export function generateToken(user) {
|
|||||||
export function verifyToken(token) {
|
export function verifyToken(token) {
|
||||||
try {
|
try {
|
||||||
return jwt.verify(token, JWT_SECRET)
|
return jwt.verify(token, JWT_SECRET)
|
||||||
} catch (error) {
|
} catch (_error) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ function isEncrypted(data) {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
} catch (e) {
|
} catch (_e) {
|
||||||
// JSON parsing failed - likely encrypted base64
|
// JSON parsing failed - likely encrypted base64
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@@ -67,7 +67,7 @@ export async function readMembers() {
|
|||||||
const plainData = JSON.parse(data)
|
const plainData = JSON.parse(data)
|
||||||
console.warn('Entschlüsselung fehlgeschlagen, versuche als unverschlüsseltes Format zu lesen')
|
console.warn('Entschlüsselung fehlgeschlagen, versuche als unverschlüsseltes Format zu lesen')
|
||||||
return plainData
|
return plainData
|
||||||
} catch (parseError) {
|
} catch (_parseError) {
|
||||||
console.error('Konnte Mitgliederdaten weder entschlüsseln noch als JSON lesen')
|
console.error('Konnte Mitgliederdaten weder entschlüsseln noch als JSON lesen')
|
||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
@@ -118,7 +118,7 @@ export function normalizeDate(dateString) {
|
|||||||
const date = new Date(dateString)
|
const date = new Date(dateString)
|
||||||
if (isNaN(date.getTime())) return dateString.trim()
|
if (isNaN(date.getTime())) return dateString.trim()
|
||||||
return date.toISOString().split('T')[0]
|
return date.toISOString().split('T')[0]
|
||||||
} catch (e) {
|
} catch (_e) {
|
||||||
return dateString.trim()
|
return dateString.trim()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ function isEncrypted(data) {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
} catch (e) {
|
} catch (_e) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -54,7 +54,7 @@ export async function readSubscribers() {
|
|||||||
const plainData = JSON.parse(data)
|
const plainData = JSON.parse(data)
|
||||||
console.warn('Entschlüsselung fehlgeschlagen, versuche als unverschlüsseltes Format zu lesen')
|
console.warn('Entschlüsselung fehlgeschlagen, versuche als unverschlüsseltes Format zu lesen')
|
||||||
return plainData
|
return plainData
|
||||||
} catch (parseError) {
|
} catch (_parseError) {
|
||||||
console.error('Konnte Newsletter-Abonnenten weder entschlüsseln noch als JSON lesen')
|
console.error('Konnte Newsletter-Abonnenten weder entschlüsseln noch als JSON lesen')
|
||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ function formatDateWithLeadingZeros(dateString) {
|
|||||||
const month = String(date.getMonth() + 1).padStart(2, '0')
|
const month = String(date.getMonth() + 1).padStart(2, '0')
|
||||||
const year = date.getFullYear()
|
const year = date.getFullYear()
|
||||||
return `${day}.${month}.${year}`
|
return `${day}.${month}.${year}`
|
||||||
} catch (error) {
|
} catch (_error) {
|
||||||
return dateString
|
return dateString
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
* Clean Code: Single Responsibility Principle
|
* 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'
|
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
|
return // Field already has content, don't overwrite
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (_error) {
|
||||||
// Ignore getter errors and proceed to set
|
// Ignore getter errors and proceed to set
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -66,11 +66,11 @@ export function setCheckboxIfNeeded(field, fieldName, data) {
|
|||||||
if (!(typeof field.isChecked === 'function' && field.isChecked())) {
|
if (!(typeof field.isChecked === 'function' && field.isChecked())) {
|
||||||
field.check && field.check()
|
field.check && field.check()
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (_error) {
|
||||||
field.check && field.check()
|
field.check && field.check()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (_error) {
|
||||||
// Ignore errors
|
// Ignore errors
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -106,7 +106,7 @@ export async function fillFormFields(pdfDoc, form, data) {
|
|||||||
try {
|
try {
|
||||||
const helveticaFont = await pdfDoc.embedFont(StandardFonts.Helvetica)
|
const helveticaFont = await pdfDoc.embedFont(StandardFonts.Helvetica)
|
||||||
form.updateFieldAppearances(helveticaFont)
|
form.updateFieldAppearances(helveticaFont)
|
||||||
} catch (error) {
|
} catch (_error) {
|
||||||
console.warn('Could not update field appearances:', error.message)
|
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
|
// Check if PLZ/Ort field on page 1 is empty and fix it
|
||||||
await fixPLZOrtField(pdfDoc, data)
|
await fixPLZOrtField(pdfDoc, data)
|
||||||
} catch (error) {
|
} catch (_error) {
|
||||||
console.warn('Form filling failed, using fallback:', error.message)
|
console.warn('Form filling failed, using fallback:', error.message)
|
||||||
await fillFormFieldsPositionally(pdfDoc, data)
|
await fillFormFieldsPositionally(pdfDoc, data)
|
||||||
}
|
}
|
||||||
@@ -137,8 +137,7 @@ export async function fillPdfForm(pdfDoc, form, data) {
|
|||||||
async function fixPLZOrtField(pdfDoc, data) {
|
async function fixPLZOrtField(pdfDoc, data) {
|
||||||
try {
|
try {
|
||||||
const pages = pdfDoc.getPages()
|
const pages = pdfDoc.getPages()
|
||||||
const firstPage = pages[0]
|
await pdfDoc.embedFont(StandardFonts.Helvetica)
|
||||||
const helveticaFont = await pdfDoc.embedFont(StandardFonts.Helvetica)
|
|
||||||
|
|
||||||
// Draw PLZ/Ort at the correct position on page 1
|
// Draw PLZ/Ort at the correct position on page 1
|
||||||
const plzOrtText = `${data.plz || ''} ${data.ort || ''}`.trim()
|
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)
|
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 })
|
firstPage.drawText('X', { x: 116, y: -8, size: 12, font: helveticaFont })
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (error) {
|
} catch (_error) {
|
||||||
console.error('Positional filling failed:', error.message)
|
console.error('Positional filling failed:', error.message)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ export class PDFGeneratorService {
|
|||||||
const pdfBytes = await pdfDoc.save()
|
const pdfBytes = await pdfDoc.save()
|
||||||
|
|
||||||
return new PDFGenerationResult(true, Buffer.from(pdfBytes), filename)
|
return new PDFGenerationResult(true, Buffer.from(pdfBytes), filename)
|
||||||
} catch (error) {
|
} catch (_error) {
|
||||||
console.error('Template PDF generation failed:', error.message)
|
console.error('Template PDF generation failed:', error.message)
|
||||||
return new PDFGenerationResult(false, null, null, error.message)
|
return new PDFGenerationResult(false, null, null, error.message)
|
||||||
}
|
}
|
||||||
@@ -69,11 +69,11 @@ export class PDFGeneratorService {
|
|||||||
try {
|
try {
|
||||||
await fs.access(this.templatePath)
|
await fs.access(this.templatePath)
|
||||||
return this.templatePath
|
return this.templatePath
|
||||||
} catch (error) {
|
} catch (_error) {
|
||||||
try {
|
try {
|
||||||
await fs.access(this.fallbackTemplatePath)
|
await fs.access(this.fallbackTemplatePath)
|
||||||
return this.fallbackTemplatePath
|
return this.fallbackTemplatePath
|
||||||
} catch (fallbackError) {
|
} catch (_fallbackError) {
|
||||||
throw new Error('No PDF template found')
|
throw new Error('No PDF template found')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -86,7 +86,6 @@ export class PDFGeneratorService {
|
|||||||
*/
|
*/
|
||||||
generateFilename(data) {
|
generateFilename(data) {
|
||||||
const timestamp = Date.now()
|
const timestamp = Date.now()
|
||||||
const name = `${data.nachname || 'Unbekannt'}_${data.vorname || 'Unbekannt'}`
|
|
||||||
return `beitrittserklärung_${timestamp}.pdf`
|
return `beitrittserklärung_${timestamp}.pdf`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ export const useAuthStore = defineStore('auth', {
|
|||||||
this.roles = response.roles || (response.role ? [response.role] : [])
|
this.roles = response.roles || (response.role ? [response.role] : [])
|
||||||
this.role = response.role || (this.roles.length > 0 ? this.roles[0] : null) // Rückwärtskompatibilität
|
this.role = response.role || (this.roles.length > 0 ? this.roles[0] : null) // Rückwärtskompatibilität
|
||||||
return response
|
return response
|
||||||
} catch (error) {
|
} catch (_error) {
|
||||||
this.isLoggedIn = false
|
this.isLoggedIn = false
|
||||||
this.user = null
|
this.user = null
|
||||||
this.roles = []
|
this.roles = []
|
||||||
@@ -61,7 +61,7 @@ export const useAuthStore = defineStore('auth', {
|
|||||||
this.user = null
|
this.user = null
|
||||||
this.roles = []
|
this.roles = []
|
||||||
this.role = null
|
this.role = null
|
||||||
} catch (error) {
|
} catch (_error) {
|
||||||
console.error('Logout fehlgeschlagen:', error)
|
console.error('Logout fehlgeschlagen:', error)
|
||||||
throw error
|
throw error
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user