Anlegen ist Verwaltungssache: Ein Token ist ein Zugang zur ganzen Anwendung, nicht zu einer Aufgabe. Beim Anlegen erscheint der Wert ein einziges Mal, mit dem Hinweis, dass er danach weg ist, und einem curl-Aufruf zum Ausprobieren. Ein Ablauf laesst sich setzen — ein Token mit Ablauf ist einer, den man nicht vergisst. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
78 lines
2.4 KiB
TypeScript
78 lines
2.4 KiB
TypeScript
import type { Metadata } from 'next'
|
|
import { KeyRound } from 'lucide-react'
|
|
import { TokenVerwaltung } from '@/app/(app)/verwaltung/api/token-verwaltung'
|
|
import {
|
|
Card,
|
|
CardBeschreibung,
|
|
CardInhalt,
|
|
CardKopf,
|
|
CardTitel,
|
|
} from '@/components/ui/card'
|
|
import { rechteLesen } from '@/lib/api'
|
|
import { alsDatumUhrzeit } from '@/lib/zeit'
|
|
import { verlangeRolle } from '@/server/berechtigung'
|
|
import { db } from '@/server/db'
|
|
import { umgebung } from '@/server/umgebung'
|
|
|
|
export const metadata: Metadata = { title: 'API-Tokens' }
|
|
|
|
export default async function ApiSeite() {
|
|
await verlangeRolle('ADMIN', '/verwaltung/api')
|
|
|
|
const tokens = await db.apiToken.findMany({
|
|
orderBy: [{ widerrufenAm: 'asc' }, { erstelltAm: 'desc' }],
|
|
select: {
|
|
id: true,
|
|
name: true,
|
|
praefix: true,
|
|
rechte: true,
|
|
gueltigBis: true,
|
|
letzteNutzung: true,
|
|
widerrufenAm: true,
|
|
erstelltAm: true,
|
|
},
|
|
})
|
|
|
|
const adresse = umgebung().APP_URL
|
|
|
|
return (
|
|
<div className="flex flex-col gap-6">
|
|
<div className="flex items-center gap-3">
|
|
<KeyRound className="text-gedaempft-vordergrund size-6" aria-hidden />
|
|
<div>
|
|
<h1 className="text-2xl font-semibold tracking-tight">API-Tokens</h1>
|
|
<p className="text-gedaempft-vordergrund text-sm">
|
|
Zugänge für fremde Anwendungen — mit so wenig Rechten wie möglich.
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
<Card>
|
|
<CardKopf>
|
|
<CardTitel className="text-base">Tokens</CardTitel>
|
|
<CardBeschreibung>
|
|
Ein Token ist ein Passwort. Er wird beim Anlegen ein einziges Mal angezeigt;
|
|
danach liegt in der Datenbank nur noch sein Fingerabdruck. Wer ihn verliert,
|
|
legt einen neuen an — nachschlagen lässt er sich nicht.
|
|
</CardBeschreibung>
|
|
</CardKopf>
|
|
<CardInhalt>
|
|
<TokenVerwaltung
|
|
adresse={adresse}
|
|
tokens={tokens.map((t) => ({
|
|
id: t.id,
|
|
name: t.name,
|
|
praefix: t.praefix,
|
|
rechte: rechteLesen(t.rechte),
|
|
gueltigBis: t.gueltigBis ? alsDatumUhrzeit(t.gueltigBis) : null,
|
|
letzteNutzung: t.letzteNutzung ? alsDatumUhrzeit(t.letzteNutzung) : null,
|
|
widerrufen: t.widerrufenAm !== null,
|
|
erstelltAm: alsDatumUhrzeit(t.erstelltAm),
|
|
}))}
|
|
/>
|
|
</CardInhalt>
|
|
</Card>
|
|
</div>
|
|
)
|
|
}
|