package ui import ( "net/http" "strconv" "git.wntrmute.dev/kyle/mcias/internal/db" "git.wntrmute.dev/kyle/mcias/internal/model" ) const auditPageSize = 50 // auditEventTypes lists all known event types for the filter dropdown. var auditEventTypes = []string{ model.EventLoginOK, model.EventLoginFail, model.EventLoginTOTPFail, model.EventTokenIssued, model.EventTokenRenewed, model.EventTokenRevoked, model.EventTokenExpired, model.EventAccountCreated, model.EventAccountUpdated, model.EventAccountDeleted, model.EventRoleGranted, model.EventRoleRevoked, model.EventTOTPEnrolled, model.EventTOTPRemoved, model.EventPGCredAccessed, model.EventPGCredUpdated, } // handleAuditPage renders the full audit log page with the first page embedded. func (u *UIServer) handleAuditPage(w http.ResponseWriter, r *http.Request) { csrfToken, err := u.setCSRFCookies(w) if err != nil { http.Error(w, "internal error", http.StatusInternalServerError) return } data, err := u.buildAuditData(r, 1, csrfToken) if err != nil { u.renderError(w, r, http.StatusInternalServerError, "failed to load audit log") return } u.render(w, "audit", data) } // handleAuditRows returns only the rows fragment for HTMX partial updates. func (u *UIServer) handleAuditRows(w http.ResponseWriter, r *http.Request) { pageStr := r.URL.Query().Get("page") page, _ := strconv.Atoi(pageStr) if page < 1 { page = 1 } data, err := u.buildAuditData(r, page, "") if err != nil { u.renderError(w, r, http.StatusInternalServerError, "failed to load audit log") return } u.render(w, "audit_rows", data) } // buildAuditData fetches one page of audit events and builds AuditData. func (u *UIServer) buildAuditData(r *http.Request, page int, csrfToken string) (AuditData, error) { filterType := r.URL.Query().Get("event_type") offset := (page - 1) * auditPageSize params := db.AuditQueryParams{ Limit: auditPageSize, Offset: offset, EventType: filterType, } events, total, err := u.db.ListAuditEventsPaged(params) if err != nil { return AuditData{}, err } totalPages := int(total) / auditPageSize if int(total)%auditPageSize != 0 { totalPages++ } if totalPages < 1 { totalPages = 1 } return AuditData{ PageData: PageData{CSRFToken: csrfToken}, Events: events, EventTypes: auditEventTypes, FilterType: filterType, Total: total, Page: page, TotalPages: totalPages, }, nil }