Commit Graph

65 Commits

Author SHA1 Message Date
olivier 66aeb04cb5 feat: collapsible groups in IP addressing view
Groups are collapsed by default. Click a header to toggle it; chevron
rotates to indicate state. "Expand all" / "Collapse all" buttons in the
page header; each is disabled when the action is already complete.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22 09:16:16 +02:00
olivier 6b4de6f792 feat: add DeviceFormModal and IpAddressing components
- DeviceFormModal: device create/edit form with interfaces, virt_type,
  url, type selector — no OS field (auto-detected from description)
- IpAddressing: IP address view grouped by VLAN with inline OS icon
  detected via detectOs() from name/description

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22 09:11:32 +02:00
olivier 5001ce192d feat: auto-map all 3098 simple-icons via import * and word-boundary detection
Replace hand-curated named imports with `import * as si from 'simple-icons'`.
BRANDS keeps only entries requiring custom aliases, absent icons, or colour
overrides. AUTO_SI covers all remaining simple-icons (title >= 4 chars) with
pre-compiled word-boundary regexes to avoid substring false positives.

detectBrands() now runs two passes:
1. BRANDS — curated aliases (pve → Proxmox, unifi → Ubiquiti, k3s → k8s…)
2. AUTO_SI — automatic match on any icon title as a whole word

Bundle: +5 MB minified / +2 MB gzip (acceptable for a self-hosted tool).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22 09:09:33 +02:00
olivier fd289cc00f feat: auto-detect OS from description; expand OS_LIST to 51 distros
- Remove os field from Device API and form — OS is now detected
  automatically from name/description via detectOs() in brandIcons.js
- Expand OS_LIST from 20 to 51 entries covering all major distros
  (Debian/Ubuntu flavours, Red Hat, SUSE, Arch, BSD, security distros,
  Windows/macOS/iOS/Android, generic Linux/BSD catch-alls)
- Display detected OS icon in IpAddressing.vue description column
- Fix virt_type validator to normalise empty string to null

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22 08:52:53 +02:00
olivier 954b5cefa6 chore: bump version to 1.0.1
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 18:32:35 +02:00
olivier 41cd9c096c i18n: pass all visible UI strings through t() — no more hardcoded labels
Move Link, GW, LXC, VM chip tags, WAN labels, form placeholders, and
confirm-dialog delete verbs into i18n.js for all three locales (fr/en/es).
confirmDeleteDevice and confirmDeleteNetwork now include the action verb
so the JS callers no longer hardcode "Supprimer".

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 18:31:31 +02:00
olivier de03e38a3c fix: use :global(html.dark .selector) for scoped dark mode rules
Vue scoped styles append [data-v-xxx] to child selectors, so
`:global(html.dark) .foo` compiled to `.foo[data-v-xxx]` which never
matched. Wrapping the full rule in :global() prevents Vue from adding
the scope attribute.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 18:25:10 +02:00
olivier a0b5a55daf fix: isolate tests on in-memory SQLite to protect production database
Tests were importing the production engine and dropping all tables on
teardown, corrupting topology.db in the Docker volume. Set DATABASE_URL
to sqlite:///:memory: before any import in the test file, and use
StaticPool in database.py when running against :memory: so all
connections share the same in-memory database.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 18:22:32 +02:00
olivier e8ca10f1b7 fix: cap /api/discovery/ping at 4096 IPs and fix test suite
- Add MAX_PING_IPS=4096 constant and validate list size in PingRequest
  before spawning futures, returning 422 on overflow
- Add test_ping_too_many_ips_rejected to cover the new cap
- Pin httpx<0.28 in requirements-test.txt (0.28 broke TestClient API)
- Fix reset_db fixture to set a known admin password regardless of
  INITIAL_ADMIN_PASSWORD env var (was causing 401 on all auth tests)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 18:16:08 +02:00
