Implemented the possibility ofa hidden user for playstore tests
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import { readMembers } from '../utils/members.js'
|
||||
import { readUsers, getUserFromToken, verifyToken } from '../utils/auth.js'
|
||||
import { readUsers, getUserFromToken, verifyToken, isHiddenUser, normalizeUserEmail } from '../utils/auth.js'
|
||||
|
||||
// Helper: returns array of upcoming birthdays within daysAhead (inclusive)
|
||||
function getUpcomingBirthdays(entries, daysAhead = 28) {
|
||||
@@ -53,10 +53,14 @@ export default defineEventHandler(async (event) => {
|
||||
const manualMembers = await readMembers()
|
||||
const registeredUsers = await readUsers()
|
||||
|
||||
const hiddenUserEmails = new Set(registeredUsers.filter(isHiddenUser).map(user => normalizeUserEmail(user.email)).filter(Boolean))
|
||||
|
||||
// Build unified list of candidates with geburtsdatum and visibility
|
||||
const candidates = []
|
||||
|
||||
for (const m of manualMembers) {
|
||||
const memberEmail = normalizeUserEmail(m.email)
|
||||
if (m.hidden === true || m.invisible === true || m.isHidden === true || hiddenUserEmails.has(memberEmail)) continue
|
||||
const normalizedStatus = m.status ? String(m.status).toLowerCase() : ''
|
||||
const hasExplicitAcceptanceFlag = m.active !== undefined || m.accepted !== undefined || normalizedStatus !== ''
|
||||
const isAccepted = hasExplicitAcceptanceFlag
|
||||
@@ -73,7 +77,7 @@ export default defineEventHandler(async (event) => {
|
||||
}
|
||||
|
||||
for (const u of registeredUsers) {
|
||||
if (!u.active) continue
|
||||
if (!u.active || isHiddenUser(u)) 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' })
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { getUserFromToken, hasRole, readUsers } from '../../utils/auth.js'
|
||||
import { getUserFromToken, hasRole, readUsers, isHiddenUser } from '../../utils/auth.js'
|
||||
import {
|
||||
fingerprintResetEmail,
|
||||
normalizeResetEmail,
|
||||
@@ -59,17 +59,20 @@ export default defineEventHandler(async (event) => {
|
||||
const email = normalizeResetEmail(query.email)
|
||||
const failedOnly = query.failedOnly !== 'false'
|
||||
const users = await readUsers()
|
||||
const visibleUsers = users.filter(user => !isHiddenUser(user))
|
||||
const hiddenEmailFingerprints = new Set(users.filter(isHiddenUser).map(user => fingerprintResetEmail(user.email)).filter(Boolean))
|
||||
const logs = await readPasswordResetLogs()
|
||||
const filteredLogs = email
|
||||
const filteredLogs = (email
|
||||
? logs.filter(entry => entry.emailFingerprint === fingerprintResetEmail(email))
|
||||
: logs
|
||||
: logs)
|
||||
.filter(entry => !hiddenEmailFingerprints.has(entry.emailFingerprint))
|
||||
const attempts = summarizeAttempts(filteredLogs)
|
||||
.filter(attempt => !failedOnly || attempt.failed)
|
||||
|
||||
let matchingUsers = []
|
||||
if (email) {
|
||||
const term = email.toLowerCase()
|
||||
matchingUsers = users
|
||||
matchingUsers = visibleUsers
|
||||
.filter(user => {
|
||||
const userEmail = normalizeResetEmail(user.email)
|
||||
const name = String(user.name || '').toLowerCase()
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { getUserFromToken, readUsers, hasAnyRole, migrateUserRoles } from '../../../utils/auth.js'
|
||||
import { getUserFromToken, readUsers, hasAnyRole, migrateUserRoles, isHiddenUser } from '../../../utils/auth.js'
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
try {
|
||||
@@ -18,7 +18,7 @@ export default defineEventHandler(async (event) => {
|
||||
// Nur Admin oder Vorstand duerfen vollen Benutzer-Contact und Rollen sehen.
|
||||
const canSeePrivate = hasAnyRole(currentUser, 'admin', 'vorstand')
|
||||
|
||||
const safeUsers = users.map(u => {
|
||||
const safeUsers = users.filter(u => !isHiddenUser(u)).map(u => {
|
||||
const migrated = migrateUserRoles({ ...u })
|
||||
const roles = Array.isArray(migrated.roles) ? migrated.roles : (migrated.role ? [migrated.role] : ['mitglied'])
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ import nodemailer from 'nodemailer'
|
||||
import { promises as fs } from 'fs'
|
||||
import path from 'path'
|
||||
import { createContactRequest } from '../utils/contact-requests.js'
|
||||
import { readUsers, migrateUserRoles } from '../utils/auth.js'
|
||||
import { readUsers, migrateUserRoles, isHiddenUser } from '../utils/auth.js'
|
||||
|
||||
// nosemgrep: javascript.lang.security.audit.path-traversal.path-join-resolve-traversal.path-join-resolve-traversal
|
||||
// filename is always a hardcoded constant ('config.json'), never user input
|
||||
@@ -54,6 +54,7 @@ async function collectRecipients(config) {
|
||||
try {
|
||||
const users = await readUsers()
|
||||
for (const rawUser of users) {
|
||||
if (isHiddenUser(rawUser)) continue
|
||||
const user = migrateUserRoles({ ...rawUser })
|
||||
const roles = Array.isArray(user.roles) ? user.roles : []
|
||||
if (roles.includes('trainer') && user.email && String(user.email).trim()) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { verifyToken, getUserFromToken, hasRole } from '../utils/auth.js'
|
||||
import { readMembers } from '../utils/members.js'
|
||||
import { readUsers, migrateUserRoles } from '../utils/auth.js'
|
||||
import { readUsers, migrateUserRoles, isHiddenUser, normalizeUserEmail } from '../utils/auth.js'
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
try {
|
||||
@@ -52,7 +52,7 @@ export default defineEventHandler(async (event) => {
|
||||
// Skip applications that are not yet accepted
|
||||
continue
|
||||
}
|
||||
const normalizedEmail = member.email?.toLowerCase().trim() || ''
|
||||
const normalizedEmail = normalizeUserEmail(member.email)
|
||||
const fullName = `${member.firstName || ''} ${member.lastName || ''}`.trim()
|
||||
const normalizedName = fullName.toLowerCase()
|
||||
|
||||
@@ -90,11 +90,13 @@ export default defineEventHandler(async (event) => {
|
||||
}
|
||||
}
|
||||
|
||||
const hiddenUserEmails = new Set(registeredUsers.filter(isHiddenUser).map(user => normalizeUserEmail(user.email)).filter(Boolean))
|
||||
|
||||
// Then add registered users (only active ones)
|
||||
for (const user of registeredUsers) {
|
||||
if (!user.active) continue
|
||||
if (!user.active || isHiddenUser(user)) continue
|
||||
|
||||
const normalizedEmail = user.email?.toLowerCase().trim() || ''
|
||||
const normalizedEmail = normalizeUserEmail(user.email)
|
||||
const normalizedName = user.name?.toLowerCase().trim() || ''
|
||||
|
||||
// Hilfsfunktion: Extrahiere Vorname/Nachname aus user.name
|
||||
@@ -208,7 +210,10 @@ export default defineEventHandler(async (event) => {
|
||||
const isPrivilegedViewer = currentUser ? hasRole(currentUser, 'vorstand') : false
|
||||
|
||||
// Filtere den Admin-Account heraus
|
||||
const filteredMembers = mergedMembers.filter(m => m.email?.toLowerCase() !== 'admin@harheimertc.de')
|
||||
const filteredMembers = mergedMembers.filter(m => {
|
||||
const email = normalizeUserEmail(m.email || m.loginEmail)
|
||||
return email !== 'admin@harheimertc.de' && !hiddenUserEmails.has(email) && !m.hidden && !m.invisible && !m.isHidden
|
||||
})
|
||||
const sanitizedMembers = filteredMembers.map(member => {
|
||||
// Default: show email/phone/address to other logged-in members unless member.visibility explicitly hides them
|
||||
const visibility = member.visibility || {}
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import { readFile } from 'fs/promises'
|
||||
import { getServerDataPath } from '../../utils/paths.js'
|
||||
import { getUserFromToken, verifyToken } from '../../utils/auth.js'
|
||||
import { getUserFromToken, verifyToken, readUsers, isHiddenUser, normalizeUserEmail } from '../../utils/auth.js'
|
||||
import { readMembers } from '../../utils/members.js'
|
||||
import { readUsers } from '../../utils/auth.js'
|
||||
|
||||
const QTTR_FILE = getServerDataPath('qttr-values.json')
|
||||
|
||||
@@ -62,15 +61,27 @@ export default defineEventHandler(async (event) => {
|
||||
readMembers(),
|
||||
readUsers()
|
||||
])
|
||||
const birthdateLookup = buildBirthdateLookup([...manualMembers, ...registeredUsers])
|
||||
const hiddenUserEmails = new Set(registeredUsers.filter(isHiddenUser).map(user => normalizeUserEmail(user.email)).filter(Boolean))
|
||||
const visibleManualMembers = manualMembers.filter(member => {
|
||||
const email = normalizeUserEmail(member.email)
|
||||
return member.hidden !== true && member.invisible !== true && member.isHidden !== true && !hiddenUserEmails.has(email)
|
||||
})
|
||||
const visibleUsers = registeredUsers.filter(user => !isHiddenUser(user))
|
||||
const hiddenNames = new Set([
|
||||
...manualMembers.filter(member => member.hidden === true || member.invisible === true || member.isHidden === true || hiddenUserEmails.has(normalizeUserEmail(member.email))),
|
||||
...registeredUsers.filter(isHiddenUser)
|
||||
].flatMap(entry => [entry?.name, `${entry?.firstName || ''} ${entry?.lastName || ''}`.trim()]).map(normalizeName).filter(Boolean))
|
||||
const birthdateLookup = buildBirthdateLookup([...visibleManualMembers, ...visibleUsers])
|
||||
|
||||
return {
|
||||
...payload,
|
||||
rows: Array.isArray(payload.rows)
|
||||
? payload.rows.map((row) => ({
|
||||
...row,
|
||||
birthdate: birthdateLookup.get(normalizeName(row.playerName)) || row.birthdate || ''
|
||||
}))
|
||||
? payload.rows
|
||||
.filter(row => !hiddenNames.has(normalizeName(row.playerName)))
|
||||
.map((row) => ({
|
||||
...row,
|
||||
birthdate: birthdateLookup.get(normalizeName(row.playerName)) || row.birthdate || ''
|
||||
}))
|
||||
: []
|
||||
}
|
||||
} catch (error) {
|
||||
|
||||
Reference in New Issue
Block a user