Commit graph

77 commits

Author SHA1 Message Date
19abd5508a
ux: improve mobile responsiveness across all pages
- Hide less-critical table columns on small screens (IP, subs, MRR, etc.)
- Add overflow-x-auto wrappers on tables to prevent horizontal scroll
- Fix <.header> component to flex-wrap action buttons on mobile
- Make page action button labels icon-only on small screens
- Add min-w-0 on grid children to prevent viewport overflow
- Right-align device detail dt/dd values consistently
- Fix schedule timeline cards with overflow-x-auto wrappers
2026-03-12 16:49:59 -05:00
72f81c572d
add real-time GraphQL API with time-series queries and subscriptions
- add absinthe_phoenix for WebSocket subscription support
- create GraphQL WebSocket socket with API token auth at /socket/graphql
- add time-series queries: deviceSensors, sensorReadings, interfaceTraffic, checkResults
- add subscriptions: deviceStatusChanged, alertEvent, sensorReadingsUpdated
- wire subscription triggers into agent_channel and alerts contexts
- add org-scoped access control for sensors/interfaces via join queries
- add 17 tests covering queries, org isolation, empty data edge cases, and auth
- update GraphQL API docs page with time-series and subscription sections
2026-03-12 10:24:39 -05:00
3c0157d2ea
docs: update user-facing changelog with recent UI and feature improvements
Added missing entries:
- UI button styling improvements (2026-03-09)
- Backhaul capacity analysis feature (2026-03-07)
2026-03-09 15:53:37 -05:00
d811bcb503
feat: add ErrorTrackerNotifier and fix PagerDuty notification handling
- Add error_tracker_notifier for email alerts on exceptions
  * Sends alerts to graham@towerops.net
  * Configured in production only (gracefully shuts down in dev/test)
  * Includes throttling to prevent duplicate error spam

- Fix AlertNotificationWorker when PagerDuty not configured
  * Worker now handles :not_configured gracefully instead of failing
  * Prevents unnecessary retries and error noise
  * Logs as debug when PagerDuty integration isn't set up

Files changed:
- mix.exs, mix.lock
- config/runtime.exs
- lib/towerops/application.ex
- lib/towerops/workers/alert_notification_worker.ex
- CHANGELOG.txt, priv/static/changelog.txt
2026-03-09 13:14:30 -05:00
d5b0f38ed6
feat: add remaining e2e tests and fix 'too many open files' error
- Added e2e tests for auth flows (registration, login, password reset, TOTP)
- Added e2e tests for onboarding and organization creation
- Added e2e tests for team collaboration (org switching, invitations)
- Added e2e tests for activity feed
- Added e2e tests for device graphs (sensors, time ranges, interfaces)
- Added e2e tests for MikroTik backup comparison
- Added e2e tests for sites map (geographic view)
- Added e2e tests for network trace tool

- Fixed 'too many open files' error by configuring Phoenix code reloader
  to ignore deps/, _build/, node_modules/, e2e/, and other non-source directories
