Commit Graph

1365 Commits

Author SHA1 Message Date
rcourtman 052a6dd03f Replace collapsible sidebars with hover-based expansion
Removed chevron toggle buttons from Settings and Alerts navigation sidebars. Sidebars now expand automatically on hover and collapse on mouse leave, providing a cleaner interface and more intuitive interaction pattern.
2025-10-11 20:26:15 +00:00
rcourtman a4c3f1605c Add icon library and collapsible sidebars to navigation menus
Integrate lucide-solid icon library to enhance visual navigation in Alerts
and Settings pages. Sidebars now display icons alongside labels and can
collapse to icon-only view for more screen space. Icons provide better
visual scanning and the collapsible design improves usability on smaller
displays while maintaining quick access to all sections.
2025-10-11 20:12:32 +00:00
rcourtman 44460b4596 Remove .dev-aliases from repository (environment-specific file) 2025-10-11 19:42:47 +00:00
rcourtman 7ff9966037 Disable auto-start in dev environment for Claude Code management 2025-10-11 19:40:50 +00:00
rcourtman 4ad53f27fe Implement data isolation between mock and production modes
Adds automatic data directory separation to prevent mock data from contaminating production alerts and configuration:

- hot-dev.sh: Explicitly sets PULSE_DATA_DIR based on PULSE_MOCK_MODE
  - Production: /etc/pulse (real, persistent data)
  - Mock: /opt/pulse/tmp/mock-data (isolated, throwaway data)
- clean-mock-alerts.sh: New utility to remove mock contamination from production alerts
- Auto-creates mock data directory when switching to mock mode

This prevents issues where mock alerts appear in production alert history after switching between modes.
2025-10-11 19:09:15 +00:00
rcourtman 54f68c00a5 Restore wider layout and add intelligent column scaling
Restores v4.22.0-rc.6 wider page layout (110rem/1760px max-width) and implements responsive column widths for dashboard table. Name column and progress bars scale wider on xl screens while small columns (Type, VMID, I/O metrics) stay compact. This better utilizes screen space without creating wasteful empty gaps.
2025-10-11 18:55:13 +00:00
rcourtman 26e52b531e Add success icon and fix mock/production data separation
Add green checkmark icon to "No active alerts" empty state for better visual feedback. Separate mock and production data directories to prevent contamination. Mock mode now uses /opt/pulse/tmp/mock-data while production uses /etc/pulse. Update toggle script to dynamically set data directory based on mode.
2025-10-11 18:43:13 +00:00
rcourtman a08c1ca79d Debug and enhance reset to defaults feature
Add debug logging to track prop changes and hasCustomGlobalDefaults checks in ResourceTable. Fix quick tips documentation to use 0 instead of -1 for disabling alerts. Add factory defaults and reset support for PBS Servers section. Reorder PBS section to appear before Guests section.
2025-10-11 18:31:57 +00:00
rcourtman 6430838361 Fix: Use actual v4.21.0 condensed layout values
Corrected to match v4.21.0 exactly:
- Width: 95% (not 98%)
- Max-width: 80rem/1280px (not 120rem/1920px)
- No horizontal padding on shell
- Fixed 0.75rem (12px) panel padding

This restores the more condensed, narrower layout from v4.21.0.
2025-10-11 18:03:40 +00:00
rcourtman 1efff8ed27 Return to more condensed layout like v4.21.0
Adjusted container width and padding to reduce whitespace:
- Increased max-width from 110rem (1760px) to 120rem (1920px)
- Reduced shell horizontal padding from 20-52px to 8-16px
- Reduced panel padding from 12-24px to 8-12px

Maintains responsive behavior while matching the condensed feel of v4.21.0.
2025-10-11 18:01:18 +00:00
rcourtman 10eaa9c66d Add trash bin and Custom badge for Global Defaults row
When global defaults differ from factory defaults:
- Show blue "Custom" badge next to "Global Defaults" label
- Show red trash bin icon in Actions column
- Clicking trash bin resets to factory defaults
- Matches existing pattern used for individual resource rows
2025-10-11 17:57:27 +00:00
rcourtman 5ca1ba234e Add threshold discoverability and reset to defaults
- Add tooltips to threshold inputs explaining -1 disables alerts
- Add help banner at top of thresholds page with usage tips
- Add FAQ entry documenting how to disable specific metrics
- Add reset to defaults button for each threshold table
- Define factory default constants for all resource types
- Reset button restores defaults and marks form as unsaved
2025-10-11 17:53:16 +00:00
rcourtman afc51a106f Fix threshold sub-tab routing by allowing nested paths
The Alerts page was redirecting any path that didn't exactly match the expected tab path. This prevented threshold sub-tabs (/alerts/thresholds/proxmox, /docker, /mail-gateway) from working.

