@vm0/cli 9.215.1 → 9.215.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/{agent-H6EHGFPZ.js → agent-AZQKRG4B.js} +4 -4
- package/{automation-QV3AWLCI.js → automation-ZIEV4Q72.js} +2 -2
- package/{banking-HZVGHSLM.js → banking-2CDU223M.js} +2 -2
- package/{chunk-LRUD7ROI.js → chunk-2MYK53HJ.js} +2 -2
- package/{chunk-L6GC6AUS.js → chunk-DMAXHLSM.js} +25 -5
- package/chunk-DMAXHLSM.js.map +1 -0
- package/{chunk-PSFY2ETN.js → chunk-EWITRIWZ.js} +2 -2
- package/{chunk-R2HX7TVW.js → chunk-GBGNRPZ5.js} +3 -3
- package/{chunk-A6UR5VOC.js → chunk-LCMCP2WQ.js} +2 -2
- package/{chunk-ZXOCKNRI.js → chunk-QE6HJUL2.js} +3 -3
- package/{chunk-KZJ4S6U5.js → chunk-RVZTMBZ7.js} +2 -2
- package/{chunk-DQDALBWF.js → chunk-SS5WCV7W.js} +13 -7
- package/{chunk-DQDALBWF.js.map → chunk-SS5WCV7W.js.map} +1 -1
- package/{chunk-INN5SRMT.js → chunk-WL7EL2UG.js} +2 -2
- package/{computer-use-ZKUBXP6V.js → computer-use-AZPPQK7I.js} +2 -2
- package/{connector-ZSGIGADY.js → connector-NADUUXPW.js} +3 -3
- package/{credit-VMJYM4DD.js → credit-JHOMWMFK.js} +2 -2
- package/{developer-support-EVU3TTCS.js → developer-support-U7JULAYC.js} +2 -2
- package/{doctor-NL5HUJ6F.js → doctor-A7V3ZJEY.js} +272 -33
- package/doctor-A7V3ZJEY.js.map +1 -0
- package/{generate-KNCZMJNB.js → generate-2SJTN5W2.js} +3 -3
- package/{github-2MLRXIUS.js → github-GRU4EHAJ.js} +2 -2
- package/{goal-JWNBPZMQ.js → goal-GURJHZXL.js} +2 -2
- package/{host-XCU3JVEP.js → host-GYT2IEH4.js} +2 -2
- package/index.js +13 -13
- package/{logs-VLNWK6EJ.js → logs-N3PNIAGS.js} +6 -6
- package/{maps-UUYNXLCH.js → maps-D5QH3GHE.js} +2 -2
- package/{model-XQ6PKJLP.js → model-MM25EQUD.js} +3 -3
- package/{model-provider-ZDVTD7R5.js → model-provider-5OZ222EJ.js} +3 -3
- package/{org-IFSQQBDR.js → org-QBMRMNB4.js} +2 -2
- package/package.json +1 -1
- package/{phone-KCBQJ424.js → phone-FXXNTGIC.js} +2 -2
- package/{preference-2L2WBMTL.js → preference-KHMX4NLR.js} +2 -2
- package/{resource-WLS4LTR3.js → resource-EZHY7PAW.js} +2 -2
- package/{search-6NLSGHYB.js → search-PXKNMVKT.js} +6 -6
- package/{secret-3ZXJAPVT.js → secret-Y32Q5NUL.js} +3 -3
- package/{slack-QIMOKJW4.js → slack-DTGXXB4X.js} +2 -2
- package/{telegram-HYFTWR3Y.js → telegram-SXAGLUSM.js} +2 -2
- package/{variable-BJEI7JVT.js → variable-POHEUC5N.js} +2 -2
- package/{web-T4YMNTPC.js → web-NHHGB5F5.js} +2 -2
- package/{whoami-NTKQA7XK.js → whoami-QVS4BRD6.js} +4 -4
- package/{workflow-Q6PLLIZ3.js → workflow-65JJ6IXI.js} +2 -2
- package/zero.js +30 -30
- package/chunk-L6GC6AUS.js.map +0 -1
- package/doctor-NL5HUJ6F.js.map +0 -1
- /package/{agent-H6EHGFPZ.js.map → agent-AZQKRG4B.js.map} +0 -0
- /package/{automation-QV3AWLCI.js.map → automation-ZIEV4Q72.js.map} +0 -0
- /package/{banking-HZVGHSLM.js.map → banking-2CDU223M.js.map} +0 -0
- /package/{chunk-LRUD7ROI.js.map → chunk-2MYK53HJ.js.map} +0 -0
- /package/{chunk-PSFY2ETN.js.map → chunk-EWITRIWZ.js.map} +0 -0
- /package/{chunk-R2HX7TVW.js.map → chunk-GBGNRPZ5.js.map} +0 -0
- /package/{chunk-A6UR5VOC.js.map → chunk-LCMCP2WQ.js.map} +0 -0
- /package/{chunk-ZXOCKNRI.js.map → chunk-QE6HJUL2.js.map} +0 -0
- /package/{chunk-KZJ4S6U5.js.map → chunk-RVZTMBZ7.js.map} +0 -0
- /package/{chunk-INN5SRMT.js.map → chunk-WL7EL2UG.js.map} +0 -0
- /package/{computer-use-ZKUBXP6V.js.map → computer-use-AZPPQK7I.js.map} +0 -0
- /package/{connector-ZSGIGADY.js.map → connector-NADUUXPW.js.map} +0 -0
- /package/{credit-VMJYM4DD.js.map → credit-JHOMWMFK.js.map} +0 -0
- /package/{developer-support-EVU3TTCS.js.map → developer-support-U7JULAYC.js.map} +0 -0
- /package/{generate-KNCZMJNB.js.map → generate-2SJTN5W2.js.map} +0 -0
- /package/{github-2MLRXIUS.js.map → github-GRU4EHAJ.js.map} +0 -0
- /package/{goal-JWNBPZMQ.js.map → goal-GURJHZXL.js.map} +0 -0
- /package/{host-XCU3JVEP.js.map → host-GYT2IEH4.js.map} +0 -0
- /package/{logs-VLNWK6EJ.js.map → logs-N3PNIAGS.js.map} +0 -0
- /package/{maps-UUYNXLCH.js.map → maps-D5QH3GHE.js.map} +0 -0
- /package/{model-XQ6PKJLP.js.map → model-MM25EQUD.js.map} +0 -0
- /package/{model-provider-ZDVTD7R5.js.map → model-provider-5OZ222EJ.js.map} +0 -0
- /package/{org-IFSQQBDR.js.map → org-QBMRMNB4.js.map} +0 -0
- /package/{phone-KCBQJ424.js.map → phone-FXXNTGIC.js.map} +0 -0
- /package/{preference-2L2WBMTL.js.map → preference-KHMX4NLR.js.map} +0 -0
- /package/{resource-WLS4LTR3.js.map → resource-EZHY7PAW.js.map} +0 -0
- /package/{search-6NLSGHYB.js.map → search-PXKNMVKT.js.map} +0 -0
- /package/{secret-3ZXJAPVT.js.map → secret-Y32Q5NUL.js.map} +0 -0
- /package/{slack-QIMOKJW4.js.map → slack-DTGXXB4X.js.map} +0 -0
- /package/{telegram-HYFTWR3Y.js.map → telegram-SXAGLUSM.js.map} +0 -0
- /package/{variable-BJEI7JVT.js.map → variable-POHEUC5N.js.map} +0 -0
- /package/{web-T4YMNTPC.js.map → web-NHHGB5F5.js.map} +0 -0
- /package/{whoami-NTKQA7XK.js.map → whoami-QVS4BRD6.js.map} +0 -0
- /package/{workflow-Q6PLLIZ3.js.map → workflow-65JJ6IXI.js.map} +0 -0
|
@@ -3,7 +3,7 @@ import { createRequire as __createRequire } from "node:module";
|
|
|
3
3
|
const require = __createRequire(import.meta.url);
|
|
4
4
|
import {
|
|
5
5
|
UNKNOWN_PERMISSION_GRANT
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-DMAXHLSM.js";
|
|
7
7
|
import {
|
|
8
8
|
init_esm_shims
|
|
9
9
|
} from "./chunk-DIRAZ3YX.js";
|
|
@@ -3078,4 +3078,4 @@ export {
|
|
|
3078
3078
|
resolveFirewallMetadataPolicies,
|
|
3079
3079
|
permissionGrantsToFirewallPolicies
|
|
3080
3080
|
};
|
|
3081
|
-
//# sourceMappingURL=chunk-
|
|
3081
|
+
//# sourceMappingURL=chunk-WL7EL2UG.js.map
|
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
createComputerUseWriteCommand,
|
|
7
7
|
fetchComputerUseScreenshot,
|
|
8
8
|
getComputerUseCommand
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-DMAXHLSM.js";
|
|
10
10
|
import {
|
|
11
11
|
ApiRequestError,
|
|
12
12
|
withErrorHandler
|
|
@@ -472,4 +472,4 @@ export {
|
|
|
472
472
|
formatComputerUseResultForConsole,
|
|
473
473
|
zeroComputerUseCommand
|
|
474
474
|
};
|
|
475
|
-
//# sourceMappingURL=computer-use-
|
|
475
|
+
//# sourceMappingURL=computer-use-AZPPQK7I.js.map
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
getConnectorAuthMethodScopeDiff,
|
|
14
14
|
getConnectorEnvBindingEntries,
|
|
15
15
|
hasRequiredConnectorAuthMethodScopes
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-2MYK53HJ.js";
|
|
17
17
|
import {
|
|
18
18
|
CONNECTOR_TYPES,
|
|
19
19
|
CONNECTOR_TYPE_KEYS,
|
|
@@ -28,7 +28,7 @@ import {
|
|
|
28
28
|
listZeroConnectors,
|
|
29
29
|
listZeroCustomConnectors,
|
|
30
30
|
searchZeroConnectors
|
|
31
|
-
} from "./chunk-
|
|
31
|
+
} from "./chunk-DMAXHLSM.js";
|
|
32
32
|
import "./chunk-LTDQISD7.js";
|
|
33
33
|
import {
|
|
34
34
|
withErrorHandler
|
|
@@ -845,4 +845,4 @@ var zeroConnectorCommand = new Command().name("connector").description("Check th
|
|
|
845
845
|
export {
|
|
846
846
|
zeroConnectorCommand
|
|
847
847
|
};
|
|
848
|
-
//# sourceMappingURL=connector-
|
|
848
|
+
//# sourceMappingURL=connector-NADUUXPW.js.map
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
import {
|
|
8
8
|
createZeroCreditCheckout,
|
|
9
9
|
getZeroOrgMembers
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-DMAXHLSM.js";
|
|
11
11
|
import "./chunk-LTDQISD7.js";
|
|
12
12
|
import {
|
|
13
13
|
withErrorHandler
|
|
@@ -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-
|
|
90
|
+
//# sourceMappingURL=credit-JHOMWMFK.js.map
|
|
@@ -4,7 +4,7 @@ const require = __createRequire(import.meta.url);
|
|
|
4
4
|
import {
|
|
5
5
|
requestDeveloperSupportConsent,
|
|
6
6
|
submitDeveloperSupport
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-DMAXHLSM.js";
|
|
8
8
|
import "./chunk-LTDQISD7.js";
|
|
9
9
|
import {
|
|
10
10
|
withErrorHandler
|
|
@@ -61,4 +61,4 @@ Notes:
|
|
|
61
61
|
export {
|
|
62
62
|
zeroDeveloperSupportCommand
|
|
63
63
|
};
|
|
64
|
-
//# sourceMappingURL=developer-support-
|
|
64
|
+
//# sourceMappingURL=developer-support-U7JULAYC.js.map
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
findFirewallMetadataPermission,
|
|
6
6
|
getFirewallPermissionSummary,
|
|
7
7
|
loadFirewallPermissionMetadata
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-WL7EL2UG.js";
|
|
9
9
|
import {
|
|
10
10
|
getPlatformOrigin,
|
|
11
11
|
toPlatformUrl
|
|
@@ -13,11 +13,11 @@ import {
|
|
|
13
13
|
import {
|
|
14
14
|
findMatchingRoutingPermissions,
|
|
15
15
|
matchFirewallBaseUrl
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-LCMCP2WQ.js";
|
|
17
17
|
import {
|
|
18
18
|
getConnectorEnvBindingEntries,
|
|
19
19
|
getDiagnosticConnectorTypeForRuntimeEnvName
|
|
20
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-2MYK53HJ.js";
|
|
21
21
|
import {
|
|
22
22
|
CONNECTOR_TYPES,
|
|
23
23
|
UNKNOWN_PERMISSION_GRANT,
|
|
@@ -28,9 +28,10 @@ import {
|
|
|
28
28
|
getZeroOrg,
|
|
29
29
|
getZeroOrgMembers,
|
|
30
30
|
getZeroRunContext,
|
|
31
|
+
hasUnsafeFirewallPath,
|
|
31
32
|
resolveFirewallBaseUrlTemplate,
|
|
32
33
|
searchZeroConnectors
|
|
33
|
-
} from "./chunk-
|
|
34
|
+
} from "./chunk-DMAXHLSM.js";
|
|
34
35
|
import "./chunk-LTDQISD7.js";
|
|
35
36
|
import {
|
|
36
37
|
ApiRequestError,
|
|
@@ -7803,8 +7804,9 @@ init_esm_shims();
|
|
|
7803
7804
|
var COMPUTER_USE_CONNECTOR_REF = "computer-use";
|
|
7804
7805
|
var COMPUTER_USE_CAPABILITY = "computer-use:write";
|
|
7805
7806
|
var COMPUTER_USE_PATH_PREFIX = "/computer-use";
|
|
7807
|
+
var COMPUTER_USE_PATH_PREFIX_WITH_SLASH = `${COMPUTER_USE_PATH_PREFIX}/`;
|
|
7806
7808
|
function isComputerUsePermissionTarget(target) {
|
|
7807
|
-
return target.connectorRef === COMPUTER_USE_CONNECTOR_REF || target.permission === COMPUTER_USE_CAPABILITY || target.path?.startsWith(
|
|
7809
|
+
return target.connectorRef === COMPUTER_USE_CONNECTOR_REF || target.permission === COMPUTER_USE_CAPABILITY || target.path === COMPUTER_USE_PATH_PREFIX || target.path?.startsWith(COMPUTER_USE_PATH_PREFIX_WITH_SLASH) === true;
|
|
7808
7810
|
}
|
|
7809
7811
|
function printComputerUsePermissionGuidance() {
|
|
7810
7812
|
console.log("Computer Use access is not managed as a connector permission.");
|
|
@@ -7823,6 +7825,226 @@ function printComputerUsePermissionGuidance() {
|
|
|
7823
7825
|
function unknownPermissionChangeCommand2(connectorRef) {
|
|
7824
7826
|
return `zero doctor permission-change ${connectorRef} --permission ${UNKNOWN_PERMISSION_GRANT} --enable --duration 1h`;
|
|
7825
7827
|
}
|
|
7828
|
+
var BASE_URL_VAR_PATTERN = /\$\{\{\s*vars\.([a-zA-Z_][a-zA-Z0-9_]*)\s*\}\}/g;
|
|
7829
|
+
var WHOLE_BASE_URL_VAR_PATTERN = /^\$\{\{\s*vars\.([a-zA-Z_][a-zA-Z0-9_]*)\s*\}\}$/;
|
|
7830
|
+
var VALID_DENIED_METHODS = /* @__PURE__ */ new Set([
|
|
7831
|
+
"GET",
|
|
7832
|
+
"POST",
|
|
7833
|
+
"PUT",
|
|
7834
|
+
"PATCH",
|
|
7835
|
+
"DELETE",
|
|
7836
|
+
"HEAD",
|
|
7837
|
+
"OPTIONS"
|
|
7838
|
+
]);
|
|
7839
|
+
function pathOnlyError() {
|
|
7840
|
+
return new Error(
|
|
7841
|
+
"permission-deny now requires --url because method/path alone can match the wrong API base."
|
|
7842
|
+
);
|
|
7843
|
+
}
|
|
7844
|
+
function invalidUrlError() {
|
|
7845
|
+
return new Error(
|
|
7846
|
+
"permission-deny requires --url to be a valid absolute http or https URL."
|
|
7847
|
+
);
|
|
7848
|
+
}
|
|
7849
|
+
function invalidMethodError() {
|
|
7850
|
+
return new Error(
|
|
7851
|
+
"permission-deny requires --method to be one of GET, POST, PUT, PATCH, DELETE, HEAD, or OPTIONS."
|
|
7852
|
+
);
|
|
7853
|
+
}
|
|
7854
|
+
function unsafePathError() {
|
|
7855
|
+
return new Error(
|
|
7856
|
+
"permission-deny cannot diagnose unsafe URL paths because they are blocked before permission policy evaluation."
|
|
7857
|
+
);
|
|
7858
|
+
}
|
|
7859
|
+
function parseDeniedMethod(method) {
|
|
7860
|
+
const upperMethod = method.toUpperCase();
|
|
7861
|
+
if (!VALID_DENIED_METHODS.has(upperMethod)) {
|
|
7862
|
+
throw invalidMethodError();
|
|
7863
|
+
}
|
|
7864
|
+
return upperMethod;
|
|
7865
|
+
}
|
|
7866
|
+
function rawAuthorityFromDeniedUrl(url) {
|
|
7867
|
+
const schemeEnd = url.indexOf("://");
|
|
7868
|
+
if (schemeEnd === -1) return null;
|
|
7869
|
+
const authorityStart = schemeEnd + 3;
|
|
7870
|
+
let authorityEnd = url.length;
|
|
7871
|
+
for (const delimiter of ["/", "?", "#"]) {
|
|
7872
|
+
const index = url.indexOf(delimiter, authorityStart);
|
|
7873
|
+
if (index !== -1) authorityEnd = Math.min(authorityEnd, index);
|
|
7874
|
+
}
|
|
7875
|
+
return url.slice(authorityStart, authorityEnd);
|
|
7876
|
+
}
|
|
7877
|
+
function rawAuthorityHasUnsafeSyntax(url) {
|
|
7878
|
+
const authority = rawAuthorityFromDeniedUrl(url);
|
|
7879
|
+
if (authority === null) return false;
|
|
7880
|
+
return authority === "" || authority.includes("\\") || authority.includes("%") || [...authority].some((char) => {
|
|
7881
|
+
return char.charCodeAt(0) > 127;
|
|
7882
|
+
});
|
|
7883
|
+
}
|
|
7884
|
+
function parseDeniedUrl(url) {
|
|
7885
|
+
if (!url.includes("://") || /\s/.test(url) || rawAuthorityHasUnsafeSyntax(url)) {
|
|
7886
|
+
throw invalidUrlError();
|
|
7887
|
+
}
|
|
7888
|
+
try {
|
|
7889
|
+
const parsed = new URL(url);
|
|
7890
|
+
if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
|
|
7891
|
+
throw invalidUrlError();
|
|
7892
|
+
}
|
|
7893
|
+
if (parsed.username !== "" || parsed.password !== "") {
|
|
7894
|
+
throw invalidUrlError();
|
|
7895
|
+
}
|
|
7896
|
+
return parsed;
|
|
7897
|
+
} catch {
|
|
7898
|
+
throw invalidUrlError();
|
|
7899
|
+
}
|
|
7900
|
+
}
|
|
7901
|
+
function baseUrlTemplateVarNames(base) {
|
|
7902
|
+
return [...base.matchAll(BASE_URL_VAR_PATTERN)].map((match) => {
|
|
7903
|
+
return match[1];
|
|
7904
|
+
});
|
|
7905
|
+
}
|
|
7906
|
+
function wholeBaseUrlTemplateVarName(base) {
|
|
7907
|
+
return WHOLE_BASE_URL_VAR_PATTERN.exec(base)?.[1] ?? null;
|
|
7908
|
+
}
|
|
7909
|
+
function resolveBaseUrlTemplateFromEnv(base) {
|
|
7910
|
+
const names = baseUrlTemplateVarNames(base);
|
|
7911
|
+
if (names.length === 0) return base;
|
|
7912
|
+
let missing = false;
|
|
7913
|
+
const resolved = base.replace(
|
|
7914
|
+
BASE_URL_VAR_PATTERN,
|
|
7915
|
+
(_match, name) => {
|
|
7916
|
+
const value = process.env[name];
|
|
7917
|
+
if (!value) {
|
|
7918
|
+
missing = true;
|
|
7919
|
+
return "";
|
|
7920
|
+
}
|
|
7921
|
+
return value;
|
|
7922
|
+
}
|
|
7923
|
+
);
|
|
7924
|
+
return missing ? null : resolved;
|
|
7925
|
+
}
|
|
7926
|
+
function baseUrlTemplateToPattern(base) {
|
|
7927
|
+
if (baseUrlTemplateVarNames(base).length === 0) return null;
|
|
7928
|
+
const pattern = base.replace(BASE_URL_VAR_PATTERN, (_match, name) => {
|
|
7929
|
+
return `{${name}}`;
|
|
7930
|
+
});
|
|
7931
|
+
return pattern.includes("://") ? pattern : null;
|
|
7932
|
+
}
|
|
7933
|
+
function connectorRefHostToken(connectorRef) {
|
|
7934
|
+
return connectorRef.toLowerCase().replaceAll(/[^a-z0-9]/g, "");
|
|
7935
|
+
}
|
|
7936
|
+
function hostLabelToken(label) {
|
|
7937
|
+
return label.toLowerCase().replaceAll(/[^a-z0-9]/g, "");
|
|
7938
|
+
}
|
|
7939
|
+
function hostLabelMatchesConnectorRef(label, connectorRef) {
|
|
7940
|
+
const normalizedConnectorRef = connectorRef.toLowerCase();
|
|
7941
|
+
const token = connectorRefHostToken(connectorRef);
|
|
7942
|
+
const normalizedLabel = label.toLowerCase();
|
|
7943
|
+
if (normalizedConnectorRef === token) {
|
|
7944
|
+
return normalizedLabel === token;
|
|
7945
|
+
}
|
|
7946
|
+
return hostLabelToken(normalizedLabel) === token;
|
|
7947
|
+
}
|
|
7948
|
+
function hostnameMatchesConnectorRef(url, connectorRef) {
|
|
7949
|
+
const token = connectorRefHostToken(connectorRef);
|
|
7950
|
+
if (token.length < 3) return false;
|
|
7951
|
+
const labels = (url.hostname || "").toLowerCase().replace(/\.$/, "").split(".").filter((part) => {
|
|
7952
|
+
return part !== "";
|
|
7953
|
+
});
|
|
7954
|
+
if (labels.length < 2) return false;
|
|
7955
|
+
return hostLabelMatchesConnectorRef(labels[labels.length - 2], connectorRef);
|
|
7956
|
+
}
|
|
7957
|
+
function stripUrlQueryAndFragment(url) {
|
|
7958
|
+
const queryIndex = url.indexOf("?");
|
|
7959
|
+
const fragmentIndex = url.indexOf("#");
|
|
7960
|
+
let end = url.length;
|
|
7961
|
+
if (queryIndex !== -1) end = Math.min(end, queryIndex);
|
|
7962
|
+
if (fragmentIndex !== -1) end = Math.min(end, fragmentIndex);
|
|
7963
|
+
return url.slice(0, end);
|
|
7964
|
+
}
|
|
7965
|
+
function rawPathFromDeniedUrl(url) {
|
|
7966
|
+
const urlWithoutQuery = stripUrlQueryAndFragment(url);
|
|
7967
|
+
const schemeEnd = urlWithoutQuery.indexOf("://");
|
|
7968
|
+
const authorityStart = schemeEnd === -1 ? 0 : schemeEnd + 3;
|
|
7969
|
+
const pathStart = urlWithoutQuery.indexOf("/", authorityStart);
|
|
7970
|
+
return pathStart === -1 ? "/" : urlWithoutQuery.slice(pathStart);
|
|
7971
|
+
}
|
|
7972
|
+
function matchApiBaseUrl(url, apiBase) {
|
|
7973
|
+
const directMatch = matchFirewallBaseUrl(url, apiBase);
|
|
7974
|
+
if (directMatch) {
|
|
7975
|
+
return {
|
|
7976
|
+
apiBase,
|
|
7977
|
+
displayBase: directMatch.displayBase,
|
|
7978
|
+
relativePath: directMatch.relativePath,
|
|
7979
|
+
score: directMatch.score
|
|
7980
|
+
};
|
|
7981
|
+
}
|
|
7982
|
+
const resolvedBase = resolveBaseUrlTemplateFromEnv(apiBase);
|
|
7983
|
+
if (resolvedBase !== null && resolvedBase !== apiBase) {
|
|
7984
|
+
const resolvedMatch = matchFirewallBaseUrl(url, resolvedBase);
|
|
7985
|
+
if (resolvedMatch) {
|
|
7986
|
+
return {
|
|
7987
|
+
apiBase,
|
|
7988
|
+
displayBase: resolvedMatch.displayBase,
|
|
7989
|
+
relativePath: resolvedMatch.relativePath,
|
|
7990
|
+
score: resolvedMatch.score
|
|
7991
|
+
};
|
|
7992
|
+
}
|
|
7993
|
+
return null;
|
|
7994
|
+
}
|
|
7995
|
+
const patternBase = baseUrlTemplateToPattern(apiBase);
|
|
7996
|
+
if (patternBase === null) return null;
|
|
7997
|
+
const patternMatch = matchFirewallBaseUrl(url, patternBase);
|
|
7998
|
+
if (!patternMatch) return null;
|
|
7999
|
+
return {
|
|
8000
|
+
apiBase,
|
|
8001
|
+
displayBase: apiBase,
|
|
8002
|
+
relativePath: patternMatch.relativePath,
|
|
8003
|
+
score: patternMatch.score
|
|
8004
|
+
};
|
|
8005
|
+
}
|
|
8006
|
+
function findBestBaseMatch(url, deniedUrl, connectorRef, apis) {
|
|
8007
|
+
let bestMatch = null;
|
|
8008
|
+
for (const api2 of apis) {
|
|
8009
|
+
const match = matchApiBaseUrl(url, api2.base);
|
|
8010
|
+
if (match && (!bestMatch || match.score > bestMatch.score)) {
|
|
8011
|
+
bestMatch = match;
|
|
8012
|
+
}
|
|
8013
|
+
}
|
|
8014
|
+
if (bestMatch !== null) return bestMatch;
|
|
8015
|
+
const unresolvedWholeBaseApis = apis.filter((api2) => {
|
|
8016
|
+
const name = wholeBaseUrlTemplateVarName(api2.base);
|
|
8017
|
+
return name !== null && !process.env[name];
|
|
8018
|
+
});
|
|
8019
|
+
if (unresolvedWholeBaseApis.length !== 1) return null;
|
|
8020
|
+
if (!hostnameMatchesConnectorRef(deniedUrl, connectorRef)) return null;
|
|
8021
|
+
const api = unresolvedWholeBaseApis[0];
|
|
8022
|
+
return {
|
|
8023
|
+
apiBase: api.base,
|
|
8024
|
+
displayBase: api.base,
|
|
8025
|
+
relativePath: rawPathFromDeniedUrl(url),
|
|
8026
|
+
score: 0
|
|
8027
|
+
};
|
|
8028
|
+
}
|
|
8029
|
+
function printPermissionChangeGuidance(connectorRef, permissions) {
|
|
8030
|
+
const sortedPermissions = [...permissions].sort();
|
|
8031
|
+
if (sortedPermissions.length === 1) {
|
|
8032
|
+
const permission = sortedPermissions[0];
|
|
8033
|
+
console.log(`This is covered by the "${permission}" permission.`);
|
|
8034
|
+
console.log(
|
|
8035
|
+
`To allow this permission, run: zero doctor permission-change ${connectorRef} --permission ${permission} --enable --duration 1h`
|
|
8036
|
+
);
|
|
8037
|
+
return;
|
|
8038
|
+
}
|
|
8039
|
+
console.log(
|
|
8040
|
+
`This is covered by these permissions: ${sortedPermissions.join(", ")}.`
|
|
8041
|
+
);
|
|
8042
|
+
for (const permission of sortedPermissions) {
|
|
8043
|
+
console.log(
|
|
8044
|
+
`To allow ${permission}, run: zero doctor permission-change ${connectorRef} --permission ${permission} --enable --duration 1h`
|
|
8045
|
+
);
|
|
8046
|
+
}
|
|
8047
|
+
}
|
|
7826
8048
|
var permissionDenyCommand = new Command().name("permission-deny").description(
|
|
7827
8049
|
"Diagnose a permission denial and find the permission that covers it"
|
|
7828
8050
|
).argument("<connector-ref>", "The connector type (e.g. github)").addOption(
|
|
@@ -7831,23 +8053,44 @@ var permissionDenyCommand = new Command().name("permission-deny").description(
|
|
|
7831
8053
|
"The denied HTTP method"
|
|
7832
8054
|
).makeOptionMandatory()
|
|
7833
8055
|
).addOption(
|
|
7834
|
-
new Option(
|
|
7835
|
-
|
|
8056
|
+
new Option(
|
|
8057
|
+
"--url <url>",
|
|
8058
|
+
"The denied request URL; query strings are ignored (required)"
|
|
8059
|
+
)
|
|
8060
|
+
).addOption(new Option("--path <path>", "Deprecated: use --url").hideHelp()).addHelpText(
|
|
7836
8061
|
"after",
|
|
7837
8062
|
`
|
|
7838
8063
|
Examples:
|
|
7839
|
-
zero doctor permission-deny github --method GET --
|
|
7840
|
-
zero doctor permission-deny slack --method POST --
|
|
7841
|
-
zero doctor permission-deny
|
|
8064
|
+
zero doctor permission-deny github --method GET --url https://api.github.com/repos/owner/repo/pulls
|
|
8065
|
+
zero doctor permission-deny slack --method POST --url https://slack.com/api/chat.postMessage
|
|
8066
|
+
zero doctor permission-deny youtube --method PUT --url https://youtube.googleapis.com/upload/youtube/v3/videos
|
|
7842
8067
|
|
|
7843
8068
|
Notes:
|
|
7844
8069
|
- Identifies which named permission covers a denied request
|
|
8070
|
+
- If the firewall denial response includes a url field, pass that value to --url
|
|
8071
|
+
- Requires the denied URL origin and path because method/path alone can match the wrong API base
|
|
8072
|
+
- Query strings and fragments are ignored for matching; omit them when they may contain secrets
|
|
7845
8073
|
- Use permission-change to request or enable the permission
|
|
7846
8074
|
- Permission-change enable requests default to --duration 1h; pick 24h, 7d, or always only when appropriate`
|
|
7847
8075
|
).action(
|
|
7848
8076
|
withErrorHandler(
|
|
7849
8077
|
async (connectorRef, opts) => {
|
|
7850
|
-
if (
|
|
8078
|
+
if (opts.path !== void 0) {
|
|
8079
|
+
throw pathOnlyError();
|
|
8080
|
+
}
|
|
8081
|
+
if (!opts.url) {
|
|
8082
|
+
throw pathOnlyError();
|
|
8083
|
+
}
|
|
8084
|
+
const method = parseDeniedMethod(opts.method);
|
|
8085
|
+
const deniedUrl = parseDeniedUrl(opts.url);
|
|
8086
|
+
const deniedPath = rawPathFromDeniedUrl(opts.url);
|
|
8087
|
+
if (hasUnsafeFirewallPath(deniedPath)) {
|
|
8088
|
+
throw unsafePathError();
|
|
8089
|
+
}
|
|
8090
|
+
if (isComputerUsePermissionTarget({
|
|
8091
|
+
connectorRef,
|
|
8092
|
+
path: deniedPath
|
|
8093
|
+
})) {
|
|
7851
8094
|
printComputerUsePermissionGuidance();
|
|
7852
8095
|
return;
|
|
7853
8096
|
}
|
|
@@ -7856,14 +8099,25 @@ Notes:
|
|
|
7856
8099
|
throw new Error(`Unknown connector type: ${connectorRef}`);
|
|
7857
8100
|
}
|
|
7858
8101
|
const label = getFirewallPermissionSummary(connectorRef)?.label ?? connectorRef;
|
|
8102
|
+
const match = findBestBaseMatch(
|
|
8103
|
+
opts.url,
|
|
8104
|
+
deniedUrl,
|
|
8105
|
+
connectorRef,
|
|
8106
|
+
metadata.apis
|
|
8107
|
+
);
|
|
8108
|
+
if (!match) {
|
|
8109
|
+
throw new Error(
|
|
8110
|
+
`No registered ${label} base URL matches the provided URL.`
|
|
8111
|
+
);
|
|
8112
|
+
}
|
|
7859
8113
|
const permissions = findMatchingRoutingPermissions(
|
|
7860
|
-
|
|
7861
|
-
|
|
8114
|
+
method,
|
|
8115
|
+
match.relativePath,
|
|
7862
8116
|
metadata.apis,
|
|
7863
|
-
{ serviceName: connectorRef }
|
|
8117
|
+
{ apiBase: match.apiBase, serviceName: connectorRef }
|
|
7864
8118
|
);
|
|
7865
8119
|
console.log(
|
|
7866
|
-
`The ${label} permission filtered ${
|
|
8120
|
+
`The ${label} permission filtered ${method} ${match.relativePath} relative to base URL ${match.displayBase}.`
|
|
7867
8121
|
);
|
|
7868
8122
|
if (permissions.length === 0) {
|
|
7869
8123
|
console.log("No named permission was found covering this request.");
|
|
@@ -7875,22 +8129,7 @@ Notes:
|
|
|
7875
8129
|
);
|
|
7876
8130
|
return;
|
|
7877
8131
|
}
|
|
7878
|
-
|
|
7879
|
-
for (const api of metadata.apis) {
|
|
7880
|
-
for (const route of api.routes) {
|
|
7881
|
-
ruleCount.set(
|
|
7882
|
-
route.permissionName,
|
|
7883
|
-
(ruleCount.get(route.permissionName) ?? 0) + 1
|
|
7884
|
-
);
|
|
7885
|
-
}
|
|
7886
|
-
}
|
|
7887
|
-
const permission = permissions.reduce((narrowest, current) => {
|
|
7888
|
-
return (ruleCount.get(current) ?? Infinity) < (ruleCount.get(narrowest) ?? Infinity) ? current : narrowest;
|
|
7889
|
-
});
|
|
7890
|
-
console.log(`This is covered by the "${permission}" permission.`);
|
|
7891
|
-
console.log(
|
|
7892
|
-
`To allow this permission, run: zero doctor permission-change ${connectorRef} --permission ${permission} --enable --duration 1h`
|
|
7893
|
-
);
|
|
8132
|
+
printPermissionChangeGuidance(connectorRef, permissions);
|
|
7894
8133
|
}
|
|
7895
8134
|
)
|
|
7896
8135
|
);
|
|
@@ -8161,7 +8400,7 @@ Examples:
|
|
|
8161
8400
|
Check a URL? zero doctor check-connector --url https://api.github.com/repos/owner/repo
|
|
8162
8401
|
Check credits? zero doctor credit
|
|
8163
8402
|
Check with permission? zero doctor check-connector --env-name SLACK_TOKEN --check-permission chat:write
|
|
8164
|
-
Permission denied? zero doctor permission-deny github --method GET --
|
|
8403
|
+
Permission denied? zero doctor permission-deny github --method GET --url https://api.github.com/repos/owner/repo
|
|
8165
8404
|
Change a permission? zero doctor permission-change github --permission contents:read --enable --duration 1h
|
|
8166
8405
|
Disable unknown URLs? zero doctor permission-change cloudflare --permission __unknown__ --disable
|
|
8167
8406
|
|
|
@@ -8174,4 +8413,4 @@ Notes:
|
|
|
8174
8413
|
export {
|
|
8175
8414
|
zeroDoctorCommand
|
|
8176
8415
|
};
|
|
8177
|
-
//# sourceMappingURL=doctor-
|
|
8416
|
+
//# sourceMappingURL=doctor-A7V3ZJEY.js.map
|