@vm0/cli 9.222.1 → 9.222.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.
Files changed (83) hide show
  1. package/{agent-URKTRVVY.js → agent-LPPBYNS2.js} +4 -4
  2. package/{automation-7TUOVCC6.js → automation-BB4N3JL7.js} +5 -5
  3. package/{banking-7XABHZ5S.js → banking-WAVEYEQR.js} +2 -2
  4. package/{chat-GZ4XQAP5.js → chat-WLUTTBQU.js} +2 -2
  5. package/{chunk-LR3SNXFF.js → chunk-3QZMZ46V.js} +133 -4
  6. package/chunk-3QZMZ46V.js.map +1 -0
  7. package/{chunk-EZKHVXE7.js → chunk-4IPZWDAI.js} +3 -3
  8. package/{chunk-BYBPO5VT.js → chunk-5FY5RVWK.js} +3 -3
  9. package/chunk-72DXWQL4.js +1178 -0
  10. package/chunk-72DXWQL4.js.map +1 -0
  11. package/{chunk-P2NVIMW4.js → chunk-A5RF3VZM.js} +2 -2
  12. package/{chunk-L7YXAPYN.js → chunk-K7F6VF2Z.js} +2 -2
  13. package/{chunk-CS63UKLQ.js → chunk-OFENJD2Q.js} +25 -5
  14. package/{chunk-CS63UKLQ.js.map → chunk-OFENJD2Q.js.map} +1 -1
  15. package/{chunk-SYUXIMDL.js → chunk-V2NS7MND.js} +2 -2
  16. package/{chunk-XTEZGNJE.js → chunk-XX44OKQX.js} +2 -2
  17. package/{computer-use-6THXLNRO.js → computer-use-V7RXYM5A.js} +2 -2
  18. package/{connector-BGMSHIXW.js → connector-ZFFOQO63.js} +2 -2
  19. package/{credit-XRZDIE2G.js → credit-O3ELRY7X.js} +2 -2
  20. package/{developer-support-EJDZWL42.js → developer-support-2VYEJ4UE.js} +2 -2
  21. package/{doctor-EYR3IG4Y.js → doctor-F5ETPBLW.js} +261 -65
  22. package/doctor-F5ETPBLW.js.map +1 -0
  23. package/{generate-3P3NAGH5.js → generate-MESJMO2O.js} +2 -2
  24. package/{github-JT7U4DRN.js → github-3QYZVKIQ.js} +2 -2
  25. package/{goal-45PIBJPM.js → goal-A5RMK7GY.js} +2 -2
  26. package/{host-AAOX4PLN.js → host-3R44HEX5.js} +2 -2
  27. package/index.js +13 -13
  28. package/{logs-T3NAE3H7.js → logs-TCWPJYIU.js} +6 -6
  29. package/{maps-FWZYMSGN.js → maps-OADWY7SG.js} +2 -2
  30. package/{model-IMFZNZ6Y.js → model-VEADPWRX.js} +3 -3
  31. package/{model-provider-KEK475GA.js → model-provider-SHA27BOM.js} +3 -3
  32. package/{org-YG2ZZRRJ.js → org-MI6FIM3U.js} +2 -2
  33. package/package.json +1 -1
  34. package/{phone-JFF2IT5G.js → phone-IIC43L5Z.js} +2 -2
  35. package/{preference-WVQAW5ME.js → preference-JE7EYXOC.js} +2 -2
  36. package/{resource-U3LUKPPU.js → resource-Q646DK57.js} +2 -2
  37. package/{search-GTOC3GPL.js → search-5A5HM5EN.js} +6 -6
  38. package/{secret-QGULS25L.js → secret-JGEU4F2W.js} +3 -3
  39. package/{slack-DVAIY7U3.js → slack-QLEY2HSE.js} +2 -2
  40. package/{telegram-5C3ALERN.js → telegram-UCBPY4FU.js} +2 -2
  41. package/{variable-G6CSZGS2.js → variable-XB45XMPQ.js} +2 -2
  42. package/{web-PJK4UZXI.js → web-DWIOAOMH.js} +2 -2
  43. package/{whoami-P7IJ4FES.js → whoami-P7LQBBTB.js} +4 -4
  44. package/{workflow-4JOVGGV6.js → workflow-ETGLSZ5Y.js} +2 -2
  45. package/zero.js +31 -31
  46. package/chunk-KJNJT27A.js +0 -612
  47. package/chunk-KJNJT27A.js.map +0 -1
  48. package/chunk-LR3SNXFF.js.map +0 -1
  49. package/doctor-EYR3IG4Y.js.map +0 -1
  50. /package/{agent-URKTRVVY.js.map → agent-LPPBYNS2.js.map} +0 -0
  51. /package/{automation-7TUOVCC6.js.map → automation-BB4N3JL7.js.map} +0 -0
  52. /package/{banking-7XABHZ5S.js.map → banking-WAVEYEQR.js.map} +0 -0
  53. /package/{chat-GZ4XQAP5.js.map → chat-WLUTTBQU.js.map} +0 -0
  54. /package/{chunk-EZKHVXE7.js.map → chunk-4IPZWDAI.js.map} +0 -0
  55. /package/{chunk-BYBPO5VT.js.map → chunk-5FY5RVWK.js.map} +0 -0
  56. /package/{chunk-P2NVIMW4.js.map → chunk-A5RF3VZM.js.map} +0 -0
  57. /package/{chunk-L7YXAPYN.js.map → chunk-K7F6VF2Z.js.map} +0 -0
  58. /package/{chunk-SYUXIMDL.js.map → chunk-V2NS7MND.js.map} +0 -0
  59. /package/{chunk-XTEZGNJE.js.map → chunk-XX44OKQX.js.map} +0 -0
  60. /package/{computer-use-6THXLNRO.js.map → computer-use-V7RXYM5A.js.map} +0 -0
  61. /package/{connector-BGMSHIXW.js.map → connector-ZFFOQO63.js.map} +0 -0
  62. /package/{credit-XRZDIE2G.js.map → credit-O3ELRY7X.js.map} +0 -0
  63. /package/{developer-support-EJDZWL42.js.map → developer-support-2VYEJ4UE.js.map} +0 -0
  64. /package/{generate-3P3NAGH5.js.map → generate-MESJMO2O.js.map} +0 -0
  65. /package/{github-JT7U4DRN.js.map → github-3QYZVKIQ.js.map} +0 -0
  66. /package/{goal-45PIBJPM.js.map → goal-A5RMK7GY.js.map} +0 -0
  67. /package/{host-AAOX4PLN.js.map → host-3R44HEX5.js.map} +0 -0
  68. /package/{logs-T3NAE3H7.js.map → logs-TCWPJYIU.js.map} +0 -0
  69. /package/{maps-FWZYMSGN.js.map → maps-OADWY7SG.js.map} +0 -0
  70. /package/{model-IMFZNZ6Y.js.map → model-VEADPWRX.js.map} +0 -0
  71. /package/{model-provider-KEK475GA.js.map → model-provider-SHA27BOM.js.map} +0 -0
  72. /package/{org-YG2ZZRRJ.js.map → org-MI6FIM3U.js.map} +0 -0
  73. /package/{phone-JFF2IT5G.js.map → phone-IIC43L5Z.js.map} +0 -0
  74. /package/{preference-WVQAW5ME.js.map → preference-JE7EYXOC.js.map} +0 -0
  75. /package/{resource-U3LUKPPU.js.map → resource-Q646DK57.js.map} +0 -0
  76. /package/{search-GTOC3GPL.js.map → search-5A5HM5EN.js.map} +0 -0
  77. /package/{secret-QGULS25L.js.map → secret-JGEU4F2W.js.map} +0 -0
  78. /package/{slack-DVAIY7U3.js.map → slack-QLEY2HSE.js.map} +0 -0
  79. /package/{telegram-5C3ALERN.js.map → telegram-UCBPY4FU.js.map} +0 -0
  80. /package/{variable-G6CSZGS2.js.map → variable-XB45XMPQ.js.map} +0 -0
  81. /package/{web-PJK4UZXI.js.map → web-DWIOAOMH.js.map} +0 -0
  82. /package/{whoami-P7IJ4FES.js.map → whoami-P7LQBBTB.js.map} +0 -0
  83. /package/{workflow-4JOVGGV6.js.map → workflow-ETGLSZ5Y.js.map} +0 -0
