Enhance user contact data visibility based on role permissions
Some checks failed
Code Analysis (JS/Vue) / analyze (push) Failing after 52s

This commit introduces role-based access control for user contact information in the CMS. It updates the user list display to show email and phone details only to users with the 'vorstand' role, while masking this information for others. Additionally, it modifies the API endpoints to ensure that contact data is only returned for authorized users, improving data privacy and security.
This commit is contained in:
Torsten Schulz (local)
2026-02-06 10:12:37 +01:00
parent 1474591137
commit 8045542f8f
3 changed files with 51 additions and 9 deletions

View File

@@ -143,12 +143,28 @@
</td>
<td class="px-6 py-4 whitespace-nowrap">
<div class="text-sm text-gray-600">
{{ user.email }}
<template v-if="canViewContactData">
{{ user.email || '-' }}
</template>
<span
v-else
class="text-gray-400"
>
Nur für Vorstand
</span>
</div>
</td>
<td class="px-6 py-4 whitespace-nowrap">
<div class="text-sm text-gray-600">
<template v-if="canViewContactData">
{{ user.phone || '-' }}
</template>
<span
v-else
class="text-gray-400"
>
Nur für Vorstand
</span>
</div>
</td>
<td class="px-6 py-4 whitespace-nowrap">
@@ -307,6 +323,13 @@
import { ref, computed, onMounted } from 'vue'
import { AlertCircle, Check, X } from 'lucide-vue-next'
const authStore = useAuthStore()
const canViewContactData = computed(() => {
// Kontaktdaten nur für Vorstand sichtbar
return authStore.hasRole('vorstand')
})
const allUsers = ref([])
const currentUserId = ref(null)
const successMessage = ref('')

View File

@@ -1,4 +1,4 @@
import { getUserFromToken, readUsers, hasAnyRole, migrateUserRoles } from '../../../utils/auth.js'
import { getUserFromToken, readUsers, hasAnyRole, hasRole, migrateUserRoles } from '../../../utils/auth.js'
export default defineEventHandler(async (event) => {
try {
@@ -14,17 +14,23 @@ export default defineEventHandler(async (event) => {
const users = await readUsers()
// Return users without passwords
const isVorstand = hasRole(currentUser, 'vorstand')
// Return users without Passwörter; Kontaktdaten nur für Vorstand
const safeUsers = users.map(u => {
const migrated = migrateUserRoles({ ...u })
const roles = Array.isArray(migrated.roles) ? migrated.roles : (migrated.role ? [migrated.role] : ['mitglied'])
const email = isVorstand ? u.email : undefined
const phone = isVorstand ? (u.phone || '') : undefined
return {
id: u.id,
email: u.email,
email,
name: u.name,
roles: roles,
role: roles[0] || 'mitglied', // Rückwärtskompatibilität
phone: u.phone || '',
phone,
active: u.active,
created: u.created,
lastLogin: u.lastLogin

View File

@@ -1,4 +1,4 @@
import { verifyToken } from '../utils/auth.js'
import { verifyToken, getUserFromToken, hasRole } from '../utils/auth.js'
import { readMembers } from '../utils/members.js'
import { readUsers, migrateUserRoles } from '../utils/auth.js'
@@ -22,6 +22,8 @@ export default defineEventHandler(async (event) => {
})
}
const currentUser = await getUserFromToken(token)
// Get manual members and registered users
const manualMembers = await readMembers()
const registeredUsers = await readUsers()
@@ -141,9 +143,20 @@ export default defineEventHandler(async (event) => {
// Sort by name
mergedMembers.sort((a, b) => a.name.localeCompare(b.name))
// Serverseitiger Datenschutz: Kontaktdaten nur für Vorstand
const isVorstand = hasRole(currentUser, 'vorstand')
const safeMembers = isVorstand
? mergedMembers
: mergedMembers.map(m => ({
...m,
email: undefined,
phone: undefined,
address: undefined
}))
return {
success: true,
members: mergedMembers
members: safeMembers
}
} catch (error) {
console.error('Fehler beim Abrufen der Mitgliederliste:', error)