olivier ec669c87b4 fix: validate interface vlan_id existence before write in devices router
Added _validate_iface_vlans() helper that checks all non-null vlan_ids
against the DB before any insert or update, returning a 400 instead of
letting SQLite raise an IntegrityError 500.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 18:06:01 +02:00
olivier 28e7a3e3d2 fix: return 400 on duplicate vlan_id in update_vlan
update_vlan now checks for vlan_id conflicts (excluding the current
record) before committing, matching the behaviour of create_vlan and
preventing an unhandled IntegrityError 500.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 18:05:06 +02:00
olivier d5a90f6f1d feat: display semantic version in sidebar footer
Reads version from package.json via Vite's define (__APP_VERSION__)
and shows it as a small label at the bottom of the sidebar.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 16:45:52 +02:00
olivier 3d37a19e1e feat: add Nginx, Windows and Firefox brand icons
- Nginx: siNginx (#009639) — keywords: nginx
- Windows: custom icon (#0078D4) — keywords: windows, win10, win11, winserver, windows server
- Firefox: siFirefox (#FF7139) — keywords: firefox
- Apache/Apache2 was already supported (no change needed)

Update README (en/fr/es) brand tables accordingly.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 16:40:50 +02:00
olivier dbd6dc5f2a refactor: keep 'Soft scan' untranslated in French and Spanish labels
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 15:39:04 +02:00
olivier c2f7c5f5e3 fix: escape apostrophe in French softScanHint string
Single-quoted JS string broke the Vite build.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 15:29:40 +02:00
olivier 5c34143b52 feat: add soft scan mode (slow ICMP) to avoid switch/AP rate-limiting
Reduces ICMP concurrency from 100 to 10 workers when soft_scan=true,
spreading out probes to avoid rate-limiting on managed switches and APs.
The option is hidden in the UI when TCP check is active (redundant).

Update README (en/fr/es), docs/backend.md with the new scan modes table
and a troubleshooting entry for ICMP rate-limiting.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 15:26:50 +02:00
olivier aa39898c80 refactor: rename 'Livebox / Box FAI' to 'Passerelle Internet' in device form
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 15:19:58 +02:00
olivier 93ab343db7 fix: switch tcp_check mode to TCP-only instead of ICMP+TCP
Previously tcp_check required both ICMP and TCP to pass. This caused
two failure modes: hosts with ICMP rate-limiting under scan load were
missed (ICMP fails → TCP never tried), and the AND logic was confusing.

In TCP-only mode, proxy-ARP gateways are still filtered out because
they never spoof TCP replies. Hosts with rate-limited ICMP (e.g. some
WiFi APs during a full /24 sweep) are now correctly detected via TCP.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 15:12:04 +02:00
olivier 4b0aa1edf2 fix: handle ping output with hostname when DNS resolves scan target
When the Docker container's DNS can resolve a target IP to a hostname,
ping formats the reply line as "from hostname (ip):" instead of the
plain "from ip:" format. The proxy-ARP source-IP guard only checked
for the plain format, causing those hosts to be incorrectly reported
as unreachable despite a valid ICMP response.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 14:40:19 +02:00
olivier 4c61ae9456 feat: add custom icons for Zabbix, Centreon, Nagios, PRTG, Eaton, Riello, Vertiv
UPS: Eaton (lightning bolt, #E22000), Riello (battery+, #0066B3),
     Vertiv (server rack, #0079A7)
Monitoring: Zabbix (activity line, #D40000), Centreon (bulb/hub, #0071CE),
            Nagios (magnifier, #2D72D2), PRTG (speedometer, #7AB648)

All use thematic SVG paths on 24×24 viewBox, consistent with existing
custom icons (ICON_FREE, ICON_BASTION, ICON_MAIL, etc.).
READMEs (fr/en/es) updated.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 14:04:09 +02:00
olivier ca45fa5caa feat: add UPS, network security, monitoring and log stack brand icons
UPS: Schneider Electric / APC (siSchneiderelectric)
Network security: Fortinet / FortiGate (siFortinet)
Monitoring: Prometheus, Grafana, Datadog, Netdata, Checkmk, Icinga,
            InfluxDB, VictoriaMetrics
Alerting: Opsgenie, PagerDuty
Logs/Traces: Elastic/ELK, Kibana, Logstash, Splunk, Graylog, Jaeger,
             OpenTelemetry

Color overrides for near-black icons: Icinga → #3F5FBA, Opsgenie → #2684FF,
Splunk → #65A637, OpenTelemetry → #425CC7.

Not available in simple-icons: Zabbix, Centreon, Nagios, PRTG, Eaton,
Riello, Vertiv (noted in CLAUDE.md).

READMEs (fr/en/es) updated with all new entries.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 12:42:15 +02:00
olivier 29e32d3911 fix: escape apostrophe in French dnsHint string (broke Vite build)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 12:26:22 +02:00
olivier 806fe1caec feat: DNS_SERVER env var — pre-fills discovery UI, optional for scan
- DNS_SERVER env var configures the default DNS server for PTR lookups
- GET /api/discovery/config exposes it to the frontend
- DiscoveryModal fetches it on mount and pre-fills the field (editable)
- dns_server is now optional in ScanRequest (default empty string)
- PTR lookup is skipped when dns_server is empty — scan still proceeds
- Validator only runs when dns_server is non-empty
- .env.example, docker-compose.yml, READMEs (fr/en/es) updated

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 12:22:05 +02:00
olivier c8607831a4 fix: remove default DNS server in backend — dns_server is now required
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 12:17:16 +02:00
olivier b7c2e86673 fix: remove default DNS server value — user must enter their own
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 12:16:07 +02:00
olivier 06577fd245 fix: replace hardcoded personal DNS with neutral default (8.8.8.8)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 12:15:32 +02:00
olivier ce1402b5f3 docs: add Apple to brand tables and troubleshooting section (proxy-ARP)
- Add Apple ecosystem row in all three README brand tables
- Add Troubleshooting section explaining proxy-ARP false positives and
  the TCP check fix (fr/en/es)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 12:00:58 +02:00
olivier 4d1e49671b feat: add Apple brand icon (iPhone, iPad, MacBook, iMac, macOS, iOS…)
Uses siApple with hex override #555555 (visible on both light and dark
themes — Apple's brand color #000000 is invisible on dark backgrounds).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 11:48:49 +02:00
olivier a4538b7fe0 fix: correct tcp_check hint — RST on closed port means host is detected
The previous wording wrongly implied smartphones and firewalled PCs could
be missed. Only devices that silently DROP (not REJECT) all probed ports
are undetected; a RST reply on a closed port correctly identifies the host.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 11:21:20 +02:00
olivier cc716783ea feat: add optional TCP check to scan to filter proxy-ARP false positives
Some gateways (e.g. UniFi) respond to ICMP for every IP in a subnet via
proxy-ARP, spoofing the source IP so the existing ICMP guard cannot help.
A secondary TCP probe (ports 22, 80, 443, 8080, 8443) distinguishes real
hosts (RST/connect on closed ports) from ghost IPs (gateway drops SYN →
timeout). The check is opt-in (disabled by default) to avoid missing
devices whose firewall DROPs all probed ports.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 11:17:55 +02:00
olivier 14de657deb feat: cascade-delete hosts when removing a network
When a VLAN/LAN is deleted, all non-gateway, non-livebox devices
with an interface in that network are deleted automatically.
Gateway and livebox devices are preserved; their interface is
unlinked (vlan_id set to NULL).

The confirmation dialog now shows the exact count of devices
that will be deleted (all three locales: fr/en/es).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 10:48:36 +02:00
olivier cf07461436 fix: guard _ping() against proxy-ARP false positives
Verify that the ICMP reply source IP matches the target before
reporting a host as alive. Prevents scan from returning the entire
CIDR range when a gateway answers ARP requests on behalf of all IPs.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 08:38:58 +02:00
olivier 0a91d840be fix: keep layout always in DOM via v-show to avoid Firefox click dispatch bug
Replace v-if/v-else-if/v-else auth guard with v-if on LoginPage and
v-show on the layout div. Firefox fails to dispatch clicks to children
after a DOM node is inserted into a display:flex container; using v-show
means the layout is always present (just display:none), so no node
replacement ever occurs in .app-root. Move the forced AccountModal
(mustChangePassword) inside the layout as a first child with v-if.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 08:09:06 +02:00
olivier 6ae7fac766 feat: add Free, Bouygues Telecom and SFR brand icons
None of the three are in simple-icons — custom wifi icons with
official brand colors (Free #CD1126, Bouygues #0099CC, SFR #E2001A).
Keywords avoid the bare word "free" to prevent false positives on
freenas/freebsd/etc.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-17 13:43:55 +02:00
olivier f6162c59a6 docs: sync brand keyword tables across all three READMEs
Add 9 missing trigger keywords that were present in brandIcons.js
but absent from the documentation: tp link, maria db, raspberrypi,
kde desktop, paperless-ng, uptimekuma, material for mkdocs, hass,
hue hub.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-17 13:41:43 +02:00
olivier c729cec54d feat: add smart TV and TV box brand icons (13 brands)
TV manufacturers: Samsung, LG, Sony (hex overridden #1A1A1A — white
would be invisible), Panasonic, Sharp, Toshiba, Vestel.
Hisense is absent from simple-icons.

TV boxes: Chromecast/Google TV, Android TV, Apple TV, Amazon Fire TV,
Roku, Kodi.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-17 13:33:29 +02:00
olivier a4f276a5eb feat: add French ISP logos, Guacamole and generic bastion icon
French ISPs: Orange (#FF7900, keywords: orange/sosh/livebox),
OVH (#123F6D, keywords: ovh/ovhcloud/kimsufi/soyoustart).
Free, SFR and Bouygues are absent from simple-icons.

Bastion: Apache Guacamole (#578B34, keyword: guacamole) + generic
shield-lock icon (#1E3A8A) for bastion/jumphost/teleport/bastillion.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-17 12:51:10 +02:00
olivier dc04567c48 feat: expand VLAN color palette to 50 presets in a 5×10 grid
Replace the 10-color row with a 5-row × 10-column palette covering
red, rose, orange, amber, yellow, green, teal, cyan, blue, indigo,
violet, purple, fuchsia and gray families. Selected swatch is
highlighted with a border ring.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-17 12:47:47 +02:00
olivier fb6bcdb968 feat: add generic archive server icon
Custom archive-box icon (stone #78716C) triggered by: archive, archiver
(FR/EN), archivage (FR), archivar (ES), archivebox.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-17 12:44:17 +02:00
olivier 379f258ffb feat: add generic mail server icon
Custom envelope icon (slate #64748B) triggered by: mail, smtp, imap,
postfix, dovecot, mailcow, mailu, roundcube. Uses the same {title, hex,
path} format as simple-icons so no consumer changes are needed.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-17 12:33:54 +02:00
olivier ea1d96f99e feat: add brand icons for CMS/blog engines and analytics
CMS/Blog: WordPress, Ghost, Grav, Jekyll, Hugo, Hexo, Drupal, Joomla,
TYPO3, OctoberCMS, Textpattern
Analytics: Matomo, Plausible

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-17 12:29:35 +02:00
olivier 5eb3860201 feat: add brand icons for IDP, password vaults and media apps
Auth/SSO: Keycloak, Authentik, Okta, Auth0 (Authelia already present)
Password vaults: Vaultwarden, Bitwarden, 1Password, KeePassXC, HashiCorp Vault
Media/torrent: Radarr, Sonarr, Transmission

Jackett, Zitadel and Prowlarr are absent from simple-icons.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-17 12:26:35 +02:00
olivier 3e2d9e6a77 feat: add Authelia brand logo detection
Trigger keyword: authelia. Icon colour: #113155.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-17 12:22:53 +02:00
olivier 9fe6b25786 fix: add smart_tv, printer, smartphone to backend _VALID_TYPES
The backend validator was rejecting the three new device types added
in the previous commit, returning HTTP 422.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-17 11:54:17 +02:00
olivier 7b32e9b4fd feat: add smart_tv, printer and smartphone device types
Add three new device types (21 total) with Lucide icons (Tv2, Printer,
Smartphone), colour-coded badges, and translations in fr/en/es.
No backend migration needed — type is a free string field.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-17 11:48:23 +02:00
olivier 8b39554982 docs: add brand logo detection section to all READMEs
Documents keyword-based detection mechanism and lists all 34 supported
brands with their trigger keywords, organised by category.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-17 11:39:46 +02:00
olivier cd1be8eaa5 docs: add update procedure section to all READMEs
Explains that db_data/ is preserved across container rebuilds and that
database migrations run automatically on startup.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-17 10:41:30 +02:00
olivier 44c502dc50 feat(i18n): pluralize sidebar network/device counters
Show singular form when count is 1 (Network, Device, Réseau, Équip., Red, Equipo)
across all three supported languages (fr, en, es).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-17 10:40:11 +02:00
olivier 89a77e0e9e docs: add GPL v3 license and AI attribution section to all READMEs
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-17 10:30:56 +02:00
olivier bda8ac0546 docs: add Traefik reverse proxy examples (labels and file provider) to all READMEs
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-17 10:23:23 +02:00