feat: add GeoIP country lookup with embedded DB-IP Lite database (PLAN.md 4.3)

Embeds a DB-IP Lite country MMDB (~5MB) in the binary via go:embed,
keeping the single-binary deployment story clean. Country codes are
stored alongside login attempts and sessions, shown in the dashboard
(Top IPs, Top Countries card, Recent/Active Sessions, session detail).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-15 15:27:46 +01:00
parent 8fff893d25
commit 94f1f1c266
28 changed files with 353 additions and 71 deletions

View File

@@ -13,6 +13,7 @@ type dashboardData struct {
TopUsernames []storage.TopEntry
TopPasswords []storage.TopEntry
TopIPs []storage.TopEntry
TopCountries []storage.TopEntry
ActiveSessions []storage.Session
RecentSessions []storage.Session
}
@@ -48,6 +49,13 @@ func (s *Server) handleDashboard(w http.ResponseWriter, r *http.Request) {
return
}
topCountries, err := s.store.GetTopCountries(ctx, 10)
if err != nil {
s.logger.Error("failed to get top countries", "err", err)
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
return
}
activeSessions, err := s.store.GetRecentSessions(ctx, 50, true)
if err != nil {
s.logger.Error("failed to get active sessions", "err", err)
@@ -67,6 +75,7 @@ func (s *Server) handleDashboard(w http.ResponseWriter, r *http.Request) {
TopUsernames: topUsernames,
TopPasswords: topPasswords,
TopIPs: topIPs,
TopCountries: topCountries,
ActiveSessions: activeSessions,
RecentSessions: recentSessions,
}