package webui import ( "net/http" "strings" "mailgoserver/internal/db" ) func emailDomain(addr string) string { if i := strings.LastIndex(addr, "@"); i >= 0 { return strings.ToLower(addr[i+1:]) } return "" } // dashboard mirrors dashboard.py's dashboard(), scoped to the current admin's // assigned domains unless they're a global admin. func (a *App) dashboard(w http.ResponseWriter, r *http.Request) { scope := scopeFromContext(r) allowedNames, isGlobal, err := a.accessibleDomainNames(r) if err != nil { a.Logger.Error("dashboard: %v", err) } var domainCount, senderCount, dkimCount int if isGlobal { domainCount, _ = a.DB.CountActiveDomains() senderCount, _ = a.DB.CountActiveSenders() dkimCount, _ = a.DB.CountActiveDKIMKeys() } else { domains, _ := a.DB.ListDomains() for _, d := range domains { if d.IsActive && scope.Allowed(d.ID) { domainCount++ } } senders, _ := a.DB.ListSenders() for _, s := range senders { if s.IsActive && scope.Allowed(s.DomainID) { senderCount++ } } keys, _ := a.DB.ListActiveDKIMKeysWithDomain() for _, k := range keys { if scope.Allowed(k.DomainID) { dkimCount++ } } } allEmails, err := a.DB.ListEmailLogsPage(0, 50) if err != nil { setFlash(w, "error", "Error loading recent activity") } var recentEmails []db.EmailLog for _, e := range allEmails { if isGlobal || allowedNames[emailDomain(e.MailFrom)] { recentEmails = append(recentEmails, e) } if len(recentEmails) == 10 { break } } allAuths, _ := a.DB.ListRecentAuthLogs(50) var recentAuths []db.AuthLog for _, au := range allAuths { if isGlobal || allowedNames[authLogDomain(au.Identifier)] { recentAuths = append(recentAuths, au) } if len(recentAuths) == 10 { break } } a.render(w, r, "dashboard.html", M{ "active": "dashboard", "domain_count": domainCount, "sender_count": senderCount, "dkim_count": dkimCount, "recent_emails": recentEmails, "recent_auths": recentAuths, }) } // authLogDomain best-effort extracts a domain name from an AuthLog identifier, whose // format varies by auth_type: a bare email ("sender"), "ip -> domain" (ip), or // "sender@x -> target@y" (sender_validation). There's no domain_id column on this // table (it predates admin scoping), so this is a text heuristic, not a foreign key. func authLogDomain(identifier string) string { if idx := strings.LastIndex(identifier, "->"); idx >= 0 { return emailOrBareDomain(strings.TrimSpace(identifier[idx+2:])) } return emailOrBareDomain(identifier) } func emailOrBareDomain(s string) string { if strings.Contains(s, "@") { return emailDomain(s) } return strings.ToLower(s) }