Modified the path validation logic to allow sub-paths under /alerts/thresholds/ to pass through without triggering redirects.
2025-10-11 17:36:25 +00:00
rcourtman 6309a9ca2f Add URL routing to threshold sub-tabs
Implement proper URL-based navigation for threshold sub-tabs (Proxmox, Docker, Mail Gateway). This enables bookmarking specific tabs and provides browser history integration.

Changes:
- Add route-based tab state management with useLocation
- Implement tab navigation using useNavigate
- Auto-redirect /alerts/thresholds to /alerts/thresholds/proxmox
- Add cursor-pointer CSS to improve UX
2025-10-11 17:32:23 +00:00
rcourtman f783fef716 Fix frontend performance issues by caching system settings
Backend was loading system settings from disk on every HTTP request
causing massive log spam and UI responsiveness issues. System settings
are now cached at startup and reloaded only when updated.

Also fixed tab cursor showing text cursor instead of pointer cursor.

Changes:
- Cache system settings in Router struct with mutex protection
- Load settings once at startup instead of on every request
- Add reloadSystemSettings() method to refresh cache when settings change
- Hook up cache reload in config handlers after successful save
- Add cursor-pointer to tab CSS classes for proper hover cursor
2025-10-11 17:22:22 +00:00
rcourtman 9c21d86212 Add multi-target Docker agent support and update installer 2025-10-11 16:34:33 +00:00
rcourtman 66aaf060d8 Improve update modal restart handling 2025-10-11 14:56:49 +00:00
rcourtman 6e6d2dec6c Add quiet hours category suppression 2025-10-11 13:23:27 +00:00
rcourtman 11e80bbcbb chore: bump version to v4.22.0-rc.6 2025-10-11 12:44:33 +00:00
rcourtman 168777d5ad Ship docker agent installer in container image 2025-10-11 12:38:28 +00:00
rcourtman 853a1e7914 refactor: consolidate PMG thresholds into single table with differentiated tooltips
Replaced 4 separate PMG threshold tables with a single unified table containing all 16 columns. Each PMG instance now appears once instead of four times, with a single global defaults row.

Changes:
- Consolidated Queue/Deferred, Hold/Oldest, Spam/Virus, and Growth tables into one
- Removed index() === 0 workaround for offline alerts column
- Added 16 PMG tooltips with clear warn vs crit differentiation
- Warning tooltips emphasize early detection and monitoring
- Critical tooltips emphasize urgency and required action

This improves UX by eliminating duplicate instance rows and making threshold severity levels immediately clear to operators.
2025-10-11 12:28:09 +00:00
rcourtman 539dc9495b fix: show offline alerts toggle only once per PMG instance
Each of the 4 PMG threshold tables was showing its own offline alerts column, resulting in 4 duplicate toggles per instance. Now only the first table displays the offline alerts column since the setting is per-instance, not per-threshold-group.
2025-10-11 11:52:09 +00:00
rcourtman c827b7cc59 Add PMG threshold configuration UI
Adds dedicated PMG sub-tab under Alerts → Configuration with comprehensive
threshold management for all 7 PMG alert types:
- Queue depth monitoring (total, deferred, hold)
- Message age tracking (oldest message warnings)
- Quarantine monitoring (spam/virus absolute thresholds)
- Quarantine growth detection (percentage and minimum thresholds)

ThresholdsTable.tsx changes:
- Add PMG tab to threshold table with 16 editable threshold columns
- Implement PMG column groups for organized display (4 groups of 4 columns)
- Add PMG global defaults with normalization and mapping
- Support per-instance threshold overrides
- Include connectivity toggle support

Alerts.tsx changes:
- Add PMGTab component with 4 organized sections using SettingsPanel
- Create pmgThresholds signal with default values matching backend
- Wire PMG threshold loading from backend config
- Include pmgDefaults in config save payload
- Add PMG to AlertTab type and tab navigation
- Render PMGTab following same pattern as other configuration tabs

