Add multi-guild Discord OAuth support
- Users can now login via Bacanaks OR Piccadilly Discord server - Highest role from all servers is used (superadmin > moderator > user) - Lazy initialization fixes env loading timing issue - Updated documentation with implementation details and troubleshooting Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
97
discord.js
97
discord.js
@@ -1,6 +1,29 @@
|
||||
// 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,
|
||||
@@ -48,9 +71,10 @@ export async function getDiscordUser(accessToken) {
|
||||
return response.json();
|
||||
}
|
||||
|
||||
export async function getGuildMember(userId) {
|
||||
// Prüft einen einzelnen Server
|
||||
async function fetchGuildMember(guildId, userId) {
|
||||
const response = await fetch(
|
||||
`${DISCORD_API}/guilds/${process.env.DISCORD_GUILD_ID}/members/${userId}`,
|
||||
`${DISCORD_API}/guilds/${guildId}/members/${userId}`,
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bot ${process.env.DISCORD_BOT_TOKEN}`
|
||||
@@ -60,17 +84,78 @@ export async function getGuildMember(userId) {
|
||||
|
||||
if (!response.ok) {
|
||||
if (response.status === 404) {
|
||||
return null; // User not in guild
|
||||
return null;
|
||||
}
|
||||
throw new Error('Failed to get guild member');
|
||||
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;
|
||||
const modRoleId = process.env.DISCORD_MOD_ROLE_ID;
|
||||
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';
|
||||
|
||||
Reference in New Issue
Block a user