sfcc-dev-mcp 1.0.21 → 1.0.22
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/README.md +79 -30
- package/dist/clients/agent-instructions-client.d.ts +3 -0
- package/dist/clients/agent-instructions-client.d.ts.map +1 -1
- package/dist/clients/agent-instructions-client.js +42 -10
- package/dist/clients/agent-instructions-client.js.map +1 -1
- package/dist/clients/base/abstract-documentation-client.d.ts +4 -0
- package/dist/clients/base/abstract-documentation-client.d.ts.map +1 -1
- package/dist/clients/base/abstract-documentation-client.js +9 -1
- package/dist/clients/base/abstract-documentation-client.js.map +1 -1
- package/dist/clients/base/http-client.d.ts +10 -3
- package/dist/clients/base/http-client.d.ts.map +1 -1
- package/dist/clients/base/http-client.js +94 -16
- package/dist/clients/base/http-client.js.map +1 -1
- package/dist/clients/base/oauth-token.d.ts +3 -0
- package/dist/clients/base/oauth-token.d.ts.map +1 -1
- package/dist/clients/base/oauth-token.js +23 -3
- package/dist/clients/base/oauth-token.js.map +1 -1
- package/dist/clients/base/ocapi-auth-client.d.ts.map +1 -1
- package/dist/clients/base/ocapi-auth-client.js +22 -2
- package/dist/clients/base/ocapi-auth-client.js.map +1 -1
- package/dist/clients/docs/class-name-resolver.d.ts +7 -4
- package/dist/clients/docs/class-name-resolver.d.ts.map +1 -1
- package/dist/clients/docs/class-name-resolver.js.map +1 -1
- package/dist/clients/docs/documentation-scanner.d.ts +2 -0
- package/dist/clients/docs/documentation-scanner.d.ts.map +1 -1
- package/dist/clients/docs/documentation-scanner.js +39 -17
- package/dist/clients/docs/documentation-scanner.js.map +1 -1
- package/dist/clients/docs-client.d.ts +4 -3
- package/dist/clients/docs-client.d.ts.map +1 -1
- package/dist/clients/docs-client.js.map +1 -1
- package/dist/clients/logs/log-client.d.ts +1 -0
- package/dist/clients/logs/log-client.d.ts.map +1 -1
- package/dist/clients/logs/log-client.js +13 -21
- package/dist/clients/logs/log-client.js.map +1 -1
- package/dist/clients/logs/log-file-discovery.d.ts +1 -0
- package/dist/clients/logs/log-file-discovery.d.ts.map +1 -1
- package/dist/clients/logs/log-file-discovery.js +19 -6
- package/dist/clients/logs/log-file-discovery.js.map +1 -1
- package/dist/clients/logs/log-file-reader.d.ts +2 -0
- package/dist/clients/logs/log-file-reader.d.ts.map +1 -1
- package/dist/clients/logs/log-file-reader.js +31 -8
- package/dist/clients/logs/log-file-reader.js.map +1 -1
- package/dist/clients/logs/log-formatter.d.ts +2 -2
- package/dist/clients/logs/log-formatter.d.ts.map +1 -1
- package/dist/clients/logs/log-formatter.js.map +1 -1
- package/dist/clients/logs/log-types.d.ts +4 -0
- package/dist/clients/logs/log-types.d.ts.map +1 -1
- package/dist/clients/logs/webdav-client-manager.d.ts.map +1 -1
- package/dist/clients/logs/webdav-client-manager.js.map +1 -1
- package/dist/clients/ocapi/code-versions-client.d.ts +23 -4
- package/dist/clients/ocapi/code-versions-client.d.ts.map +1 -1
- package/dist/clients/ocapi/code-versions-client.js +2 -2
- package/dist/clients/ocapi/code-versions-client.js.map +1 -1
- package/dist/clients/ocapi/site-preferences-client.d.ts +2 -42
- package/dist/clients/ocapi/site-preferences-client.d.ts.map +1 -1
- package/dist/clients/ocapi/site-preferences-client.js.map +1 -1
- package/dist/clients/ocapi/system-objects-client.d.ts +7 -39
- package/dist/clients/ocapi/system-objects-client.d.ts.map +1 -1
- package/dist/clients/ocapi/system-objects-client.js.map +1 -1
- package/dist/clients/script-debugger/script-debugger-client.d.ts +9 -1
- package/dist/clients/script-debugger/script-debugger-client.d.ts.map +1 -1
- package/dist/clients/script-debugger/script-debugger-client.js +182 -127
- package/dist/clients/script-debugger/script-debugger-client.js.map +1 -1
- package/dist/clients/sfra-client.d.ts.map +1 -1
- package/dist/clients/sfra-client.js.map +1 -1
- package/dist/config/cli-options.d.ts +16 -0
- package/dist/config/cli-options.d.ts.map +1 -0
- package/dist/config/cli-options.js +56 -0
- package/dist/config/cli-options.js.map +1 -0
- package/dist/config/configuration-factory.d.ts.map +1 -1
- package/dist/config/configuration-factory.js +12 -6
- package/dist/config/configuration-factory.js.map +1 -1
- package/dist/config/credential-validation.d.ts +25 -0
- package/dist/config/credential-validation.d.ts.map +1 -0
- package/dist/config/credential-validation.js +42 -0
- package/dist/config/credential-validation.js.map +1 -0
- package/dist/config/dw-json-loader.d.ts.map +1 -1
- package/dist/config/dw-json-loader.js +19 -68
- package/dist/config/dw-json-loader.js.map +1 -1
- package/dist/config/path-security-policy.d.ts +6 -0
- package/dist/config/path-security-policy.d.ts.map +1 -0
- package/dist/config/path-security-policy.js +63 -0
- package/dist/config/path-security-policy.js.map +1 -0
- package/dist/config/workspace-roots.d.ts +1 -0
- package/dist/config/workspace-roots.d.ts.map +1 -1
- package/dist/config/workspace-roots.js +26 -77
- package/dist/config/workspace-roots.js.map +1 -1
- package/dist/core/handlers/abstract-client-handler.d.ts +23 -2
- package/dist/core/handlers/abstract-client-handler.d.ts.map +1 -1
- package/dist/core/handlers/abstract-client-handler.js +33 -3
- package/dist/core/handlers/abstract-client-handler.js.map +1 -1
- package/dist/core/handlers/agent-instructions-handler.d.ts +1 -1
- package/dist/core/handlers/agent-instructions-handler.d.ts.map +1 -1
- package/dist/core/handlers/agent-instructions-handler.js +2 -2
- package/dist/core/handlers/agent-instructions-handler.js.map +1 -1
- package/dist/core/handlers/base-handler.d.ts +14 -11
- package/dist/core/handlers/base-handler.d.ts.map +1 -1
- package/dist/core/handlers/base-handler.js +38 -22
- package/dist/core/handlers/base-handler.js.map +1 -1
- package/dist/core/handlers/cartridge-handler.d.ts +3 -8
- package/dist/core/handlers/cartridge-handler.d.ts.map +1 -1
- package/dist/core/handlers/cartridge-handler.js +10 -18
- package/dist/core/handlers/cartridge-handler.js.map +1 -1
- package/dist/core/handlers/code-version-handler.d.ts +3 -9
- package/dist/core/handlers/code-version-handler.d.ts.map +1 -1
- package/dist/core/handlers/code-version-handler.js +10 -21
- package/dist/core/handlers/code-version-handler.js.map +1 -1
- package/dist/core/handlers/job-log-handler.d.ts +3 -9
- package/dist/core/handlers/job-log-handler.d.ts.map +1 -1
- package/dist/core/handlers/job-log-handler.js +10 -21
- package/dist/core/handlers/job-log-handler.js.map +1 -1
- package/dist/core/handlers/lifecycle-utils.d.ts +5 -0
- package/dist/core/handlers/lifecycle-utils.d.ts.map +1 -0
- package/dist/core/handlers/lifecycle-utils.js +18 -0
- package/dist/core/handlers/lifecycle-utils.js.map +1 -0
- package/dist/core/handlers/log-handler.d.ts +3 -9
- package/dist/core/handlers/log-handler.d.ts.map +1 -1
- package/dist/core/handlers/log-handler.js +10 -21
- package/dist/core/handlers/log-handler.js.map +1 -1
- package/dist/core/handlers/script-debugger-handler.d.ts +3 -9
- package/dist/core/handlers/script-debugger-handler.d.ts.map +1 -1
- package/dist/core/handlers/script-debugger-handler.js +10 -21
- package/dist/core/handlers/script-debugger-handler.js.map +1 -1
- package/dist/core/handlers/simple-client-handler.d.ts +3 -3
- package/dist/core/handlers/simple-client-handler.d.ts.map +1 -1
- package/dist/core/handlers/simple-client-handler.js +5 -3
- package/dist/core/handlers/simple-client-handler.js.map +1 -1
- package/dist/core/handlers/system-object-handler.d.ts +3 -9
- package/dist/core/handlers/system-object-handler.d.ts.map +1 -1
- package/dist/core/handlers/system-object-handler.js +10 -21
- package/dist/core/handlers/system-object-handler.js.map +1 -1
- package/dist/core/handlers/validation-helpers.d.ts +5 -26
- package/dist/core/handlers/validation-helpers.d.ts.map +1 -1
- package/dist/core/handlers/validation-helpers.js +79 -81
- package/dist/core/handlers/validation-helpers.js.map +1 -1
- package/dist/core/instruction-advisor.d.ts +3 -0
- package/dist/core/instruction-advisor.d.ts.map +1 -1
- package/dist/core/instruction-advisor.js +25 -2
- package/dist/core/instruction-advisor.js.map +1 -1
- package/dist/core/server-tool-call-lifecycle.d.ts +38 -0
- package/dist/core/server-tool-call-lifecycle.d.ts.map +1 -0
- package/dist/core/server-tool-call-lifecycle.js +128 -0
- package/dist/core/server-tool-call-lifecycle.js.map +1 -0
- package/dist/core/server-tool-catalog.d.ts +19 -0
- package/dist/core/server-tool-catalog.d.ts.map +1 -0
- package/dist/core/server-tool-catalog.js +52 -0
- package/dist/core/server-tool-catalog.js.map +1 -0
- package/dist/core/server-workspace-discovery.d.ts +38 -0
- package/dist/core/server-workspace-discovery.d.ts.map +1 -0
- package/dist/core/server-workspace-discovery.js +68 -0
- package/dist/core/server-workspace-discovery.js.map +1 -0
- package/dist/core/server.d.ts +27 -3
- package/dist/core/server.d.ts.map +1 -1
- package/dist/core/server.js +247 -165
- package/dist/core/server.js.map +1 -1
- package/dist/core/tool-argument-validator.d.ts +24 -0
- package/dist/core/tool-argument-validator.d.ts.map +1 -0
- package/dist/core/tool-argument-validator.js +186 -0
- package/dist/core/tool-argument-validator.js.map +1 -0
- package/dist/core/tool-error-response.d.ts +21 -0
- package/dist/core/tool-error-response.d.ts.map +1 -0
- package/dist/core/tool-error-response.js +64 -0
- package/dist/core/tool-error-response.js.map +1 -0
- package/dist/core/tool-schemas/agent-instruction-tools.d.ts +4 -0
- package/dist/core/tool-schemas/agent-instruction-tools.d.ts.map +1 -1
- package/dist/core/tool-schemas/agent-instruction-tools.js +6 -2
- package/dist/core/tool-schemas/agent-instruction-tools.js.map +1 -1
- package/dist/core/tool-schemas/cartridge-tools.d.ts +3 -0
- package/dist/core/tool-schemas/cartridge-tools.d.ts.map +1 -1
- package/dist/core/tool-schemas/cartridge-tools.js +3 -0
- package/dist/core/tool-schemas/cartridge-tools.js.map +1 -1
- package/dist/core/tool-schemas/code-version-tools.d.ts +1 -0
- package/dist/core/tool-schemas/code-version-tools.d.ts.map +1 -1
- package/dist/core/tool-schemas/code-version-tools.js +1 -0
- package/dist/core/tool-schemas/code-version-tools.js.map +1 -1
- package/dist/core/tool-schemas/documentation-tools.d.ts +6 -0
- package/dist/core/tool-schemas/documentation-tools.d.ts.map +1 -1
- package/dist/core/tool-schemas/documentation-tools.js +6 -0
- package/dist/core/tool-schemas/documentation-tools.js.map +1 -1
- package/dist/core/tool-schemas/isml-tools.d.ts +3 -0
- package/dist/core/tool-schemas/isml-tools.d.ts.map +1 -1
- package/dist/core/tool-schemas/isml-tools.js +4 -1
- package/dist/core/tool-schemas/isml-tools.js.map +1 -1
- package/dist/core/tool-schemas/log-tools.d.ts +28 -0
- package/dist/core/tool-schemas/log-tools.d.ts.map +1 -1
- package/dist/core/tool-schemas/log-tools.js +21 -7
- package/dist/core/tool-schemas/log-tools.js.map +1 -1
- package/dist/core/tool-schemas/script-debugger-tools.d.ts +7 -0
- package/dist/core/tool-schemas/script-debugger-tools.d.ts.map +1 -1
- package/dist/core/tool-schemas/script-debugger-tools.js +9 -2
- package/dist/core/tool-schemas/script-debugger-tools.js.map +1 -1
- package/dist/core/tool-schemas/sfra-tools.d.ts +3 -0
- package/dist/core/tool-schemas/sfra-tools.d.ts.map +1 -1
- package/dist/core/tool-schemas/sfra-tools.js +3 -0
- package/dist/core/tool-schemas/sfra-tools.js.map +1 -1
- package/dist/core/tool-schemas/shared-schemas.d.ts +72 -4
- package/dist/core/tool-schemas/shared-schemas.d.ts.map +1 -1
- package/dist/core/tool-schemas/shared-schemas.js +29 -3
- package/dist/core/tool-schemas/shared-schemas.js.map +1 -1
- package/dist/core/tool-schemas/system-object-tools.d.ts +93 -4
- package/dist/core/tool-schemas/system-object-tools.d.ts.map +1 -1
- package/dist/core/tool-schemas/system-object-tools.js +13 -6
- package/dist/core/tool-schemas/system-object-tools.js.map +1 -1
- package/dist/docs/isml/isprint.md +1 -1
- package/dist/docs/isml/isredirect.md +1 -1
- package/dist/docs/isml/isremove.md +1 -1
- package/dist/docs/isml/isreplace.md +1 -1
- package/dist/docs/isml/isscript.md +1 -1
- package/dist/main.js +18 -33
- package/dist/main.js.map +1 -1
- package/dist/tool-configs/agent-instructions-tool-config.d.ts +1 -1
- package/dist/tool-configs/agent-instructions-tool-config.d.ts.map +1 -1
- package/dist/tool-configs/agent-instructions-tool-config.js +0 -33
- package/dist/tool-configs/agent-instructions-tool-config.js.map +1 -1
- package/dist/tool-configs/cartridge-tool-config.d.ts +1 -1
- package/dist/tool-configs/cartridge-tool-config.d.ts.map +1 -1
- package/dist/tool-configs/cartridge-tool-config.js +3 -5
- package/dist/tool-configs/cartridge-tool-config.js.map +1 -1
- package/dist/tool-configs/code-version-tool-config.d.ts +1 -1
- package/dist/tool-configs/code-version-tool-config.d.ts.map +1 -1
- package/dist/tool-configs/code-version-tool-config.js +0 -4
- package/dist/tool-configs/code-version-tool-config.js.map +1 -1
- package/dist/tool-configs/docs-tool-config.d.ts +1 -1
- package/dist/tool-configs/docs-tool-config.d.ts.map +1 -1
- package/dist/tool-configs/docs-tool-config.js +0 -13
- package/dist/tool-configs/docs-tool-config.js.map +1 -1
- package/dist/tool-configs/isml-tool-config.d.ts +1 -1
- package/dist/tool-configs/isml-tool-config.d.ts.map +1 -1
- package/dist/tool-configs/isml-tool-config.js +0 -10
- package/dist/tool-configs/isml-tool-config.js.map +1 -1
- package/dist/tool-configs/job-log-tool-config.d.ts +1 -1
- package/dist/tool-configs/job-log-tool-config.d.ts.map +1 -1
- package/dist/tool-configs/job-log-tool-config.js +1 -21
- package/dist/tool-configs/job-log-tool-config.js.map +1 -1
- package/dist/tool-configs/log-tool-config.d.ts +1 -1
- package/dist/tool-configs/log-tool-config.d.ts.map +1 -1
- package/dist/tool-configs/log-tool-config.js +6 -16
- package/dist/tool-configs/log-tool-config.js.map +1 -1
- package/dist/tool-configs/script-debugger-tool-config.d.ts +1 -1
- package/dist/tool-configs/script-debugger-tool-config.d.ts.map +1 -1
- package/dist/tool-configs/script-debugger-tool-config.js +0 -8
- package/dist/tool-configs/script-debugger-tool-config.js.map +1 -1
- package/dist/tool-configs/sfra-tool-config.d.ts +1 -1
- package/dist/tool-configs/sfra-tool-config.d.ts.map +1 -1
- package/dist/tool-configs/sfra-tool-config.js +0 -10
- package/dist/tool-configs/sfra-tool-config.js.map +1 -1
- package/dist/tool-configs/system-object-tool-config.d.ts +1 -1
- package/dist/tool-configs/system-object-tool-config.d.ts.map +1 -1
- package/dist/tool-configs/system-object-tool-config.js +14 -24
- package/dist/tool-configs/system-object-tool-config.js.map +1 -1
- package/dist/types/ocapi-search.d.ts +50 -0
- package/dist/types/ocapi-search.d.ts.map +1 -0
- package/dist/types/ocapi-search.js +7 -0
- package/dist/types/ocapi-search.js.map +1 -0
- package/dist/types/types.d.ts +4 -4
- package/dist/types/types.d.ts.map +1 -1
- package/dist/utils/abort-utils.d.ts +18 -0
- package/dist/utils/abort-utils.d.ts.map +1 -0
- package/dist/utils/abort-utils.js +60 -0
- package/dist/utils/abort-utils.js.map +1 -0
- package/dist/utils/cache.d.ts +7 -7
- package/dist/utils/cache.d.ts.map +1 -1
- package/dist/utils/cache.js.map +1 -1
- package/dist/utils/category-utils.d.ts +0 -10
- package/dist/utils/category-utils.d.ts.map +1 -1
- package/dist/utils/category-utils.js +0 -12
- package/dist/utils/category-utils.js.map +1 -1
- package/dist/utils/log-tool-constants.d.ts +3 -4
- package/dist/utils/log-tool-constants.d.ts.map +1 -1
- package/dist/utils/log-tool-constants.js +2 -13
- package/dist/utils/log-tool-constants.js.map +1 -1
- package/dist/utils/logger.d.ts +20 -7
- package/dist/utils/logger.d.ts.map +1 -1
- package/dist/utils/logger.js +72 -11
- package/dist/utils/logger.js.map +1 -1
- package/dist/utils/query-builder.d.ts +2 -5
- package/dist/utils/query-builder.d.ts.map +1 -1
- package/dist/utils/query-builder.js +1 -4
- package/dist/utils/query-builder.js.map +1 -1
- package/dist/utils/validator.d.ts +5 -3
- package/dist/utils/validator.d.ts.map +1 -1
- package/dist/utils/validator.js +20 -14
- package/dist/utils/validator.js.map +1 -1
- package/package.json +14 -7
- package/dist/clients/docs/index.d.ts +0 -10
- package/dist/clients/docs/index.d.ts.map +0 -1
- package/dist/clients/docs/index.js +0 -10
- package/dist/clients/docs/index.js.map +0 -1
- package/dist/constants/index.d.ts +0 -1
- package/dist/constants/index.d.ts.map +0 -1
- package/dist/constants/index.js +0 -3
- package/dist/constants/index.js.map +0 -1
- package/dist/utils/path-validation.d.ts +0 -40
- package/dist/utils/path-validation.d.ts.map +0 -1
- package/dist/utils/path-validation.js +0 -84
- package/dist/utils/path-validation.js.map +0 -1
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI option parsing helpers.
|
|
3
|
+
*/
|
|
4
|
+
const TRUE_VALUES = new Set(['true', '1', 'yes']);
|
|
5
|
+
const FALSE_VALUES = new Set(['false', '0', 'no']);
|
|
6
|
+
function parseBoolean(value) {
|
|
7
|
+
const normalized = value.toLowerCase();
|
|
8
|
+
if (TRUE_VALUES.has(normalized)) {
|
|
9
|
+
return true;
|
|
10
|
+
}
|
|
11
|
+
if (FALSE_VALUES.has(normalized)) {
|
|
12
|
+
return false;
|
|
13
|
+
}
|
|
14
|
+
throw new Error(`Invalid value for --debug: "${value}". Use true/false, 1/0, or yes/no.`);
|
|
15
|
+
}
|
|
16
|
+
function isFlagToken(value) {
|
|
17
|
+
return value?.startsWith('-') ?? false;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Parse command line arguments to extract configuration options.
|
|
21
|
+
*/
|
|
22
|
+
export function parseCommandLineArgs(argv = process.argv.slice(2)) {
|
|
23
|
+
const options = {};
|
|
24
|
+
for (let i = 0; i < argv.length; i++) {
|
|
25
|
+
const arg = argv[i];
|
|
26
|
+
if (arg === '--dw-json') {
|
|
27
|
+
const nextToken = argv[i + 1];
|
|
28
|
+
if (!nextToken || isFlagToken(nextToken)) {
|
|
29
|
+
throw new Error('Missing value for --dw-json. Provide a path to dw.json.');
|
|
30
|
+
}
|
|
31
|
+
options.dwJsonPath = nextToken;
|
|
32
|
+
i++;
|
|
33
|
+
continue;
|
|
34
|
+
}
|
|
35
|
+
if (arg !== '--debug') {
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
const nextToken = argv[i + 1];
|
|
39
|
+
if (!nextToken || isFlagToken(nextToken)) {
|
|
40
|
+
options.debug = true;
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
43
|
+
options.debug = parseBoolean(nextToken);
|
|
44
|
+
i++;
|
|
45
|
+
}
|
|
46
|
+
return options;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Check if environment variables provide SFCC credentials.
|
|
50
|
+
*/
|
|
51
|
+
export function hasEnvironmentCredentials(env = process.env) {
|
|
52
|
+
const hasBasicAuth = !!(env.SFCC_USERNAME && env.SFCC_PASSWORD);
|
|
53
|
+
const hasOAuth = !!(env.SFCC_CLIENT_ID && env.SFCC_CLIENT_SECRET);
|
|
54
|
+
return !!(env.SFCC_HOSTNAME && (hasBasicAuth || hasOAuth));
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=cli-options.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli-options.js","sourceRoot":"","sources":["../../src/config/cli-options.ts"],"names":[],"mappings":"AAAA;;GAEG;AAOH,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC;AAClD,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC,CAAC,OAAO,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC;AAEnD,SAAS,YAAY,CAAC,KAAa;IACjC,MAAM,UAAU,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC;IAEvC,IAAI,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC;QAChC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,YAAY,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC;QACjC,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,IAAI,KAAK,CACb,+BAA+B,KAAK,oCAAoC,CACzE,CAAC;AACJ,CAAC;AAED,SAAS,WAAW,CAAC,KAAyB;IAC5C,OAAO,KAAK,EAAE,UAAU,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC;AACzC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,oBAAoB,CAAC,OAAiB,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;IACzE,MAAM,OAAO,GAAe,EAAE,CAAC;IAE/B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACrC,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QAEpB,IAAI,GAAG,KAAK,WAAW,EAAE,CAAC;YACxB,MAAM,SAAS,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YAC9B,IAAI,CAAC,SAAS,IAAI,WAAW,CAAC,SAAS,CAAC,EAAE,CAAC;gBACzC,MAAM,IAAI,KAAK,CAAC,yDAAyD,CAAC,CAAC;YAC7E,CAAC;YAED,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC;YAC/B,CAAC,EAAE,CAAC;YACJ,SAAS;QACX,CAAC;QAED,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;YACtB,SAAS;QACX,CAAC;QAED,MAAM,SAAS,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QAC9B,IAAI,CAAC,SAAS,IAAI,WAAW,CAAC,SAAS,CAAC,EAAE,CAAC;YACzC,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC;YACrB,SAAS;QACX,CAAC;QAED,OAAO,CAAC,KAAK,GAAG,YAAY,CAAC,SAAS,CAAC,CAAC;QACxC,CAAC,EAAE,CAAC;IACN,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,yBAAyB,CAAC,MAAyB,OAAO,CAAC,GAAG;IAC5E,MAAM,YAAY,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,aAAa,IAAI,GAAG,CAAC,aAAa,CAAC,CAAC;IAChE,MAAM,QAAQ,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,cAAc,IAAI,GAAG,CAAC,kBAAkB,CAAC,CAAC;IAClE,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,aAAa,IAAI,CAAC,YAAY,IAAI,QAAQ,CAAC,CAAC,CAAC;AAC7D,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"configuration-factory.d.ts","sourceRoot":"","sources":["../../src/config/configuration-factory.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"configuration-factory.d.ts","sourceRoot":"","sources":["../../src/config/configuration-factory.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAO7D,qBAAa,oBAAoB;IAC/B;;OAEG;IACH,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE;QACrB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,GAAG,UAAU;IA+Bd;;;;;;OAMG;IACH,OAAO,CAAC,MAAM,CAAC,cAAc;IAY7B;;;;;;;;OAQG;IACH,MAAM,CAAC,iBAAiB,CAAC,QAAQ,EAAE,YAAY,GAAG,UAAU;IA0B5D;;;;;;;;OAQG;IACH,OAAO,CAAC,MAAM,CAAC,QAAQ;IAoCvB;;;;;;;;OAQG;IACH,MAAM,CAAC,eAAe,CAAC,MAAM,EAAE,UAAU,GAAG;QAC1C,aAAa,EAAE,OAAO,CAAC;QACvB,cAAc,EAAE,OAAO,CAAC;QACxB,eAAe,EAAE,OAAO,CAAC;QACzB,qBAAqB,EAAE,OAAO,CAAC;QAC/B,WAAW,EAAE,OAAO,CAAC;KACtB;IAqBD;;;;;;;OAOG;IACH,MAAM,CAAC,eAAe,IAAI,UAAU;CAUrC"}
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
import { existsSync } from 'fs';
|
|
9
9
|
import { resolve } from 'path';
|
|
10
10
|
import { loadSecureDwJson } from './dw-json-loader.js';
|
|
11
|
+
import { assertCredentialConsistency, assertValidHostnameFormat, } from './credential-validation.js';
|
|
11
12
|
export class ConfigurationFactory {
|
|
12
13
|
/**
|
|
13
14
|
* Create configuration from various sources with proper validation
|
|
@@ -108,24 +109,29 @@ export class ConfigurationFactory {
|
|
|
108
109
|
* @throws Error if configuration is invalid for any supported mode
|
|
109
110
|
*/
|
|
110
111
|
static validate(config) {
|
|
111
|
-
const hasBasicAuth
|
|
112
|
-
|
|
112
|
+
const { hasBasicAuth, hasOAuth } = assertCredentialConsistency({
|
|
113
|
+
username: config.username,
|
|
114
|
+
password: config.password,
|
|
115
|
+
clientId: config.clientId,
|
|
116
|
+
clientSecret: config.clientSecret,
|
|
117
|
+
});
|
|
113
118
|
const hasHostname = config.hostname && config.hostname.trim() !== '';
|
|
114
119
|
// Allow local mode if no credentials or hostname are provided
|
|
115
120
|
if (!hasBasicAuth && !hasOAuth && !hasHostname) {
|
|
116
121
|
// Local mode - only class documentation available
|
|
117
122
|
return;
|
|
118
123
|
}
|
|
124
|
+
// Credentials without hostname is an invalid partial configuration.
|
|
125
|
+
if (!hasHostname && (hasBasicAuth || hasOAuth)) {
|
|
126
|
+
throw new Error('When credentials are provided, hostname must also be provided');
|
|
127
|
+
}
|
|
119
128
|
// If hostname is provided, require credentials
|
|
120
129
|
if (hasHostname && !hasBasicAuth && !hasOAuth) {
|
|
121
130
|
throw new Error('When hostname is provided, either username/password or OAuth credentials (clientId/clientSecret) must be provided');
|
|
122
131
|
}
|
|
123
132
|
// Additional hostname validation if provided
|
|
124
133
|
if (hasHostname) {
|
|
125
|
-
|
|
126
|
-
if (!trimmedHostname.match(/^[a-zA-Z0-9.-]+(?::[0-9]+)?$/)) {
|
|
127
|
-
throw new Error('Invalid hostname format in configuration');
|
|
128
|
-
}
|
|
134
|
+
assertValidHostnameFormat(config.hostname, 'Invalid hostname format in configuration');
|
|
129
135
|
}
|
|
130
136
|
}
|
|
131
137
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"configuration-factory.js","sourceRoot":"","sources":["../../src/config/configuration-factory.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAChC,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAE/B,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"configuration-factory.js","sourceRoot":"","sources":["../../src/config/configuration-factory.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared credential and hostname validation helpers.
|
|
3
|
+
*/
|
|
4
|
+
export interface CredentialPresence {
|
|
5
|
+
hasBasicAuth: boolean;
|
|
6
|
+
hasOAuth: boolean;
|
|
7
|
+
hasPartialBasicAuth: boolean;
|
|
8
|
+
hasPartialOAuth: boolean;
|
|
9
|
+
}
|
|
10
|
+
interface CredentialValidationInput {
|
|
11
|
+
username?: unknown;
|
|
12
|
+
password?: unknown;
|
|
13
|
+
clientId?: unknown;
|
|
14
|
+
clientSecret?: unknown;
|
|
15
|
+
}
|
|
16
|
+
interface CredentialValidationMessages {
|
|
17
|
+
basicPairMessage?: string;
|
|
18
|
+
oauthPairMessage?: string;
|
|
19
|
+
requireAnyCredentialsMessage?: string;
|
|
20
|
+
}
|
|
21
|
+
export declare function getCredentialPresence(input: CredentialValidationInput): CredentialPresence;
|
|
22
|
+
export declare function assertCredentialConsistency(input: CredentialValidationInput, messages?: CredentialValidationMessages): CredentialPresence;
|
|
23
|
+
export declare function assertValidHostnameFormat(hostname: string, message?: string): void;
|
|
24
|
+
export {};
|
|
25
|
+
//# sourceMappingURL=credential-validation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"credential-validation.d.ts","sourceRoot":"","sources":["../../src/config/credential-validation.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,kBAAkB;IACjC,YAAY,EAAE,OAAO,CAAC;IACtB,QAAQ,EAAE,OAAO,CAAC;IAClB,mBAAmB,EAAE,OAAO,CAAC;IAC7B,eAAe,EAAE,OAAO,CAAC;CAC1B;AAED,UAAU,yBAAyB;IACjC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,UAAU,4BAA4B;IACpC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,4BAA4B,CAAC,EAAE,MAAM,CAAC;CACvC;AAWD,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,yBAAyB,GAAG,kBAAkB,CAY1F;AAED,wBAAgB,2BAA2B,CACzC,KAAK,EAAE,yBAAyB,EAChC,QAAQ,GAAE,4BAAiC,GAC1C,kBAAkB,CAgBpB;AAED,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,MAAiC,GACzC,IAAI,CAKN"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared credential and hostname validation helpers.
|
|
3
|
+
*/
|
|
4
|
+
const DEFAULT_BASIC_PAIR_MESSAGE = 'Basic auth credentials must include both username and password';
|
|
5
|
+
const DEFAULT_OAUTH_PAIR_MESSAGE = 'OAuth credentials must include both clientId and clientSecret';
|
|
6
|
+
const DEFAULT_HOSTNAME_MESSAGE = 'Invalid hostname format in configuration';
|
|
7
|
+
const HOSTNAME_PATTERN = /^[a-zA-Z0-9.-]+(?::[0-9]+)?$/;
|
|
8
|
+
function hasNonEmptyString(value) {
|
|
9
|
+
return typeof value === 'string' && value.trim().length > 0;
|
|
10
|
+
}
|
|
11
|
+
export function getCredentialPresence(input) {
|
|
12
|
+
const hasBasicUser = hasNonEmptyString(input.username);
|
|
13
|
+
const hasBasicPassword = hasNonEmptyString(input.password);
|
|
14
|
+
const hasClientId = hasNonEmptyString(input.clientId);
|
|
15
|
+
const hasClientSecret = hasNonEmptyString(input.clientSecret);
|
|
16
|
+
return {
|
|
17
|
+
hasBasicAuth: hasBasicUser && hasBasicPassword,
|
|
18
|
+
hasOAuth: hasClientId && hasClientSecret,
|
|
19
|
+
hasPartialBasicAuth: hasBasicUser !== hasBasicPassword,
|
|
20
|
+
hasPartialOAuth: hasClientId !== hasClientSecret,
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
export function assertCredentialConsistency(input, messages = {}) {
|
|
24
|
+
const presence = getCredentialPresence(input);
|
|
25
|
+
if (presence.hasPartialBasicAuth) {
|
|
26
|
+
throw new Error(messages.basicPairMessage ?? DEFAULT_BASIC_PAIR_MESSAGE);
|
|
27
|
+
}
|
|
28
|
+
if (presence.hasPartialOAuth) {
|
|
29
|
+
throw new Error(messages.oauthPairMessage ?? DEFAULT_OAUTH_PAIR_MESSAGE);
|
|
30
|
+
}
|
|
31
|
+
if (messages.requireAnyCredentialsMessage && !presence.hasBasicAuth && !presence.hasOAuth) {
|
|
32
|
+
throw new Error(messages.requireAnyCredentialsMessage);
|
|
33
|
+
}
|
|
34
|
+
return presence;
|
|
35
|
+
}
|
|
36
|
+
export function assertValidHostnameFormat(hostname, message = DEFAULT_HOSTNAME_MESSAGE) {
|
|
37
|
+
const trimmedHostname = hostname.trim();
|
|
38
|
+
if (!HOSTNAME_PATTERN.test(trimmedHostname)) {
|
|
39
|
+
throw new Error(message);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=credential-validation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"credential-validation.js","sourceRoot":"","sources":["../../src/config/credential-validation.ts"],"names":[],"mappings":"AAAA;;GAEG;AAsBH,MAAM,0BAA0B,GAAG,gEAAgE,CAAC;AACpG,MAAM,0BAA0B,GAAG,+DAA+D,CAAC;AACnG,MAAM,wBAAwB,GAAG,0CAA0C,CAAC;AAC5E,MAAM,gBAAgB,GAAG,8BAA8B,CAAC;AAExD,SAAS,iBAAiB,CAAC,KAAc;IACvC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC;AAC9D,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,KAAgC;IACpE,MAAM,YAAY,GAAG,iBAAiB,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IACvD,MAAM,gBAAgB,GAAG,iBAAiB,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IAC3D,MAAM,WAAW,GAAG,iBAAiB,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IACtD,MAAM,eAAe,GAAG,iBAAiB,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;IAE9D,OAAO;QACL,YAAY,EAAE,YAAY,IAAI,gBAAgB;QAC9C,QAAQ,EAAE,WAAW,IAAI,eAAe;QACxC,mBAAmB,EAAE,YAAY,KAAK,gBAAgB;QACtD,eAAe,EAAE,WAAW,KAAK,eAAe;KACjD,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,2BAA2B,CACzC,KAAgC,EAChC,WAAyC,EAAE;IAE3C,MAAM,QAAQ,GAAG,qBAAqB,CAAC,KAAK,CAAC,CAAC;IAE9C,IAAI,QAAQ,CAAC,mBAAmB,EAAE,CAAC;QACjC,MAAM,IAAI,KAAK,CAAC,QAAQ,CAAC,gBAAgB,IAAI,0BAA0B,CAAC,CAAC;IAC3E,CAAC;IAED,IAAI,QAAQ,CAAC,eAAe,EAAE,CAAC;QAC7B,MAAM,IAAI,KAAK,CAAC,QAAQ,CAAC,gBAAgB,IAAI,0BAA0B,CAAC,CAAC;IAC3E,CAAC;IAED,IAAI,QAAQ,CAAC,4BAA4B,IAAI,CAAC,QAAQ,CAAC,YAAY,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC;QAC1F,MAAM,IAAI,KAAK,CAAC,QAAQ,CAAC,4BAA4B,CAAC,CAAC;IACzD,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,yBAAyB,CACvC,QAAgB,EAChB,UAAkB,wBAAwB;IAE1C,MAAM,eAAe,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAC;IACxC,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,eAAe,CAAC,EAAE,CAAC;QAC5C,MAAM,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC;IAC3B,CAAC;AACH,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dw-json-loader.d.ts","sourceRoot":"","sources":["../../src/config/dw-json-loader.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAIH,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"dw-json-loader.d.ts","sourceRoot":"","sources":["../../src/config/dw-json-loader.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAIH,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AA4HjD;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,YAAY,CAmDjE"}
|
|
@@ -13,53 +13,8 @@
|
|
|
13
13
|
*/
|
|
14
14
|
import { readFileSync, existsSync, statSync, realpathSync } from 'fs';
|
|
15
15
|
import { resolve, basename, extname, normalize, isAbsolute } from 'path';
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
* These are blocked to prevent accidental or malicious access to sensitive areas
|
|
19
|
-
*/
|
|
20
|
-
const BLOCKED_SYSTEM_PATHS = [
|
|
21
|
-
'/etc',
|
|
22
|
-
'/proc',
|
|
23
|
-
'/sys',
|
|
24
|
-
'/dev',
|
|
25
|
-
'/root',
|
|
26
|
-
'/var/log',
|
|
27
|
-
'/var/run',
|
|
28
|
-
'/boot',
|
|
29
|
-
'/sbin',
|
|
30
|
-
'/bin',
|
|
31
|
-
// Windows system paths
|
|
32
|
-
'C:\\Windows',
|
|
33
|
-
'C:\\Program Files',
|
|
34
|
-
'C:\\ProgramData',
|
|
35
|
-
// Common sensitive directories
|
|
36
|
-
'.ssh',
|
|
37
|
-
'.gnupg',
|
|
38
|
-
'.aws',
|
|
39
|
-
'.config/gcloud',
|
|
40
|
-
];
|
|
41
|
-
/**
|
|
42
|
-
* Allowed path prefixes for configuration file access
|
|
43
|
-
* These are the typical locations where development projects and configs reside
|
|
44
|
-
*/
|
|
45
|
-
const ALLOWED_PATH_PATTERNS = [
|
|
46
|
-
// User home directories
|
|
47
|
-
/^\/Users\/[^/]+\//i, // macOS
|
|
48
|
-
/^\/home\/[^/]+\//i, // Linux (allow all users for development)
|
|
49
|
-
/^C:\\Users\\[^\\]+\\/i, // Windows
|
|
50
|
-
// Common project directories
|
|
51
|
-
/^\/opt\//i,
|
|
52
|
-
/^\/var\/www\//i,
|
|
53
|
-
/^\/srv\//i,
|
|
54
|
-
// Temp directories (for testing)
|
|
55
|
-
/^\/tmp\//i,
|
|
56
|
-
/^\/private\/tmp\//i, // macOS real temp path
|
|
57
|
-
/^\/var\/folders\//i, // macOS temp
|
|
58
|
-
/^\/private\/var\/folders\//i, // macOS real temp path (symlink resolved)
|
|
59
|
-
/^C:\\Temp\\/i, // Windows temp
|
|
60
|
-
// CI workspace paths
|
|
61
|
-
/^\/home\/runner\/work\//i, // GitHub Actions
|
|
62
|
-
];
|
|
16
|
+
import { isAllowedResolvedPath, isBlockedResolvedPath } from './path-security-policy.js';
|
|
17
|
+
import { assertCredentialConsistency, assertValidHostnameFormat, } from './credential-validation.js';
|
|
63
18
|
/**
|
|
64
19
|
* Validates that a file path is safe to access and prevents path traversal attacks
|
|
65
20
|
*
|
|
@@ -92,21 +47,11 @@ function validateSecurePath(filePath) {
|
|
|
92
47
|
if (!resolvedPath.toLowerCase().endsWith('.json')) {
|
|
93
48
|
throw new Error('Invalid file path after normalization');
|
|
94
49
|
}
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
for (const blocked of BLOCKED_SYSTEM_PATHS) {
|
|
98
|
-
const blockedLower = blocked.toLowerCase();
|
|
99
|
-
if (lowerPath === blockedLower ||
|
|
100
|
-
lowerPath.startsWith(`${blockedLower}/`) ||
|
|
101
|
-
lowerPath.startsWith(`${blockedLower}\\`) ||
|
|
102
|
-
lowerPath.includes(`/${blockedLower}/`) ||
|
|
103
|
-
lowerPath.includes(`\\${blockedLower}\\`)) {
|
|
104
|
-
throw new Error('Access to system directories not allowed');
|
|
105
|
-
}
|
|
50
|
+
if (isBlockedResolvedPath(resolvedPath)) {
|
|
51
|
+
throw new Error('Access to system directories not allowed');
|
|
106
52
|
}
|
|
107
53
|
// Check that path matches allowed patterns
|
|
108
|
-
|
|
109
|
-
if (!matchesAllowed) {
|
|
54
|
+
if (!isAllowedResolvedPath(resolvedPath)) {
|
|
110
55
|
throw new Error('Path is outside of allowed configuration directories');
|
|
111
56
|
}
|
|
112
57
|
// If the file exists, resolve symlinks and re-validate the real path
|
|
@@ -154,15 +99,21 @@ function validateFileSize(filePath) {
|
|
|
154
99
|
* @throws Error if required fields are missing or invalid
|
|
155
100
|
*/
|
|
156
101
|
function validateDwJsonContent(dwConfig) {
|
|
157
|
-
// Validate required
|
|
158
|
-
if (!dwConfig.hostname
|
|
159
|
-
throw new Error('Configuration file must contain hostname
|
|
160
|
-
}
|
|
102
|
+
// Validate required hostname
|
|
103
|
+
if (!dwConfig.hostname) {
|
|
104
|
+
throw new Error('Configuration file must contain a hostname field');
|
|
105
|
+
}
|
|
106
|
+
assertCredentialConsistency({
|
|
107
|
+
username: dwConfig.username,
|
|
108
|
+
password: dwConfig.password,
|
|
109
|
+
clientId: dwConfig['client-id'],
|
|
110
|
+
clientSecret: dwConfig['client-secret'],
|
|
111
|
+
}, {
|
|
112
|
+
oauthPairMessage: 'OAuth credentials must include both client-id and client-secret',
|
|
113
|
+
requireAnyCredentialsMessage: 'Configuration file must include either username/password or client-id/client-secret credentials',
|
|
114
|
+
});
|
|
161
115
|
// Additional validation for hostname format (trim whitespace first)
|
|
162
|
-
|
|
163
|
-
if (!trimmedHostname?.match(/^[a-zA-Z0-9.-]+(?::[0-9]+)?$/)) {
|
|
164
|
-
throw new Error('Invalid hostname format in configuration');
|
|
165
|
-
}
|
|
116
|
+
assertValidHostnameFormat(dwConfig.hostname, 'Invalid hostname format in configuration');
|
|
166
117
|
}
|
|
167
118
|
/**
|
|
168
119
|
* Securely loads and parses a dw.json file with comprehensive validation
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dw-json-loader.js","sourceRoot":"","sources":["../../src/config/dw-json-loader.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;AACtE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"dw-json-loader.js","sourceRoot":"","sources":["../../src/config/dw-json-loader.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared path security policy used by configuration and workspace-root validation.
|
|
3
|
+
*/
|
|
4
|
+
export declare function isBlockedResolvedPath(resolvedPath: string): boolean;
|
|
5
|
+
export declare function isAllowedResolvedPath(resolvedPath: string): boolean;
|
|
6
|
+
//# sourceMappingURL=path-security-policy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"path-security-policy.d.ts","sourceRoot":"","sources":["../../src/config/path-security-policy.ts"],"names":[],"mappings":"AAAA;;GAEG;AAiDH,wBAAgB,qBAAqB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAenE;AAED,wBAAgB,qBAAqB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAEnE"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared path security policy used by configuration and workspace-root validation.
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Dangerous system paths that should never be accessed.
|
|
6
|
+
*/
|
|
7
|
+
const BLOCKED_SYSTEM_PATHS = [
|
|
8
|
+
'/etc',
|
|
9
|
+
'/proc',
|
|
10
|
+
'/sys',
|
|
11
|
+
'/dev',
|
|
12
|
+
'/root',
|
|
13
|
+
'/var/log',
|
|
14
|
+
'/var/run',
|
|
15
|
+
'/boot',
|
|
16
|
+
'/sbin',
|
|
17
|
+
'/bin',
|
|
18
|
+
'C:\\Windows',
|
|
19
|
+
'C:\\Program Files',
|
|
20
|
+
'C:\\ProgramData',
|
|
21
|
+
];
|
|
22
|
+
/**
|
|
23
|
+
* Sensitive directory segments that must be blocked even under allowed roots.
|
|
24
|
+
*/
|
|
25
|
+
const BLOCKED_SENSITIVE_SEGMENT_PATTERNS = [
|
|
26
|
+
/(^|[\\/])\.ssh([\\/]|$)/i,
|
|
27
|
+
/(^|[\\/])\.gnupg([\\/]|$)/i,
|
|
28
|
+
/(^|[\\/])\.aws([\\/]|$)/i,
|
|
29
|
+
/(^|[\\/])\.config[\\/]gcloud([\\/]|$)/i,
|
|
30
|
+
];
|
|
31
|
+
/**
|
|
32
|
+
* Allowed path prefixes for local development and CI environments.
|
|
33
|
+
*/
|
|
34
|
+
const ALLOWED_PATH_PATTERNS = [
|
|
35
|
+
/^\/Users\/[^/]+\//i,
|
|
36
|
+
/^\/home\/[^/]+\//i,
|
|
37
|
+
/^C:\\Users\\[^\\]+\\/i,
|
|
38
|
+
/^\/opt\//i,
|
|
39
|
+
/^\/var\/www\//i,
|
|
40
|
+
/^\/srv\//i,
|
|
41
|
+
/^\/tmp\//i,
|
|
42
|
+
/^\/private\/tmp\//i,
|
|
43
|
+
/^\/var\/folders\//i,
|
|
44
|
+
/^\/private\/var\/folders\//i,
|
|
45
|
+
/^C:\\Temp\\/i,
|
|
46
|
+
/^\/home\/runner\/work\//i,
|
|
47
|
+
];
|
|
48
|
+
export function isBlockedResolvedPath(resolvedPath) {
|
|
49
|
+
const lowerPath = resolvedPath.toLowerCase();
|
|
50
|
+
for (const blocked of BLOCKED_SYSTEM_PATHS) {
|
|
51
|
+
const blockedLower = blocked.toLowerCase();
|
|
52
|
+
if (lowerPath === blockedLower ||
|
|
53
|
+
lowerPath.startsWith(`${blockedLower}/`) ||
|
|
54
|
+
lowerPath.startsWith(`${blockedLower}\\`)) {
|
|
55
|
+
return true;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return BLOCKED_SENSITIVE_SEGMENT_PATTERNS.some(pattern => pattern.test(resolvedPath));
|
|
59
|
+
}
|
|
60
|
+
export function isAllowedResolvedPath(resolvedPath) {
|
|
61
|
+
return ALLOWED_PATH_PATTERNS.some(pattern => pattern.test(resolvedPath));
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=path-security-policy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"path-security-policy.js","sourceRoot":"","sources":["../../src/config/path-security-policy.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;GAEG;AACH,MAAM,oBAAoB,GAAsB;IAC9C,MAAM;IACN,OAAO;IACP,MAAM;IACN,MAAM;IACN,OAAO;IACP,UAAU;IACV,UAAU;IACV,OAAO;IACP,OAAO;IACP,MAAM;IACN,aAAa;IACb,mBAAmB;IACnB,iBAAiB;CACT,CAAC;AAEX;;GAEG;AACH,MAAM,kCAAkC,GAAsB;IAC5D,0BAA0B;IAC1B,4BAA4B;IAC5B,0BAA0B;IAC1B,wCAAwC;CAChC,CAAC;AAEX;;GAEG;AACH,MAAM,qBAAqB,GAAsB;IAC/C,oBAAoB;IACpB,mBAAmB;IACnB,uBAAuB;IACvB,WAAW;IACX,gBAAgB;IAChB,WAAW;IACX,WAAW;IACX,oBAAoB;IACpB,oBAAoB;IACpB,6BAA6B;IAC7B,cAAc;IACd,0BAA0B;CAClB,CAAC;AAEX,MAAM,UAAU,qBAAqB,CAAC,YAAoB;IACxD,MAAM,SAAS,GAAG,YAAY,CAAC,WAAW,EAAE,CAAC;IAE7C,KAAK,MAAM,OAAO,IAAI,oBAAoB,EAAE,CAAC;QAC3C,MAAM,YAAY,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;QAC3C,IACE,SAAS,KAAK,YAAY;YAC1B,SAAS,CAAC,UAAU,CAAC,GAAG,YAAY,GAAG,CAAC;YACxC,SAAS,CAAC,UAAU,CAAC,GAAG,YAAY,IAAI,CAAC,EACzC,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IAED,OAAO,kCAAkC,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC;AACxF,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,YAAoB;IACxD,OAAO,qBAAqB,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC;AAC3E,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workspace-roots.d.ts","sourceRoot":"","sources":["../../src/config/workspace-roots.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAKH,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"workspace-roots.d.ts","sourceRoot":"","sources":["../../src/config/workspace-roots.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAKH,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAIjD;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,mCAAmC;IACnC,GAAG,EAAE,MAAM,CAAC;IACZ,6BAA6B;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,iCAAiC;IACjC,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC,uCAAuC;IACvC,OAAO,EAAE,OAAO,CAAC;IACjB,gDAAgD;IAChD,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,0CAA0C;IAC1C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,iCAAiC;IACjC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,qDAAqD;IACrD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,sDAAsD;IACtD,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAsHD;;;;;;GAMG;AACH,qBAAa,qBAAqB;IAChC,OAAO,CAAC,KAAK,CAAgC;IAC7C,OAAO,CAAC,MAAM,CAAS;gBAEX,MAAM,CAAC,EAAE,MAAM;IAI3B,OAAO,CAAC,sBAAsB;IAK9B;;;;;OAKG;IACH,WAAW,CAAC,WAAW,EAAE,KAAK,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,GAAG,sBAAsB,EAAE;IAsBzF;;OAEG;IACH,QAAQ,IAAI,sBAAsB,EAAE;IAIpC;;;;;;OAMG;IACH,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,GAAE,MAAU,GAAG,MAAM,GAAG,SAAS;IAkBpE;;;;;;;;OAQG;IACH,OAAO,CAAC,iBAAiB;IA2CzB;;;;;;;;OAQG;IACH,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;IAoC5C;;OAEG;IACH,KAAK,IAAI,IAAI;IAKb;;;;;;;;;OASG;IACH,cAAc,CAAC,WAAW,EAAE,aAAa,EAAE,GAAG,SAAS,GAAG,wBAAwB;CAgFnF;AAED;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAezF"}
|
|
@@ -26,53 +26,7 @@ import { resolve, normalize, join, isAbsolute } from 'path';
|
|
|
26
26
|
import { fileURLToPath } from 'url';
|
|
27
27
|
import { Logger } from '../utils/logger.js';
|
|
28
28
|
import { loadSecureDwJson } from './dw-json-loader.js';
|
|
29
|
-
|
|
30
|
-
* Dangerous system paths that should never be accessed
|
|
31
|
-
* These are blocked to prevent accidental or malicious access to sensitive areas
|
|
32
|
-
*/
|
|
33
|
-
const BLOCKED_SYSTEM_PATHS = [
|
|
34
|
-
'/etc',
|
|
35
|
-
'/proc',
|
|
36
|
-
'/sys',
|
|
37
|
-
'/dev',
|
|
38
|
-
'/root',
|
|
39
|
-
'/var/log',
|
|
40
|
-
'/var/run',
|
|
41
|
-
'/boot',
|
|
42
|
-
'/sbin',
|
|
43
|
-
'/bin',
|
|
44
|
-
// Windows system paths
|
|
45
|
-
'C:\\Windows',
|
|
46
|
-
'C:\\Program Files',
|
|
47
|
-
'C:\\ProgramData',
|
|
48
|
-
// Common sensitive directories
|
|
49
|
-
'.ssh',
|
|
50
|
-
'.gnupg',
|
|
51
|
-
'.aws',
|
|
52
|
-
'.config/gcloud',
|
|
53
|
-
];
|
|
54
|
-
/**
|
|
55
|
-
* Allowed path prefixes for workspace roots
|
|
56
|
-
* These are the typical locations where development projects reside
|
|
57
|
-
*/
|
|
58
|
-
const ALLOWED_PATH_PATTERNS = [
|
|
59
|
-
// User home directories
|
|
60
|
-
/^\/Users\/[^/]+\//i, // macOS
|
|
61
|
-
/^\/home\/[^/]+\//i, // Linux (allow all users, not just runner)
|
|
62
|
-
/^C:\\Users\\[^\\]+\\/i, // Windows
|
|
63
|
-
// Common project directories
|
|
64
|
-
/^\/opt\//i,
|
|
65
|
-
/^\/var\/www\//i,
|
|
66
|
-
/^\/srv\//i,
|
|
67
|
-
// Temp directories (for testing)
|
|
68
|
-
/^\/tmp\//i,
|
|
69
|
-
/^\/private\/tmp\//i, // macOS real temp path
|
|
70
|
-
/^\/var\/folders\//i, // macOS temp
|
|
71
|
-
/^\/private\/var\/folders\//i, // macOS real temp path (symlink resolved)
|
|
72
|
-
/^C:\\Temp\\/i, // Windows temp
|
|
73
|
-
// CI workspace paths
|
|
74
|
-
/^\/home\/runner\/work\//i, // GitHub Actions
|
|
75
|
-
];
|
|
29
|
+
import { isAllowedResolvedPath, isBlockedResolvedPath } from './path-security-policy.js';
|
|
76
30
|
/**
|
|
77
31
|
* Validates that a file URI is safe and converts it to an absolute path
|
|
78
32
|
*
|
|
@@ -127,17 +81,12 @@ function validatePath(inputPath) {
|
|
|
127
81
|
if (!isAbsolute(resolvedPath)) {
|
|
128
82
|
return { isValid: false, error: 'Path must be absolute' };
|
|
129
83
|
}
|
|
130
|
-
// Check against blocked system paths
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
const blockedLower = blocked.toLowerCase();
|
|
134
|
-
if (lowerPath === blockedLower || lowerPath.startsWith(`${blockedLower}/`) || lowerPath.startsWith(`${blockedLower}\\`)) {
|
|
135
|
-
return { isValid: false, error: 'Access to system directories is not allowed' };
|
|
136
|
-
}
|
|
84
|
+
// Check against blocked system paths and sensitive directory segments
|
|
85
|
+
if (isBlockedResolvedPath(resolvedPath)) {
|
|
86
|
+
return { isValid: false, error: 'Access to system directories is not allowed' };
|
|
137
87
|
}
|
|
138
88
|
// Check that path matches allowed patterns
|
|
139
|
-
|
|
140
|
-
if (!matchesAllowed) {
|
|
89
|
+
if (!isAllowedResolvedPath(resolvedPath)) {
|
|
141
90
|
return {
|
|
142
91
|
isValid: false,
|
|
143
92
|
error: 'Path is outside of allowed workspace directories',
|
|
@@ -187,6 +136,10 @@ export class WorkspaceRootsService {
|
|
|
187
136
|
constructor(logger) {
|
|
188
137
|
this.logger = logger ?? Logger.getInstance();
|
|
189
138
|
}
|
|
139
|
+
sanitizeRootNameForLog(root) {
|
|
140
|
+
const trimmedName = root.name?.trim();
|
|
141
|
+
return trimmedName && trimmedName.length > 0 ? trimmedName : '(unnamed root)';
|
|
142
|
+
}
|
|
190
143
|
/**
|
|
191
144
|
* Update workspace roots from MCP client response
|
|
192
145
|
*
|
|
@@ -349,26 +302,26 @@ export class WorkspaceRootsService {
|
|
|
349
302
|
* @returns Discovery result with config if found
|
|
350
303
|
*/
|
|
351
304
|
discoverDwJson(clientRoots) {
|
|
352
|
-
this.logger.
|
|
305
|
+
this.logger.debug('[WorkspaceRoots] Starting dw.json discovery from client roots');
|
|
353
306
|
// Log what we received from the client
|
|
354
307
|
if (!clientRoots) {
|
|
355
|
-
this.logger.
|
|
308
|
+
this.logger.debug('[WorkspaceRoots] No roots array received from client (undefined)');
|
|
356
309
|
return { success: false, reason: 'No roots array received from client' };
|
|
357
310
|
}
|
|
358
|
-
this.logger.
|
|
311
|
+
this.logger.debug(`[WorkspaceRoots] Received ${clientRoots.length} root(s) from client`);
|
|
359
312
|
if (clientRoots.length === 0) {
|
|
360
|
-
this.logger.
|
|
313
|
+
this.logger.debug('[WorkspaceRoots] Client returned empty roots array');
|
|
361
314
|
return { success: false, reason: 'Client returned empty roots array', rootsReceived: 0 };
|
|
362
315
|
}
|
|
363
|
-
// Log
|
|
316
|
+
// Log root names at debug level only (avoid leaking full URIs routinely).
|
|
364
317
|
clientRoots.forEach((root, index) => {
|
|
365
|
-
this.logger.
|
|
318
|
+
this.logger.debug(`[WorkspaceRoots] Root ${index + 1}: ${this.sanitizeRootNameForLog(root)}`);
|
|
366
319
|
});
|
|
367
320
|
// Validate and store the workspace roots
|
|
368
321
|
const validRoots = this.updateRoots(clientRoots);
|
|
369
|
-
this.logger.
|
|
322
|
+
this.logger.debug(`[WorkspaceRoots] After validation: ${validRoots.length} valid root(s)`);
|
|
370
323
|
if (validRoots.length === 0) {
|
|
371
|
-
this.logger.
|
|
324
|
+
this.logger.debug('[WorkspaceRoots] No valid roots after security validation');
|
|
372
325
|
return {
|
|
373
326
|
success: false,
|
|
374
327
|
reason: 'No valid workspace roots after security validation',
|
|
@@ -376,15 +329,11 @@ export class WorkspaceRootsService {
|
|
|
376
329
|
validRoots: 0,
|
|
377
330
|
};
|
|
378
331
|
}
|
|
379
|
-
// Log validated roots
|
|
380
|
-
validRoots.forEach((root, index) => {
|
|
381
|
-
this.logger.log(`[WorkspaceRoots] Valid root ${index + 1}: path="${root.path}"`);
|
|
382
|
-
});
|
|
383
332
|
// Search for dw.json in workspace roots
|
|
384
|
-
this.logger.
|
|
333
|
+
this.logger.debug('[WorkspaceRoots] Searching for dw.json in workspace roots...');
|
|
385
334
|
const dwJsonPath = this.findFile('dw.json');
|
|
386
335
|
if (!dwJsonPath) {
|
|
387
|
-
this.logger.
|
|
336
|
+
this.logger.debug('[WorkspaceRoots] No dw.json found in any workspace root');
|
|
388
337
|
return {
|
|
389
338
|
success: false,
|
|
390
339
|
reason: 'No dw.json found in workspace roots',
|
|
@@ -392,16 +341,16 @@ export class WorkspaceRootsService {
|
|
|
392
341
|
validRoots: validRoots.length,
|
|
393
342
|
};
|
|
394
343
|
}
|
|
395
|
-
this.logger.
|
|
344
|
+
this.logger.debug('[WorkspaceRoots] Found dw.json in workspace roots');
|
|
396
345
|
// Load and validate the dw.json
|
|
397
346
|
try {
|
|
398
347
|
const config = loadSecureDwJson(dwJsonPath);
|
|
399
|
-
this.logger.log('[WorkspaceRoots]
|
|
400
|
-
this.logger.
|
|
401
|
-
this.logger.
|
|
402
|
-
this.logger.
|
|
403
|
-
this.logger.
|
|
404
|
-
this.logger.
|
|
348
|
+
this.logger.log('[WorkspaceRoots] Discovered valid dw.json from workspace roots');
|
|
349
|
+
this.logger.debug(`[WorkspaceRoots] hostname: ${config.hostname}`);
|
|
350
|
+
this.logger.debug(`[WorkspaceRoots] username: ${config.username ? '(set)' : '(not set)'}`);
|
|
351
|
+
this.logger.debug(`[WorkspaceRoots] password: ${config.password ? '(set)' : '(not set)'}`);
|
|
352
|
+
this.logger.debug(`[WorkspaceRoots] client-id: ${config['client-id'] ? '(set)' : '(not set)'}`);
|
|
353
|
+
this.logger.debug(`[WorkspaceRoots] client-secret: ${config['client-secret'] ? '(set)' : '(not set)'}`);
|
|
405
354
|
return {
|
|
406
355
|
success: true,
|
|
407
356
|
config,
|