"use client" // Kontoinnstillinger (ADR-021): sett/fjern passord (valgfritt tillegg til // magic-link), aktiver/deaktiver 2FA. Frivillig 2FA-oppsett herfra bruker // SAMME TwoFactorSetupForm som den tvungne flyten rett etter innlogging // (forced=false her -- kun tekst-copyen skiller de to). import type React from "react" import { useEffect, useState } from "react" import Link from "next/link" import { ArrowLeft, KeyRound, Lock, ShieldCheck, ShieldOff } from "lucide-react" import { Button } from "@/components/ui/button" import { Input } from "@/components/ui/input" import { Label } from "@/components/ui/label" import { TwoFactorSetupForm } from "@/components/two-factor-flow" type Me = { id: string email: string display_name: string has_password: boolean two_factor_method: "totp" | "email" | null } export function AccountSettings() { const [me, setMe] = useState(null) const [loading, setLoading] = useState(true) const [settingUp2fa, setSettingUp2fa] = useState(false) async function loadMe() { try { const res = await fetch("/auth/me", { credentials: "include" }) if (res.ok) setMe(await res.json()) } finally { setLoading(false) } } useEffect(() => { void loadMe() }, []) async function handleDisable2fa() { if (!confirm("Er du sikker på at du vil slå av topartsautentisering?")) return const res = await fetch("/auth/2fa/disable", { method: "POST", credentials: "include" }) if (res.ok) void loadMe() } if (loading) { return (
) } if (!me) return null return (
{settingUp2fa ? (
{ setSettingUp2fa(false) void loadMe() }} />
) : (

Topartsautentisering (2FA)

{me.two_factor_method ? ( <>

Aktivert med{" "} {me.two_factor_method === "totp" ? "autentisator-app" : "engangskode på e-post"} .

) : ( <>

Ikke aktivert. Anbefales for organisasjonseiere/administratorer -- da vil du bli bedt om å sette det opp ved neste innlogging uansett.

)}
)}
) } function PasswordSection({ hasPassword, onChanged }: { hasPassword: boolean; onChanged: () => void }) { const [password, setPassword] = useState("") const [submitting, setSubmitting] = useState(false) const [error, setError] = useState(null) const [success, setSuccess] = useState(false) async function handleSubmit(e: React.FormEvent) { e.preventDefault() if (password.length < 8 || submitting) return setSubmitting(true) setError(null) setSuccess(false) try { const res = await fetch("/auth/set-password", { method: "POST", headers: { "Content-Type": "application/json" }, credentials: "include", body: JSON.stringify({ password }), }) if (!res.ok) { const body = await res.json().catch(() => null) throw new Error(body?.detail?.message ?? "Klarte ikke å sette passordet.") } setPassword("") setSuccess(true) onChanged() } catch (err) { setError(err instanceof Error ? err.message : "Noe gikk galt. Prøv igjen.") } finally { setSubmitting(false) } } async function handleRemove() { if (!confirm("Fjerne passordet? Du kan fortsatt logge inn med magic-link.")) return const res = await fetch("/auth/remove-password", { method: "POST", credentials: "include" }) if (res.ok) onChanged() } return (

Passord

{hasPassword ? "Du har et passord satt. Du kan fortsatt logge inn med magic-link når som helst." : "Ikke satt -- du logger i dag kun inn med magic-link. Passord er et valgfritt tillegg, aldri påkrevd."}

setPassword(e.target.value)} className="h-12 rounded-xl" />
{error &&

{error}

} {success &&

Passordet er oppdatert.

} {hasPassword && ( )}
) }