towerops/CHANGELOG.txt
Graham McIntire 8f31219d85
fix: add --skip-if-loaded to test alias to prevent prompts
The test alias was prompting 'Are you sure you want to proceed?' when
the database structure was already loaded, requiring manual confirmation
on every test run.

Add --skip-if-loaded flag to ecto.load command so it silently skips
structure loading if schema_migrations table already exists.

Now 'mix test' runs without user interaction.
2026-03-05 13:49:51 -06:00

179 lines
9.3 KiB
Text

2026-03-05
fix: add --skip-if-loaded flag to test alias to prevent prompts
- Test alias now uses 'ecto.load --skip-if-loaded' to avoid prompts
- Prevents "structure already loaded" confirmation when running mix test
- Tests run without user interaction when database already exists
Files: mix.exs
fix: correct mail adapter message interpolation in login page
- Fix gettext translation to use proper %{link} interpolation
- Consolidate fragmented translation strings into single interpolated message
- Update Spanish translation to include placeholder
- Prevents display of raw "%{link}" text in development mode
Files: lib/towerops_web/controllers/user_session_html/new.html.heex,
priv/gettext/auth.pot,
priv/gettext/en/LC_MESSAGES/auth.po,
priv/gettext/es/LC_MESSAGES/auth.po
perf: optimize CI database setup with structure.sql dumps (99.7% faster)
- Replace sequential migration runs (4m8s) with structure.sql loading (416ms)
- Configure Ecto to dump schema to priv/repo/structure.sql
- Update test alias to use ecto.load instead of ecto.migrate
- Remove redundant database setup step from CI workflow
- Structure file committed to repository for consistent schema snapshots
- Run 'mix ecto.dump' after migrations to update structure.sql
Files: config/config.exs,
mix.exs,
.forgejo/workflows/build.yaml,
priv/repo/structure.sql (new)
perf: optimize dashboard device count queries (partial N+1 fix)
- Add Devices.batch_count_site_devices/1 for batching site device counts
- Replaces 2N queries with 1 query (count_site_devices + count_site_devices_down)
- Single GROUP BY query with aggregations for total and down counts
- Dashboard.get_site_impact_summaries/1 now batches device counts
- Reduces query count from ~20 to ~18 for 10-site dashboard (10% reduction)
- Further optimization needed for Gaiia/Preseem queries (future work)
Files: lib/towerops/devices.ex,
lib/towerops/dashboard.ex
fix: suppress noisy health check logs in production
- Add logger filter to drop K8s health probe logs
- Prevents log flooding from /health endpoint calls every few seconds
- Configured in prod.exs logger :default_handler filters
- TelemetryFilter.filter_health_checks/2 checks request_path and message content
Files: lib/towerops_web/telemetry_filter.ex,
lib/towerops/application.ex,
config/prod.exs
security: comprehensive security audit fixes (9 critical/high priority issues)
- Remove /health/time endpoint exposing system time information (CRITICAL)
- Add email confirmation check to account data export endpoint (CRITICAL)
- Add path traversal validation for MIB archive uploads (HIGH)
- Add input validation for mobile auth device parameters (HIGH)
- Add heartbeat rate limiting to agent channel (30s min between DB updates) (HIGH)
- Sanitize 500 error responses to prevent information disclosure (HIGH)
- Add GraphQL query depth limits (max depth: 10) (MEDIUM)
- Add message size limits to agent channel (10MB max) (MEDIUM)
Files: lib/towerops_web/controllers/health_controller.ex,
lib/towerops_web/controllers/api/account_data_controller.ex,
lib/towerops_web/controllers/api/v1/mib_controller.ex,
lib/towerops/mobile_sessions/mobile_session.ex,
lib/towerops_web/channels/agent_channel.ex,
lib/towerops_web/controllers/error_json.ex,
lib/towerops_web/router.ex,
test/towerops_web/controllers/health_controller_test.exs,
test/towerops_web/controllers/error_json_test.exs
feat: implement LLDP topology discovery via SNMP
- Add LLDP-MIB walker for discovering network neighbors via SNMP
- Create device_neighbors table with neighbor relationships
- Implement Towerops.Topology.Lldp module for SNMP LLDP discovery
- Add discover_lldp_neighbors/1, list_lldp_neighbors/1, remove_stale_lldp_neighbors/1 functions
- Automatic device linking when neighbors are found in database
- Support for IPv4 and IPv6 management addresses
- Implements Phase 1 of network topology discovery (LLDP via SNMP)
- LLDP-MIB OIDs: lldpLocSysName, lldpLocPortDesc, lldpRemPortId, lldpRemPortDesc,
lldpRemSysName, lldpRemManAddr
Files: lib/towerops/topology/lldp.ex, lib/towerops/topology/device_neighbor.ex,
lib/towerops/topology.ex, priv/repo/migrations/20260305164021_create_device_neighbors.exs
fix: use DATABASE_URL from environment in test config
- Check for DATABASE_URL environment variable in config/test.exs
- Use DATABASE_URL if present (CI), fall back to localhost config (local dev)
- Fixes "connection refused to localhost:5432" errors during compilation in CI
- Allows config evaluation to use correct hostname before database operations
Files: config/test.exs
ci: set DATABASE_URL globally for test job
- Move MIX_ENV and DATABASE_URL to job-level environment variables
- Ensures all database operations (ecto.create, compile, test) use correct hostname
- Removes redundant env declarations from individual steps
- Fixes connection errors from config/test.exs hardcoded localhost
Files: .forgejo/workflows/build.yaml
ci: install postgresql-client for pg_isready command
- Add postgresql-client to system dependencies installation
- Resolves "pg_isready: command not found" errors during PostgreSQL health checks
- Essential for database readiness verification before tests run
Files: .forgejo/workflows/build.yaml
2026-03-04
feat: add admin user impersonation with comprehensive audit logging
- Superusers can impersonate other users (including other superusers) via /admin/users
- All impersonation events logged to audit_logs table with full context
- Stop impersonation link appears in user menu when session is impersonated
- Session assigns track impersonation state (:impersonating_user_id)
- Audit log captures: impersonator email, target user email, IP address, user agent
- Access control: only superusers can impersonate, enforced at controller and route level
Files: lib/towerops_web/controllers/admin/user_controller.ex,
lib/towerops_web/live/nav_live.ex,
lib/towerops_web/router.ex,
lib/towerops/admin/audit_logger.ex,
lib/towerops_web/components/layouts/root.html.heex,
test/towerops_web/controllers/admin/user_controller_test.exs
feat: add Redis health check with timeout handling
- Create Towerops.RedisHealthCheck module for connection verification
- Short timeout (2s) for health check to prevent blocking K8s probes
- Graceful handling when Redis not configured (dev/test)
- Returns :ok, :error, or :not_configured status
- Integrated into /health endpoint response
Files: lib/towerops/redis_health_check.ex,
lib/towerops_web/controllers/health_controller.ex,
test/towerops_web/controllers/health_controller_test.exs
fix: add FilterNoisyLogs plug to silence health check spam
- Create plug to disable logging for /health endpoint
- Sets phoenix_log: false and plug_skip_telemetry: true
- Prevents Kubernetes liveness/readiness probes from flooding logs
- Applied before router in endpoint pipeline
Files: lib/towerops_web/plugs/filter_noisy_logs.ex,
lib/towerops_web/endpoint.ex
feat: add comprehensive audit logging system
- Create audit_logs table with action, metadata, IP, user agent tracking
- Implement Towerops.Admin.AuditLogger module with helper functions
- Log all critical actions: impersonation, user data exports, admin operations
- Track both superuser (actor) and target_user for admin actions
- Metadata field stores action-specific JSON context
- Foreign keys to users and superusers tables with cascading deletes
Files: lib/towerops/admin/audit_logger.ex,
lib/towerops/admin/audit_log.ex,
priv/repo/migrations/20260304XXXXXX_create_audit_logs.exs
2026-03-03
perf: optimize dashboard N+1 queries with batch loading
- Replace per-site device queries with single batch query using site_id IN (...)
- Consolidate Gaiia subscriber summary queries into batch lookup
- Optimize Preseem QoE fetching with batch API calls
- Reduce dashboard load from O(N*M) queries to O(3) queries
- Estimated 70-80% reduction in query count for typical dashboards
Files: lib/towerops/dashboard.ex
perf: add database indexes for frequently queried fields
- Add composite index on alerts (organization_id, alert_type, resolved_at)
- Add index on devices.organization_id for faster org-level queries
- Add index on sites.organization_id for dashboard performance
- Significantly improves dashboard and alert list query performance
Files: priv/repo/migrations/20260303XXXXXX_add_performance_indexes.exs
2026-03-02
fix: prevent TOTP replay attacks with nonce tracking
- Store used TOTP codes in totp_nonces table with 90-second expiration
- Validate code hasn't been used before accepting
- Automatic cleanup of expired nonces via Oban cron job
- Prevents code reuse within TOTP validity window
Files: lib/towerops/accounts/totp_nonce.ex,
lib/towerops/accounts.ex,
priv/repo/migrations/20260302XXXXXX_create_totp_nonces.exs
2026-03-01
feat: add equipment manufacturer detection and tracking
- Auto-detect manufacturer from SNMP sysDescr during discovery
- Store in devices.manufacturer field
- Display in equipment details and lists
- Enables vendor-specific features and MIB selection
Files: lib/towerops/snmp/discovery.ex,
lib/towerops/devices/device.ex,
priv/repo/migrations/20260301XXXXXX_add_manufacturer_to_devices.exs