Verbessere Codequalität und Sicherheit durch Refactoring, Hinzufügen von ESLint-Regeln und Aktualisierung der OSV-Scanner-Konfiguration
This commit is contained in:
@@ -9,9 +9,6 @@ import { getClientIp } from '../../../utils/rate-limit.js'
|
||||
|
||||
// Local fallback for Nitro globals when lint/run env doesn't provide them
|
||||
const getMethod = globalThis.getMethod ?? ((e) => (e?.req?.method || e?.method || 'GET'))
|
||||
const getRequestURL = globalThis.getRequestURL ?? ((e) => {
|
||||
try { return new URL(e?.req?.url, 'http://localhost') } catch { return { href: String(e?.req?.url || ''), pathname: String(e?.req?.url || '').split('?')[0] || '' } }
|
||||
})
|
||||
|
||||
function findUserByCredentialId(users, credentialId) {
|
||||
const cid = String(credentialId || '')
|
||||
|
||||
@@ -613,7 +613,6 @@ export default defineEventHandler(async (event) => {
|
||||
// E-Mail senden via zentralen Service (pass full path)
|
||||
emailResult = await sendMembershipEmailUtil(data, finalPdfPath)
|
||||
// Antragsdaten verschlüsselt speichern
|
||||
const encryptionKey = process.env.ENCRYPTION_KEY || 'local_development_encryption_key_change_in_production'
|
||||
const encryptedData = JSON.stringify(data)
|
||||
// nosemgrep: javascript.lang.security.audit.path-traversal.path-join-resolve-traversal.path-join-resolve-traversal
|
||||
// filename is generated from timestamp, not user input, path traversal prevented
|
||||
@@ -674,7 +673,6 @@ export default defineEventHandler(async (event) => {
|
||||
emailResult = await sendMembershipEmailUtil(data, finalPdfPath)
|
||||
|
||||
// Antragsdaten verschlüsselt speichern
|
||||
const encryptionKey = process.env.ENCRYPTION_KEY || 'local_development_encryption_key_change_in_production'
|
||||
const encryptedData = JSON.stringify(data)
|
||||
// nosemgrep: javascript.lang.security.audit.path-traversal.path-join-resolve-traversal.path-join-resolve-traversal
|
||||
// filename is generated from timestamp, not user input, path traversal prevented
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import fs from 'fs/promises'
|
||||
import path from 'path'
|
||||
import { getUserFromToken, hasAnyRole } from '../../../../../utils/auth.js'
|
||||
import { decryptObject } from '../../../../../utils/encryption.js'
|
||||
|
||||
// nosemgrep: javascript.lang.security.audit.path-traversal.path-join-resolve-traversal.path-join-resolve-traversal
|
||||
// filename is always a hardcoded constant (e.g., 'newsletter-posts.json'), never user input
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { promises as fs } from 'fs'
|
||||
import path from 'path'
|
||||
import { getCurrentSeasonSlug, validateSeasonSlug } from '../../utils/spielplan-data.js'
|
||||
import { getServerDataPath } from '../../utils/paths.js'
|
||||
import { error as loggerError } from '../../utils/logger.js'
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { promises as fs } from 'fs'
|
||||
import path from 'path'
|
||||
import { randomUUID } from 'crypto'
|
||||
import { encrypt, decrypt, encryptObject, decryptObject } from './encryption.js'
|
||||
import { encryptObject, decryptObject } from './encryption.js'
|
||||
import { writeDataFileWithRotation } from './data-file-rotation.js'
|
||||
|
||||
// Handle both dev and production paths
|
||||
|
||||
@@ -106,7 +106,7 @@ export async function fillFormFields(pdfDoc, form, data) {
|
||||
try {
|
||||
const helveticaFont = await pdfDoc.embedFont(StandardFonts.Helvetica)
|
||||
form.updateFieldAppearances(helveticaFont)
|
||||
} catch (_error) {
|
||||
} catch (error) {
|
||||
console.warn('Could not update field appearances:', error.message)
|
||||
}
|
||||
}
|
||||
@@ -123,7 +123,7 @@ export async function fillPdfForm(pdfDoc, form, data) {
|
||||
|
||||
// Check if PLZ/Ort field on page 1 is empty and fix it
|
||||
await fixPLZOrtField(pdfDoc, data)
|
||||
} catch (_error) {
|
||||
} catch (error) {
|
||||
console.warn('Form filling failed, using fallback:', error.message)
|
||||
await fillFormFieldsPositionally(pdfDoc, data)
|
||||
}
|
||||
@@ -136,7 +136,6 @@ export async function fillPdfForm(pdfDoc, form, data) {
|
||||
*/
|
||||
async function fixPLZOrtField(pdfDoc, data) {
|
||||
try {
|
||||
const pages = pdfDoc.getPages()
|
||||
await pdfDoc.embedFont(StandardFonts.Helvetica)
|
||||
|
||||
// Draw PLZ/Ort at the correct position on page 1
|
||||
@@ -160,7 +159,7 @@ async function fixPLZOrtField(pdfDoc, data) {
|
||||
}
|
||||
}
|
||||
|
||||
} catch (_error) {
|
||||
} catch (error) {
|
||||
console.warn('Could not fix PLZ/Ort field:', error.message)
|
||||
}
|
||||
}
|
||||
@@ -221,7 +220,7 @@ async function fillFormFieldsPositionally(pdfDoc, data) {
|
||||
firstPage.drawText('X', { x: 116, y: -8, size: 12, font: helveticaFont })
|
||||
}
|
||||
|
||||
} catch (_error) {
|
||||
} catch (error) {
|
||||
console.error('Positional filling failed:', error.message)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ export class PDFGeneratorService {
|
||||
const pdfBytes = await pdfDoc.save()
|
||||
|
||||
return new PDFGenerationResult(true, Buffer.from(pdfBytes), filename)
|
||||
} catch (_error) {
|
||||
} catch (error) {
|
||||
console.error('Template PDF generation failed:', error.message)
|
||||
return new PDFGenerationResult(false, null, null, error.message)
|
||||
}
|
||||
@@ -84,7 +84,7 @@ export class PDFGeneratorService {
|
||||
* @param {Object} data - Form data
|
||||
* @returns {string} Filename
|
||||
*/
|
||||
generateFilename(data) {
|
||||
generateFilename(_data) {
|
||||
const timestamp = Date.now()
|
||||
return `beitrittserklärung_${timestamp}.pdf`
|
||||
}
|
||||
|
||||
@@ -57,16 +57,6 @@ function toNumberOrNull(value) {
|
||||
return Number.isNaN(numberValue) ? null : numberValue
|
||||
}
|
||||
|
||||
function normalizeName(value) {
|
||||
return String(value || '')
|
||||
.trim()
|
||||
.toLowerCase()
|
||||
.normalize('NFKD')
|
||||
.replace(/[\u0300-\u036f]/g, '')
|
||||
.replace(/\s+/g, ' ')
|
||||
.replace(/[’'`]/g, '')
|
||||
}
|
||||
|
||||
function normalizeGender(value) {
|
||||
const normalized = String(value || '').trim().toLowerCase()
|
||||
if (normalized === 'm' || normalized === 'männlich') return 'männlich'
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { promises as fs } from 'fs'
|
||||
import path from 'path'
|
||||
import { getProjectPath, getServerDataPath } from './paths.js'
|
||||
import { error as loggerError, info as loggerInfo } from './logger.js'
|
||||
import { error as loggerError } from './logger.js'
|
||||
|
||||
const SPIELPLAN_HEADERS = [
|
||||
'Termin',
|
||||
|
||||
@@ -12,10 +12,6 @@ const OUTPUT_DIR = getServerDataPath('spielplan-import')
|
||||
const JSON_FILE = path.join(OUTPUT_DIR, 'harheimer_tc_spielplan.json')
|
||||
const HTML_FILE = path.join(OUTPUT_DIR, 'harheimer_tc_spielplan.html')
|
||||
|
||||
function pad2(value) {
|
||||
return String(value).padStart(2, '0')
|
||||
}
|
||||
|
||||
export function getSpieljahrForDate(date = new Date()) {
|
||||
const year = date.getFullYear()
|
||||
const startYear = date.getMonth() >= 6 ? year : year - 1
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { promises as fs } from 'fs'
|
||||
import path from 'path'
|
||||
import { randomUUID } from 'crypto'
|
||||
import { writeDataFileWithRotation } from './data-file-rotation.js'
|
||||
|
||||
|
||||
Reference in New Issue
Block a user