// Discord OAuth2 Service const DISCORD_API = 'https://discord.com/api/v10'; // Lazy initialization - wird erst bei Verwendung geladen (nach dotenv) let _guildConfigs = null; function getGuildConfigs() { if (_guildConfigs === null) { _guildConfigs = [ { name: 'Bacanaks', guildId: process.env.DISCORD_GUILD_ID_1, adminRoleId: process.env.DISCORD_ADMIN_ROLE_ID_1, modRoleId: process.env.DISCORD_MOD_ROLE_ID_1 }, { name: 'Piccadilly', guildId: process.env.DISCORD_GUILD_ID_2, adminRoleId: process.env.DISCORD_ADMIN_ROLE_ID_2, modRoleId: process.env.DISCORD_MOD_ROLE_ID_2 } ].filter(config => config.guildId); } return _guildConfigs; } export function getDiscordAuthUrl() { const params = new URLSearchParams({ client_id: process.env.DISCORD_CLIENT_ID, redirect_uri: process.env.DISCORD_REDIRECT_URI, response_type: 'code', scope: 'identify guilds.members.read' }); return `https://discord.com/oauth2/authorize?${params}`; } export async function exchangeCode(code) { const response = await fetch(`${DISCORD_API}/oauth2/token`, { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, body: new URLSearchParams({ client_id: process.env.DISCORD_CLIENT_ID, client_secret: process.env.DISCORD_CLIENT_SECRET, grant_type: 'authorization_code', code, redirect_uri: process.env.DISCORD_REDIRECT_URI }) }); if (!response.ok) { const error = await response.text(); throw new Error(`Failed to exchange code: ${error}`); } return response.json(); } export async function getDiscordUser(accessToken) { const response = await fetch(`${DISCORD_API}/users/@me`, { headers: { Authorization: `Bearer ${accessToken}` } }); if (!response.ok) { throw new Error('Failed to get Discord user'); } return response.json(); } // Prüft einen einzelnen Server async function fetchGuildMember(guildId, userId) { const response = await fetch( `${DISCORD_API}/guilds/${guildId}/members/${userId}`, { headers: { Authorization: `Bot ${process.env.DISCORD_BOT_TOKEN}` } } ); if (!response.ok) { if (response.status === 404) { return null; } throw new Error(`Failed to get guild member from ${guildId}`); } return response.json(); } // Prüft alle konfigurierten Server und gibt Memberships zurück export async function getGuildMemberships(userId) { const configs = getGuildConfigs(); const memberships = []; for (const config of configs) { try { const member = await fetchGuildMember(config.guildId, userId); if (member) { memberships.push({ config, member, roles: member.roles || [] }); } } catch (err) { console.error(`[Discord] Failed to check membership for guild ${config.name}:`, err.message); } } return memberships.length > 0 ? memberships : null; } // Legacy-Funktion für Kompatibilität export async function getGuildMember(userId) { const memberships = await getGuildMemberships(userId); if (!memberships || memberships.length === 0) { return null; } return memberships[0].member; } // Rollen-Priorität: superadmin > moderator > user const ROLE_PRIORITY = { superadmin: 3, moderator: 2, user: 1 }; // Bestimmt die höchste Rolle aus allen Server-Memberships export function getUserRoleFromMemberships(memberships) { if (!memberships || memberships.length === 0) { return 'user'; } let highestRole = 'user'; for (const { config, roles } of memberships) { let role = 'user'; if (roles.includes(config.adminRoleId)) { role = 'superadmin'; } else if (roles.includes(config.modRoleId)) { role = 'moderator'; } if (ROLE_PRIORITY[role] > ROLE_PRIORITY[highestRole]) { highestRole = role; } } return highestRole; } // Legacy-Funktion für Kompatibilität export function getUserRole(memberRoles) { const adminRoleId = process.env.DISCORD_ADMIN_ROLE_ID || process.env.DISCORD_ADMIN_ROLE_ID_1; const modRoleId = process.env.DISCORD_MOD_ROLE_ID || process.env.DISCORD_MOD_ROLE_ID_1; if (memberRoles.includes(adminRoleId)) { return 'superadmin'; } if (memberRoles.includes(modRoleId)) { return 'moderator'; } return 'user'; }