Files
harheimertc/server/api/birthdays.get.js
2026-02-13 17:27:27 +01:00

91 lines
3.3 KiB
JavaScript

import { readMembers, normalizeDate } from '../utils/members.js'
import { readUsers, migrateUserRoles, getUserFromToken, verifyToken } from '../utils/auth.js'
// Helper: returns array of upcoming birthdays within daysAhead (inclusive)
function getUpcomingBirthdays(entries, daysAhead = 28) {
const now = new Date()
const results = []
// iterate entries with geburtsdatum and name
for (const e of entries) {
const raw = e.geburtsdatum
if (!raw) continue
const parsed = new Date(raw)
if (isNaN(parsed.getTime())) continue
// Build next occurrence for this year
const thisYear = now.getFullYear()
const occ = new Date(thisYear, parsed.getMonth(), parsed.getDate())
// If already passed this year, consider next year
if (occ < now) {
occ.setFullYear(thisYear + 1)
}
const diffDays = Math.ceil((occ - now) / (1000 * 60 * 60 * 24))
if (diffDays >= 0 && diffDays <= daysAhead) {
results.push({
name: e.name || `${e.firstName || ''} ${e.lastName || ''}`.trim(),
dayMonth: `${String(occ.getDate()).padStart(2, '0')}.${String(occ.getMonth()+1).padStart(2, '0')}`,
date: occ,
diffDays
})
}
}
// Sort by upcoming date
results.sort((a, b) => a.date - b.date)
return results
}
export default defineEventHandler(async (event) => {
try {
// Determine viewer for visibility rules; token optional
const token = getCookie(event, 'auth_token')
let currentUser = null
if (token) {
const decoded = verifyToken(token)
if (decoded) {
currentUser = await getUserFromToken(token)
}
}
const manualMembers = await readMembers()
const registeredUsers = await readUsers()
// Build unified list of candidates with geburtsdatum and visibility
const candidates = []
for (const m of manualMembers) {
const isAccepted = m.active === true || (m.status && String(m.status).toLowerCase() === 'accepted') || m.accepted === true
if (!isAccepted) continue
const vis = m.visibility || {}
const showBirthday = vis.showBirthday === undefined ? true : Boolean(vis.showBirthday)
candidates.push({ name: `${m.firstName || ''} ${m.lastName || ''}`.trim(), geburtsdatum: m.geburtsdatum, visibility: { showBirthday }, source: 'manual' })
}
for (const u of registeredUsers) {
if (!u.active) continue
const vis = u.visibility || {}
const showBirthday = vis.showBirthday === undefined ? true : Boolean(vis.showBirthday)
candidates.push({ name: u.name, geburtsdatum: u.geburtsdatum, visibility: { showBirthday }, source: 'login' })
}
// Respect visibility: if viewer is vorstand they see all birthdays
const isPrivilegedViewer = currentUser ? (Array.isArray(currentUser.roles) ? currentUser.roles.includes('vorstand') : currentUser.role === 'vorstand') : false
const filtered = candidates.filter(c => c.geburtsdatum && (isPrivilegedViewer || c.visibility.showBirthday === true))
const upcoming = getUpcomingBirthdays(filtered, 28)
// Return only next 4 weeks entries with name and dayMonth
return {
success: true,
birthdays: upcoming.map(b => ({ name: b.name, dayMonth: b.dayMonth, inDays: b.diffDays }))
}
} catch (error) {
console.error('Fehler beim Abrufen der Geburtstage:', error)
throw error
}
})