1import * as Cloudflare from "@/Cloudflare";
2import { CloudflareEnvironment } from "@/Cloudflare/CloudflareEnvironment";
3import { findZoneByName } from "@/Cloudflare/Zone/lookup";
4import * as Provider from "@/Provider";
5import * as Test from "@/Test/Alchemy";
6import { describe, expect } from "alchemy-test";
7import * as Effect from "effect/Effect";
8import { MinimumLogLevel } from "effect/References";
9const { test } = Test.make({ providers: Cloudflare.providers() });
10
11const logLevel = Effect.provideService(
12 MinimumLogLevel,
13 process.env.DEBUG ? "Debug" : "Info",
14);
15
16const zoneName =
17 process.env.CLOUDFLARE_TEST_DNS_ZONE_NAME ?? "alchemy-test-2.us";
18
19// Custom detections are plan-gated — the standard testing zone has a zero
20// custom-detection quota, so any create fails with the typed
21// `DetectionQuotaExceeded` error ("exceeded the maximum number of rules:
22// 1 out of 0"). Deploying a detection to assert presence in `list()` is
23// only feasible on an entitled zone supplied via env; otherwise the test
24// runs read-only and asserts a well-typed (possibly empty) result.
25const detectionZoneId = process.env.CLOUDFLARE_TEST_LCC_DETECTION_ZONE_ID;
26
27const resolveZoneId = Effect.gen(function* () {
28 const { accountId } = yield* yield* CloudflareEnvironment;
29 const zone = yield* findZoneByName({ accountId, name: zoneName });
30 if (!zone) {
31 return yield* Effect.die(
32 new Error(`zone "${zoneName}" not found in account`),
33 );
34 }
35 return zone.id;
36});
37
38describe.sequential(
39 "LeakedCredentialDetection",
40 {
41 tags: [
42 "provider:cloudflare",
43 "provider:cloudflare:leakedcredentialcheck",
44 "provider:cloudflare:zone",
45 "live",
46 ],
47 },
48 () => {
49 // Canonical `list()` test (zone-scoped collection): there is no account-wide
50 // enumeration API for custom detections, so `list()` fans out over every
51 // zone via `listAllZones` and exhaustively paginates the per-zone list,
52 // skipping zones whose LCC toggle is off (typed
53 // `LeakedCredentialChecksDisabled`) or that 403 (`Forbidden`).
54 //
55 // On the standard testing account no zone has detections (quota is zero),
56 // so the result is a well-typed empty array. When an entitled zone is
57 // supplied, deploy a detection and assert it appears in the result.
58 test.provider(
59 "list enumerates custom detections across all zones",
60 (stack) =>
61 Effect.gen(function* () {
62 const zoneId = yield* resolveZoneId;
63
64 yield* stack.destroy();
65
66 const provider = yield* Provider.findProvider(
67 Cloudflare.LeakedCredentialCheck.LeakedCredentialDetection,
68 );
69
70 if (detectionZoneId) {
71 const usernameExpr =
72 'lookup_json_string(http.request.body.raw, "user")';
73 const passwordExpr =
74 'lookup_json_string(http.request.body.raw, "pass")';
75
76 const detection = yield* stack.deploy(
77 Effect.gen(function* () {
78 const check =
79 yield* Cloudflare.LeakedCredentialCheck.LeakedCredentialCheck(
80 "Lcc",
81 {
82 zoneId: detectionZoneId,
83 enabled: true,
84 },
85 );
86 return yield* Cloudflare.LeakedCredentialCheck.LeakedCredentialDetection(
87 "ListDetection",
88 {
89 zoneId: check.zoneId,
90 username: usernameExpr,
91 password: passwordExpr,
92 },
93 );
94 }),
95 );
96
97 const all = yield* provider.list();
98 expect(
99 all.some((d) => d.detectionId === detection.detectionId),
100 ).toBe(true);
101 } else {
102 // Read-only assertion: the result is a well-typed array (empty on the
103 // unentitled standard account). `zoneId` is resolved to prove the
104 // standing test zone exists in the enumeration scope.
105 expect(zoneId).toBeTruthy();
106 const all = yield* provider.list();
107 expect(Array.isArray(all)).toBe(true);
108 }
109
110 yield* stack.destroy();
111 }).pipe(logLevel),
112 );
113 },
114);