import { AuthRequestError } from '@/services/authSession' export interface AdminUser { id: string userName: string roles: string[] isActive: boolean mustChangePassword: boolean } interface ApiMessageResponse { message?: unknown } function isObject(value: unknown): value is Record { return typeof value === 'object' && value !== null } function normalizeAdminUser(value: unknown): AdminUser | null { if (!isObject(value)) { return null } const { id, userName, roles, isActive, mustChangePassword } = value if (typeof id !== 'string') { return null } const normalizedRoles = Array.isArray(roles) ? roles .filter((entry): entry is string => typeof entry === 'string') .map((entry) => entry.trim()) .filter((entry) => entry.length > 0) : [] return { id, userName: typeof userName === 'string' ? userName : '', roles: normalizedRoles, isActive: Boolean(isActive), mustChangePassword: Boolean(mustChangePassword), } } async function readApiMessage(response: Response): Promise { const contentType = response.headers.get('content-type') ?? '' if (!contentType.toLowerCase().includes('application/json')) { return null } try { const payload = (await response.json()) as ApiMessageResponse if (typeof payload.message === 'string' && payload.message.trim().length > 0) { return payload.message.trim() } } catch { return null } return null } function toAdminUserError(error: unknown, fallbackMessage: string): AuthRequestError { if (error instanceof AuthRequestError) { return error } return new AuthRequestError(fallbackMessage, 0) } export async function fetchAdminUsers(): Promise { let response: Response try { response = await fetch('/auth/user', { method: 'GET', credentials: 'include', headers: { Accept: 'application/json', }, }) } catch (error) { throw toAdminUserError(error, 'Server ist nicht erreichbar. Bitte später erneut versuchen.') } if (response.status === 401) { throw new AuthRequestError('Session abgelaufen. Bitte melde dich erneut an.', response.status) } if (response.status === 403) { throw new AuthRequestError('Du bist angemeldet, aber nicht als Admin autorisiert.', response.status) } if (!response.ok) { const apiMessage = await readApiMessage(response) throw new AuthRequestError( apiMessage ?? 'Benutzerliste konnte nicht geladen werden.', response.status, ) } const payload: unknown = await response.json() if (!Array.isArray(payload)) { throw new AuthRequestError('Antwortformat von /auth/user ist ungültig.', response.status) } const users = payload.map(normalizeAdminUser) if (users.some((user) => user === null)) { throw new AuthRequestError('Antwortformat von /auth/user ist ungültig.', response.status) } return users as AdminUser[] } export async function fetchAdminUserById(userId: string): Promise { const normalizedId = userId.trim() if (normalizedId.length === 0) { throw new AuthRequestError('Ungültige Benutzer-ID.', 400) } let response: Response try { response = await fetch(`/auth/user/${encodeURIComponent(normalizedId)}`, { method: 'GET', credentials: 'include', headers: { Accept: 'application/json', }, }) } catch (error) { throw toAdminUserError(error, 'Server ist nicht erreichbar. Bitte später erneut versuchen.') } if (response.status === 401) { throw new AuthRequestError('Session abgelaufen. Bitte melde dich erneut an.', response.status) } if (response.status === 403) { throw new AuthRequestError('Du bist angemeldet, aber nicht als Admin autorisiert.', response.status) } if (response.status === 404) { throw new AuthRequestError('Benutzer wurde nicht gefunden.', response.status) } if (!response.ok) { const apiMessage = await readApiMessage(response) throw new AuthRequestError( apiMessage ?? 'Benutzerdetails konnten nicht geladen werden.', response.status, ) } const payload: unknown = await response.json() const user = normalizeAdminUser(payload) if (!user) { throw new AuthRequestError('Antwortformat von /auth/user/{id} ist ungültig.', response.status) } return user }