- This prevents the file system watcher from monitoring unnecessary files
2026-03-06 17:08:27 -06:00
a2ce5817a2
fix: use transparent background for stoplight favicon
Replace white background with transparent for better appearance
in browser tabs with different background colors.
2026-03-06 14:46:02 -06:00
e278d320ce
design: improve stoplight favicon with transparent background
Make circles more prominent with transparent background and better spacing.
2026-03-06 14:36:32 -06:00
45579813bd
design: update favicon to stoplight style with app colors
Replace standard favicon with stoplight design using red (#ef4444),
yellow (#eab308), and green (#22c55e) circles matching the app's
status indicator colors.
2026-03-06 14:33:29 -06:00
ac2547e7c9
Merge branch 'feature/dynamic-global-pricing' 2026-03-06 14:04:12 -06:00
6e2bba4e88
docs: update changelogs for dynamic pricing feature 2026-03-06 14:00:58 -06:00
6d3fc15f4a
fix: allow data URLs in CSP for dynamic favicon
The dashboard status indicator favicon (colored circle) uses canvas
to generate a data URL that's set as the favicon. This was blocked
by CSP in staging/production because default-src didn't include data:.

Added data: to default-src directive to fix favicon not updating in
browser tabs when device status changes.
2026-03-06 13:51:31 -06:00
9229e6e920
fix: remove internal details from public changelog 2026-03-06 13:03:36 -06:00
e161aaab83
docs: update changelogs for billing overrides and interface stats fix 2026-03-06 13:02:55 -06:00
8f52d87854
feat: add rate limiting to admin endpoints (100 req/min)
- Add :admin type to RateLimit plug with 100 requests per minute per IP
- Apply rate limiting to all /admin routes (LiveView and controller actions)
- Protects superuser endpoints from abuse and brute force attempts
- Aligns with existing auth (10 req/min) and API (1000 req/min) limits
2026-03-05 14:11:19 -06:00
1d928d4356
security: implement comprehensive security audit fixes
Critical Fixes:
- Remove /health/time endpoint exposing system time information
  * Prevents attackers from detecting time sync issues for TOTP attacks
  * Removed route and controller function, updated tests
- Add email confirmation check to account data export
  * GDPR export now requires confirmed email address
  * Prevents unconfirmed accounts from accessing data export
- Add path traversal validation for MIB archive uploads
  * Extract to temp directory, validate all paths, then copy if safe
  * Prevents malicious tar/zip files from writing outside target directory
  * Added validate_extracted_paths/1 helper function

High Priority Fixes:
- Add comprehensive input validation for mobile auth
  * Length limits: device_name (255), device_os (100), app_version (50), push_token (512)
  * Prevents database corruption and storage exhaustion
- Add heartbeat rate limiting to agent channel
  * Limit database updates to once per 30 seconds (max ~2/min per agent)
  * Prevents malicious agents from exhausting database connections
- Sanitize 500 error responses
  * Return generic error messages to clients
  * Log full details server-side with request_id for support
  * Prevents leaking stack traces and module names
- Add message size limits to agent channel
  * 10MB maximum for all protobuf messages (result, heartbeat, error)
  * Prevents DoS attacks via oversized payloads

Medium Priority Fixes:
- Add GraphQL query depth limits (max_depth: 10)
  * Prevents DoS from deeply nested queries
  * Complements existing complexity limits

Code Quality:
- Refactor agent channel handlers to reduce nesting depth
  * Extract message processing into separate private functions
  * Fixes Credo warnings about excessive nesting
  * Improves code readability and maintainability

Files changed:
- 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
- CHANGELOG.txt
- priv/static/changelog.txt
- test/towerops_web/controllers/health_controller_test.exs
- test/towerops_web/controllers/error_json_test.exs

All 7,424 tests passing.
2026-03-05 13:08:10 -06:00
7d73193dc6
docs: update changelog for LLDP topology discovery 2026-03-05 10:54:53 -06:00
29b23fb06c
docs: update changelogs for reliability audit completion
- Added entries for organization_id alert optimization
- Added entries for cascade delete safety improvements
- Added entry for sensor state validation
- Updated user-facing changelog with performance improvements
- All 23 bugs from reliability audit now addressed
2026-03-05 09:34:57 -06:00
1d1a686634
docs: update changelog and memory with bug fix details
- Added comprehensive CHANGELOG.txt entry documenting all 16 bug fixes
- Updated priv/static/changelog.txt with user-facing improvements
- Enhanced MEMORY.md with key learnings:
  * Task.yield_many race condition patterns
  * Enum.zip data corruption prevention
  * LiveView timer memory leak fixes
  * PubSub subscription cleanup
  * Pattern match error handling
  * Health check log silencing

Also fixed:
- Added error checking for sensor reading batch inserts
2026-03-05 08:55:59 -06:00
c231cbdf4c
docs: update changelog for log filtering improvements 2026-03-05 08:23:52 -06:00
5e1f8d3ebe
docs: update changelog for TimescaleDB limit fix 2026-03-04 17:44:44 -06:00
b07c322dc9 docs: update changelogs with navigation and visual polish 2026-02-13 19:18:36 -06:00
5a6643c6aa docs: update changelogs with UX polish and activity feed improvements 2026-02-13 19:13:32 -06:00
dec6f0f271 feat: rewrite marketing landing page for WISP operators
- Pain point section: disconnected tools, slow impact assessment
- WISP-specific features: impact dashboard, subscriber trace, alert triage, config tracking
- Pricing tiers: Starter (free/10 devices), Pro (/dev/mo), Business (/dev/mo)
- Use case sections: NOC, Help Desk, Owner perspectives
- Tech details: 786 device profiles, secure agent arch, SNMP v1/v2c/v3
- Updated both changelogs
2026-02-13 19:07:04 -06:00
5fb585d4fd docs: update changelogs with all new features 2026-02-13 18:59:25 -06:00
9c266e57ff feat: wire up Trace and Activity Feed routes + nav 2026-02-13 18:50:28 -06:00
c512f30e5a feat: add device list health indicators
- Health status dot (green/yellow/red/gray) from worst-case check state
- Relative 'last seen' with color-coded staleness thresholds
- Response time badge from latest monitoring check
- Subscriber count badge from Gaiia inventory items
- Batch queries to avoid N+1: Monitoring.get_device_health_summary/1,
  Monitoring.get_device_latest_response_times/1,
  Gaiia.get_device_subscriber_counts/1
2026-02-13 18:14:29 -06:00
5a3ede1f71 feat: config change → performance correlation system (Roadmap #2)
- New config_change_events table linking backup diffs to time windows
- ConfigChanges context with record/list functions and date filters
- Auto-detect changed sections from MikroTik config diffs
- Agent channel emits change events after backup creation
- Correlator engine: 2h before / 4h after QoE metric comparison
- Creates suspect_config_change insights on significant degradation
- Config Timeline LiveView with chart data, change list, detail view
- Device page: Config Timeline tab + Recent Config Changes card
- Dashboard: Recent Config Changes section with impact indicators
- Fix pre-existing integrations_live.html.heex scope bug
2026-02-13 17:56:55 -06:00
02f837ca5b
fix: replace em-dashes with hyphens in changelog to avoid encoding issues 2026-02-13 17:48:07 -06:00
314d93f3ab
docs: update changelogs for impact dashboard and integration nav improvements 2026-02-13 16:45:45 -06:00
872bef3512
feat: add 12/24-hour time format setting with consistent timezone display
wire time_format into scope, add settings UI selector, change defaults
to 24h, and replace all user-facing Calendar.strftime calls with
centralized TimeHelpers using the user's timezone and time format.
2026-02-13 15:16:29 -06:00
a6d5563b41
docs: update changelogs for command center dashboard feature 2026-02-13 14:56:01 -06:00
ee277a457e
update changelogs for gaiia integration 2026-02-13 13:29:54 -06:00
4174987a88 feat: complete DevicePollerWorker to CheckExecutorWorker migration
Completes full migration from device-level polling to per-check polling.

Migration Changes:
- Removed DevicePollerWorker scheduling from device lifecycle
- Checks automatically scheduled when created
- Discovery creates and schedules checks atomically

New Functions:
- Monitoring.stop_device_checks/1: Cancel all check jobs for device
- Monitoring.disable_device_checks/1: Disable checks when SNMP off

Discovery Integration:
- All create_*_check functions now schedule checks after creation

JobHealthCheckWorker Updates:
- Removed DevicePollerWorker recovery logic
- Only recovers DeviceMonitorWorker jobs now

Test Updates:
- Marked DevicePollerWorkerTest as skipped (deprecated)
- Updated JobHealthCheckWorkerTest expectations

All 6953 tests passing, 0 failures

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-12 17:52:33 -06:00
75d64d8772
feat: add check creation from discovery and backfill tool (Phase 5)
Completes Phase 5 of the unified checks system by enabling automatic check
creation during SNMP discovery and providing a backfill tool for existing devices.

Discovery Integration:
- create_checks_from_discovery/2: Creates checks for all discovered entities
  (sensors, interfaces, processors, storage) after SNMP discovery completes
- Links each check to its source entity via source_id for data lookup
- Returns detailed results with counts per type and error tracking
- Logs creation results with total counts and any failures

Helper Functions:
- create_sensor_check/2: Creates snmp_sensor checks with config
- create_interface_check/2: Creates snmp_interface checks
- create_processor_check/2: Creates snmp_processor checks
- create_storage_check/2: Creates snmp_storage checks

All checks configured with:
- 60-second poll intervals (default)
- Auto-discovery source type
- Enabled by default
- Type-specific configuration in JSONB config field

Backfill Tool:
- mix backfill.checks: Creates checks for existing SNMP-enabled devices
- Supports --dry-run mode for preview
- Shows counts per device (sensors, interfaces, processors, storage)
- Reports success/failure counts and detailed errors
- Safely handles devices without discovery data
- Reduced nesting depth using cond and helper functions for credo compliance

This enables the unified monitoring system to work with both new discoveries
and existing devices, ensuring all SNMP data can be monitored through the
unified checks interface.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-12 17:04:06 -06:00
d7741cdc0e
feat: implement unified checks system (Phase 1-4)
This commit implements the unified checks architecture that consolidates
SNMP monitoring with HTTP/TCP/DNS checks under a single "check" abstraction,
enabling consistent graphing, alerting, and management across all check types.

Database Changes:
- Add source_type and source_id to checks table for tracking auto-discovered
  vs manually created checks
- Add value field to check_results for storing numeric sensor readings
- Maintain backward compatibility with existing check_results data

New SNMP Executors:
- SnmpSensorExecutor: Poll sensor OIDs and return formatted values with
  status determination (OK/WARNING/CRITICAL based on limits)
- SnmpInterfaceExecutor: Poll interface stats (bandwidth, packets, errors)
- SnmpProcessorExecutor: Poll CPU/processor usage
- SnmpStorageExecutor: Poll disk/memory usage with percentage calculations

Check Execution Worker:
- CheckExecutorWorker: Unified Oban worker that dispatches to appropriate
  executor based on check_type (snmp_sensor, snmp_interface, http, tcp, etc.)
- Self-schedules next execution with distributed polling offsets
- Records results in check_results TimescaleDB hypertable
- Updates check state (OK/WARNING/CRITICAL/UNKNOWN)

Discovery Integration:
- Auto-creates checks during SNMP discovery for sensors, interfaces,
  processors, and storage
- Links checks to source entities via source_id for data lookup
- Enables/disables checks based on discovery results

UI Enhancements:
- Checks tab on device detail page with grouped display
- FormComponent for adding manual HTTP/TCP/DNS checks
- Empty state with "Run Discovery" prompt
- Check status badges and last checked times

Graphing:
- Update GraphLive to accept check_id parameter
- Query check_results table for time-series data
- Support all check types (SNMP, HTTP response times, etc.)

Testing:
- Comprehensive test suite for SnmpSensorExecutor (5 tests)
- Test suite for CheckExecutorWorker (7 tests)
- Test coverage for discovery check creation (6 tests)
- Remove deprecated monitoring_test.exs testing old API

Bug Fixes:
- Fix SNMP executors reading credentials from correct Device schema fields
  (device.snmp_version instead of device.snmp_device.version)
- Update agent channel test to query MonitoringCheck table directly

Code Quality:
- Extract add_snmp_credentials helper to reduce cyclomatic complexity
- Use map-based lookups for sensor formatting and check type grouping
- Apply pattern matching in dispatcher to reduce complexity
- All credo checks passing with no issues

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-12 16:58:40 -06:00
c6b271d204
docs: update changelogs for BruteForceProtection fix 2026-02-12 12:54:25 -06:00
cd6f2153ce
fix: reload device stream when switching back to existing devices tab 2026-02-12 12:47:30 -06:00
4e58bf24dd
docs: update changelogs for graceful shutdown handling 2026-02-12 12:18:15 -06:00
f44510bf47
docs: update user-facing changelog and document changelog maintenance
Updated priv/static/changelog.txt with all recent changes from CHANGELOG.txt
in concise, user-facing format. Enhanced CLAUDE.md to document the dual
changelog system (technical CHANGELOG.txt vs user-facing priv/static/changelog.txt)
with clear guidelines on what to include in each and when to update them.
2026-02-12 10:38:27 -06:00
e8abd8fd60
Update changelog for agent self-update feature
Added entry for agent self-update capability within Docker.
2026-02-10 13:28:48 -06:00
ba56dee1ca
remove date helper 2026-02-10 09:15:41 -06:00
631d03536e
security: add session inactivity timeout and comprehensive security documentation
Session Security Enhancements:
- Add 30-minute inactivity timeout to UpdateSessionActivity plug
- Automatic logout with user notification after inactivity
- Session timeout check happens on every request
- Graceful logout with flash message
- Refactored for Credo compliance (reduced nesting depth)

Security Documentation:
- Create comprehensive SECURITY.md covering all security features
- Document authentication, authorization, and encryption
- List OWASP Top 10 mitigations
- Include security checklist for developers
- Document recent security fixes and improvements

Verification:
- Password reset already rate-limited (confirmed)
- All 6,145 tests passing
- Zero Credo issues
- Zero security warnings

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-08 10:47:44 -06:00
3b0c2a36dd
update changelog 2026-02-06 13:07:20 -06:00
156d9a47bf
UI improvements 2026-02-05 14:57:11 -06:00
ed16033ac4
include changelog 2026-02-05 08:07:33 -06:00
89911bae9c
Device list bug fix 2026-02-04 16:49:17 -06:00
8382b5df6a
make devices site optional and many test fix 2026-02-04 15:05:42 -06:00
09f2907ede
Remove debugging logs, fix Mix.env call 2026-02-04 12:10:48 -06:00
c198fdeaa1
add snmp port 2026-02-03 12:51:50 -06:00
19b635c46f
feat: migrate email templates to gettext (Phase 2 - Emails)
- Update UserNotifier to use t_email() helper for all email content
- Extract 4 email subjects and 4 email bodies to emails domain:
  * Update email instructions
  * Log in instructions
  * Confirmation instructions
  * Reset password instructions
- Replace string interpolation with Gettext bindings (%{email}, %{url})
- Auto-populate English translations (msgstr = msgid)
- All emails now ready for future internationalization

First module migration complete per design plan.
2026-02-02 09:48:30 -06:00