@@ -4,7 +4,7 @@ const require = __createRequire(import.meta.url);
4
4
  import {
5
5
  loadFirewallPermissionMetadata,
6
6
  resolveFirewallMetadataPolicies
7
- } from "./chunk-L7YXAPYN.js";
7
+ } from "./chunk-K7F6VF2Z.js";
8
8
  import {
9
9
  source_default
10
10
  } from "./chunk-JUTUEPIR.js";
@@ -87,4 +87,4 @@ export {
87
87
  policyIcon,
88
88
  loadConnectorPermissionInfos
89
89
  };
90
- //# sourceMappingURL=chunk-SYUXIMDL.js.map
90
+ //# sourceMappingURL=chunk-V2NS7MND.js.map
@@ -3,7 +3,7 @@ import { createRequire as __createRequire } from "node:module";
3
3
  const require = __createRequire(import.meta.url);
4
4
  import {
5
5
  MODEL_PROVIDER_TYPES
6
- } from "./chunk-LR3SNXFF.js";
6
+ } from "./chunk-3QZMZ46V.js";
7
7
  import {
8
8
  init_esm_shims
9
9
  } from "./chunk-DIRAZ3YX.js";
@@ -40,4 +40,4 @@ export {
40
40
  formatModelProviderRoute,
41
41
  formatModelPolicyStatus
42
42
  };
