Files
pulse/internal/api
rcourtman 552173b262 fix: improve alert system robustness and security
Addresses multiple issues identified during comprehensive alert system audit:

1. Fix ZFS device loop lock issue
   - Moved lock acquisition outside loop in checkZFSPoolHealth
   - Changed clearAlert to clearAlertNoLock when lock already held
   - Prevents multiple lock acquisitions in same iteration

2. Add alert deduplication on restore
   - Prevents duplicate alerts after service restart
   - Tracks seen alert IDs during LoadActiveAlerts
   - Logs warnings for any duplicates found

3. Add API input validation
   - validateAlertID function prevents DOS attacks
   - Limit alert ID length to 500 characters
   - Whitelist allowed characters (alphanumeric, -, _, :, /, .)
   - Cap history limit parameter at 10,000 records
   - Applied validation to acknowledge, unacknowledge, and clear endpoints

4. Add panic recovery to goroutines
   - All SaveActiveAlerts goroutines now have defer/recover
   - Cleanup goroutines protected from panics
   - Contextual error logging for each goroutine type

5. Document lock ordering
   - Added comprehensive documentation for Manager mutexes
   - Explains m.mu and resolvedMutex relationship
   - Clarifies acquisition rules to prevent deadlocks
   - Inline comments for resolvedMutex field

These fixes improve stability, security, data integrity, and maintainability
of the alert system without breaking API compatibility.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-30 15:35:39 +00:00
..
2025-09-29 10:22:27 +00:00
2025-09-29 10:22:27 +00:00
2025-09-29 10:22:27 +00:00
2025-09-29 10:22:27 +00:00

Internal API Package

This directory contains the API server implementation for Pulse.

Important Note About frontend-modern/

The frontend-modern/ subdirectory that appears here is:

  • AUTO-GENERATED during builds
  • NOT the source code - just a build artifact
  • IN .gitignore - never committed
  • REQUIRED BY GO - The embed directive needs it here

Frontend Development Location

👉 Edit frontend files at: /opt/pulse/frontend-modern/src/

Why This Structure?

Go's //go:embed directive has limitations:

  1. Cannot use ../ paths to access parent directories
  2. Cannot follow symbolic links
  3. Must embed files within the Go module

This is a known Go limitation and our structure works around it.