fix(security): harden TLS, timeouts, validation, logging, and token generation

- Default TLS verification on, opt-in UPKEEP_INSECURE_SKIP_VERIFY
- Alert webhooks use 10s timeout client, close response bodies
- URL input validates http/https scheme for HTTP monitors
- Stdlib logs route to stderr instead of discard
- Panic on crypto/rand failure in token generation
- Cluster startup warnings for non-HTTPS and missing secret
- Replace demo SMTP creds with obvious placeholders
- Color-coded log entries and scroll hints in logs tab
This commit is contained in:
2026-05-14 11:46:06 -04:00
parent b7592ee9e5
commit 11848ce674
7 changed files with 156 additions and 34 deletions
+51 -2
View File
@@ -1,5 +1,54 @@
package tui
func (m Model) viewLogsTab() string {
return "\n" + m.logViewport.View()
import (
"fmt"
"strings"
)
func colorizeLog(line string) string {
lower := strings.ToLower(line)
switch {
case strings.Contains(lower, "confirmed down"),
strings.Contains(lower, "is down"),
strings.Contains(lower, "missed heartbeat"),
strings.Contains(lower, "failed check"),
strings.Contains(lower, "ssl warning"):
return dangerStyle.Render(line)
case strings.Contains(lower, "recovered"),
strings.Contains(lower, "is up"),
strings.Contains(lower, "recovery"):
return specialStyle.Render(line)
case strings.Contains(lower, "engine"),
strings.Contains(lower, "cluster"):
return titleStyle.Render(line)
default:
return line
}
}
func (m Model) viewLogsTab() string {
content := m.logViewport.View()
if strings.TrimSpace(content) == "" || content == "Waiting for logs..." {
return "\n No log entries yet. Logs appear as monitors run checks."
}
lines := strings.Split(content, "\n")
var colored []string
for _, line := range lines {
if line == "" {
colored = append(colored, line)
continue
}
colored = append(colored, colorizeLog(line))
}
count := 0
for _, l := range lines {
if strings.TrimSpace(l) != "" {
count++
}
}
header := subtleStyle.Render(fmt.Sprintf(" %d entries [↑/↓] Scroll [PgUp/PgDn] Page", count))
return "\n" + header + "\n\n" + strings.Join(colored, "\n")
}