| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105 |
- // M13a W5: admin HTTP routes for deliverd-telegram. Same
- // shape as deliverd-fcm/admin.go but scoped to the
- // `telegram` channel. Cross-channel safety: rows for any
- // other channel return 404 (we don't leak data the
- // telegram deliverd shouldn't see).
- package main
- import (
- "encoding/json"
- "log/slog"
- "net/http"
- "strconv"
- "git3.techno-world.net/lrosales/broad-announce/internal/authd"
- "git3.techno-world.net/lrosales/broad-announce/internal/dlq"
- "git3.techno-world.net/lrosales/broad-announce/internal/postgres"
- )
- func wireAdminRoutes(mux *http.ServeMux, pool *postgres.Pool, logger *slog.Logger) {
- if !authd.EnvEnabled() {
- logger.Warn("admin routes are DISABLED (set BA_AUTHD_JWT_SECRET to enable)")
- return
- }
- ad, err := authd.NewFromEnv()
- if err != nil {
- logger.Error("BA_AUTHD_JWT_SECRET set but authd init failed; admin routes DISABLED", "err", err)
- return
- }
- logger.Info("admin routes enabled with JWT gate (telegram)")
- mux.Handle("GET /v1/admin/dlq",
- ad.RequireAuth(http.HandlerFunc(handleListDLQ(pool, logger))))
- mux.Handle("GET /v1/admin/dlq/{id}",
- ad.RequireAuth(http.HandlerFunc(handleGetDLQ(pool, logger))))
- }
- func handleListDLQ(pool *postgres.Pool, logger *slog.Logger) http.HandlerFunc {
- return func(w http.ResponseWriter, r *http.Request) {
- limit, _ := strconv.Atoi(r.URL.Query().Get("limit"))
- offset, _ := strconv.Atoi(r.URL.Query().Get("offset"))
- rows, err := dlq.List(r.Context(), pool, dlq.ListFilters{
- Channel: telegramChannel,
- CompanyID: r.URL.Query().Get("company_id"),
- AlertID: r.URL.Query().Get("alert_id"),
- IncludeDiscarded: r.URL.Query().Get("include") == "all",
- Limit: limit,
- Offset: offset,
- })
- if err != nil {
- logger.Error("dlq list (telegram)", "err", err)
- http.Error(w, "dlq list: "+err.Error(), http.StatusInternalServerError)
- return
- }
- w.Header().Set("Content-Type", "application/json")
- _ = json.NewEncoder(w).Encode(map[string]any{
- "channel": telegramChannel,
- "rows": rows,
- "limit": effectiveLimit(limit),
- "offset": effectiveOffset(offset),
- })
- }
- }
- func handleGetDLQ(pool *postgres.Pool, logger *slog.Logger) http.HandlerFunc {
- return func(w http.ResponseWriter, r *http.Request) {
- raw := r.PathValue("id")
- id, err := strconv.ParseInt(raw, 10, 64)
- if err != nil || id <= 0 {
- http.Error(w, "bad id", http.StatusBadRequest)
- return
- }
- row, err := dlq.Get(r.Context(), pool, id)
- if err != nil {
- logger.Error("dlq get (telegram)", "err", err, "id", id)
- http.Error(w, "dlq get: "+err.Error(), http.StatusInternalServerError)
- return
- }
- if row == nil {
- http.Error(w, "not found", http.StatusNotFound)
- return
- }
- // Cross-channel safety: this deliverd-telegram binary
- // only knows about the telegram channel.
- if row.Channel != telegramChannel {
- http.Error(w, "not found", http.StatusNotFound)
- return
- }
- w.Header().Set("Content-Type", "application/json")
- _ = json.NewEncoder(w).Encode(row)
- }
- }
- func effectiveLimit(n int) int {
- if n <= 0 || n > 500 {
- return 50
- }
- return n
- }
- func effectiveOffset(n int) int {
- if n < 0 {
- return 0
- }
- return n
- }
|