Files
jackboxpartypack-gamepicker/backend/config/load-admins.js
cottongin b2bb2989e9 feat: role-aware presence bar, WebSocket logging fixes
- findAdminByKey returns role from admins.json (defaults to 'admin')
- JWT includes config-defined role instead of hardcoded 'admin'
- PresenceBar split into "who's here?" (page admins) and "connected"
  (bot/utility services with icon+color badges)
- Bot/utility roles appear in presence on all pages when connected
- usePresence hook uses refs to avoid WS reconnect on navigation
- WS auth log prints admin name instead of generic 'admin'
- WS connection log reads X-Forwarded-For for real client IP
- AuthContext stores adminRole from login response
- Uncomment admins.json Docker volume mount, add SELinux :z flags

Made-with: Cursor
2026-04-05 04:46:56 -04:00

69 lines
1.9 KiB
JavaScript

const fs = require('fs');
const path = require('path');
const DEFAULT_CONFIG_PATH = path.join(__dirname, 'admins.json');
function canRead(filePath) {
try {
fs.accessSync(filePath, fs.constants.R_OK);
return true;
} catch {
return false;
}
}
function loadAdmins() {
const configPath = process.env.ADMIN_CONFIG_PATH || DEFAULT_CONFIG_PATH;
if (canRead(configPath)) {
const raw = fs.readFileSync(configPath, 'utf-8');
const admins = JSON.parse(raw);
if (!Array.isArray(admins) || admins.length === 0) {
throw new Error(`Admin config at ${configPath} must be a non-empty array`);
}
const names = new Set();
const keys = new Set();
for (const admin of admins) {
if (!admin.name || !admin.key) {
throw new Error('Each admin must have a "name" and "key" property');
}
if (names.has(admin.name)) {
throw new Error(`Duplicate admin name: ${admin.name}`);
}
if (keys.has(admin.key)) {
throw new Error(`Duplicate admin key found`);
}
names.add(admin.name);
keys.add(admin.key);
}
console.log(`[Auth] Loaded ${admins.length} admin(s) from ${configPath}`);
return admins;
}
if (fs.existsSync(configPath) && !canRead(configPath)) {
console.warn(`[Auth] Config file exists at ${configPath} but is not readable, skipping`);
}
if (process.env.ADMIN_KEY) {
console.log('[Auth] No admins config file found, falling back to ADMIN_KEY env var');
return [{ name: 'Admin', key: process.env.ADMIN_KEY }];
}
throw new Error(
'No admin configuration found. Provide backend/config/admins.json or set ADMIN_KEY env var.'
);
}
const admins = loadAdmins();
function findAdminByKey(key) {
const match = admins.find(a => a.key === key);
return match ? { name: match.name, role: match.role || 'admin' } : null;
}
module.exports = { findAdminByKey, admins };