43
- //# sourceMappingURL=chunk-XTEZGNJE.js.map
43
+ //# sourceMappingURL=chunk-XX44OKQX.js.map
@@ -9,7 +9,7 @@ import {
9
9
  fetchComputerUsePluginContent,
10
10
  fetchComputerUseScreenshot,
11
11
  getComputerUseCommand
12
- } from "./chunk-LR3SNXFF.js";
12
+ } from "./chunk-3QZMZ46V.js";
13
13
  import {
14
14
  ApiRequestError,
15
15
  withErrorHandler
@@ -881,4 +881,4 @@ export {
881
881
  formatComputerUseResultForConsole,
882
882
  zeroComputerUseCommand
883
883
  };
884
- //# sourceMappingURL=computer-use-6THXLNRO.js.map
884
+ //# sourceMappingURL=computer-use-V7RXYM5A.js.map
@@ -16,7 +16,7 @@ import {
16
16
  getZeroCustomConnector,
17
17
  listZeroConnectorCatalogStatus,
18
18
  listZeroCustomConnectors
19
- } from "./chunk-LR3SNXFF.js";
19
+ } from "./chunk-3QZMZ46V.js";
20
20
  import {
21
21
  withErrorHandler
22
22
  } from "./chunk-3F4RFLPX.js";
@@ -832,4 +832,4 @@ var zeroConnectorCommand = new Command().name("connector").description("Check th
832
832
  export {
833
833
  zeroConnectorCommand
834
834
  };
835
- //# sourceMappingURL=connector-BGMSHIXW.js.map
835
+ //# sourceMappingURL=connector-ZFFOQO63.js.map
@@ -8,7 +8,7 @@ import "./chunk-LTDQISD7.js";
8
8
  import {
9
9
  createZeroCreditCheckout,
10
10
  getZeroOrgMembers
11
- } from "./chunk-LR3SNXFF.js";
11
+ } from "./chunk-3QZMZ46V.js";
12
12
  import {
13
13
  withErrorHandler
14
14
  } from "./chunk-3F4RFLPX.js";
@@ -87,4 +87,4 @@ var zeroCreditCommand = new Command().name("credit").description("Create a Strip
87
87
  export {
88
88
  zeroCreditCommand
89
89
  };
90
- //# sourceMappingURL=credit-XRZDIE2G.js.map
90
+ //# sourceMappingURL=credit-O3ELRY7X.js.map
@@ -5,7 +5,7 @@ import "./chunk-LTDQISD7.js";
5
5
  import {
6
6
  requestDeveloperSupportConsent,
7
7
  submitDeveloperSupport
8
- } from "./chunk-LR3SNXFF.js";
8
+ } from "./chunk-3QZMZ46V.js";
9
9
  import {
10
10
  withErrorHandler
11
11
  } from "./chunk-3F4RFLPX.js";
@@ -61,4 +61,4 @@ Notes:
61
61
  export {
62
62
  zeroDeveloperSupportCommand
63
63
  };
64
- //# sourceMappingURL=developer-support-EJDZWL42.js.map
64
+ //# sourceMappingURL=developer-support-2VYEJ4UE.js.map
@@ -5,19 +5,19 @@ import {
5
5
  findFirewallMetadataPermission,
6
6
  getFirewallPermissionSummary,
7
7
  loadFirewallPermissionMetadata
8
- } from "./chunk-L7YXAPYN.js";
8
+ } from "./chunk-K7F6VF2Z.js";
9
9
  import {
10
10
  getPlatformOrigin,
11
11
  toPlatformUrl
12
12
  } from "./chunk-ZFETZTKV.js";
13
13
  import {
14
- findMatchingRoutingPermissions,
15
- matchFirewallBaseUrl
16
- } from "./chunk-KJNJT27A.js";
14
+ matchFirewallBaseUrl,
15
+ matchFirewallRequestDecision
16
+ } from "./chunk-72DXWQL4.js";
17
17
  import {
18
18
  getConnectorEnvBindingEntries,
19
19
  getDiagnosticConnectorTypeForRuntimeEnvName
20
- } from "./chunk-P2NVIMW4.js";
20
+ } from "./chunk-A5RF3VZM.js";
21
21
  import "./chunk-LTDQISD7.js";
