feat: Discord-Anmeldung -- im Panel einrichtbar, nicht in der .env
Auf Wunsch ueber die Oberflaeche statt ueber Umgebungsvariablen. Der Gewinn ist
nicht nur Bequemlichkeit: das Panel legt die REDIRECT-URI zum Kopieren hin, und
genau daran scheitert ein OAuth-Anlauf fast immer.
settings.ts Schluessel/Wert in SQLite, mit Umgebung als Rueckfall. Wer
schon Stack-Variablen gesetzt hat, behaelt sie; das Panel
uebersteuert. In der Umgebung bleibt, was den Dienst ueberhaupt
erreichbar macht (PUBLIC_URL, PORT, DATA_DIR) -- wer das per
Formular verstellen koennte, sperrt sich mit einem Klick aus.
discord.ts Der Weg in drei Schritten, ohne Bibliothek und OHNE BOT-TOKEN:
die Rolle wird mit dem Merkmal des BENUTZERS geholt
(guilds.members.read). Kein Bot, keine Bot-Rechte, kein zweites
Geheimnis, das ablaufen kann.
DAS GEHEIMNIS GEHT NIE HERAUS -- auch nicht an eine angemeldete Sitzung. Das
Panel bekommt nur "hatGeheimnis: true". Ein Formular, das den Client-Schluessel
im Klartext zurueckschickt, streut ihn in jeden Browser-Cache. Ein leeres Feld
heisst "unveraendert", nicht "loeschen"; zum Entfernen gibt es "-".
JEDER ABBRUCH IST SICHTBAR: kein weisser Bildschirm, sondern zurueck aufs
Formular mit dem Grund im Adressfeld -- "Du bist nicht auf diesem Server",
"Dir fehlt die noetige Rolle", oder bei 4xx vom Tausch der Hinweis auf die
Redirect-URI. Die IDs werden schon beim Speichern geprueft (17-20 Ziffern),
damit ein halber Link nicht erst beim Anmelden auffaellt.
Das Passwort bleibt als Notausgang. Ein ueber Discord angelegtes Konto bekommt
KEIN brauchbares Passwort ("nur-ueber-discord"): verifyPassword scheitert an
allem, was nicht dem scrypt-Format entspricht -- nachgesehen, nicht vermutet.
Dazu der Verlauf, wie gewuenscht: Suche nach Pfad (mit derselben
LIKE-Maskierung wie in der Galerie -- Suche nach "_" findet 0 statt allem),
waehlbare Seitengroesse (25/50/100/200, Standard 50) und mehr Luft zwischen
"Groesse" und "Von wem".
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
+33
-2
@@ -147,6 +147,24 @@ export type Folders = {
|
||||
wurzel: { files: number; bytes: number }
|
||||
}
|
||||
|
||||
export type Einstellungen = {
|
||||
discord: {
|
||||
clientId: string
|
||||
guildId: string
|
||||
roleId: string
|
||||
/** Nur OB eines hinterlegt ist — das Geheimnis selbst geht nie heraus. */
|
||||
hatGeheimnis: boolean
|
||||
bereit: boolean
|
||||
redirectUri: string
|
||||
ausDerUmgebung: {
|
||||
clientId: boolean
|
||||
clientSecret: boolean
|
||||
guildId: boolean
|
||||
roleId: boolean
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export type EventKind = 'upload' | 'replace' | 'delete'
|
||||
|
||||
export type MediaEvent = {
|
||||
@@ -198,6 +216,8 @@ export const api = {
|
||||
login: (username: string, password: string) =>
|
||||
post<{ user: User }>('/api/dash/auth/login', { username, password }),
|
||||
logout: () => post<{ ok: true }>('/api/dash/auth/logout'),
|
||||
/** Was die ANMELDESEITE wissen darf, bevor jemand angemeldet ist. */
|
||||
authConfig: () => get<{ discord: boolean }>('/api/dash/auth/config'),
|
||||
me: () => get<{ user: User }>('/api/dash/auth/me'),
|
||||
changePassword: (current: string, next: string) =>
|
||||
post<{ ok: true }>('/api/dash/auth/password', { current, next }),
|
||||
@@ -212,12 +232,23 @@ export const api = {
|
||||
deleteMediaBulk: (ids: number[]) =>
|
||||
post<{ deleted: string[]; count: number }>('/api/dash/media/delete', { ids }),
|
||||
|
||||
events: (kind: string, actor: string, limit: number, offset: number) =>
|
||||
events: (
|
||||
kind: string,
|
||||
actor: string,
|
||||
query: string,
|
||||
limit: number,
|
||||
offset: number,
|
||||
) =>
|
||||
get<EventsSeite>(
|
||||
`/api/dash/events?kind=${encodeURIComponent(kind)}` +
|
||||
`&actor=${encodeURIComponent(actor)}&limit=${limit}&offset=${offset}`,
|
||||
`&actor=${encodeURIComponent(actor)}` +
|
||||
`&query=${encodeURIComponent(query)}&limit=${limit}&offset=${offset}`,
|
||||
),
|
||||
|
||||
einstellungen: () => get<Einstellungen>('/api/dash/settings'),
|
||||
einstellungenSpeichern: (discord: Record<string, string>) =>
|
||||
post<{ ok: true; bereit: boolean; fehlt: string[] }>('/api/dash/settings', { discord }),
|
||||
|
||||
stats: () => get<Stats>('/api/dash/stats'),
|
||||
thumbsNachziehen: () => post<ThumbLauf>('/api/dash/maintenance/thumbs'),
|
||||
|
||||
|
||||
Reference in New Issue
Block a user