// Tests for the M13a W5 JWT gate in deliverd-telegram. // Mirrors cmd/deliverd-fcm/admin_test.go but for the // telegram channel. The actual DLQ handlers need a real // Postgres pool; those paths are covered by the M8 smoke // and the m13a E2E. package main import ( "crypto/hmac" "crypto/sha256" "encoding/base64" "encoding/json" "io" "log/slog" "net/http" "net/http/httptest" "os" "testing" "time" ) const testSecret = "test-secret-with-32-bytes-min-len-abc" func mintTestJWT(t *testing.T, secret, role string) string { t.Helper() hb, _ := json.Marshal(map[string]string{"alg": "HS256", "typ": "JWT"}) body, _ := json.Marshal(map[string]any{ "sub": "u-test", "tid": "t-test", "role": role, "typ": "access", "iss": "broad-announce", "exp": time.Now().Add(15 * time.Minute).Unix(), "iat": time.Now().Unix(), }) enc := base64.RawURLEncoding.EncodeToString(hb) + "." + base64.RawURLEncoding.EncodeToString(body) mac := hmac.New(sha256.New, []byte(secret)) mac.Write([]byte(enc)) return enc + "." + base64.RawURLEncoding.EncodeToString(mac.Sum(nil)) } func discardLogger() *slog.Logger { return slog.New(slog.NewTextHandler(io.Discard, nil)) } func TestWireAdminRoutes_NoSecret_Disabled(t *testing.T) { os.Unsetenv("BA_AUTHD_JWT_SECRET") mux := http.NewServeMux() wireAdminRoutes(mux, nil, discardLogger()) for _, tc := range []struct{ method, path string }{ {"GET", "/v1/admin/dlq"}, {"GET", "/v1/admin/dlq/1"}, } { rr := httptest.NewRecorder() mux.ServeHTTP(rr, httptest.NewRequest(tc.method, tc.path, nil)) if rr.Code != http.StatusNotFound { t.Errorf("%s %s with no secret: got %d, want 404", tc.method, tc.path, rr.Code) } } } func TestWireAdminRoutes_WithSecret_Gated(t *testing.T) { t.Setenv("BA_AUTHD_JWT_SECRET", testSecret) t.Setenv("BA_AUTHD_ISSUER", "broad-announce") mux := http.NewServeMux() wireAdminRoutes(mux, nil, discardLogger()) for _, tc := range []struct{ method, path string }{ {"GET", "/v1/admin/dlq"}, {"GET", "/v1/admin/dlq/1"}, } { rr := httptest.NewRecorder() mux.ServeHTTP(rr, httptest.NewRequest(tc.method, tc.path, nil)) if rr.Code != http.StatusUnauthorized { t.Errorf("%s %s with secret+no-token: status = %d, want 401", tc.method, tc.path, rr.Code) } } } func TestAdminDLQ_AnyAuthenticatedUser_CanList(t *testing.T) { t.Setenv("BA_AUTHD_JWT_SECRET", testSecret) mux := http.NewServeMux() wireAdminRoutes(mux, nil, discardLogger()) for _, role := range []string{"viewer", "tenant_admin", "super_admin"} { t.Run(role, func(t *testing.T) { tok := mintTestJWT(t, testSecret, role) req := httptest.NewRequest("GET", "/v1/admin/dlq", nil) req.Header.Set("Authorization", "Bearer "+tok) rr := httptest.NewRecorder() func() { defer func() { _ = recover() }() mux.ServeHTTP(rr, req) }() if rr.Code == http.StatusUnauthorized || rr.Code == http.StatusForbidden { t.Errorf("%s: status = %d, want gate passed (500/panic expected)", role, rr.Code) } }) } }