Implements Phase 1.5 — an embedded web UI using Go templates, Pico CSS (dark theme), and htmx for auto-refreshing stats and active sessions. Adds read query methods to the Store interface (GetDashboardStats, GetTopUsernames, GetTopPasswords, GetTopIPs, GetRecentSessions) with implementations for both SQLite and MemoryStore. Introduces the internal/web package with server, handlers, templates, and tests. Web server is opt-in via [web] config section and runs alongside SSH with graceful shutdown. Bumps version to 0.2.0. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
38 lines
733 B
Go
38 lines
733 B
Go
package web
|
|
|
|
import (
|
|
"embed"
|
|
"html/template"
|
|
"time"
|
|
)
|
|
|
|
//go:embed templates/*.html templates/fragments/*.html
|
|
var templateFS embed.FS
|
|
|
|
func loadTemplates() (*template.Template, error) {
|
|
funcMap := template.FuncMap{
|
|
"formatTime": func(t time.Time) string {
|
|
return t.Format("2006-01-02 15:04:05 UTC")
|
|
},
|
|
"truncateID": func(id string) string {
|
|
if len(id) > 8 {
|
|
return id[:8]
|
|
}
|
|
return id
|
|
},
|
|
"derefTime": func(t *time.Time) time.Time {
|
|
if t == nil {
|
|
return time.Time{}
|
|
}
|
|
return *t
|
|
},
|
|
}
|
|
|
|
return template.New("").Funcs(funcMap).ParseFS(templateFS,
|
|
"templates/layout.html",
|
|
"templates/dashboard.html",
|
|
"templates/fragments/stats.html",
|
|
"templates/fragments/active_sessions.html",
|
|
)
|
|
}
|