Files
harheimertc/server/api/newsletter/unsubscribe-by-email.post.js
2025-12-20 11:15:31 +01:00

126 lines
3.5 KiB
JavaScript

import { readSubscribers, writeSubscribers } from '../../utils/newsletter.js'
import fs from 'fs/promises'
import path from 'path'
// nosemgrep: javascript.lang.security.audit.path-traversal.path-join-resolve-traversal
// filename is always a hardcoded constant (e.g., 'newsletter-subscribers.json'), never user input
const getDataPath = (filename) => {
const cwd = process.cwd()
if (cwd.endsWith('.output')) {
// nosemgrep: javascript.lang.security.audit.path-traversal.path-join-resolve-traversal
return path.join(cwd, '../server/data', filename)
}
// nosemgrep: javascript.lang.security.audit.path-traversal.path-join-resolve-traversal
return path.join(cwd, 'server/data', filename)
}
const NEWSLETTER_GROUPS_FILE = getDataPath('newsletter-groups.json')
async function readGroups() {
try {
const data = await fs.readFile(NEWSLETTER_GROUPS_FILE, 'utf-8')
return JSON.parse(data)
} catch (error) {
if (error.code === 'ENOENT') {
return []
}
throw error
}
}
export default defineEventHandler(async (event) => {
try {
const body = await readBody(event)
const { email, groupId } = body
if (!email || !email.match(/^[^\s@]+@[^\s@]+\.[^\s@]+$/)) {
throw createError({
statusCode: 400,
statusMessage: 'Ungültige E-Mail-Adresse'
})
}
if (!groupId) {
throw createError({
statusCode: 400,
statusMessage: 'Newsletter-Gruppe muss angegeben werden'
})
}
// Prüfe ob Gruppe existiert
const groups = await readGroups()
const group = groups.find(g => g.id === groupId)
if (!group) {
throw createError({
statusCode: 404,
statusMessage: 'Newsletter-Gruppe nicht gefunden'
})
}
if (group.type !== 'subscription') {
throw createError({
statusCode: 400,
statusMessage: 'Diese Funktion ist nur für Abonnenten-Newsletter verfügbar'
})
}
const subscribers = await readSubscribers()
const emailLower = email.toLowerCase()
const subscriber = subscribers.find(s => {
const sEmail = (s.email || '').toLowerCase()
return sEmail === emailLower
})
if (!subscriber) {
// Nicht gefunden - aber trotzdem Erfolg zurückgeben (keine Information preisgeben)
return {
success: true,
message: 'Sie wurden erfolgreich vom Newsletter abgemeldet'
}
}
// Stelle sicher, dass groupIds existiert
if (!subscriber.groupIds || !Array.isArray(subscriber.groupIds)) {
subscriber.groupIds = []
}
// Prüfe ob für diese Gruppe angemeldet
if (!subscriber.groupIds.includes(groupId)) {
// Nicht für diese Gruppe angemeldet - aber trotzdem Erfolg zurückgeben
return {
success: true,
message: 'Sie wurden erfolgreich vom Newsletter abgemeldet'
}
}
// Entferne Gruppe aus groupIds
const index = subscriber.groupIds.indexOf(groupId)
subscriber.groupIds.splice(index, 1)
// Wenn keine Gruppen mehr vorhanden, als abgemeldet markieren
if (subscriber.groupIds.length === 0) {
subscriber.unsubscribedAt = new Date().toISOString()
subscriber.confirmed = false
}
await writeSubscribers(subscribers)
return {
success: true,
message: 'Sie wurden erfolgreich vom Newsletter abgemeldet'
}
} catch (error) {
console.error('Fehler bei Newsletter-Abmeldung:', error)
if (error.statusCode) {
throw error
}
throw createError({
statusCode: 500,
statusMessage: 'Fehler bei der Newsletter-Abmeldung'
})
}
})