feat: Tokens verwalten
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>
This commit is contained in:
co-authored by
Claude Opus 5
parent
6d3ebd05ae
commit
b17c42af56
@@ -0,0 +1,77 @@
|
||||
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>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user