Single Sign-On: der Bot als Identity-Provider für die anderen Dienste
Andere Apps (Kanban, Platform …) nutzen ab sofort den Discord-Login des Bots mit, statt jeweils eigenes OAuth zu bauen — und bekommen die Discord-Rollen des Users gleich mitgeliefert. Ablauf: App leitet auf /sso/authorize weiter, der Bot prüft die Session (ggf. erst Discord-Login) und schickt einen signierten Token zurück, den die App serverseitig per POST /sso/verify gegen die Nutzerdaten tauscht. Sicherheit: - Rücksprung-Ziele müssen einem registrierten Präfix entsprechen (kein Open Redirect, kein Token-Abgriff über fremde Hosts) - Token HMAC-signiert, 60 Sekunden gültig, nur einmal einlösbar - Verify braucht das App-Secret (timing-safe verglichen) - SSO bleibt Mitgliedern des Discord-Servers vorbehalten - App-Verwaltung ist Owner-only, Secret wird nur einmal angezeigt Dazu: sso_apps-Tabelle, Verwaltung im API-Tab, Rücksprung nach dem Login (return-Cookie, nur interne Pfade), Anleitung in docs/sso.md. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -516,6 +516,31 @@ export function deleteUserData(userId) {
|
||||
return result;
|
||||
}
|
||||
|
||||
// SSO: Fremd-Apps (Kanban, Platform …), die den Discord-Login des Bots mitnutzen
|
||||
db.exec(`
|
||||
CREATE TABLE IF NOT EXISTS sso_apps (
|
||||
slug TEXT PRIMARY KEY,
|
||||
name TEXT NOT NULL,
|
||||
redirect_prefix TEXT NOT NULL,
|
||||
secret TEXT NOT NULL,
|
||||
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
||||
last_used TEXT
|
||||
);
|
||||
`);
|
||||
const upsertSsoApp = db.prepare(`
|
||||
INSERT INTO sso_apps (slug, name, redirect_prefix, secret) VALUES (@slug, @name, @redirect_prefix, @secret)
|
||||
ON CONFLICT(slug) DO UPDATE SET name = excluded.name, redirect_prefix = excluded.redirect_prefix
|
||||
`);
|
||||
const getSsoAppStmt = db.prepare('SELECT * FROM sso_apps WHERE slug = ?');
|
||||
const listSsoAppsStmt = db.prepare('SELECT slug, name, redirect_prefix, created_at, last_used FROM sso_apps ORDER BY name');
|
||||
const deleteSsoAppStmt = db.prepare('DELETE FROM sso_apps WHERE slug = ?');
|
||||
const touchSsoAppStmt = db.prepare(`UPDATE sso_apps SET last_used = datetime('now') WHERE slug = ?`);
|
||||
export const saveSsoApp = (app) => upsertSsoApp.run(app);
|
||||
export const getSsoApp = (slug) => getSsoAppStmt.get(slug) ?? null;
|
||||
export const listSsoApps = () => listSsoAppsStmt.all();
|
||||
export const deleteSsoApp = (slug) => deleteSsoAppStmt.run(slug).changes > 0;
|
||||
export const touchSsoApp = (slug) => touchSsoAppStmt.run(slug);
|
||||
|
||||
// Audit-Log: wer (Owner/Team) hat wann was im Webinterface geändert
|
||||
db.exec(`
|
||||
CREATE TABLE IF NOT EXISTS audit_log (
|
||||
|
||||
Reference in New Issue
Block a user