import type { Metadata } from "next"; import { AccountManager, type AccountData } from "@/components/account/AccountManager"; import { NotificationSection, type NotificationTargetEntry, } from "@/components/account/NotificationSection"; import { emailAvailable } from "@/lib/notify"; import { requireUserPage } from "@/lib/auth/guard"; import { WEBAUTHN_AVAILABLE } from "@/lib/config"; import { prisma } from "@/lib/db"; export const dynamic = "force-dynamic"; export async function generateMetadata(): Promise { return { title: "Mein Konto" }; } export default async function AccountPage() { const user = await requireUserPage(); const [passkeys, sessions, targets, konto, offeneCodes] = await Promise.all([ prisma.credential.findMany({ where: { userId: user.id }, select: { id: true, name: true, deviceType: true, backedUp: true, createdAt: true, lastUsedAt: true, }, orderBy: { createdAt: "asc" }, }), prisma.session.findMany({ where: { userId: user.id, expiresAt: { gt: new Date() } }, select: { id: true, userAgent: true, ip: true, createdAt: true, lastSeenAt: true, }, orderBy: { lastSeenAt: "desc" }, }), prisma.notificationTarget.findMany({ where: { userId: user.id }, select: { id: true, name: true, channel: true, target: true, secretHint: true, events: true, isActive: true, lastSentAt: true, lastOk: true, lastMessage: true, }, orderBy: { name: "asc" }, }), prisma.user.findUniqueOrThrow({ where: { id: user.id }, select: { totpEnabledAt: true }, }), prisma.recoveryCode.count({ where: { userId: user.id, usedAt: null } }), ]); const data: AccountData = { username: user.username, displayName: user.displayName, email: user.email, role: user.role, hasPassword: user.hasPassword, passkeys, sessions, passkeysAvailable: WEBAUTHN_AVAILABLE, totp: { enabled: Boolean(konto.totpEnabledAt), enabledAt: konto.totpEnabledAt, recoveryCodesLeft: offeneCodes, }, }; return (

Mein Konto

Profil, Anmeldemittel und aktive Sitzungen.

); }