Backend alert logic (already implemented in alerts.go) monitors:
- Offline detection (3-poll confirmation)
- Queue depths with per-node outlier detection
- Oldest message age tracking
- Quarantine backlog with growth rate detection
- Spam/virus rate anomaly detection with 24h baseline
2025-10-11 11:48:13 +00:00
rcourtman 1ffcfbeaf6 Guard storage backups from failed polls 2025-10-11 10:00:05 +00:00
rcourtman 74bc5d5229 Merge branch 'pr/532' 2025-10-11 09:13:41 +00:00
rcourtman dfeb670ec3 fix: force C locale for advanced storage listing 2025-10-11 09:13:32 +00:00
rcourtman 96b6454463 Sync alert configuration updates 2025-10-11 07:36:54 +00:00
rcourtman d7cc972265 Improve LXC disk usage reporting 2025-10-11 07:35:44 +00:00
Matthieu 82c82ae093 fixing printf failing under non-C locales
Ensuring numeric values are parsed using a consistent locale.
Fixes an issue where printf failed under non-C locales (e.g. fr_FR) due to the use of . as a decimal separator.
2025-10-11 07:34:16 +02:00
rcourtman 80b4f50532 fix: improve update experience and handle missing releases gracefully
Backend:
- Handle 'no releases found' error gracefully instead of returning 500
- Return proper response indicating no updates available for the channel
- Fixes the 500 error when checking for updates on development versions

Frontend:
- Detect when backend enters 'restarting' phase during updates
- Show 'Pulse is restarting...' message instead of getting stuck on 'Initializing...'
- Implement health check polling with exponential backoff (2s → 15s max)
- Auto-reload page when backend becomes healthy again
- Improve messaging: inform users page will reload automatically

This fixes the stuck update modal issue where users would see
'Initializing...' forever when the backend restarted during updates.
2025-10-10 21:31:36 +00:00
rcourtman f42308456a fix: comprehensive sanitization of diagnostics export for GitHub sharing
Closes all data leakage paths in the sanitized diagnostics export:
- Rebuild nodeStatus from sanitized nodes to prevent name leakage
- Sanitize storage entries (nodes arrays, nodeIds, instance, storage field)
- Sanitize activeAlerts (id, resourceId, resourceName, node, instance)
- Sanitize nested physicalDisks and vmDiskCheck data in nodes array

The sanitized export now properly redacts all sensitive data including
IP addresses, hostnames, node names, instance names, and storage names
while preserving the data structure for debugging purposes.
2025-10-10 21:10:53 +00:00
rcourtman 335c15fb3f refactor: remove Update History tab from Settings UI
The Update History panel was never populated for Manager updates and
only works with InstallShAdapter (systemd deployments). For a home lab
tool, this adds unnecessary UI clutter.

Removed:
- Update History tab from Administration section
- UpdateHistoryPanel import and component usage

The UpdateHistoryPanel.tsx file remains for potential future use with
InstallShAdapter, but is no longer visible in the main Settings UI.
2025-10-10 20:47:53 +00:00
rcourtman b250febcdd refactor: remove update history tracking from Manager
The update history infrastructure (history.go, UI panel) already exists
and is used by InstallShAdapter. However, for a home lab monitoring tool,
tracking every update in the Manager is overkill.

Removed:
- History field and initialization from Manager
- Event tracking in ApplyUpdate function
- Update history population on success/failure

The history.go file and UI panel remain for InstallShAdapter usage,
but the main Manager update path is now simpler and more focused.
2025-10-10 20:43:25 +00:00
rcourtman f05f47f935 fix: comprehensive update system improvements
Fixed 12 critical issues in the update system:

Critical bugs:
- Cache invalidation when channel auto-detected vs explicitly provided
- Data race on cache access (added proper RWMutex locking)
- Incorrect error handling when already on latest version

Security improvements:
- Command injection prevention with version string validation
- Symlink vulnerabilities in backup/restore (replaced cp with safe Go implementations)
- SHA256 checksum verification for downloads
- Improved backup completeness (now includes binary and VERSION file)

Quality improvements:
- Channel-keyed cache map instead of single cache value
- Update history tracking with event IDs and rollback support
- Cleanup of old temp directories (24+ hours)
- Proper resource cleanup with Close() method
2025-10-10 20:35:11 +00:00
rcourtman fe1518457a fix: auto-detect update channel from current version and add background checker
- Auto-detect update channel from current version when config is empty
  (RC users automatically get RC updates, stable users get stable)
- Add background update checker that runs on startup and hourly
- Add GetCachedUpdateInfo() method to return cached update info
- Update /api/version endpoint to include updateAvailable from cache
- Fixes issue where RC users on rc.4 weren't seeing rc.5 updates

