← Back
Editing: ARCHITECTURE.md
# Rspamd WebUI Architecture ## Overview The Rspamd WebUI is a single-page application (SPA) providing a web interface for monitoring and managing Rspamd. It communicates with Rspamd's Controller API and supports multiple server instances. **Main capabilities:** - Real-time statistics and throughput monitoring - Message processing history inspection - Message scanning and analysis - Bayes classifier and Fuzzy storage training - Symbol and action configuration - Map editing - Selector testing - Multi-server management ## Technology Stack ### Module System - **RequireJS** - AMD (Asynchronous Module Definition) pattern for modular code organization ### Core Libraries - **jQuery** - DOM manipulation, event handling, AJAX - **Bootstrap** - UI framework for responsive layout and components ### Visualization & Data Display - **D3.js** - Base visualization library - **D3Evolution** - Time-series line charts (throughput graphs) - **D3Pie** - Pie charts (action distribution) - **Tabulator** - Responsive data tables with sorting, filtering, and pagination ### Code Editing - **CodeJar** - Lightweight code editor - **CodeJar Line Numbers** - Line numbering extension for CodeJar - **Prism.js** - Syntax highlighting ### Utilities - **NProgress** - Progress bars for async operations - **Visibility.js** - Page Visibility API wrapper for timer management - **Font Awesome** - Icon glyphs (local subset SVG sprite, see Icons below) - **jQuery Sticky Tabs** - Persistent tab state via URL hash ### Theme System Custom implementation supporting light/dark/auto modes with system preference detection. ### Icons Font Awesome glyphs are served as a local **subset SVG sprite** (`img/icons.svg`), not the full "SVG with JS" framework. `app/icons.js` replaces `<i class="fas fa-<name>">` placeholders with inline `<svg><use href="img/icons.svg#fa-<name>"/></svg>` (an initial sweep plus a MutationObserver for lazily inserted nodes); its `setIcon()` swaps an icon in place (theme toggle, map modal). Each icon keeps its natural aspect ratio: the default box is 1em square, and non-square glyphs get explicit widths in `css/icons.css`, generated alongside the sprite. The sprite is generated from the Font Awesome package by `icons-build.mjs` (repo root); edit `icons-manifest.txt` and re-run `node icons-build.mjs` to add or remove icons. ## Project Structure ``` interface/ ├── index.html # Main HTML file with tab structure ├── css/ # Stylesheets │ ├── bootstrap.min.css │ ├── rspamd.css # Custom styles │ ├── icons.css # Generated Font Awesome icon widths │ └── ... # Third-party CSS ├── js/ │ ├── main.js # Entry point & RequireJS configuration │ ├── app/ # Application modules │ │ ├── common.js # Shared utilities and API client │ │ ├── rspamd.js # Main application logic, auth, tab management │ │ ├── stats.js # Statistics tab (status widgets) │ │ ├── history.js # History tab (message log, errors) │ │ ├── graph.js # Throughput tab (time-series graphs) │ │ ├── symbols.js # Symbols tab (symbol scores editing) │ │ ├── config.js # Configuration tab (actions, maps) │ │ ├── upload.js # Scan tab (message upload/scanning) │ │ ├── selectors.js # Selectors tab (testing selectors) │ │ ├── libft.js # Tabulator table utilities (history/scan rendering) │ │ ├── icons.js # Icon rendering: <i class="fas fa-*"> -> inline SVG from sprite │ │ └── tab-utils.js # Shared Tabulator UI helpers (footer, scroll, row-toggle) │ └── lib/ # Third-party libraries (minified) ├── img/ # Images, logos, and icons.svg (icon subset sprite) └── README.md # Setup instructions ``` ## Module System The WebUI uses **RequireJS** (AMD pattern) for modular code organization. **Module definition pattern:** ```javascript define(["dependency1", "dependency2"], (dep1, dep2) => { const ui = {}; ui.publicMethod = function() { /* ... */ }; return ui; }); ``` **Entry point:** `js/main.js` - configures RequireJS, initializes theme, loads main app module **Module loading:** - Main app module (`app/rspamd`) loads on page load - Tab-specific modules lazy-load when tabs are activated ## Key Components ### Authentication & Connection `js/app/rspamd.js` - `ui.connect()` Handles password authentication, stores credentials in `sessionStorage`, detects read-only mode ### Tab Management & Navigation `js/app/rspamd.js` - `tabClick()` Manages tab switching, lazy-loads tab-specific modules, handles auto-refresh ### Auto-Refresh System `js/app/rspamd.js` - `setAutoRefresh()` Periodically refreshes tab data, pauses when page hidden (via Visibility.js), shows countdown timer ### API Communication `js/app/common.js` - `ui.query(url, options)` Sends HTTP requests to Controller API, supports multi-server queries, handles authentication and errors ### Theme System `js/main.js` - Theme initialization and `window.rspamd.theme` API Manages light/dark/auto theme switching, persists preferences, responds to system theme changes ### Statistics Display `js/app/stats.js` Fetches and displays server statistics (Status tab): version, uptime, message counts, action distribution ### Throughput Graphs `js/app/graph.js` Renders time-series graphs and pie charts (Throughput tab) using D3Evolution and D3Pie ### Message History `js/app/history.js` (data fetching), `js/app/libft.js` (table rendering) Displays processed message history (History tab), handles Tabulator initialization, row expansion, symbol details ### Configuration Management `js/app/config.js` Manages actions and maps (Configuration tab): load, edit, save settings ### Symbol Management `js/app/symbols.js` Displays and edits symbol scores (Symbols tab) ### Message Scanning & Learning `js/app/upload.js` Handles message upload, scanning, Bayes classifier training, fuzzy hash management (Scan tab) ### Selector Testing `js/app/selectors.js` Tests Rspamd selectors against messages (Selectors tab) ### Table Utilities `js/app/libft.js` Shared Tabulator table utilities: data preprocessing, table initialization, pagination, sorting ### Shared Tabulator UI Helpers `js/app/tab-utils.js` Cross-table UI helpers used by every Tabulator table: scroll-into-view patching, tableholder tabindex stripping, single-page footer hiding, click-to-toggle responsive rows, and scroll-position preservation across renders. Depends only on `common` (no jQuery). ## Data Flow **Typical interaction pattern:** 1. User action (click, input) → Event handler 2. Data preparation 3. `common.query()` → API request(s) to server(s) 4. Response processing 5. UI update (DOM, tables, charts) ## Common Patterns ### Event Handlers Use function expressions `function() {}` when you need `this` context (event target element), otherwise use arrow functions `() => {}`. ### API Calls Most API communication goes through `common.query(endpoint, options)` which handles multi-server requests, authentication, progress tracking, and error handling. ### Table Management Tables use Tabulator. Two main patterns: - **Initial load**: destroy old table → process data → initialize Tabulator → bind event handlers - **Update data**: use Tabulator API to update existing table without re-initialization ### Module Structure Each tab module returns a `ui` object with public methods (e.g., `ui.getSymbols()`, `ui.draw()`). These methods are called when tabs are activated. ## State Management **Persistent storage (localStorage):** - Theme preference - Locale settings - AJAX timeout - Page size preferences **Session storage (sessionStorage):** - Authentication password - Server credentials and capabilities - Error suppression flags **Global state:** - `common.neighbours[]` - Configured servers - `common.tables{}` - Tabulator instances - `timer_id[]` - Active refresh timers - `checked_server` - Currently selected server ## Technical Requirements **Browser capabilities needed:** - Modern JavaScript (ES6+: arrow functions, const/let, template literals) - Page Visibility API - CSS Custom Properties **Network:** - Browser must have network access to all configured controllers - WebUI makes API requests from the browser to each controller independently (the controller serving the WebUI does not act as an intermediary)
Save File
Cancel