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.
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,7 +397,7 @@ 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)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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