User Panel Module
The User Panel Module (@zumito-team/user-panel-module) provides a web dashboard where Discord users can manage their servers, view account info, and access module-specific pages (like music queues). It features Discord OAuth2 authentication, multi-language support, and a dynamic sidebar that other modules can extend.
Installation
Section titled “Installation”npm install @zumito-team/user-panel-moduleAdd to your zumito.config.ts:
bundles: ['@zumito-team/user-panel-module']What it provides
Section titled “What it provides”Dashboard
Section titled “Dashboard”A full web interface at /panel showing:
- Server list — all guilds where the user has Administrator, ManageGuild, or owner permissions.
- Guild-specific dashboard at
/panel/:guildIdwith extensible sidebar sections. - Multi-language support with automatic detection via cookies or
Accept-Languageheaders.
Authentication
Section titled “Authentication”Discord OAuth2-based login flow via the shared discord-auth module:
- User visits
/panel/login→ redirected to Discord authorization (identifyscope). - Discord redirects back to
/panel/login/callback. - A JWT (
panel_token,purpose: 'panel') is issued with the full Discord user profile, stored in an httpOnly cookie with 30-day expiry. - All panel routes validate this token via
UserPanelAuthService(which extendsDiscordAuthService). - Tokens issued for other modules (e.g., Admin) are rejected thanks to the
purposeclaim.
Services
Section titled “Services”| Service | Purpose |
|---|---|---|
| UserPanelNavigationService | Register sidebar items in the user panel. |
| UserPanelViewService | Render pages within the panel layout (EJS templates). |
| UserPanelAuthService | Extends DiscordAuthService. Validates JWT tokens with purpose: 'panel' and extracts Discord user data. |
| UserPanelLanguageManager | Resolve language from cookies or headers, provide translation functions. |
| UserPanelColorsService | Manage the panel color palette. |
Routes
Section titled “Routes”| Method | Path | Description |
|---|---|---|
GET | /panel | Main dashboard with server list. |
GET | /panel/:guildId | Guild-specific dashboard. |
GET | /panel/login | Redirect to Discord OAuth2. |
GET | /panel/login/callback | OAuth2 callback handler. |
GET | /panel/logout | Clear auth cookie and redirect to /panel. |
Navigation default items
Section titled “Navigation default items”The module registers these initial entries:
- Back — Link to
/panel. - Dashboard — Guild overview at
/panel/:guildIdwith ageneralsection.
Configuration
Section titled “Configuration”Environment variables
Section titled “Environment variables”| Variable | Required | Description |
|---|---|---|
DISCORD_CLIENT_ID | Yes | Discord application client ID. |
DISCORD_CLIENT_SECRET | Yes | Discord application client secret. |
SECRET_KEY | Yes | Secret key for JWT signing. |
HOST | Yes | Bot host URL. |
FRONTEND_URL | Yes | Frontend URL for redirects. |
USER_PANEL_COLORS_FILE | No | Path to a JSON file with color overrides. |
USER_PANEL_COLORS | No | JSON string with color overrides. |
Color palette
Section titled “Color palette”Same structure as the admin module. Configurable via USER_PANEL_COLORS env var or JSON file:
{ "primary": "#5865f2", "accent": "#5865f2", "success": "#57f287", "warning": "#fee75c", "danger": "#ed4245", "foreground": "#ffffff", "dark": { "100": "#36393f", "200": "#2f3136", "300": "#292b2f", "400": "#202225" }}Extending the user panel
Section titled “Extending the user panel”Adding navigation items
Section titled “Adding navigation items”Other modules can register sidebar items by consuming UserPanelNavigationService:
import { ServiceContainer } from 'zumito-framework';
const nav = ServiceContainer.getService('UserPanelNavigationService');
// Register a top-level nav itemnav.registerItem({ id: 'my-feature', label: 'My Feature', icon: 'star', link: '/panel/my-feature'});
// Register sub-items under an existing parent's sectionnav.registerSubItems('dashboard', 'general', [ { id: 'my-sub-page', label: 'My Sub Page', icon: 'settings', link: '/panel/:guildId/my-page' }]);Adding routes
Section titled “Adding routes”Create your own route classes that use UserPanelViewService.render():
import { Route, RouteMethod, ServiceContainer } from 'zumito-framework';
class MyPanelRoute extends Route { method = RouteMethod.get; path = '/panel/:guildId/my-page';
async execute(req, res) { const auth = ServiceContainer.getService('UserPanelAuthService'); const { isValid, data } = await auth.isLoginValid(req);
if (!isValid) return res.redirect('/panel/login');
const view = ServiceContainer.getService('UserPanelViewService'); const html = await view.render({ content: '<h1>My Custom Page</h1>', reqPath: req.path, req, res });
res.send(html); }}Module requirements declaration
Section titled “Module requirements declaration”Your module must declare the dependency when extending the panel:
class MyModule extends Module { requirements = { services: ['UserPanelNavigationService'] };
async initialize() { const nav = ServiceContainer.getService('UserPanelNavigationService'); nav.registerSubItems('dashboard', 'general', [ { id: 'my-page', label: 'My Page', link: '/panel/:guildId/my-page' } ]); }}Language support
Section titled “Language support”The panel automatically detects the user’s language. Use the UserPanelLanguageManager to access translations:
const langManager = ServiceContainer.getService('UserPanelLanguageManager');const { t, lang } = langManager.getLanguageVariables(req, res);
const greeting = t('welcome_message'); // Returns translated stringconst availableLanguages = langManager.getAvailableLanguages(); // ['en', 'es', ...]Architecture comparison with Admin
Section titled “Architecture comparison with Admin”Both modules share the same auth foundation via discord-auth, with different configurations:
| Feature | Admin | User Panel |
|---|---|---|
| Auth service | AdminAuthService → DiscordAuthService | UserPanelAuthService → DiscordAuthService |
| View service | AdminViewService | UserPanelViewService |
| Nav service | NavigationService | UserPanelNavigationService |
| Colors service | AdminColorsService | UserPanelColorsService |
| Cookie name | admin_token | panel_token |
| JWT purpose | 'admin' | 'panel' |
| Sub-item key | sectionLabel | sectionId |
Dependencies
Section titled “Dependencies”discord-auth— Shared Discord OAuth2 authentication service.ejs— Template rendering for panel pages.jose— JWT verification and signing.zumito-framework
Related modules
Section titled “Related modules”- DisTube Module — Registers a music queue page in the user panel sidebar.
- Admin Module — Similar architecture for admin-level dashboards.