22
22
  import {
23
23
  CONNECTOR_TYPES,
@@ -32,7 +32,7 @@ import {
32
32
  hasUnsafeFirewallPath,
33
33
  resolveFirewallBaseUrlTemplate,
34
34
  searchZeroConnectors
35
- } from "./chunk-LR3SNXFF.js";
35
+ } from "./chunk-3QZMZ46V.js";
36
36
  import {
37
37
  ApiRequestError,
38
38
  getApiUrl,
@@ -7235,11 +7235,45 @@ async function connectorTypeIsAvailable(type) {
7235
7235
  function connectorEnvName(type) {
7236
7236
  return getConnectorEnvBindingEntries(type)[0]?.envName ?? null;
7237
7237
  }
7238
- function hasRoutingPermissionRules(config) {
7239
- return config.apis.some((api) => {
7240
- return api.routes.length > 0;
7238
+ function stripUrlQueryAndFragment(url) {
7239
+ const queryIndex = url.indexOf("?");
7240
+ const fragmentIndex = url.indexOf("#");
7241
+ let end = url.length;
7242
+ if (queryIndex !== -1) end = Math.min(end, queryIndex);
7243
+ if (fragmentIndex !== -1) end = Math.min(end, fragmentIndex);
7244
+ return url.slice(0, end);
7245
+ }
7246
+ function shellQuoteArg(value) {
7247
+ return `'${value.replaceAll("'", "'\\''")}'`;
7248
+ }
7249
+ function routesToDecisionPermissions(routes) {
7250
+ const rulesByPermission = /* @__PURE__ */ new Map();
7251
+ for (const route of routes) {
7252
+ const rules = rulesByPermission.get(route.permissionName);
7253
+ if (rules) {
7254
+ rules.push(route.rule);
7255
+ } else {
7256
+ rulesByPermission.set(route.permissionName, [route.rule]);
7257
+ }
7258
+ }
7259
+ return [...rulesByPermission.entries()].map(([name, rules]) => {
7260
+ return { name, rules };
7241
7261
  });
7242
7262
  }
7263
+ function routingConfigToDecisionFirewalls(config) {
7264
+ return [
7265
+ {
7266
+ name: config.type,
7267
+ apis: config.apis.map((api) => {
7268
+ return {
7269
+ base: api.base,
7270
+ auth: {},
7271
+ permissions: routesToDecisionPermissions(api.routes)
7272
+ };
7273
+ })
7274
+ }
7275
+ ];
7276
+ }
7243
7277
  function routingBaseExecutionTemplate(type, base) {
7244
7278
  const executionMetadata = getFirewallExecutionMetadata(type);
7245
7279
  const template = executionMetadata?.baseUrlTemplates.find((entry) => {
@@ -7358,7 +7392,7 @@ async function resolveConnectorFromRunContext(url, runContext) {
7358
7392
  envName,
7359
7393
  matchedBase: bestMatch.match.displayBase,
7360
7394
  relativePath: bestMatch.match.relativePath,
7361
- ...hasRoutingPermissionRules(bestMatch.routingConfig) ? { routingConfig: bestMatch.routingConfig } : {}
7395
+ routingConfig: bestMatch.routingConfig
7362
7396
  };
7363
7397
  }
7364
7398
  async function getCurrentRunContext() {
@@ -7566,21 +7600,27 @@ function checkPermissionPolicy(connectorType, label, permissionName, networkPoli
7566
7600
  console.log(`Permission policies for the ${label} connector:`);
7567
7601
  console.log(` allow list: [${connectorPolicies.allow.join(", ")}]`);
7568
7602
  console.log(` deny list: [${connectorPolicies.deny.join(", ")}]`);
7603
+ console.log(` ask list: [${connectorPolicies.ask.join(", ")}]`);
7569
7604
  console.log(` unknown endpoint policy: ${connectorPolicies.unknownPolicy}`);
7570
7605
  console.log("");
7571
7606
  const isInAllow = connectorPolicies.allow.includes(permissionName);
7572
7607
  const isInDeny = connectorPolicies.deny.includes(permissionName);
7573
- if (isInAllow) {
7608
+ const isInAsk = connectorPolicies.ask.includes(permissionName);
7609
+ if (isInDeny) {
7574
7610
  console.log(
7575
- `Result: "${permissionName}" is in the allow list. Requests matching this permission are allowed.`
7611
+ `Result: "${permissionName}" is in the deny list. Requests matching this permission are denied.`
7576
7612
  );
7577
- } else if (isInDeny) {
7613
+ } else if (isInAsk) {
7578
7614
  console.log(
7579
- `Result: "${permissionName}" is in the deny list. Requests matching this permission are denied.`
7615
+ `Result: "${permissionName}" is in the ask list. Requests matching this permission are blocked until approval.`
7616
+ );
7617
+ } else if (isInAllow) {
7618
+ console.log(
7619
+ `Result: "${permissionName}" is in the allow list. Requests matching this permission are allowed.`
7580
7620
  );
7581
7621
  } else {
7582
7622
  console.log(
7583
- `Result: "${permissionName}" is not in any permission list. It will be handled by the unknown endpoint policy: ${connectorPolicies.unknownPolicy}.`
7623
+ `Result: "${permissionName}" is not in the deny or ask list. Requests matching this permission are allowed; the unknown endpoint policy only applies when no named permission matches a request.`
7584
7624
  );
7585
7625
  }
7586
7626
  console.log("");
@@ -7588,7 +7628,116 @@ function checkPermissionPolicy(connectorType, label, permissionName, networkPoli
7588
7628
  function unknownPermissionChangeCommand(connectorRef) {
7589
7629
  return `zero doctor permission-change ${connectorRef} --permission ${UNKNOWN_PERMISSION_GRANT} --enable --duration 1h`;
7590
7630
  }
7591
- async function resolvePermissionFromUrl(connectorType, label, method, relativePath, matchedBase, routingConfig, networkPolicies, configuredForRun) {
7631
+ function matchedPermissionsFromDecision(decision) {
7632
+ if (decision.kind === "allow") {
7633
+ return decision.permission === void 0 ? [] : [decision.permission];
7634
+ }
7635
+ if (decision.kind === "block" && decision.reason === "permission_denied") {
7636
+ return [...decision.permissions];
7637
+ }
7638
+ return [];
7639
+ }
7640
+ function printMatchedPermissionsSummary(method, relativePath, decision) {
7641
+ const matchedPermissions = matchedPermissionsFromDecision(decision);
7642
+ if (matchedPermissions.length > 0) {
7643
+ console.log(`Matched permissions: [${matchedPermissions.join(", ")}]`);
7644
+ return;
7645
+ }
7646
+ if (decision.kind === "allow" || decision.kind === "block" && decision.reason === "unknown_endpoint") {
7647
+ console.log(
7648
+ `No named permission matches ${method} ${relativePath}. This request falls through to the unknown-endpoint policy.`
7649
+ );
7650
+ return;
7651
+ }
7652
+ if (decision.kind === "no_match") {
7653
+ console.log(
7654
+ "No connector firewall base matched this request during final permission evaluation."
7655
+ );
7656
+ return;
7657
+ }
7658
+ if (decision.reason === "malformed_firewall_config") {
7659
+ console.log(
7660
+ "Permission matching could not complete because the matched firewall config is malformed."
7661
+ );
7662
+ return;
7663
+ }
7664
+ if (decision.reason === "malformed_network_policy") {
7665
+ console.log(
7666
+ "Permission matching could not complete because the matched network policy is malformed."
7667
+ );
7668
+ return;
7669
+ }
7670
+ console.log(
7671
+ "Permission matching could not complete because the request path contains unsafe path syntax."
7672
+ );
7673
+ }
7674
+ function printAllowedPermissionResult(permission, connectorPolicies) {
7675
+ if (connectorPolicies.allow.includes(permission)) {
7676
+ console.log(`Result: "${permission}" is in the allow list \u2014 allowed.`);
7677
+ return;
7678
+ }
7679
+ console.log(
7680
+ `Result: "${permission}" is not blocked by the deny or ask list \u2014 allowed.`
7681
+ );
7682
+ }
7683
+ function printDeniedPermissionResult(permission, connectorPolicies) {
7684
+ if (connectorPolicies.deny.includes(permission)) {
7685
+ console.log(`Result: "${permission}" is in the deny list \u2014 denied.`);
7686
+ return;
7687
+ }
7688
+ if (connectorPolicies.ask.includes(permission)) {
7689
+ console.log(`Result: "${permission}" is in the ask list \u2014 blocked.`);
7690
+ return;
7691
+ }
7692
+ console.log(`Result: "${permission}" is blocked by permission policy.`);
7693
+ }
7694
+ function printFirewallDecisionResult(connectorType, decision, connectorPolicies) {
7695
+ if (decision.kind === "allow") {
7696
+ if (decision.permission === void 0) {
7697
+ console.log(
7698
+ "Result: No permission matched. The unknown endpoint policy applies: allow."
7699
+ );
7700
+ return;
7701
+ }
7702
+ printAllowedPermissionResult(decision.permission, connectorPolicies);
7703
+ return;
7704
+ }
7705
+ if (decision.kind === "no_match") {
7706
+ console.log("Result: No connector firewall base matched this request.");
7707
+ return;
7708
+ }
7709
+ switch (decision.reason) {
7710
+ case "permission_denied":
7711
+ for (const permission of decision.permissions) {
7712
+ printDeniedPermissionResult(permission, connectorPolicies);
7713
+ }
7714
+ return;
7715
+ case "unknown_endpoint":
7716
+ console.log(
7717
+ `Result: No permission matched. The unknown endpoint policy applies: ${connectorPolicies.unknownPolicy}.`
7718
+ );
7719
+ console.log(
7720
+ `To allow unknown endpoints, run: ${unknownPermissionChangeCommand(connectorType)}`
7721
+ );
7722
+ return;
7723
+ case "malformed_firewall_config":
7724
+ console.log(
7725
+ "Result: The matched firewall config is malformed, so the request is blocked."
7726
+ );
7727
+ return;
7728
+ case "malformed_network_policy":
7729
+ console.log(
7730
+ "Result: The matched network policy is malformed, so the request is blocked."
7731
+ );
7732
+ return;
7733
+ case "unsafe_path":
7734
+ console.log(
7735
+ "Result: The request path contains unsafe path syntax, so the request is blocked."
7736
+ );
7737
+ return;
7738
+ }
7739
+ }
7740
+ async function resolvePermissionFromUrl(connectorType, label, method, url, relativePath, matchedBase, routingConfig, networkPolicies, configuredForRun) {
7592
7741
  console.log("## Step 3: Permission policy check (auto-detected from URL)");
7593
7742
  console.log("");
7594
7743
  console.log(
@@ -7607,19 +7756,13 @@ async function resolvePermissionFromUrl(connectorType, label, method, relativePa
7607
7756
  console.log("");
7608
7757
  return;
7609
7758
  }
7610
- const matchedPermissions = findMatchingRoutingPermissions(
7759
+ const decision = matchFirewallRequestDecision(
7760
+ routingConfigToDecisionFirewalls(config),
7611
7761
  method,
7612
- relativePath,
7613
- config.apis,
7614
- { apiBase: matchedBase }
7762
+ url,
7763
+ networkPolicies
7615
7764
  );
7616
- if (matchedPermissions.length === 0) {
7617
- console.log(
7618
- `No named permission matches ${method} ${relativePath}. This request falls through to the unknown-endpoint policy.`
7619
- );
7620
- } else {
7621
- console.log(`Matched permissions: [${matchedPermissions.join(", ")}]`);
7622
- }
7765
+ printMatchedPermissionsSummary(method, relativePath, decision);
7623
7766
  console.log("");
7624
7767
  if (!networkPolicies) {
7625
7768
  console.log(
@@ -7649,32 +7792,10 @@ async function resolvePermissionFromUrl(connectorType, label, method, relativePa
7649
7792
  console.log(`Permission policies for the ${label} connector:`);
7650
7793
  console.log(` allow list: [${connectorPolicies.allow.join(", ")}]`);
7651
7794
  console.log(` deny list: [${connectorPolicies.deny.join(", ")}]`);
7795
+ console.log(` ask list: [${connectorPolicies.ask.join(", ")}]`);
7652
7796
  console.log(` unknown endpoint policy: ${connectorPolicies.unknownPolicy}`);
7653
7797
  console.log("");
7654
- if (matchedPermissions.length === 0) {
7655
- console.log(
7656
- `Result: No permission matched. The unknown endpoint policy applies: ${connectorPolicies.unknownPolicy}.`
7657
- );
7658
- if (connectorPolicies.unknownPolicy !== "allow") {
7659
- console.log(
7660
- `To allow unknown endpoints, run: ${unknownPermissionChangeCommand(connectorType)}`
7661
- );
7662
- }
7663
- } else {
7664
- for (const perm of matchedPermissions) {
7665
- const isInAllow = connectorPolicies.allow.includes(perm);
7666
- const isInDeny = connectorPolicies.deny.includes(perm);
7667
- if (isInAllow) {
7668
- console.log(`Result: "${perm}" is in the allow list \u2014 allowed.`);
7669
- } else if (isInDeny) {
7670
- console.log(`Result: "${perm}" is in the deny list \u2014 denied.`);
7671
- } else {
7672
- console.log(
7673
- `Result: "${perm}" is not in any list \u2014 falls through to unknown endpoint policy: ${connectorPolicies.unknownPolicy}.`
7674
- );
7675
- }
7676
- }
7677
- }
7798
+ printFirewallDecisionResult(connectorType, decision, connectorPolicies);
7678
7799
  console.log("");
7679
7800
  }
7680
7801
  var checkConnectorCommand = new Command().name("check-connector").description(
@@ -7739,13 +7860,14 @@ How connectors work:
7739
7860
  }
7740
7861
  if (!urlLookup) {
7741
7862
  throw new Error(
7742
- `No connector found for URL: ${opts.url} \u2014 no registered base URL matches this URL`
7863
+ "No connector found for provided URL \u2014 no registered base URL matches this URL"
7743
7864
  );
7744
7865
  }
7866
+ const displayUrl = stripUrlQueryAndFragment(opts.url);
7745
7867
  connectorType = urlLookup.connectorType;
7746
7868
  envName = opts.envName ?? urlLookup.envName;
7747
7869
  console.log(
7748
- `URL ${opts.url} matches the ${CONNECTOR_TYPES[connectorType].label} connector (type: ${connectorType}).`
7870
+ `URL ${displayUrl} matches the ${CONNECTOR_TYPES[connectorType].label} connector (type: ${connectorType}).`
7749
7871
  );
7750
7872
  console.log(` Matched base URL: ${urlLookup.matchedBase}`);
7751
7873
  console.log(` Relative path: ${urlLookup.relativePath}`);
@@ -7794,11 +7916,13 @@ How connectors work:
7794
7916
  );
7795
7917
  }
7796
7918
  console.log("");
7797
- if (urlLookup) {
7919
+ const diagnosedUrl = opts.url;
7920
+ if (urlLookup && diagnosedUrl) {
7798
7921
  await resolvePermissionFromUrl(
7799
7922
  connectorType,
7800
7923
  label,
7801
7924
  opts.method,
7925
+ diagnosedUrl,
7802
7926
  urlLookup.relativePath,
7803
7927
  urlLookup.matchedBase,
7804
7928
  urlLookup.routingConfig,
@@ -7816,15 +7940,15 @@ How connectors work:
7816
7940
  }
7817
7941
  const args = [];
7818
7942
  if (opts.url) {
7819
- args.push(`--url ${opts.url}`);
7943
+ args.push(`--url ${shellQuoteArg(stripUrlQueryAndFragment(opts.url))}`);
7820
7944
  if (opts.method !== "GET") {
7821
- args.push(`--method ${opts.method}`);
7945
+ args.push(`--method ${shellQuoteArg(opts.method)}`);
7822
7946
  }
7823
7947
  } else {
7824
- args.push(`--env-name ${envName}`);
7948
+ args.push(`--env-name ${shellQuoteArg(envName)}`);
7825
7949
  }
7826
7950
  if (opts.checkPermission) {
7827
- args.push(`--check-permission ${opts.checkPermission}`);
7951
+ args.push(`--check-permission ${shellQuoteArg(opts.checkPermission)}`);
7828
7952
  }
7829
7953
  console.log(
7830
7954
  `To re-diagnose after changes, run: zero doctor check-connector ${args.join(" ")}`
@@ -7990,7 +8114,7 @@ function hostnameMatchesConnectorRef(url, connectorRef) {
7990
8114
  if (labels.length < 2) return false;
7991
8115
  return hostLabelMatchesConnectorRef(labels[labels.length - 2], connectorRef);
7992
8116
  }
7993
- function stripUrlQueryAndFragment(url) {
8117
+ function stripUrlQueryAndFragment2(url) {
7994
8118
  const queryIndex = url.indexOf("?");
7995
8119
  const fragmentIndex = url.indexOf("#");
7996
8120
  let end = url.length;
@@ -7998,8 +8122,11 @@ function stripUrlQueryAndFragment(url) {
7998
8122
  if (fragmentIndex !== -1) end = Math.min(end, fragmentIndex);
7999
8123
  return url.slice(0, end);
8000
8124
  }
8125
+ function stripTrailingSlash(value) {
8126
+ return value.endsWith("/") ? value.slice(0, -1) : value;
8127
+ }
8001
8128
  function rawPathFromDeniedUrl(url) {
8002
- const urlWithoutQuery = stripUrlQueryAndFragment(url);
8129
+ const urlWithoutQuery = stripUrlQueryAndFragment2(url);
8003
8130
  const schemeEnd = urlWithoutQuery.indexOf("://");
8004
8131
  const authorityStart = schemeEnd === -1 ? 0 : schemeEnd + 3;
8005
8132
  const pathStart = urlWithoutQuery.indexOf("/", authorityStart);
@@ -8010,6 +8137,7 @@ function matchApiBaseUrl(url, apiBase) {
8010
8137
  if (directMatch) {
8011
8138
  return {
8012
8139
  apiBase,
8140
+ decisionBase: apiBase,
8013
8141
  displayBase: directMatch.displayBase,
8014
8142
  relativePath: directMatch.relativePath,
8015
8143
  score: directMatch.score
@@ -8021,6 +8149,7 @@ function matchApiBaseUrl(url, apiBase) {
8021
8149
  if (resolvedMatch) {
8022
8150
  return {
8023
8151
  apiBase,
8152
+ decisionBase: resolvedBase,
8024
8153
  displayBase: resolvedMatch.displayBase,
8025
8154
  relativePath: resolvedMatch.relativePath,
8026
8155
  score: resolvedMatch.score
@@ -8034,6 +8163,7 @@ function matchApiBaseUrl(url, apiBase) {
8034
8163
  if (!patternMatch) return null;
8035
8164
  return {
8036
8165
  apiBase,
8166
+ decisionBase: patternBase,
8037
8167
  displayBase: apiBase,
8038
8168
  relativePath: patternMatch.relativePath,
8039
8169
  score: patternMatch.score
@@ -8057,11 +8187,76 @@ function findBestBaseMatch(url, deniedUrl, connectorRef, apis) {
8057
8187
  const api = unresolvedWholeBaseApis[0];
8058
8188
  return {
8059
8189
  apiBase: api.base,
8190
+ decisionBase: deniedUrl.origin,
8060
8191
  displayBase: api.base,
8061
8192
  relativePath: rawPathFromDeniedUrl(url),
8062
8193
  score: 0
8063
8194
  };
8064
8195
  }
8196
+ function routesForMatchedBase(apis, apiBase) {
8197
+ const normalizedApiBase = stripTrailingSlash(apiBase);
8198
+ const routes = [];
8199
+ for (const api of apis) {
8200
+ if (stripTrailingSlash(api.base) === normalizedApiBase) {
8201
+ routes.push(...api.routes);
8202
+ }
8203
+ }
8204
+ return routes;
8205
+ }
8206
+ function routesToDecisionPermissions2(routes) {
8207
+ const rulesByPermission = /* @__PURE__ */ new Map();
8208
+ for (const route of routes) {
8209
+ const rules = rulesByPermission.get(route.permissionName);
8210
+ if (rules) {
8211
+ rules.push(route.rule);
8212
+ } else {
8213
+ rulesByPermission.set(route.permissionName, [route.rule]);
8214
+ }
8215
+ }
8216
+ return [...rulesByPermission.entries()].map(([name, rules]) => {
8217
+ return { name, rules };
8218
+ });
8219
+ }
8220
+ function buildDecisionFirewall(connectorRef, base, permissions) {
8221
+ return [
8222
+ {
8223
+ name: connectorRef,
8224
+ apis: [
8225
+ {
8226
+ base,
8227
+ auth: {},
8228
+ permissions
8229
+ }
8230
+ ]
8231
+ }
8232
+ ];
8233
+ }
8234
+ function buildAllDeniedNetworkPolicies(connectorRef, permissions) {
8235
+ return {
8236
+ [connectorRef]: {
8237
+ allow: [],
8238
+ deny: permissions.map((permission) => {
8239
+ return permission.name;
8240
+ }),
8241
+ ask: [],
8242
+ unknownPolicy: "deny"
8243
+ }
8244
+ };
8245
+ }
8246
+ function findDeniedDecisionPermissions(connectorRef, method, url, match, apis) {
8247
+ const routes = routesForMatchedBase(apis, match.apiBase);
8248
+ const permissions = routesToDecisionPermissions2(routes);
8249
+ const decision = matchFirewallRequestDecision(
8250
+ buildDecisionFirewall(connectorRef, match.decisionBase, permissions),
8251
+ method,
8252
+ url,
8253
+ buildAllDeniedNetworkPolicies(connectorRef, permissions)
8254
+ );
8255
+ if (decision.kind !== "block" || decision.reason !== "permission_denied") {
8256
+ return [];
8257
+ }
8258
+ return [...decision.permissions];
8259
+ }
8065
8260
  function printPermissionChangeGuidance(connectorRef, permissions) {
8066
8261
  const sortedPermissions = [...permissions].sort();
8067
8262
  if (sortedPermissions.length === 1) {
@@ -8146,11 +8341,12 @@ Notes:
8146
8341
  `No registered ${label} base URL matches the provided URL.`
8147
8342
  );
8148
8343
  }
8149
- const permissions = findMatchingRoutingPermissions(
8344
+ const permissions = findDeniedDecisionPermissions(
8345
+ connectorRef,
8150
8346
  method,
8151
- match.relativePath,
8152
- metadata.apis,
8153
- { apiBase: match.apiBase, serviceName: connectorRef }
8347
+ opts.url,
8348
+ match,
8349
+ metadata.apis
8154
8350
  );
8155
8351
  console.log(
8156
8352
  `The ${label} permission filtered ${method} ${match.relativePath} relative to base URL ${match.displayBase}.`
@@ -8449,4 +8645,4 @@ Notes:
8449
8645
  export {
8450
8646
  zeroDoctorCommand
8451
8647
  };
8452
- //# sourceMappingURL=doctor-EYR3IG4Y.js.map
8648
+ //# sourceMappingURL=doctor-F5ETPBLW.js.map