Member-Bereich: Profilseite, Rollen-Selfservice, Web-Voting, Member-Gate
Der Discord-Login ist jetzt für alle Member nützlich: - /profil: Rang + XP-Fortschritt, Discord-Rollen als Chips, Playtester- Badge, eigener Alpha-Key mit Kopier-Button - Rollen-Selfservice: veröffentlichte Rollen-Menüs direkt im Browser togglen (gleiche Exklusiv-Logik wie die Discord-Buttons; nur Rollen aus aktiven Menüs erlaubt) - Wunsch-Voting im Web: auf /roadmap Wünsche einreichen (postet wie /wunsch in den Voting-Kanal) und upvoten (wish_votes-Tabelle, ein Vote pro Member, unabhängig von Discord-👍) - Member-Gate: Login nur für Mitglieder der konfigurierten Guild; Abgewiesene sehen einen Banner mit Discord-Invite-Link (neue Settings member_gate_enabled + discord_invite_url im System-Tab) - Membership-Check mit 5-Minuten-Cache, Owner immer erlaubt Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
+18
-2
@@ -1,7 +1,7 @@
|
||||
// Discord-OAuth2-Login: /auth/login → Discord → /auth/callback → signiertes Session-Cookie
|
||||
import crypto from 'node:crypto';
|
||||
import { config } from '../config.js';
|
||||
import { publicUrl } from '../runtime-settings.js';
|
||||
import { publicUrl, discordGuildId, memberGateEnabled } from '../runtime-settings.js';
|
||||
|
||||
const DISCORD_API = 'https://discord.com/api/v10';
|
||||
const SESSION_COOKIE = 'd4rkbot_session';
|
||||
@@ -28,7 +28,18 @@ export function isAdmin(user) {
|
||||
return user?.id === config.adminDiscordId;
|
||||
}
|
||||
|
||||
export function registerAuthRoutes(app) {
|
||||
/** Member-Gate: ist die User-ID Mitglied der konfigurierten Guild? (Owner immer) */
|
||||
export async function isGuildMember(client, userId) {
|
||||
if (userId === config.adminDiscordId) return true;
|
||||
const guildId = discordGuildId();
|
||||
if (!guildId) return true; // ohne Guild-Konfig kein Gate
|
||||
const guild = client.guilds.cache.get(guildId) ?? await client.guilds.fetch(guildId).catch(() => null);
|
||||
if (!guild) return true; // Bot nicht auf der Guild → Gate nicht erzwingbar
|
||||
const member = await guild.members.fetch(userId).catch(() => null);
|
||||
return Boolean(member);
|
||||
}
|
||||
|
||||
export function registerAuthRoutes(app, client) {
|
||||
// Login: mit CSRF-State zu Discord weiterleiten
|
||||
app.get('/auth/login', async (request, reply) => {
|
||||
const state = crypto.randomBytes(16).toString('hex');
|
||||
@@ -81,6 +92,11 @@ export function registerAuthRoutes(app) {
|
||||
}
|
||||
const me = await userRes.json();
|
||||
|
||||
// Member-Gate: nur Mitglieder des Discord-Servers bekommen eine Session
|
||||
if (memberGateEnabled() && !(await isGuildMember(client, me.id))) {
|
||||
return reply.clearCookie(STATE_COOKIE, { path: '/auth' }).redirect('/?gate=1');
|
||||
}
|
||||
|
||||
// Nur das Nötigste in die Session — keine Tokens speichern
|
||||
const session = {
|
||||
id: me.id,
|
||||
|
||||
Reference in New Issue
Block a user