This ensures RC testers continue receiving RC notifications while
stable users stay on the stable channel, all without explicit config.
2025-10-10 19:46:52 +00:00
rcourtman 64df42c62c chore: bump version to v4.22.0-rc.5 2025-10-10 19:07:09 +00:00
rcourtman 3ad41829ab revert: undo version bump to 4.22.0-rc.5 2025-10-10 18:51:15 +00:00
rcourtman e305b245f5 fix: remove unused tokenAvailable function in DockerAgents 2025-10-10 18:45:33 +00:00
rcourtman 07d9e389bd chore: bump version to v4.22.0-rc.5 2025-10-10 18:43:15 +00:00
rcourtman ef6adfc121 test: add comprehensive regression tests for memory cache-aware calculation (#435)
Adds TestMemoryStatusEffectiveAvailable_RegressionIssue435 with 5 test scenarios
covering all memory calculation edge cases reported in GitHub issue #435:

1. Proxmox 8.x with 'available' field (most common)
2. Older Proxmox with 'avail' field
3. Derived calculation from free+buffers+cached
4. Real user case: 86% displayed when actual usage was 42%
5. Missing all cache fields (fallback behavior)

Tests verify EffectiveAvailable() correctly returns cache-aware memory values
and calculates realistic usage percentages that exclude reclaimable cache.

These tests ensure future changes don't regress the cache-aware behavior
that was fixed in v4.15.0-rc.3.
2025-10-10 18:35:16 +00:00
rcourtman d6e61e73ec fix: resolve Docker container permission and path errors in v4.22.0-rc.4
- Fix update history using hardcoded /var/lib/pulse instead of configured data dir
- Skip mock.env watching in Docker environments to avoid 'no such file' errors

Fixes issue #529

Update History Path:
- Modified NewUpdateHandlers to accept dataDir parameter
- Pass r.config.DataPath from router (honors PULSE_DATA_DIR=/data in Docker)
- Maintains backward compatibility with default /var/lib/pulse when empty

Mock Env Watcher:
- Check PULSE_DOCKER env var and skip mock.env watching if true
- Only watch /opt/pulse/mock.env if directory exists (not in containers)
- Guard all mock.env operations to prevent errors when path is empty
- Clean up log messages to only show mock_env_path when actually watching
2025-10-10 18:17:38 +00:00
rcourtman 81f96537e2 fix: resolve docker-agent-install 401 error from trailing slash in PULSE_URL
- Strip trailing slash from PULSE_URL in install script to prevent double-slash URLs
- Add path normalization in router for defense-in-depth on public endpoint matching
- Fixes issue #528 where users copying URLs with trailing slashes got 401 errors

The install script now normalizes PULSE_URL with ${PULSE_URL%/} before concatenating
with /download/pulse-docker-agent, preventing https://example.com//download URLs.

The router normalization provides additional resilience for path matching, though the
existing path traversal check already blocks double slashes at ServeHTTP level.
2025-10-10 18:09:55 +00:00
rcourtman 91222face7 fix: comprehensive Docker agent token security improvements
This commit addresses 6 critical security and UX issues in Docker agent
token handling identified through code review:

**High Priority Fixes:**
1. Fix stale token in command preview - Changed DockerAgents to use
   getInstallCommandTemplate() that always returns placeholder, allowing
   CommandBuilder to handle all token substitution reactively. Command
   preview now updates live as user types.

2. Fix misleading "multiple tokens" messaging - Updated token generation
   modal to accurately reflect single-token backend model with red warning:
   "This will immediately invalidate your existing token". Prevents operators
   from unknowingly breaking active Docker agents.

3. Close proxy auth bypass vulnerability - Both HandleRegenerateAPIToken
   and HandleValidateAPIToken now explicitly reject requests when proxy auth
   is configured but validation fails (returns 401). Prevents unauthenticated
   access when proxy auth is enabled.

**Medium Priority Fixes:**
4. Disable buttons when no stored token - "Use This Token" and "Copy" buttons
   now properly disabled with contextual tooltips when browser hasn't saved
   a token, eliminating confusing silent no-ops.

5. Improve frontend error handling - Token validation now distinguishes
   between authentication errors (401/403), rate limiting (429), network
   failures, and actual invalid tokens. No longer mislabels auth failures
   as "invalid token".

**Low Priority Fixes:**
6. Add authentication to validate-token endpoint - Endpoint now requires
   admin authentication (same as regenerate-token), preventing unauthenticated
   token guessing oracle despite rate limiting.

**New Component:**
- CommandBuilder.tsx: Interactive command builder with live preview,
  state-based visual cues, inline token generation, and validation

**Security Impact:**
- Closes unauthenticated validation surface
- Enforces proper proxy auth gating
- Prevents accidental exposure of security model
- Rate limiting maintained (10 attempts/min)

**UX Impact:**
- Clear, accurate error messages
- Live-updating command preview
- Contextual token management
- Disabled states prevent confusion

Reviewed and verified by both Claude Code and Codex with no regressions found.
2025-10-10 17:54:53 +00:00
rcourtman ddd0b7d3d3 fix: remove unused formatRelativeTime import and fix UpdateBanner type safety 2025-10-10 16:09:15 +00:00
rcourtman a1649d2e03 fix: resolve test failures and TypeScript errors
- Add missing postfix queue endpoint to PMG test mock server
- Add 'pmg' to DiscoveredServer type in Settings.tsx
- Fix potentially undefined object in UpdateBanner.tsx
- Remove unused imports and variables in Dashboard.tsx, MailGateway.tsx, NodeSummaryTable.tsx
2025-10-10 16:08:09 +00:00
rcourtman 3aa8e387e4 chore: bump version to v4.22.0-rc.4 2025-10-10 16:04:27 +00:00
rcourtman 8d3acbef5c fix: add navigation to Update History from progress modal
The "View History" button in UpdateProgressModal now properly navigates
to /settings/updates instead of just closing the modal.

This completes the update flow UX - users can now seamlessly transition
from update completion to viewing the full audit log.
2025-10-10 15:59:49 +00:00
rcourtman 5f911afe21 feat: add complete update UI with modals and history panel
Implements full update UX based on adapter system:

Components:
- UpdateConfirmationModal: Shows version jump, prerequisites, root warning, acknowledgement checkbox
- UpdateProgressModal: Real-time polling of /api/updates/status with progress bar and stage display
- UpdateHistoryPanel: Settings tab showing full audit log with filtering and status badges
- UpdateBanner: Enhanced with Apply button for automated deployments, manual instructions accordion with copy buttons

Features:
- Automated deployments: Single-click "Apply Update" button launches confirmation modal
- Manual deployments: Displays instruction steps with individual copy buttons
- Progress tracking: Polls status every 2s during updates, shows success/error states
- History: Dedicated Settings → Update History tab with filterable table
- Banner integration: Shows "Manual steps required" badge for non-automated deployments

All components use proper SolidJS signals and effects, fully typed with TypeScript.
2025-10-10 15:55:26 +00:00
rcourtman df2aae0246 feat: add UpdatePlan and history types to frontend API
Add TypeScript interfaces and API methods for new update system:

**New Types:**
- UpdatePlan: Deployment-specific update plan with canAutoUpdate flag
- UpdateHistoryEntry: Complete audit log entry with all metadata

**New API Methods:**
- getUpdatePlan(version, channel?) - Get deployment-specific update plan
- getUpdateHistory(limit?, status?) - List update history with filters
- getUpdateHistoryEntry(eventId) - Get specific history entry details

These types match the backend Go structs and enable frontend
integration with the adapter-based update system.

Next: Implement UI components (confirmation modal, progress modal,
update banner enhancements, settings history panel).
2025-10-10 15:45:12 +00:00
rcourtman 5294ed8e4e feat: integrate update system with API endpoints
Wire up the adapter-based update system to HTTP API:

**Enhanced UpdateHandlers:**
- Initialize UpdateHistory and UpdaterRegistry
- Register all deployment adapters (systemd, proxmoxve, docker, aur)
- Handlers now have access to history and updater registry

**New API Endpoints:**
- GET /api/updates/plan?version=X - Get update plan for deployment
  * Returns canAutoUpdate, instructions, prerequisites, estimated time
  * Deployment-specific based on detected type
- GET /api/updates/history?limit=N&status=X - List update history
  * Supports filtering by status (success/failed/in_progress)
  * Returns audit log entries with full metadata
- GET /api/updates/history/entry?id=X - Get specific history entry
  * Retrieve detailed information about past update

**Existing Endpoints Still Work:**
- GET /api/updates/check - Check for available updates
- POST /api/updates/apply - Apply update (legacy manager)
- GET /api/updates/status - Get current update status

The system now supports both:
- Legacy update flow (existing install.sh wrapper in manager.go)
- New adapter-based flow (prepared for frontend integration)

Next: Frontend components to consume new endpoints.
2025-10-10 15:42:21 +00:00