feat(reporting): enhance PDF reports with Executive Summary and actionable insights

- Add professional cover page with branding and report period
- Add Executive Summary page with health status banner (HEALTHY/WARNING/CRITICAL)
- Add Quick Stats section with color-coded metrics and trend indicators
- Add Key Observations with automated analysis of CPU, memory, disk, and disk wear
- Add Recommended Actions section with prioritized, actionable items
- Add Resource Details page with hardware info, storage pools, physical disks
- Add color-coded tables for alerts, storage, and disk health
- Add performance charts with area fills and proper scaling
- Improve overall visual design with consistent color scheme
- Fix SAML session invalidation to use correct SessionStore method
This commit is contained in:
rcourtman 2026-02-03 18:17:31 +00:00
parent 2e4e7b06a8
commit 442d29e9b9
2 changed files with 1519 additions and 254 deletions

View file

@ -258,8 +258,8 @@ func (r *Router) handleSAMLACS(w http.ResponseWriter, req *http.Request) {
LogAuditEventForTenant(GetOrgID(req.Context()), "saml_login", username, GetClientIP(req), req.URL.Path, true, "SAML login success via "+providerID)
// Redirect to return URL
target := relayState
// Redirect to return URL - sanitize relayState to prevent open redirect
target := sanitizeOIDCReturnTo(relayState)
if target == "" {
target = "/"
}
@ -455,22 +455,45 @@ func (r *Router) getSAMLSessionInfo(req *http.Request) *SAMLSessionInfo {
}
}
// clearSession clears the current session
// clearSession clears the current session - properly invalidates server-side session
// and clears both pulse_session and pulse_csrf cookies
func (r *Router) clearSession(w http.ResponseWriter, req *http.Request) {
// Clear session cookie
isSecure, sameSitePolicy := getCookieSettings(req)
// Invalidate server-side session first
if cookie, err := req.Cookie("pulse_session"); err == nil && cookie.Value != "" {
// Get username before deleting session for untracking
if username := GetSessionUsername(cookie.Value); username != "" {
UntrackUserSession(username, cookie.Value)
}
GetSessionStore().InvalidateSession(cookie.Value)
}
// Clear pulse_session cookie
http.SetCookie(w, &http.Cookie{
Name: "session",
Name: "pulse_session",
Value: "",
Path: "/",
MaxAge: -1,
HttpOnly: true,
Secure: req.TLS != nil,
SameSite: http.SameSiteLaxMode,
Secure: isSecure,
SameSite: sameSitePolicy,
})
// Clear pulse_csrf cookie
http.SetCookie(w, &http.Cookie{
Name: "pulse_csrf",
Value: "",
Path: "/",
MaxAge: -1,
Secure: isSecure,
SameSite: sameSitePolicy,
})
}
func (r *Router) redirectSAMLError(w http.ResponseWriter, req *http.Request, returnTo string, code string) {
target := returnTo
// Sanitize returnTo to prevent open redirect attacks
target := sanitizeOIDCReturnTo(returnTo)
if target == "" {
target = "/"
}

File diff suppressed because it is too large Load diff