feat: Datenmodell und Regeln fuer die oeffentliche Schnittstelle
Gespeichert wird nur der Hash eines Tokens. Der Klartext existiert genau einmal — beim Anlegen, auf dem Bildschirm. Ein Token ist ein Passwort; es gibt keinen Grund, es zurueckzulesen, und jeden Grund, es nicht zu koennen. Drei Rechte, und keines schliesst ein anderes ein. Ein Dienst, der nur meldet "hier ist etwas Neues", braucht den Bestand nicht zu sehen — genau das ist der haeufigste Fall und der, bei dem ein mitgelesener Token am wenigsten anrichtet. Der sichtbare Anfang "planer_..." ist Absicht: Wer so einen Wert versehentlich in ein oeffentliches Verzeichnis schiebt, soll ihn beim Durchsehen erkennen. 30 Tests. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
bbac268c59
commit
d5c7974af3
@@ -0,0 +1,27 @@
|
||||
-- CreateTable
|
||||
CREATE TABLE "api_token" (
|
||||
"id" TEXT NOT NULL,
|
||||
"benutzerId" TEXT NOT NULL,
|
||||
"name" TEXT NOT NULL,
|
||||
"praefix" TEXT NOT NULL,
|
||||
"hash" TEXT NOT NULL,
|
||||
"rechte" TEXT NOT NULL,
|
||||
"gueltigBis" TIMESTAMP(3),
|
||||
"letzteNutzung" TIMESTAMP(3),
|
||||
"widerrufenAm" TIMESTAMP(3),
|
||||
"erstelltAm" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "api_token_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "api_token_praefix_key" ON "api_token"("praefix");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "api_token_hash_key" ON "api_token"("hash");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "api_token_benutzerId_idx" ON "api_token"("benutzerId");
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "api_token" ADD CONSTRAINT "api_token_benutzerId_fkey" FOREIGN KEY ("benutzerId") REFERENCES "benutzer"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
@@ -39,6 +39,7 @@ model Benutzer {
|
||||
pushGeraete PushGeraet[]
|
||||
meldungen Meldungsnachweis[]
|
||||
telegramChats TelegramChat[]
|
||||
apiTokens ApiToken[]
|
||||
|
||||
@@index([aktiv])
|
||||
@@map("benutzer")
|
||||
@@ -538,3 +539,34 @@ model TelegramKopplung {
|
||||
@@index([gueltigBis])
|
||||
@@map("telegram_kopplung")
|
||||
}
|
||||
|
||||
/// Zugangstoken fuer die oeffentliche Schnittstelle.
|
||||
///
|
||||
/// Gespeichert wird nur der Hash. Der Klartext existiert genau einmal – beim
|
||||
/// Anlegen, auf dem Bildschirm. Ein Token ist ein Passwort; wer es verliert,
|
||||
/// legt ein neues an, statt das alte irgendwo nachzuschlagen.
|
||||
model ApiToken {
|
||||
id String @id @default(cuid())
|
||||
benutzerId String
|
||||
|
||||
name String
|
||||
/// Sichtbarer Anfang, macht die Zeile auffindbar und wiedererkennbar.
|
||||
praefix String @unique
|
||||
/// SHA-256 des vollstaendigen Tokens.
|
||||
hash String @unique
|
||||
|
||||
/// Kommagetrennt, siehe src/lib/api.ts.
|
||||
rechte String
|
||||
|
||||
gueltigBis DateTime?
|
||||
letzteNutzung DateTime?
|
||||
/// Gesetzt heisst: gilt nicht mehr. Die Zeile bleibt fuer das Protokoll.
|
||||
widerrufenAm DateTime?
|
||||
|
||||
erstelltAm DateTime @default(now())
|
||||
|
||||
benutzer Benutzer @relation(fields: [benutzerId], references: [id], onDelete: Cascade)
|
||||
|
||||
@@index([benutzerId])
|
||||
@@map("api_token")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user