@vigilbase/cli 0.1.2 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CLOUDFLARE.md +112 -0
- package/COMMANDS.md +147 -0
- package/ONE.md +99 -0
- package/README.md +188 -54
- package/SECURITY.md +134 -0
- package/dist/auth/device-auth.d.ts +1 -1
- package/dist/auth/device-auth.d.ts.map +1 -1
- package/dist/auth/device-auth.js +68 -72
- package/dist/auth/device-auth.js.map +1 -1
- package/dist/auth/store.d.ts +4 -6
- package/dist/auth/store.d.ts.map +1 -1
- package/dist/auth/store.js +136 -54
- package/dist/auth/store.js.map +1 -1
- package/dist/auth/types.d.ts +2 -1
- package/dist/auth/types.d.ts.map +1 -1
- package/dist/bin.js +2 -0
- package/dist/bin.js.map +1 -1
- package/dist/cli.d.ts +1 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +89 -8
- package/dist/cli.js.map +1 -1
- package/dist/commands/account.d.ts.map +1 -1
- package/dist/commands/account.js +25 -9
- package/dist/commands/account.js.map +1 -1
- package/dist/commands/auth.d.ts +1 -0
- package/dist/commands/auth.d.ts.map +1 -1
- package/dist/commands/auth.js +49 -10
- package/dist/commands/auth.js.map +1 -1
- package/dist/commands/billing.d.ts.map +1 -1
- package/dist/commands/billing.js +5 -1
- package/dist/commands/billing.js.map +1 -1
- package/dist/commands/cloudflare.d.ts +1 -0
- package/dist/commands/cloudflare.d.ts.map +1 -1
- package/dist/commands/cloudflare.js +328 -40
- package/dist/commands/cloudflare.js.map +1 -1
- package/dist/commands/helpers.d.ts +35 -0
- package/dist/commands/helpers.d.ts.map +1 -1
- package/dist/commands/helpers.js +12 -0
- package/dist/commands/helpers.js.map +1 -1
- package/dist/commands/index.d.ts.map +1 -1
- package/dist/commands/index.js +7 -0
- package/dist/commands/index.js.map +1 -1
- package/dist/commands/legacy-validation.d.ts +21 -0
- package/dist/commands/legacy-validation.d.ts.map +1 -0
- package/dist/commands/legacy-validation.js +20 -0
- package/dist/commands/legacy-validation.js.map +1 -0
- package/dist/commands/one.d.ts +6 -0
- package/dist/commands/one.d.ts.map +1 -0
- package/dist/commands/one.js +200 -0
- package/dist/commands/one.js.map +1 -0
- package/dist/commands/public-tools.d.ts.map +1 -1
- package/dist/commands/public-tools.js +68 -11
- package/dist/commands/public-tools.js.map +1 -1
- package/dist/commands/runs.d.ts.map +1 -1
- package/dist/commands/runs.js +19 -12
- package/dist/commands/runs.js.map +1 -1
- package/dist/commands/security.d.ts +6 -0
- package/dist/commands/security.d.ts.map +1 -0
- package/dist/commands/security.js +391 -0
- package/dist/commands/security.js.map +1 -0
- package/dist/commands/watchdog.d.ts.map +1 -1
- package/dist/commands/watchdog.js +15 -12
- package/dist/commands/watchdog.js.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/lib/client.d.ts +3 -0
- package/dist/lib/client.d.ts.map +1 -1
- package/dist/lib/client.js +35 -62
- package/dist/lib/client.js.map +1 -1
- package/dist/lib/cloudflare-client.d.ts +40 -0
- package/dist/lib/cloudflare-client.d.ts.map +1 -0
- package/dist/lib/cloudflare-client.js +81 -0
- package/dist/lib/cloudflare-client.js.map +1 -0
- package/dist/lib/config.d.ts +2 -0
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/config.js +37 -12
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/format.d.ts +2 -0
- package/dist/lib/format.d.ts.map +1 -1
- package/dist/lib/format.js +23 -8
- package/dist/lib/format.js.map +1 -1
- package/dist/lib/help.d.ts +2 -2
- package/dist/lib/help.d.ts.map +1 -1
- package/dist/lib/help.js +45 -12
- package/dist/lib/help.js.map +1 -1
- package/dist/lib/network.d.ts +17 -0
- package/dist/lib/network.d.ts.map +1 -0
- package/dist/lib/network.js +108 -0
- package/dist/lib/network.js.map +1 -0
- package/dist/lib/one-client.d.ts +10 -1
- package/dist/lib/one-client.d.ts.map +1 -1
- package/dist/lib/one-client.js +52 -50
- package/dist/lib/one-client.js.map +1 -1
- package/dist/lib/one-operations.d.ts +11 -0
- package/dist/lib/one-operations.d.ts.map +1 -0
- package/dist/lib/one-operations.js +67 -0
- package/dist/lib/one-operations.js.map +1 -0
- package/dist/lib/open-url.d.ts +2 -0
- package/dist/lib/open-url.d.ts.map +1 -1
- package/dist/lib/open-url.js +23 -22
- package/dist/lib/open-url.js.map +1 -1
- package/dist/lib/progress.d.ts +1 -1
- package/dist/lib/progress.d.ts.map +1 -1
- package/dist/lib/progress.js +3 -1
- package/dist/lib/progress.js.map +1 -1
- package/dist/lib/security-client.d.ts +279 -0
- package/dist/lib/security-client.d.ts.map +1 -0
- package/dist/lib/security-client.js +111 -0
- package/dist/lib/security-client.js.map +1 -0
- package/dist/lib/skill-fetch.d.ts +7 -0
- package/dist/lib/skill-fetch.d.ts.map +1 -0
- package/dist/lib/skill-fetch.js +102 -0
- package/dist/lib/skill-fetch.js.map +1 -0
- package/dist/lib/system-trust.d.ts +8 -0
- package/dist/lib/system-trust.d.ts.map +1 -0
- package/dist/lib/system-trust.js +11 -0
- package/dist/lib/system-trust.js.map +1 -0
- package/package.json +12 -2
package/dist/commands/auth.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type CommandHandler } from './helpers.js';
|
|
2
|
+
export declare function readTokenFromStdin(input?: NodeJS.ReadableStream): Promise<string>;
|
|
2
3
|
export declare const handleLogin: CommandHandler;
|
|
3
4
|
export declare const handleLogout: CommandHandler;
|
|
4
5
|
export declare const handleWhoami: CommandHandler;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/commands/auth.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/commands/auth.ts"],"names":[],"mappings":"AAiBA,OAAO,EAEL,KAAK,cAAc,EAKpB,MAAM,cAAc,CAAA;AAErB,wBAAsB,kBAAkB,CAAC,KAAK,GAAE,MAAM,CAAC,cAA8B,GAAG,OAAO,CAAC,MAAM,CAAC,CAYtG;AAED,eAAO,MAAM,WAAW,EAAE,cAoJzB,CAAA;AAED,eAAO,MAAM,YAAY,EAAE,cAY1B,CAAA;AAED,eAAO,MAAM,YAAY,EAAE,cAqD1B,CAAA"}
|
package/dist/commands/auth.js
CHANGED
|
@@ -1,13 +1,40 @@
|
|
|
1
1
|
import { clearOneCredentials, getOneAccessToken, readCredentials, requestDeviceCode, waitForDeviceAuthorization, writeOneCredentials, } from '../auth/index.js';
|
|
2
2
|
import { VigilbaseOneClient, ONE_AUTH_REQUIRED_TOOLS } from '../lib/one-client.js';
|
|
3
|
+
import { VigilbaseApiError } from '../lib/client.js';
|
|
3
4
|
import { formatUserCode, isHeadlessEnvironment, openUrlInBrowser, resolveDeviceVerificationUrl, } from '../lib/open-url.js';
|
|
4
5
|
import { shouldShowProgress, startProgress } from '../lib/progress.js';
|
|
5
|
-
import { ok, outputJson, outputLines, withSpinner, } from './helpers.js';
|
|
6
|
+
import { assertCommandFlags, ok, outputJson, outputLines, withSpinner, } from './helpers.js';
|
|
7
|
+
export async function readTokenFromStdin(input = process.stdin) {
|
|
8
|
+
if ('isTTY' in input && input.isTTY) {
|
|
9
|
+
throw new Error('--token-stdin requires piped input. Pipe the token from your secret manager to vigilbase login --token-stdin.');
|
|
10
|
+
}
|
|
11
|
+
let token = '';
|
|
12
|
+
for await (const chunk of input) {
|
|
13
|
+
token += Buffer.isBuffer(chunk) ? chunk.toString('utf8') : String(chunk);
|
|
14
|
+
if (Buffer.byteLength(token, 'utf8') > 16384)
|
|
15
|
+
throw new Error('Token input exceeds 16 KiB.');
|
|
16
|
+
}
|
|
17
|
+
token = token.trim();
|
|
18
|
+
if (!token || /\s/.test(token))
|
|
19
|
+
throw new Error('Token input must contain exactly one nonempty token.');
|
|
20
|
+
return token;
|
|
21
|
+
}
|
|
6
22
|
export const handleLogin = async (ctx) => {
|
|
23
|
+
if (ctx.rest.length)
|
|
24
|
+
throw new Error('Usage: vigilbase login [--token-stdin | --token <bearer>] [--no-open]');
|
|
25
|
+
assertCommandFlags(ctx, ['token', 'isTokenStdin', 'isNoOpen']);
|
|
7
26
|
if (ctx.loginHandler) {
|
|
8
27
|
return ctx.loginHandler(ctx.config);
|
|
9
28
|
}
|
|
10
|
-
|
|
29
|
+
if (ctx.values.isTokenStdin && (ctx.values.token !== undefined || ctx.env.VIGILBASE_ONE_TOKEN !== undefined)) {
|
|
30
|
+
throw new Error('Use --token-stdin without --token or VIGILBASE_ONE_TOKEN.');
|
|
31
|
+
}
|
|
32
|
+
const explicitToken = ctx.values.isTokenStdin
|
|
33
|
+
? await readTokenFromStdin(ctx.stdin)
|
|
34
|
+
: ctx.values.token?.trim() || ctx.env.VIGILBASE_ONE_TOKEN?.trim() || '';
|
|
35
|
+
if (ctx.values.token !== undefined && !ctx.values.token.trim()) {
|
|
36
|
+
throw new Error('The --token value must not be empty.');
|
|
37
|
+
}
|
|
11
38
|
if (explicitToken) {
|
|
12
39
|
const oneClient = new VigilbaseOneClient(ctx.config, explicitToken);
|
|
13
40
|
let user;
|
|
@@ -23,6 +50,9 @@ export const handleLogin = async (ctx) => {
|
|
|
23
50
|
await writeOneCredentials(ctx.config, {
|
|
24
51
|
accessToken: explicitToken,
|
|
25
52
|
tokenType: 'Bearer',
|
|
53
|
+
expiresAt: typeof session.session?.expiresAt === 'string'
|
|
54
|
+
? session.session.expiresAt
|
|
55
|
+
: undefined,
|
|
26
56
|
user,
|
|
27
57
|
obtainedAt: new Date().toISOString(),
|
|
28
58
|
});
|
|
@@ -96,7 +126,6 @@ export const handleLogin = async (ctx) => {
|
|
|
96
126
|
}
|
|
97
127
|
await writeOneCredentials(ctx.config, {
|
|
98
128
|
accessToken: token.access_token,
|
|
99
|
-
refreshToken: token.refresh_token,
|
|
100
129
|
tokenType: token.token_type,
|
|
101
130
|
scope: token.scope,
|
|
102
131
|
expiresAt,
|
|
@@ -120,6 +149,9 @@ export const handleLogin = async (ctx) => {
|
|
|
120
149
|
return ok();
|
|
121
150
|
};
|
|
122
151
|
export const handleLogout = async (ctx) => {
|
|
152
|
+
if (ctx.rest.length)
|
|
153
|
+
throw new Error('Usage: vigilbase logout');
|
|
154
|
+
assertCommandFlags(ctx, []);
|
|
123
155
|
const cleared = await clearOneCredentials(ctx.config);
|
|
124
156
|
if (ctx.mode === 'json') {
|
|
125
157
|
outputJson(ctx, { success: true, cleared });
|
|
@@ -133,9 +165,12 @@ export const handleLogout = async (ctx) => {
|
|
|
133
165
|
return ok();
|
|
134
166
|
};
|
|
135
167
|
export const handleWhoami = async (ctx) => {
|
|
168
|
+
if (ctx.rest.length)
|
|
169
|
+
throw new Error('Usage: vigilbase whoami');
|
|
170
|
+
assertCommandFlags(ctx, []);
|
|
136
171
|
const credentials = await readCredentials(ctx.config);
|
|
137
172
|
const accessToken = await getOneAccessToken(ctx.config);
|
|
138
|
-
let liveUser =
|
|
173
|
+
let liveUser = null;
|
|
139
174
|
if (accessToken) {
|
|
140
175
|
try {
|
|
141
176
|
const session = await withSpinner(ctx, 'Loading session', () => new VigilbaseOneClient(ctx.config, accessToken).getSession());
|
|
@@ -147,18 +182,22 @@ export const handleWhoami = async (ctx) => {
|
|
|
147
182
|
};
|
|
148
183
|
}
|
|
149
184
|
}
|
|
150
|
-
catch {
|
|
151
|
-
//
|
|
185
|
+
catch (error) {
|
|
186
|
+
// A rejected session is signed out. Connectivity and server failures
|
|
187
|
+
// must remain errors rather than claiming the cached session is valid.
|
|
188
|
+
if (!(error instanceof VigilbaseApiError) || ![401, 403].includes(error.status)) {
|
|
189
|
+
throw error;
|
|
190
|
+
}
|
|
152
191
|
}
|
|
153
192
|
}
|
|
154
|
-
const signedIn = Boolean(
|
|
193
|
+
const signedIn = Boolean(liveUser);
|
|
155
194
|
const payload = {
|
|
156
195
|
authenticated: signedIn,
|
|
157
196
|
oneBaseUrl: ctx.config.oneBaseUrl,
|
|
158
197
|
user: liveUser,
|
|
159
|
-
expiresAt: credentials.one?.expiresAt ?? null,
|
|
160
|
-
scope: credentials.one?.scope ?? null,
|
|
161
|
-
obtainedAt: credentials.one?.obtainedAt ?? null,
|
|
198
|
+
expiresAt: signedIn ? credentials.one?.expiresAt ?? null : null,
|
|
199
|
+
scope: signedIn ? credentials.one?.scope ?? null : null,
|
|
200
|
+
obtainedAt: signedIn ? credentials.one?.obtainedAt ?? null : null,
|
|
162
201
|
authRequiredTools: signedIn ? [...ONE_AUTH_REQUIRED_TOOLS] : [],
|
|
163
202
|
};
|
|
164
203
|
if (ctx.mode === 'json') {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/commands/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,mBAAmB,EACnB,iBAAiB,EACjB,eAAe,EACf,iBAAiB,EACjB,0BAA0B,EAC1B,mBAAmB,GACpB,MAAM,kBAAkB,CAAA;AACzB,OAAO,EAAE,kBAAkB,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAA;AAClF,OAAO,EACL,cAAc,EACd,qBAAqB,EACrB,gBAAgB,EAChB,4BAA4B,GAC7B,MAAM,oBAAoB,CAAA;AAC3B,OAAO,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AACtE,OAAO,
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/commands/auth.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"billing.d.ts","sourceRoot":"","sources":["../../src/commands/billing.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"billing.d.ts","sourceRoot":"","sources":["../../src/commands/billing.ts"],"names":[],"mappings":"AAEA,OAAO,EAEL,KAAK,cAAc,EAKpB,MAAM,cAAc,CAAA;AAErB,eAAO,MAAM,aAAa,EAAE,cA0D3B,CAAA"}
|
package/dist/commands/billing.js
CHANGED
|
@@ -1,8 +1,12 @@
|
|
|
1
|
+
import { validateArguments } from './legacy-validation.js';
|
|
1
2
|
import { openUrlInBrowser } from '../lib/open-url.js';
|
|
2
3
|
import { asRecord, ok, outputJson, requireOneClient, withSpinner, } from './helpers.js';
|
|
3
4
|
export const handleBilling = async (ctx) => {
|
|
4
|
-
const one = await requireOneClient(ctx);
|
|
5
5
|
const subcommand = (ctx.rest[0] ?? 'summary').toLowerCase();
|
|
6
|
+
if (!['summary', 'show', 'status', 'portal', 'open'].includes(subcommand))
|
|
7
|
+
throw new Error('Usage: vigilbase billing [summary|portal]');
|
|
8
|
+
validateArguments(ctx, ctx.rest[0] === undefined ? 0 : 1, ['portal', 'open'].includes(subcommand) ? ['isNoOpen'] : []);
|
|
9
|
+
const one = await requireOneClient(ctx);
|
|
6
10
|
if (subcommand === 'summary' ||
|
|
7
11
|
subcommand === 'show' ||
|
|
8
12
|
subcommand === 'status') {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"billing.js","sourceRoot":"","sources":["../../src/commands/billing.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AACrD,OAAO,EACL,QAAQ,EAER,EAAE,EACF,UAAU,EACV,gBAAgB,EAChB,WAAW,GACZ,MAAM,cAAc,CAAA;AAErB,MAAM,CAAC,MAAM,aAAa,GAAmB,KAAK,EAAE,GAAG,EAAE,EAAE;IACzD,MAAM,GAAG,GAAG,
|
|
1
|
+
{"version":3,"file":"billing.js","sourceRoot":"","sources":["../../src/commands/billing.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
import { type CommandHandler } from './helpers.js';
|
|
2
|
+
export declare const CLOUDFLARE_HELP = "Usage: vigilbase cf <command> [options]\nAlias: vigilbase cloudflare\n\nInventory and workspace:\n zones List zones (default); --customer-id, --account-id, --zone-id\n zone <zone-id> Zone detail; --customer-id selects live details, optional --account-id\n accounts List accessible accounts; --customer-id, --account-id\n account <account-id> Stored account detail; --customer-id\n workspace [section] Workspace bootstrap or section; --customer-id, --account-id, --zone-id\n Sections: overview, reports, zones, rule-analyzer, accounts, checkups, settings\n\nZone reads (optional --customer-id; IDs can use --zone-id):\n dns <zone-id> DNS records, TTL and proxy state\n waf <zone-id> WAF rules, expressions, analytics and suggestions\n speed-settings <zone-id> Performance settings (internal users only)\n\nAccount reads (optional --customer-id; IDs can use --account-id):\n audit-logs <account-id> Latest provider audit events (up to 100; service-read permission)\n zero-trust <account-id> Users, Access applications, tunnels and authentication analytics\n developer-platform <account-id> Workers, Workers analytics and Pages\n magic-transit <account-id> Prefixes, routes and traffic analytics\n Zero Trust, Developer Platform and Magic Transit require deployment-read permission.\n\nAnalytics and checkups:\n analytics --customer-id <uuid> [--account-id <id> | --zone-id <id>] [--days 1..30]\n Default 7 days; live zone analytics uses the most recent 23 hours.\n checkup [status] Latest completed checkup; --customer-id, --account-id\n checkup start Start and persist a scan; --customer-id, --account-id\n checkup progress <run-uuid> Read saved progress once\n checkup result <run-uuid> Read the stored Cloudflare checkup result\n checkups aliases checkup; list/show alias status; run aliases start.\n\nCommon options: --json, --one-url <origin>, --timeout <milliseconds>, --help\nCustomer IDs are UUIDs; account and zone IDs are 32 hexadecimal characters.\nOne login, tenant bindings and permissions apply to every command.\nCheckup start creates a scan run. These commands do not edit provider configuration.\nSee CLOUDFLARE.md for full grammar, API mapping, data limits and examples.";
|
|
2
3
|
export declare const handleCloudflare: CommandHandler;
|
|
3
4
|
//# sourceMappingURL=cloudflare.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cloudflare.d.ts","sourceRoot":"","sources":["../../src/commands/cloudflare.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"cloudflare.d.ts","sourceRoot":"","sources":["../../src/commands/cloudflare.ts"],"names":[],"mappings":"AAOA,OAAO,EAKL,KAAK,cAAc,EAKpB,MAAM,cAAc,CAAA;AAKrB,eAAO,MAAM,eAAe,+0EAoC+C,CAAA;AAiC3E,eAAO,MAAM,gBAAgB,EAAE,cAmO9B,CAAA"}
|
|
@@ -1,53 +1,341 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { CloudflareClient, accountResourceSchema, cloudflareScopeSchema, workspaceSectionSchema, } from '../lib/cloudflare-client.js';
|
|
3
|
+
import { assertCommandFlags, asArray, asRecord, ok, outputJson, requireOneClient, withSpinner, } from './helpers.js';
|
|
4
|
+
const usage = 'Usage: vigilbase cf [zones|zone <id>|accounts|account <id>|workspace [section]|dns <zone-id>|waf <zone-id>|speed-settings <zone-id>|audit-logs <account-id>|zero-trust <account-id>|developer-platform <account-id>|magic-transit <account-id>|analytics|checkup] [--customer-id …] [--account-id …] [--json]';
|
|
5
|
+
const checkupUsage = 'Usage: vigilbase cf checkup [status|start|progress <run-id>|result <run-id>] [--customer-id …] [--account-id …] [--json]';
|
|
6
|
+
export const CLOUDFLARE_HELP = `Usage: vigilbase cf <command> [options]
|
|
7
|
+
Alias: vigilbase cloudflare
|
|
8
|
+
|
|
9
|
+
Inventory and workspace:
|
|
10
|
+
zones List zones (default); --customer-id, --account-id, --zone-id
|
|
11
|
+
zone <zone-id> Zone detail; --customer-id selects live details, optional --account-id
|
|
12
|
+
accounts List accessible accounts; --customer-id, --account-id
|
|
13
|
+
account <account-id> Stored account detail; --customer-id
|
|
14
|
+
workspace [section] Workspace bootstrap or section; --customer-id, --account-id, --zone-id
|
|
15
|
+
Sections: overview, reports, zones, rule-analyzer, accounts, checkups, settings
|
|
16
|
+
|
|
17
|
+
Zone reads (optional --customer-id; IDs can use --zone-id):
|
|
18
|
+
dns <zone-id> DNS records, TTL and proxy state
|
|
19
|
+
waf <zone-id> WAF rules, expressions, analytics and suggestions
|
|
20
|
+
speed-settings <zone-id> Performance settings (internal users only)
|
|
21
|
+
|
|
22
|
+
Account reads (optional --customer-id; IDs can use --account-id):
|
|
23
|
+
audit-logs <account-id> Latest provider audit events (up to 100; service-read permission)
|
|
24
|
+
zero-trust <account-id> Users, Access applications, tunnels and authentication analytics
|
|
25
|
+
developer-platform <account-id> Workers, Workers analytics and Pages
|
|
26
|
+
magic-transit <account-id> Prefixes, routes and traffic analytics
|
|
27
|
+
Zero Trust, Developer Platform and Magic Transit require deployment-read permission.
|
|
28
|
+
|
|
29
|
+
Analytics and checkups:
|
|
30
|
+
analytics --customer-id <uuid> [--account-id <id> | --zone-id <id>] [--days 1..30]
|
|
31
|
+
Default 7 days; live zone analytics uses the most recent 23 hours.
|
|
32
|
+
checkup [status] Latest completed checkup; --customer-id, --account-id
|
|
33
|
+
checkup start Start and persist a scan; --customer-id, --account-id
|
|
34
|
+
checkup progress <run-uuid> Read saved progress once
|
|
35
|
+
checkup result <run-uuid> Read the stored Cloudflare checkup result
|
|
36
|
+
checkups aliases checkup; list/show alias status; run aliases start.
|
|
37
|
+
|
|
38
|
+
Common options: --json, --one-url <origin>, --timeout <milliseconds>, --help
|
|
39
|
+
Customer IDs are UUIDs; account and zone IDs are 32 hexadecimal characters.
|
|
40
|
+
One login, tenant bindings and permissions apply to every command.
|
|
41
|
+
Checkup start creates a scan run. These commands do not edit provider configuration.
|
|
42
|
+
See CLOUDFLARE.md for full grammar, API mapping, data limits and examples.`;
|
|
43
|
+
function validate(schema, input) {
|
|
44
|
+
const result = schema.safeParse(input);
|
|
45
|
+
if (!result.success)
|
|
46
|
+
throw new Error(result.error.issues.map((issue) => issue.message).join(' '));
|
|
47
|
+
return result.data;
|
|
48
|
+
}
|
|
49
|
+
function dataOf(payload) {
|
|
50
|
+
return asRecord(payload.data) ?? payload;
|
|
51
|
+
}
|
|
52
|
+
function writeLine(ctx, value) {
|
|
53
|
+
// DNS contents, rule expressions, and evidence can contain terminal controls.
|
|
54
|
+
ctx.writer.stdout(value.replace(/[\u0000-\u001f\u007f-\u009f]/g, ' '));
|
|
55
|
+
}
|
|
56
|
+
function fields(ctx, data) {
|
|
57
|
+
for (const [key, value] of Object.entries(data)) {
|
|
58
|
+
if (value === undefined || value === null)
|
|
59
|
+
continue;
|
|
60
|
+
writeLine(ctx, `${key.padEnd(20)} ${typeof value === 'object' ? JSON.stringify(value) : String(value)}`);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
function zones(ctx, values) {
|
|
64
|
+
const items = asArray(values).map(asRecord).filter((item) => item !== null);
|
|
65
|
+
if (!items.length)
|
|
66
|
+
writeLine(ctx, 'No Cloudflare zones.');
|
|
67
|
+
for (const zone of items) {
|
|
68
|
+
const plan = zone.planName ?? zone.plan_name ?? asRecord(zone.plan)?.name;
|
|
69
|
+
writeLine(ctx, `${String(zone.id ?? zone.zone_id)} ${String(zone.name ?? zone.zone_name).padEnd(28)} ${String(zone.status ?? '-')}${plan ? ` ${String(plan)}` : ''}`);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
2
72
|
export const handleCloudflare = async (ctx) => {
|
|
3
|
-
|
|
73
|
+
assertCommandFlags(ctx, ['customer-id', 'account-id', 'zone-id', 'days']);
|
|
4
74
|
const subcommand = (ctx.rest[0] ?? 'zones').toLowerCase();
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
75
|
+
const scope = validate(cloudflareScopeSchema, {
|
|
76
|
+
customerId: ctx.values['customer-id'],
|
|
77
|
+
accountId: ctx.values['account-id'],
|
|
78
|
+
zoneId: ctx.values['zone-id'],
|
|
79
|
+
});
|
|
80
|
+
if (ctx.values.days !== undefined && subcommand !== 'analytics')
|
|
81
|
+
throw new Error('--days is supported only by cf analytics.');
|
|
82
|
+
if (scope.accountId && ['dns', 'waf', 'speed-settings'].includes(subcommand))
|
|
83
|
+
throw new Error(`cf ${subcommand} accepts a zone ID and --customer-id; --account-id is not supported.`);
|
|
84
|
+
if (scope.zoneId && ['accounts', 'account', ...accountResourceSchema.options, 'checkup', 'checkups'].includes(subcommand))
|
|
85
|
+
throw new Error(`cf ${subcommand} does not support --zone-id.`);
|
|
86
|
+
const args = ctx.rest.slice(1);
|
|
87
|
+
const noExtraArgs = (count, message = usage) => {
|
|
88
|
+
if (args.length > count)
|
|
89
|
+
throw new Error(message);
|
|
90
|
+
};
|
|
91
|
+
const emit = (payload, render) => {
|
|
92
|
+
if (payload.success === false)
|
|
93
|
+
throw new Error('Cloudflare request failed.');
|
|
94
|
+
if (ctx.mode === 'json')
|
|
8
95
|
outputJson(ctx, payload);
|
|
9
|
-
|
|
96
|
+
else
|
|
97
|
+
render(dataOf(payload));
|
|
98
|
+
return ok();
|
|
99
|
+
};
|
|
100
|
+
// Validate commands before requesting credentials or making API calls.
|
|
101
|
+
if (!['zones', 'zone', 'accounts', 'workspace', 'dns', 'waf', 'speed-settings', 'account', ...accountResourceSchema.options, 'analytics', 'checkup', 'checkups'].includes(subcommand)) {
|
|
102
|
+
throw new Error(usage);
|
|
103
|
+
}
|
|
104
|
+
let zoneId;
|
|
105
|
+
let accountId;
|
|
106
|
+
const accountResource = accountResourceSchema.safeParse(subcommand);
|
|
107
|
+
if (accountResource.success || subcommand === 'account') {
|
|
108
|
+
noExtraArgs(1);
|
|
109
|
+
if (args[0] && scope.accountId && args[0] !== scope.accountId)
|
|
110
|
+
throw new Error('The positional account ID and --account-id must match.');
|
|
111
|
+
accountId = args[0] ?? scope.accountId;
|
|
112
|
+
if (!accountId)
|
|
113
|
+
throw new Error(`Usage: vigilbase cf ${subcommand} <account-id> [--customer-id …] [--json]`);
|
|
114
|
+
validate(cloudflareScopeSchema, { accountId });
|
|
115
|
+
}
|
|
116
|
+
else if (['dns', 'waf', 'zone', 'speed-settings'].includes(subcommand)) {
|
|
117
|
+
noExtraArgs(1);
|
|
118
|
+
if (args[0] && scope.zoneId && args[0] !== scope.zoneId)
|
|
119
|
+
throw new Error('The positional zone ID and --zone-id must match.');
|
|
120
|
+
zoneId = args[0] ?? scope.zoneId;
|
|
121
|
+
// Preserve the historical `cf zone` alias for the zone inventory.
|
|
122
|
+
if (subcommand !== 'zone' && !zoneId)
|
|
123
|
+
throw new Error(`Usage: vigilbase cf ${subcommand} <zone-id> [--customer-id …] [--json]`);
|
|
124
|
+
if (zoneId)
|
|
125
|
+
validate(cloudflareScopeSchema, { zoneId });
|
|
126
|
+
}
|
|
127
|
+
else if (!['workspace', 'checkup', 'checkups'].includes(subcommand)) {
|
|
128
|
+
noExtraArgs(0);
|
|
129
|
+
}
|
|
130
|
+
const section = subcommand === 'workspace'
|
|
131
|
+
? (noExtraArgs(1), args[0] ? validate(workspaceSectionSchema, args[0]) : undefined)
|
|
132
|
+
: undefined;
|
|
133
|
+
let days = 7;
|
|
134
|
+
if (subcommand === 'analytics') {
|
|
135
|
+
if (!scope.customerId)
|
|
136
|
+
throw new Error('Cloudflare analytics requires --customer-id <uuid>. Find it with `vigilbase cf accounts --json`.');
|
|
137
|
+
if (scope.zoneId && scope.accountId)
|
|
138
|
+
throw new Error('Choose either --zone-id or --account-id for analytics.');
|
|
139
|
+
days = validate(z.coerce.number().int().min(1).max(30), ctx.values.days ?? 7);
|
|
140
|
+
}
|
|
141
|
+
const action = (args[0] ?? 'status').toLowerCase();
|
|
142
|
+
let runId;
|
|
143
|
+
if (subcommand === 'checkup' || subcommand === 'checkups') {
|
|
144
|
+
if (['progress', 'result'].includes(action)) {
|
|
145
|
+
noExtraArgs(2, checkupUsage);
|
|
146
|
+
runId = validate(z.string().uuid('A checkup run UUID is required.'), args[1]);
|
|
147
|
+
if (scope.customerId || scope.accountId)
|
|
148
|
+
throw new Error(`cf checkup ${action} is scoped by run ID and does not accept --customer-id or --account-id.`);
|
|
149
|
+
}
|
|
150
|
+
else if (['status', 'list', 'show', 'start', 'run'].includes(action)) {
|
|
151
|
+
noExtraArgs(1, checkupUsage);
|
|
152
|
+
}
|
|
153
|
+
else
|
|
154
|
+
throw new Error(checkupUsage);
|
|
155
|
+
}
|
|
156
|
+
const one = await requireOneClient(ctx);
|
|
157
|
+
const cloudflare = new CloudflareClient(one);
|
|
158
|
+
if (subcommand === 'speed-settings') {
|
|
159
|
+
const payload = await withSpinner(ctx, 'Loading Cloudflare speed settings', () => cloudflare.speedSettings(zoneId, scope.customerId));
|
|
160
|
+
return emit(payload, (data) => {
|
|
161
|
+
if (!Object.keys(data).length)
|
|
162
|
+
writeLine(ctx, 'No speed settings returned; provider availability or permissions may limit this view.');
|
|
163
|
+
else
|
|
164
|
+
fields(ctx, data);
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
if (accountResource.success) {
|
|
168
|
+
const payload = await withSpinner(ctx, `Loading Cloudflare ${subcommand}`, () => cloudflare.accountResource(accountResource.data, accountId, scope.customerId));
|
|
169
|
+
return emit(payload, (data) => {
|
|
170
|
+
if (subcommand === 'audit-logs') {
|
|
171
|
+
const logs = asArray(data.logs);
|
|
172
|
+
if (!logs.length)
|
|
173
|
+
writeLine(ctx, 'No audit logs returned; provider availability or permissions may limit this view.');
|
|
174
|
+
for (const raw of logs) {
|
|
175
|
+
const log = asRecord(raw);
|
|
176
|
+
if (!log)
|
|
177
|
+
continue;
|
|
178
|
+
const action = asRecord(log.action);
|
|
179
|
+
const actor = asRecord(log.actor);
|
|
180
|
+
const resource = asRecord(log.resource);
|
|
181
|
+
writeLine(ctx, `${String(log.id ?? '-')} ${String(log.when ?? '-')} ${String(action?.type ?? '-')} ${action?.result === true ? 'success' : action?.result === false ? 'failed' : '-'} ${String(actor?.email ?? actor?.id ?? '-')} ${String(resource?.type ?? '-')} ${String(resource?.id ?? '-')}`);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
else
|
|
185
|
+
fields(ctx, data);
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
if (subcommand === 'account') {
|
|
189
|
+
const payload = await withSpinner(ctx, 'Loading Cloudflare account', () => cloudflare.workspace({ ...scope, accountId }));
|
|
190
|
+
if (payload.success === false)
|
|
191
|
+
return emit(payload, () => { });
|
|
192
|
+
const matches = asArray(dataOf(payload).accounts).map(asRecord).filter((item) => item?.id === accountId);
|
|
193
|
+
if (!matches.length)
|
|
194
|
+
throw new Error('Cloudflare account not found in the selected workspace.');
|
|
195
|
+
const customerIds = new Set(matches.map((item) => item?.customerId));
|
|
196
|
+
if (customerIds.size > 1)
|
|
197
|
+
throw new Error('This Cloudflare account is linked to multiple customers. Specify --customer-id.');
|
|
198
|
+
const account = matches.find((item) => item?.status === 'active' || item?.status === 'trialing') ?? matches[0];
|
|
199
|
+
return emit({ success: true, data: account }, (data) => fields(ctx, data));
|
|
200
|
+
}
|
|
201
|
+
if (subcommand === 'zones' || subcommand === 'zone') {
|
|
202
|
+
if (zoneId && scope.customerId) {
|
|
203
|
+
const payload = await withSpinner(ctx, 'Loading live Cloudflare zone', () => cloudflare.zoneDetail(scope.customerId, zoneId));
|
|
204
|
+
if (payload.success === false)
|
|
205
|
+
return emit(payload, () => { });
|
|
206
|
+
const zone = dataOf(payload);
|
|
207
|
+
if (zone.id !== zoneId)
|
|
208
|
+
throw new Error('The server returned a different Cloudflare zone.');
|
|
209
|
+
if (scope.accountId && asRecord(zone.account)?.id !== scope.accountId)
|
|
210
|
+
throw new Error('Cloudflare zone does not belong to the selected account.');
|
|
211
|
+
return emit(payload, (data) => fields(ctx, data));
|
|
10
212
|
}
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
213
|
+
let payload = await withSpinner(ctx, 'Loading Cloudflare zones', () => scope.customerId || scope.accountId || scope.zoneId || zoneId
|
|
214
|
+
? cloudflare.workspace({ ...scope, zoneId: zoneId ?? scope.zoneId }, 'zones')
|
|
215
|
+
: one.getCloudflareZones());
|
|
216
|
+
if (payload.success === false)
|
|
217
|
+
return emit(payload, () => { });
|
|
218
|
+
if (scope.accountId || scope.zoneId) {
|
|
219
|
+
const data = dataOf(payload);
|
|
220
|
+
const selectedZones = asArray(data.zones).filter((raw) => {
|
|
221
|
+
const zone = asRecord(raw);
|
|
222
|
+
return zone && (!scope.accountId || (zone.accountId ?? zone.account_id ?? zone.cloudflare_account_id) === scope.accountId)
|
|
223
|
+
&& (!scope.zoneId || (zone.id ?? zone.zone_id) === scope.zoneId);
|
|
224
|
+
});
|
|
225
|
+
payload = payload.data ? { ...payload, data: { ...data, zones: selectedZones } } : { ...payload, zones: selectedZones };
|
|
15
226
|
}
|
|
16
|
-
|
|
17
|
-
const zone = asRecord(
|
|
227
|
+
if (zoneId) {
|
|
228
|
+
const zone = asArray(dataOf(payload).zones).map(asRecord).find((item) => (item?.id ?? item?.zone_id) === zoneId);
|
|
18
229
|
if (!zone)
|
|
19
|
-
|
|
20
|
-
|
|
230
|
+
throw new Error('Cloudflare zone not found in the selected workspace.');
|
|
231
|
+
return emit({ success: true, data: zone }, (data) => fields(ctx, data));
|
|
21
232
|
}
|
|
22
|
-
return
|
|
233
|
+
return emit(payload, (data) => zones(ctx, data.zones));
|
|
23
234
|
}
|
|
24
|
-
if (subcommand === '
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
const
|
|
29
|
-
|
|
30
|
-
outputJson(ctx, payload);
|
|
31
|
-
return ok();
|
|
32
|
-
}
|
|
33
|
-
const data = asRecord(payload.data) || payload;
|
|
34
|
-
ctx.writer.stdout(`checkup ${String(data.status || data.success || 'ok')}`);
|
|
35
|
-
if (data.grade)
|
|
36
|
-
ctx.writer.stdout(`grade ${String(data.grade)}`);
|
|
37
|
-
return ok();
|
|
235
|
+
if (subcommand === 'accounts' || subcommand === 'workspace') {
|
|
236
|
+
let payload = await withSpinner(ctx, 'Loading Cloudflare workspace', () => cloudflare.workspace(scope, section));
|
|
237
|
+
if (subcommand === 'accounts' && scope.accountId) {
|
|
238
|
+
const data = dataOf(payload);
|
|
239
|
+
const accounts = asArray(data.accounts).filter((raw) => asRecord(raw)?.id === scope.accountId);
|
|
240
|
+
payload = { ...payload, data: { ...data, accounts } };
|
|
38
241
|
}
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
242
|
+
return emit(payload, (data) => {
|
|
243
|
+
if (subcommand === 'accounts') {
|
|
244
|
+
const accounts = asArray(data.accounts);
|
|
245
|
+
if (!accounts.length)
|
|
246
|
+
writeLine(ctx, 'No Cloudflare accounts.');
|
|
247
|
+
for (const raw of accounts) {
|
|
248
|
+
const account = asRecord(raw);
|
|
249
|
+
if (account)
|
|
250
|
+
writeLine(ctx, `${String(account.id)} ${String(account.name).padEnd(28)} ${String(account.status)} ${String(account.zoneCount ?? 0)} zones${account.customerId ? ` customer ${String(account.customerId)}` : ''}`);
|
|
251
|
+
}
|
|
44
252
|
}
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
}
|
|
49
|
-
throw new Error('Usage: vigilbase cf checkup [status|start] [--account-id …] [--json]');
|
|
253
|
+
else
|
|
254
|
+
fields(ctx, data);
|
|
255
|
+
});
|
|
50
256
|
}
|
|
51
|
-
|
|
257
|
+
if (subcommand === 'dns' || subcommand === 'waf') {
|
|
258
|
+
const payload = await withSpinner(ctx, `Loading Cloudflare ${subcommand.toUpperCase()}`, () => cloudflare.zoneRecords(subcommand, zoneId, scope.customerId));
|
|
259
|
+
return emit(payload, (data) => {
|
|
260
|
+
const records = asArray(data[subcommand === 'dns' ? 'records' : 'rules']);
|
|
261
|
+
if (!records.length)
|
|
262
|
+
writeLine(ctx, `No ${subcommand === 'dns' ? 'DNS records' : 'WAF rules'}.`);
|
|
263
|
+
for (const raw of records) {
|
|
264
|
+
const record = asRecord(raw);
|
|
265
|
+
if (!record)
|
|
266
|
+
continue;
|
|
267
|
+
if (subcommand === 'dns') {
|
|
268
|
+
writeLine(ctx, `${String(record.id)} ${String(record.type).padEnd(6)} ${String(record.name).padEnd(28)} ${String(record.content)} TTL ${String(record.ttl)} ${record.proxied ? 'proxied' : 'DNS only'}`);
|
|
269
|
+
}
|
|
270
|
+
else {
|
|
271
|
+
writeLine(ctx, `${String(record.id)} ${String(record.action).padEnd(18)} ${record.paused ? 'paused' : 'active'} ${String(record.description ?? '')}`);
|
|
272
|
+
const expression = asRecord(record.filter)?.expression;
|
|
273
|
+
if (expression)
|
|
274
|
+
writeLine(ctx, ` ${String(expression)}`);
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
if (subcommand === 'waf') {
|
|
278
|
+
writeLine(ctx, `Rule analytics: ${data.analyticsAvailable ? 'available' : 'unavailable'}`);
|
|
279
|
+
for (const raw of asArray(data.suggestions)) {
|
|
280
|
+
const suggestion = asRecord(raw);
|
|
281
|
+
if (suggestion)
|
|
282
|
+
writeLine(ctx, `[${String(suggestion.severity)}] ${String(suggestion.title)}: ${String(suggestion.recommendation)}`);
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
});
|
|
286
|
+
}
|
|
287
|
+
if (subcommand === 'analytics') {
|
|
288
|
+
const payload = await withSpinner(ctx, 'Loading Cloudflare analytics', () => cloudflare.analytics(scope, days));
|
|
289
|
+
return emit(payload, (data) => {
|
|
290
|
+
if (scope.zoneId)
|
|
291
|
+
writeLine(ctx, 'Live zone analytics use the most recent 23 hours; stored usage may cover less.');
|
|
292
|
+
fields(ctx, asRecord(data.analytics) ?? data);
|
|
293
|
+
});
|
|
294
|
+
}
|
|
295
|
+
if (action === 'progress') {
|
|
296
|
+
const payload = await withSpinner(ctx, 'Loading Cloudflare checkup progress', () => cloudflare.checkupProgress(runId));
|
|
297
|
+
return emit(payload, (data) => {
|
|
298
|
+
writeLine(ctx, `checkup ${String(data.status)} ${String(data.progressPct ?? 0)}%`);
|
|
299
|
+
for (const raw of asArray(data.events)) {
|
|
300
|
+
const event = asRecord(raw);
|
|
301
|
+
if (event)
|
|
302
|
+
writeLine(ctx, `${String(event.createdAt ?? '')} ${String(event.message ?? '')}`);
|
|
303
|
+
}
|
|
304
|
+
if (data.errorMessage)
|
|
305
|
+
writeLine(ctx, `error ${String(data.errorMessage)}`);
|
|
306
|
+
});
|
|
307
|
+
}
|
|
308
|
+
if (action === 'result') {
|
|
309
|
+
const payload = await withSpinner(ctx, 'Loading Cloudflare checkup result', () => one.getToolRun(runId));
|
|
310
|
+
const run = dataOf(payload);
|
|
311
|
+
if (run.tool_name !== 'cloudflare-checkup')
|
|
312
|
+
throw new Error('This run is not a Cloudflare checkup.');
|
|
313
|
+
return emit(payload, (data) => {
|
|
314
|
+
writeLine(ctx, `checkup ${String(data.status)}`);
|
|
315
|
+
if (data.grade)
|
|
316
|
+
writeLine(ctx, `grade ${String(data.grade)} ${String(data.grade_score ?? '')}`);
|
|
317
|
+
if (data.results)
|
|
318
|
+
fields(ctx, asRecord(data.results) ?? { results: data.results });
|
|
319
|
+
else
|
|
320
|
+
writeLine(ctx, 'No result is available yet.');
|
|
321
|
+
});
|
|
322
|
+
}
|
|
323
|
+
const isStart = action === 'start' || action === 'run';
|
|
324
|
+
const payload = await withSpinner(ctx, isStart ? 'Starting Cloudflare checkup' : 'Loading Cloudflare checkup', () => cloudflare.checkup(scope, isStart));
|
|
325
|
+
return emit(payload, (data) => {
|
|
326
|
+
if (isStart) {
|
|
327
|
+
writeLine(ctx, `started ${String(data.toolRunId ?? data.id ?? 'ok')} ${String(data.status ?? 'running')}`);
|
|
328
|
+
return;
|
|
329
|
+
}
|
|
330
|
+
const run = asRecord(data.latestRun);
|
|
331
|
+
const report = asRecord(data.report);
|
|
332
|
+
writeLine(ctx, `checkup ${data.requiresSetup ? 'setup required' : String(run?.status ?? (report ? 'completed' : 'no completed runs'))}`);
|
|
333
|
+
if (run?.id)
|
|
334
|
+
writeLine(ctx, `run ${String(run.id)}`);
|
|
335
|
+
if (run?.grade ?? report?.grade)
|
|
336
|
+
writeLine(ctx, `grade ${String(run?.grade ?? report?.grade)}`);
|
|
337
|
+
if (report)
|
|
338
|
+
fields(ctx, report);
|
|
339
|
+
});
|
|
52
340
|
};
|
|
53
341
|
//# sourceMappingURL=cloudflare.js.map
|