Respect per-user visibility; only 'vorstand' overrides visibility; UI shows contactHidden per-member
Some checks failed
Code Analysis (JS/Vue) / analyze (push) Failing after 47s

This commit is contained in:
Torsten Schulz (local)
2026-02-11 13:24:01 +01:00
parent ce5915a3bc
commit 141a15a6cb
3 changed files with 49 additions and 65 deletions

View File

@@ -22,7 +22,7 @@ export default defineEventHandler(async (event) => {
})
}
const currentUser = await getUserFromToken(token)
const currentUser = await getUserFromToken(token)
// Get manual members and registered users
const manualMembers = await readMembers()
@@ -150,8 +150,10 @@ export default defineEventHandler(async (event) => {
mergedMembers.sort((a, b) => a.name.localeCompare(b.name))
// Die Mitgliederliste ist nur für authentifizierte Nutzer sichtbar (siehe oben).
// Respektiere individuelle Sichtbarkeitspräferenzen (user.visibility)
const currentUserToken = token
const isViewerAuthenticated = !!currentUser
const currentUserToken = token
const isViewerAuthenticated = !!currentUser
// Only 'vorstand' may override member visibility
const isPrivilegedViewer = currentUser ? hasRole(currentUser, 'vorstand') : false
const sanitizedMembers = mergedMembers.map(member => {
// Default: show email/phone/address to other logged-in members unless member.visibility explicitly hides them
@@ -161,7 +163,16 @@ export default defineEventHandler(async (event) => {
const showPhone = visibility.showPhone === undefined ? true : Boolean(visibility.showPhone)
const showAddress = visibility.showAddress === undefined ? false : Boolean(visibility.showAddress)
return {
// Determine if contact info existed but was hidden to the viewer
const hadEmail = !!member.email
const hadPhone = !!member.phone
const hadAddress = !!member.address
const emailVisible = (isPrivilegedViewer || (isViewerAuthenticated && showEmail))
const phoneVisible = (isPrivilegedViewer || (isViewerAuthenticated && showPhone))
const addressVisible = (isPrivilegedViewer || (isViewerAuthenticated && showAddress))
const contactHidden = (!emailVisible && hadEmail) || (!phoneVisible && hadPhone) || (!addressVisible && hadAddress)
return {
id: member.id,
name: member.name,
source: member.source,
@@ -172,10 +183,12 @@ export default defineEventHandler(async (event) => {
lastLogin: member.lastLogin,
isMannschaftsspieler: member.isMannschaftsspieler,
notes: member.notes || '',
// Only include contact fields when viewer is authenticated and the member allows it
email: (isViewerAuthenticated && showEmail) ? member.email : undefined,
phone: (isViewerAuthenticated && showPhone) ? member.phone : undefined,
address: (isViewerAuthenticated && showAddress) ? member.address : undefined
// Privileged viewers (vorstand) always see contact fields
email: emailVisible ? member.email : undefined,
phone: phoneVisible ? member.phone : undefined,
address: addressVisible ? member.address : undefined,
// Flag for UI: data existed but is hidden to the current viewer
contactHidden
}
})

View File

@@ -64,9 +64,10 @@ export default defineEventHandler(async (event) => {
const visibility = body.visibility || body.visibilityPreferences || null
if (visibility && typeof visibility === 'object') {
user.visibility = user.visibility || {}
if (typeof visibility.showEmail === 'boolean') user.visibility.showEmail = visibility.showEmail
if (typeof visibility.showPhone === 'boolean') user.visibility.showPhone = visibility.showPhone
if (typeof visibility.showAddress === 'boolean') user.visibility.showAddress = visibility.showAddress
// Coerce values to booleans to be robust against string values from clients
if (visibility.showEmail !== undefined) user.visibility.showEmail = Boolean(visibility.showEmail)
if (visibility.showPhone !== undefined) user.visibility.showPhone = Boolean(visibility.showPhone)
if (visibility.showAddress !== undefined) user.visibility.showAddress = Boolean(visibility.showAddress)
}
// Handle password change