Files
BanGUI/Docs/Tasks.md
Lukas 57cf93b1e5 Add ensure_jail_configs startup check for required jail config files
On startup BanGUI now verifies that the four fail2ban jail config files
required by its two custom jails (manual-Jail and blocklist-import) are
present in `$fail2ban_config_dir/jail.d`.  Any missing file is created
with the correct default content; existing files are never overwritten.

Files managed:
  - manual-Jail.conf        (enabled=false template)
  - manual-Jail.local       (enabled=true override)
  - blocklist-import.conf   (enabled=false template)
  - blocklist-import.local  (enabled=true override)

The check runs in the lifespan hook immediately after logging is
configured, before the database is opened.
2026-03-16 16:26:39 +01:00

6.2 KiB

BanGUI — Task List

This document breaks the entire BanGUI project into development stages, ordered so that each stage builds on the previous one. Every task is described in prose with enough detail for a developer to begin work. References point to the relevant documentation.


Task: Ensure Required fail2ban Jail Config Files Exist DONE

Implemented: backend/app/utils/jail_config.pyensure_jail_configs(jail_d_path) creates missing manual-Jail.conf, manual-Jail.local, blocklist-import.conf, and blocklist-import.local files with correct default content. Called from the lifespan hook in main.py using Path(settings.fail2ban_config_dir) / "jail.d". Tests in backend/tests/test_utils/test_jail_config.py (6 cases: all missing, all present, only locals missing, directory creation, idempotency, correct content).

The backend must guarantee that two specific jail configuration files are present inside the fail2ban jail directory before the application starts (or on first use). If either file is missing it must be created with the correct default content. The files live inside the directory that fail2ban uses for per-jail drop-in configs (e.g. jail.d/). The path to that directory should be read from the application settings (config key fail2ban_jail_d_path or equivalent); do not hard-code it.

Files to create if missing

manual-Jail.conf The file must contain a [manual-Jail] section with enabled = false and all other jail parameters (filter, logpath, backend, maxretry, findtime, bantime, ignoreip) set to the same defaults already documented in Docker/fail2ban-dev-config/fail2ban/jail.d/manual-Jail.conf. Only enabled must be forced to false in this template — it is the .local override (see below) that activates the jail.

blocklist-import.conf The file must contain a [blocklist-import] section with enabled = false and all other jail parameters (filter, logpath, backend, maxretry, findtime, bantime, ignoreip) set to the same defaults already documented in Docker/fail2ban-dev-config/fail2ban/jail.d/blocklist-import.conf. Same rule: enabled = false here; the .local file enables it.

Local override files

For each .conf file above there must also be a corresponding .local file checked — and created if missing. The .local files must contain only the section header and the single enabled = true line. Nothing else. fail2ban merges .local on top of .conf at startup, so all other settings come from the .conf.

[manual-Jail]
enabled    = true
[blocklist-import]
enabled    = true

Implementation notes

  • Perform the check in a backend startup routine (e.g. in a lifespan hook or a dedicated ensure_jail_configs() function called from main.py).
  • Only create a file if it does not already exist. Never overwrite an existing file.
  • Log an INFO message for each file that is created and a DEBUG message when a file already exists.
  • Add unit tests that exercise: (a) all four files missing → all four created with correct content, (b) all four files present → nothing is overwritten, (c) only the .local files missing → only they are created.

Task: World Map — Country Tooltip on Hover

Currently the world map (WorldMap.tsx) shows a ban-count label painted directly onto each country's SVG path and reacts to click events. Add a floating tooltip that appears when the user hovers over a country.

Required behaviour

  • When the mouse enters a country geography, display a small floating tooltip near the cursor that shows:
    • The country's full name (already available via country_names from useMapData()).
    • The ban count for that country (from the countries map; show 0 if the country has no entry).
  • The tooltip must follow the mouse while inside the country (or at minimum appear near the cursor when it first enters).
  • When the mouse leaves the country the tooltip must disappear.
  • Countries with zero bans must also show the tooltip (name + "0 bans").

Implementation notes

  • Store tooltip state (visible, content, x, y) in a useState hook local to WorldMap.tsx.
  • Use onMouseEnter, onMouseMove, and onMouseLeave props on the <Geography> element (react-simple-maps already forwards these as standard SVG mouse events).
  • Render the tooltip as an absolutely-positioned <div> overlaid on the map container. Apply a pointer-events: none style so it does not interfere with hover detection on the map itself.
  • Reuse the existing Fluent UI design tokens (background, border, shadow, typography) so the tooltip matches the rest of the UI. Do not introduce a new third-party tooltip library.
  • Add a Vitest / React Testing Library test that mounts WorldMap with mock data, fires a mouseenter event on a geography, and asserts the tooltip text is visible.

Task: Main Menu — Tooltips on Navigation Items

The main navigation sidebar (or top bar, whichever is used) currently has no tooltips. Add a tooltip to each navigation item so that users who are unfamiliar with icon-only or collapsed menus can see the destination name without navigating.

Required behaviour

  • Each navigation item must show a tooltip containing the item's label (e.g. "Dashboard", "Map", "Blocklist", "Settings") when the user hovers over it.
  • Tooltips should appear after a short delay (≈ 300 ms) to avoid flickering during fast cursor movement past the menu.
  • The tooltip must be dismissed when the cursor leaves the item.
  • If the menu is already showing a full text label next to the icon, the tooltip is still added (it reinforces accessibility); but consider hiding it when the sidebar is expanded and the label is already visible, to avoid redundancy.

Implementation notes

  • Use the Fluent UI <Tooltip> component (from @fluentui/react-components) which is already a project dependency. Wrap each navigation <NavLink> (or equivalent element) with <Tooltip content="…" relationship="label">.
  • Keep the tooltip content string co-located with the route definition so that if a label changes in one place it changes everywhere.
  • Do not introduce any new npm dependencies.
  • Add a Vitest / React Testing Library test that renders the navigation component, triggers a hover on each item, and asserts the correct tooltip text is present in the DOM.