@skillsmith/mcp-server 0.1.0
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/dist/.tsbuildinfo +1 -0
- package/dist/src/__tests__/get-skill.test.d.ts +6 -0
- package/dist/src/__tests__/get-skill.test.d.ts.map +1 -0
- package/dist/src/__tests__/get-skill.test.js +88 -0
- package/dist/src/__tests__/get-skill.test.js.map +1 -0
- package/dist/src/__tests__/middleware/errorFormatter.test.d.ts +7 -0
- package/dist/src/__tests__/middleware/errorFormatter.test.d.ts.map +1 -0
- package/dist/src/__tests__/middleware/errorFormatter.test.js +304 -0
- package/dist/src/__tests__/middleware/errorFormatter.test.js.map +1 -0
- package/dist/src/__tests__/middleware/license.test.d.ts +7 -0
- package/dist/src/__tests__/middleware/license.test.d.ts.map +1 -0
- package/dist/src/__tests__/middleware/license.test.js +500 -0
- package/dist/src/__tests__/middleware/license.test.js.map +1 -0
- package/dist/src/__tests__/search.test.d.ts +6 -0
- package/dist/src/__tests__/search.test.d.ts.map +1 -0
- package/dist/src/__tests__/search.test.js +86 -0
- package/dist/src/__tests__/search.test.js.map +1 -0
- package/dist/src/__tests__/test-utils.d.ts +19 -0
- package/dist/src/__tests__/test-utils.d.ts.map +1 -0
- package/dist/src/__tests__/test-utils.js +87 -0
- package/dist/src/__tests__/test-utils.js.map +1 -0
- package/dist/src/context/index.d.ts +19 -0
- package/dist/src/context/index.d.ts.map +1 -0
- package/dist/src/context/index.js +25 -0
- package/dist/src/context/index.js.map +1 -0
- package/dist/src/context/project-detector.d.ts +145 -0
- package/dist/src/context/project-detector.d.ts.map +1 -0
- package/dist/src/context/project-detector.js +321 -0
- package/dist/src/context/project-detector.js.map +1 -0
- package/dist/src/context.d.ts +100 -0
- package/dist/src/context.d.ts.map +1 -0
- package/dist/src/context.js +157 -0
- package/dist/src/context.js.map +1 -0
- package/dist/src/core-shim.d.ts +7 -0
- package/dist/src/core-shim.d.ts.map +1 -0
- package/dist/src/core-shim.js +9 -0
- package/dist/src/core-shim.js.map +1 -0
- package/dist/src/health/healthCheck.d.ts +88 -0
- package/dist/src/health/healthCheck.d.ts.map +1 -0
- package/dist/src/health/healthCheck.js +117 -0
- package/dist/src/health/healthCheck.js.map +1 -0
- package/dist/src/health/index.d.ts +21 -0
- package/dist/src/health/index.d.ts.map +1 -0
- package/dist/src/health/index.js +21 -0
- package/dist/src/health/index.js.map +1 -0
- package/dist/src/health/readinessCheck.d.ts +139 -0
- package/dist/src/health/readinessCheck.d.ts.map +1 -0
- package/dist/src/health/readinessCheck.js +266 -0
- package/dist/src/health/readinessCheck.js.map +1 -0
- package/dist/src/index.d.ts +8 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +178 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/index.test.d.ts +2 -0
- package/dist/src/index.test.d.ts.map +1 -0
- package/dist/src/index.test.js +43 -0
- package/dist/src/index.test.js.map +1 -0
- package/dist/src/logger.d.ts +26 -0
- package/dist/src/logger.d.ts.map +1 -0
- package/dist/src/logger.js +179 -0
- package/dist/src/logger.js.map +1 -0
- package/dist/src/middleware/__tests__/csp.test.d.ts +2 -0
- package/dist/src/middleware/__tests__/csp.test.d.ts.map +1 -0
- package/dist/src/middleware/__tests__/csp.test.js +389 -0
- package/dist/src/middleware/__tests__/csp.test.js.map +1 -0
- package/dist/src/middleware/csp.d.ts +87 -0
- package/dist/src/middleware/csp.d.ts.map +1 -0
- package/dist/src/middleware/csp.js +273 -0
- package/dist/src/middleware/csp.js.map +1 -0
- package/dist/src/middleware/degradation.d.ts +99 -0
- package/dist/src/middleware/degradation.d.ts.map +1 -0
- package/dist/src/middleware/degradation.js +315 -0
- package/dist/src/middleware/degradation.js.map +1 -0
- package/dist/src/middleware/errorFormatter.d.ts +119 -0
- package/dist/src/middleware/errorFormatter.d.ts.map +1 -0
- package/dist/src/middleware/errorFormatter.js +294 -0
- package/dist/src/middleware/errorFormatter.js.map +1 -0
- package/dist/src/middleware/index.d.ts +10 -0
- package/dist/src/middleware/index.d.ts.map +1 -0
- package/dist/src/middleware/index.js +14 -0
- package/dist/src/middleware/index.js.map +1 -0
- package/dist/src/middleware/license.d.ts +161 -0
- package/dist/src/middleware/license.d.ts.map +1 -0
- package/dist/src/middleware/license.js +281 -0
- package/dist/src/middleware/license.js.map +1 -0
- package/dist/src/middleware/toolFeatureMapping.d.ts +36 -0
- package/dist/src/middleware/toolFeatureMapping.d.ts.map +1 -0
- package/dist/src/middleware/toolFeatureMapping.js +90 -0
- package/dist/src/middleware/toolFeatureMapping.js.map +1 -0
- package/dist/src/onboarding/first-run.d.ts +64 -0
- package/dist/src/onboarding/first-run.d.ts.map +1 -0
- package/dist/src/onboarding/first-run.js +77 -0
- package/dist/src/onboarding/first-run.js.map +1 -0
- package/dist/src/onboarding/index.d.ts +7 -0
- package/dist/src/onboarding/index.d.ts.map +1 -0
- package/dist/src/onboarding/index.js +7 -0
- package/dist/src/onboarding/index.js.map +1 -0
- package/dist/src/suggestions/index.d.ts +21 -0
- package/dist/src/suggestions/index.d.ts.map +1 -0
- package/dist/src/suggestions/index.js +20 -0
- package/dist/src/suggestions/index.js.map +1 -0
- package/dist/src/suggestions/suggestion-engine.d.ts +185 -0
- package/dist/src/suggestions/suggestion-engine.d.ts.map +1 -0
- package/dist/src/suggestions/suggestion-engine.js +352 -0
- package/dist/src/suggestions/suggestion-engine.js.map +1 -0
- package/dist/src/suggestions/types.d.ts +88 -0
- package/dist/src/suggestions/types.d.ts.map +1 -0
- package/dist/src/suggestions/types.js +21 -0
- package/dist/src/suggestions/types.js.map +1 -0
- package/dist/src/tools/analyze.d.ts +151 -0
- package/dist/src/tools/analyze.d.ts.map +1 -0
- package/dist/src/tools/analyze.js +205 -0
- package/dist/src/tools/analyze.js.map +1 -0
- package/dist/src/tools/compare.d.ts +149 -0
- package/dist/src/tools/compare.d.ts.map +1 -0
- package/dist/src/tools/compare.js +464 -0
- package/dist/src/tools/compare.js.map +1 -0
- package/dist/src/tools/get-skill.d.ts +116 -0
- package/dist/src/tools/get-skill.d.ts.map +1 -0
- package/dist/src/tools/get-skill.js +224 -0
- package/dist/src/tools/get-skill.js.map +1 -0
- package/dist/src/tools/index.d.ts +20 -0
- package/dist/src/tools/index.d.ts.map +1 -0
- package/dist/src/tools/index.js +20 -0
- package/dist/src/tools/index.js.map +1 -0
- package/dist/src/tools/install.d.ts +122 -0
- package/dist/src/tools/install.d.ts.map +1 -0
- package/dist/src/tools/install.js +314 -0
- package/dist/src/tools/install.js.map +1 -0
- package/dist/src/tools/recommend.d.ts +171 -0
- package/dist/src/tools/recommend.d.ts.map +1 -0
- package/dist/src/tools/recommend.js +325 -0
- package/dist/src/tools/recommend.js.map +1 -0
- package/dist/src/tools/search.d.ts +121 -0
- package/dist/src/tools/search.d.ts.map +1 -0
- package/dist/src/tools/search.js +249 -0
- package/dist/src/tools/search.js.map +1 -0
- package/dist/src/tools/suggest.d.ts +181 -0
- package/dist/src/tools/suggest.d.ts.map +1 -0
- package/dist/src/tools/suggest.js +342 -0
- package/dist/src/tools/suggest.js.map +1 -0
- package/dist/src/tools/uninstall.d.ts +123 -0
- package/dist/src/tools/uninstall.d.ts.map +1 -0
- package/dist/src/tools/uninstall.js +250 -0
- package/dist/src/tools/uninstall.js.map +1 -0
- package/dist/src/tools/validate.d.ts +122 -0
- package/dist/src/tools/validate.d.ts.map +1 -0
- package/dist/src/tools/validate.js +497 -0
- package/dist/src/tools/validate.js.map +1 -0
- package/dist/src/utils/installed-skills.d.ts +101 -0
- package/dist/src/utils/installed-skills.d.ts.map +1 -0
- package/dist/src/utils/installed-skills.js +220 -0
- package/dist/src/utils/installed-skills.js.map +1 -0
- package/dist/src/utils/validation.d.ts +76 -0
- package/dist/src/utils/validation.d.ts.map +1 -0
- package/dist/src/utils/validation.js +153 -0
- package/dist/src/utils/validation.js.map +1 -0
- package/dist/src/webhooks/index.d.ts +8 -0
- package/dist/src/webhooks/index.d.ts.map +1 -0
- package/dist/src/webhooks/index.js +9 -0
- package/dist/src/webhooks/index.js.map +1 -0
- package/dist/src/webhooks/webhook-endpoint.d.ts +149 -0
- package/dist/src/webhooks/webhook-endpoint.d.ts.map +1 -0
- package/dist/src/webhooks/webhook-endpoint.js +339 -0
- package/dist/src/webhooks/webhook-endpoint.js.map +1 -0
- package/dist/tests/compare.test.d.ts +6 -0
- package/dist/tests/compare.test.d.ts.map +1 -0
- package/dist/tests/compare.test.js +225 -0
- package/dist/tests/compare.test.js.map +1 -0
- package/dist/tests/context/project-detector.test.d.ts +6 -0
- package/dist/tests/context/project-detector.test.d.ts.map +1 -0
- package/dist/tests/context/project-detector.test.js +719 -0
- package/dist/tests/context/project-detector.test.js.map +1 -0
- package/dist/tests/e2e/compare.e2e.test.d.ts +10 -0
- package/dist/tests/e2e/compare.e2e.test.d.ts.map +1 -0
- package/dist/tests/e2e/compare.e2e.test.js +286 -0
- package/dist/tests/e2e/compare.e2e.test.js.map +1 -0
- package/dist/tests/e2e/install-flow.e2e.test.d.ts +10 -0
- package/dist/tests/e2e/install-flow.e2e.test.d.ts.map +1 -0
- package/dist/tests/e2e/install-flow.e2e.test.js +209 -0
- package/dist/tests/e2e/install-flow.e2e.test.js.map +1 -0
- package/dist/tests/e2e/recommend.e2e.test.d.ts +12 -0
- package/dist/tests/e2e/recommend.e2e.test.d.ts.map +1 -0
- package/dist/tests/e2e/recommend.e2e.test.js +347 -0
- package/dist/tests/e2e/recommend.e2e.test.js.map +1 -0
- package/dist/tests/e2e/skill-flow.e2e.test.d.ts +10 -0
- package/dist/tests/e2e/skill-flow.e2e.test.d.ts.map +1 -0
- package/dist/tests/e2e/skill-flow.e2e.test.js +280 -0
- package/dist/tests/e2e/skill-flow.e2e.test.js.map +1 -0
- package/dist/tests/e2e/suggest.e2e.test.d.ts +13 -0
- package/dist/tests/e2e/suggest.e2e.test.d.ts.map +1 -0
- package/dist/tests/e2e/suggest.e2e.test.js +347 -0
- package/dist/tests/e2e/suggest.e2e.test.js.map +1 -0
- package/dist/tests/e2e/utils/baseline-collector.d.ts +107 -0
- package/dist/tests/e2e/utils/baseline-collector.d.ts.map +1 -0
- package/dist/tests/e2e/utils/baseline-collector.js +211 -0
- package/dist/tests/e2e/utils/baseline-collector.js.map +1 -0
- package/dist/tests/e2e/utils/hardcoded-detector.d.ts +46 -0
- package/dist/tests/e2e/utils/hardcoded-detector.d.ts.map +1 -0
- package/dist/tests/e2e/utils/hardcoded-detector.js +255 -0
- package/dist/tests/e2e/utils/hardcoded-detector.js.map +1 -0
- package/dist/tests/e2e/utils/index.d.ts +7 -0
- package/dist/tests/e2e/utils/index.d.ts.map +1 -0
- package/dist/tests/e2e/utils/index.js +7 -0
- package/dist/tests/e2e/utils/index.js.map +1 -0
- package/dist/tests/e2e/utils/linear-reporter.d.ts +60 -0
- package/dist/tests/e2e/utils/linear-reporter.d.ts.map +1 -0
- package/dist/tests/e2e/utils/linear-reporter.js +232 -0
- package/dist/tests/e2e/utils/linear-reporter.js.map +1 -0
- package/dist/tests/health.test.d.ts +9 -0
- package/dist/tests/health.test.d.ts.map +1 -0
- package/dist/tests/health.test.js +308 -0
- package/dist/tests/health.test.js.map +1 -0
- package/dist/tests/integration/analyze.integration.test.d.ts +2 -0
- package/dist/tests/integration/analyze.integration.test.d.ts.map +1 -0
- package/dist/tests/integration/analyze.integration.test.js +244 -0
- package/dist/tests/integration/analyze.integration.test.js.map +1 -0
- package/dist/tests/integration/compare.integration.test.d.ts +2 -0
- package/dist/tests/integration/compare.integration.test.d.ts.map +1 -0
- package/dist/tests/integration/compare.integration.test.js +120 -0
- package/dist/tests/integration/compare.integration.test.js.map +1 -0
- package/dist/tests/integration/fixtures/test-skills.d.ts +62 -0
- package/dist/tests/integration/fixtures/test-skills.d.ts.map +1 -0
- package/dist/tests/integration/fixtures/test-skills.js +644 -0
- package/dist/tests/integration/fixtures/test-skills.js.map +1 -0
- package/dist/tests/integration/get-skill.integration.test.d.ts +6 -0
- package/dist/tests/integration/get-skill.integration.test.d.ts.map +1 -0
- package/dist/tests/integration/get-skill.integration.test.js +203 -0
- package/dist/tests/integration/get-skill.integration.test.js.map +1 -0
- package/dist/tests/integration/github-api.integration.test.d.ts +14 -0
- package/dist/tests/integration/github-api.integration.test.d.ts.map +1 -0
- package/dist/tests/integration/github-api.integration.test.js +190 -0
- package/dist/tests/integration/github-api.integration.test.js.map +1 -0
- package/dist/tests/integration/install.integration.test.d.ts +6 -0
- package/dist/tests/integration/install.integration.test.d.ts.map +1 -0
- package/dist/tests/integration/install.integration.test.js +282 -0
- package/dist/tests/integration/install.integration.test.js.map +1 -0
- package/dist/tests/integration/recommend.integration.test.d.ts +2 -0
- package/dist/tests/integration/recommend.integration.test.d.ts.map +1 -0
- package/dist/tests/integration/recommend.integration.test.js +215 -0
- package/dist/tests/integration/recommend.integration.test.js.map +1 -0
- package/dist/tests/integration/search.integration.test.d.ts +6 -0
- package/dist/tests/integration/search.integration.test.d.ts.map +1 -0
- package/dist/tests/integration/search.integration.test.js +229 -0
- package/dist/tests/integration/search.integration.test.js.map +1 -0
- package/dist/tests/integration/setup.d.ts +71 -0
- package/dist/tests/integration/setup.d.ts.map +1 -0
- package/dist/tests/integration/setup.js +124 -0
- package/dist/tests/integration/setup.js.map +1 -0
- package/dist/tests/integration/uninstall.integration.test.d.ts +6 -0
- package/dist/tests/integration/uninstall.integration.test.d.ts.map +1 -0
- package/dist/tests/integration/uninstall.integration.test.js +296 -0
- package/dist/tests/integration/uninstall.integration.test.js.map +1 -0
- package/dist/tests/integration/validate.integration.test.d.ts +2 -0
- package/dist/tests/integration/validate.integration.test.d.ts.map +1 -0
- package/dist/tests/integration/validate.integration.test.js +181 -0
- package/dist/tests/integration/validate.integration.test.js.map +1 -0
- package/dist/tests/onboarding/first-run.test.d.ts +7 -0
- package/dist/tests/onboarding/first-run.test.d.ts.map +1 -0
- package/dist/tests/onboarding/first-run.test.js +258 -0
- package/dist/tests/onboarding/first-run.test.js.map +1 -0
- package/dist/tests/performance/search-performance.test.d.ts +10 -0
- package/dist/tests/performance/search-performance.test.d.ts.map +1 -0
- package/dist/tests/performance/search-performance.test.js +218 -0
- package/dist/tests/performance/search-performance.test.js.map +1 -0
- package/dist/tests/recommend.test.d.ts +6 -0
- package/dist/tests/recommend.test.d.ts.map +1 -0
- package/dist/tests/recommend.test.js +208 -0
- package/dist/tests/recommend.test.js.map +1 -0
- package/dist/tests/suggestions/suggestion-engine.test.d.ts +6 -0
- package/dist/tests/suggestions/suggestion-engine.test.d.ts.map +1 -0
- package/dist/tests/suggestions/suggestion-engine.test.js +448 -0
- package/dist/tests/suggestions/suggestion-engine.test.js.map +1 -0
- package/dist/tests/test-utils.d.ts +74 -0
- package/dist/tests/test-utils.d.ts.map +1 -0
- package/dist/tests/test-utils.js +98 -0
- package/dist/tests/test-utils.js.map +1 -0
- package/dist/tests/tools.test.d.ts +5 -0
- package/dist/tests/tools.test.d.ts.map +1 -0
- package/dist/tests/tools.test.js +138 -0
- package/dist/tests/tools.test.js.map +1 -0
- package/dist/tests/unit/installed-skills.test.d.ts +6 -0
- package/dist/tests/unit/installed-skills.test.d.ts.map +1 -0
- package/dist/tests/unit/installed-skills.test.js +285 -0
- package/dist/tests/unit/installed-skills.test.js.map +1 -0
- package/dist/tests/unit/logger.test.d.ts +6 -0
- package/dist/tests/unit/logger.test.d.ts.map +1 -0
- package/dist/tests/unit/logger.test.js +281 -0
- package/dist/tests/unit/logger.test.js.map +1 -0
- package/dist/tests/validate.test.d.ts +5 -0
- package/dist/tests/validate.test.d.ts.map +1 -0
- package/dist/tests/validate.test.js +303 -0
- package/dist/tests/validate.test.js.map +1 -0
- package/dist/tests/webhooks/proxy-trust.security.test.d.ts +8 -0
- package/dist/tests/webhooks/proxy-trust.security.test.d.ts.map +1 -0
- package/dist/tests/webhooks/proxy-trust.security.test.js +145 -0
- package/dist/tests/webhooks/proxy-trust.security.test.js.map +1 -0
- package/dist/tests/webhooks/rate-limiter.security.test.d.ts +8 -0
- package/dist/tests/webhooks/rate-limiter.security.test.d.ts.map +1 -0
- package/dist/tests/webhooks/rate-limiter.security.test.js +122 -0
- package/dist/tests/webhooks/rate-limiter.security.test.js.map +1 -0
- package/dist/vitest.config.d.ts +6 -0
- package/dist/vitest.config.d.ts.map +1 -0
- package/dist/vitest.config.js +13 -0
- package/dist/vitest.config.js.map +1 -0
- package/package.json +63 -0
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SMI-583: Logging utility for MCP server
|
|
3
|
+
* SMI-883: Sanitizes sensitive data before logging to prevent data leakage
|
|
4
|
+
* Logs errors to ~/.skillsmith/logs/
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* SMI-883: Redact sensitive data from text before logging
|
|
8
|
+
* Exported for testing purposes
|
|
9
|
+
*/
|
|
10
|
+
export declare function redactSensitiveData(text: string): string;
|
|
11
|
+
/**
|
|
12
|
+
* SMI-883: Recursively redact sensitive data from objects
|
|
13
|
+
* Exported for testing purposes
|
|
14
|
+
*/
|
|
15
|
+
export declare function redactSensitiveObject(obj: unknown): unknown;
|
|
16
|
+
/**
|
|
17
|
+
* Logger interface
|
|
18
|
+
*/
|
|
19
|
+
export declare const logger: {
|
|
20
|
+
info(message: string, details?: unknown): void;
|
|
21
|
+
warn(message: string, details?: unknown): void;
|
|
22
|
+
error(message: string, details?: unknown): void;
|
|
23
|
+
debug(message: string, details?: unknown): void;
|
|
24
|
+
};
|
|
25
|
+
export default logger;
|
|
26
|
+
//# sourceMappingURL=logger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/logger.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAuEH;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CASxD;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAY3D;AA2DD;;GAEG;AACH,eAAO,MAAM,MAAM;kBACH,MAAM,YAAY,OAAO,GAAG,IAAI;kBAIhC,MAAM,YAAY,OAAO,GAAG,IAAI;mBAI/B,MAAM,YAAY,OAAO,GAAG,IAAI;mBAIhC,MAAM,YAAY,OAAO,GAAG,IAAI;CAKhD,CAAA;AAED,eAAe,MAAM,CAAA"}
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SMI-583: Logging utility for MCP server
|
|
3
|
+
* SMI-883: Sanitizes sensitive data before logging to prevent data leakage
|
|
4
|
+
* Logs errors to ~/.skillsmith/logs/
|
|
5
|
+
*/
|
|
6
|
+
import { existsSync, mkdirSync, appendFileSync } from 'node:fs';
|
|
7
|
+
import { homedir } from 'node:os';
|
|
8
|
+
import { join } from 'node:path';
|
|
9
|
+
/**
|
|
10
|
+
* SMI-883: Sensitive data patterns to redact before logging
|
|
11
|
+
* Prevents API keys, tokens, passwords, and secrets from being written to disk
|
|
12
|
+
*/
|
|
13
|
+
const SENSITIVE_PATTERNS = [
|
|
14
|
+
// GitHub tokens
|
|
15
|
+
{ pattern: /\b(ghp_[a-zA-Z0-9]{36})\b/g, replacement: 'ghp_[REDACTED]' },
|
|
16
|
+
{ pattern: /\b(github_pat_[a-zA-Z0-9_]{22,})\b/g, replacement: 'github_pat_[REDACTED]' },
|
|
17
|
+
{ pattern: /\b(gho_[a-zA-Z0-9]{36})\b/g, replacement: 'gho_[REDACTED]' },
|
|
18
|
+
{ pattern: /\b(ghs_[a-zA-Z0-9]{36})\b/g, replacement: 'ghs_[REDACTED]' },
|
|
19
|
+
{ pattern: /\b(ghu_[a-zA-Z0-9]{36})\b/g, replacement: 'ghu_[REDACTED]' },
|
|
20
|
+
{ pattern: /\b(ghr_[a-zA-Z0-9]{36})\b/g, replacement: 'ghr_[REDACTED]' },
|
|
21
|
+
// Linear API keys
|
|
22
|
+
{ pattern: /\b(lin_api_[a-zA-Z0-9]{32,})\b/g, replacement: 'lin_api_[REDACTED]' },
|
|
23
|
+
// Stripe keys
|
|
24
|
+
{ pattern: /\b(sk_live_[a-zA-Z0-9]{24,})\b/g, replacement: 'sk_live_[REDACTED]' },
|
|
25
|
+
{ pattern: /\b(sk_test_[a-zA-Z0-9]{24,})\b/g, replacement: 'sk_test_[REDACTED]' },
|
|
26
|
+
{ pattern: /\b(pk_live_[a-zA-Z0-9]{24,})\b/g, replacement: 'pk_live_[REDACTED]' },
|
|
27
|
+
{ pattern: /\b(pk_test_[a-zA-Z0-9]{24,})\b/g, replacement: 'pk_test_[REDACTED]' },
|
|
28
|
+
// OpenAI API keys
|
|
29
|
+
{ pattern: /\b(sk-[a-zA-Z0-9]{48,})\b/g, replacement: 'sk-[REDACTED]' },
|
|
30
|
+
// Anthropic API keys
|
|
31
|
+
{ pattern: /\b(sk-ant-[a-zA-Z0-9-]{32,})\b/g, replacement: 'sk-ant-[REDACTED]' },
|
|
32
|
+
// AWS keys
|
|
33
|
+
{ pattern: /\b(AKIA[A-Z0-9]{16})\b/g, replacement: 'AKIA[REDACTED]' },
|
|
34
|
+
// Slack tokens
|
|
35
|
+
{ pattern: /\b(xox[boaprs]-[a-zA-Z0-9-]{10,})\b/g, replacement: 'xox*-[REDACTED]' },
|
|
36
|
+
// npm tokens
|
|
37
|
+
{ pattern: /\b(npm_[a-zA-Z0-9]{36})\b/g, replacement: 'npm_[REDACTED]' },
|
|
38
|
+
// Bearer tokens
|
|
39
|
+
{ pattern: /\bBearer\s+([a-zA-Z0-9_\-.]{20,})/gi, replacement: 'Bearer [REDACTED]' },
|
|
40
|
+
// Basic auth
|
|
41
|
+
{ pattern: /\bBasic\s+([a-zA-Z0-9+/=]{20,})/gi, replacement: 'Basic [REDACTED]' },
|
|
42
|
+
// JWT tokens
|
|
43
|
+
{
|
|
44
|
+
pattern: /\beyJ[a-zA-Z0-9_-]*\.eyJ[a-zA-Z0-9_-]*\.[a-zA-Z0-9_-]+\b/g,
|
|
45
|
+
replacement: '[JWT_REDACTED]',
|
|
46
|
+
},
|
|
47
|
+
// Generic API key patterns
|
|
48
|
+
{
|
|
49
|
+
pattern: /\b(api[_-]?key|apikey)\s*[=:]\s*["']?([a-zA-Z0-9_-]{8,})["']?/gi,
|
|
50
|
+
replacement: 'api_key=[REDACTED]',
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
pattern: /\b(token|auth[_-]?token)\s*[=:]\s*["']?([a-zA-Z0-9_-]{8,})["']?/gi,
|
|
54
|
+
replacement: 'token=[REDACTED]',
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
pattern: /\b(password|passwd|pwd)\s*[=:]\s*["']?([^"'\s]{4,})["']?/gi,
|
|
58
|
+
replacement: 'password=[REDACTED]',
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
pattern: /\b(secret|client[_-]?secret)\s*[=:]\s*["']?([a-zA-Z0-9_-]{8,})["']?/gi,
|
|
62
|
+
replacement: 'secret=[REDACTED]',
|
|
63
|
+
},
|
|
64
|
+
// Connection strings with passwords
|
|
65
|
+
{ pattern: /(:\/\/[^:]+:)([^@]+)(@)/gi, replacement: '$1[REDACTED]$3' },
|
|
66
|
+
// Private keys
|
|
67
|
+
{
|
|
68
|
+
pattern: /-----BEGIN\s+(RSA\s+)?PRIVATE\s+KEY-----[\s\S]*?-----END\s+(RSA\s+)?PRIVATE\s+KEY-----/gi,
|
|
69
|
+
replacement: '-----[PRIVATE KEY REDACTED]-----',
|
|
70
|
+
},
|
|
71
|
+
];
|
|
72
|
+
/**
|
|
73
|
+
* SMI-883: Redact sensitive data from text before logging
|
|
74
|
+
* Exported for testing purposes
|
|
75
|
+
*/
|
|
76
|
+
export function redactSensitiveData(text) {
|
|
77
|
+
if (!text)
|
|
78
|
+
return text;
|
|
79
|
+
let redacted = text;
|
|
80
|
+
for (const { pattern, replacement } of SENSITIVE_PATTERNS) {
|
|
81
|
+
// Reset lastIndex for global regex patterns to ensure all matches are found
|
|
82
|
+
pattern.lastIndex = 0;
|
|
83
|
+
redacted = redacted.replace(pattern, replacement);
|
|
84
|
+
}
|
|
85
|
+
return redacted;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* SMI-883: Recursively redact sensitive data from objects
|
|
89
|
+
* Exported for testing purposes
|
|
90
|
+
*/
|
|
91
|
+
export function redactSensitiveObject(obj) {
|
|
92
|
+
if (obj === null || obj === undefined)
|
|
93
|
+
return obj;
|
|
94
|
+
if (typeof obj === 'string')
|
|
95
|
+
return redactSensitiveData(obj);
|
|
96
|
+
if (Array.isArray(obj))
|
|
97
|
+
return obj.map(redactSensitiveObject);
|
|
98
|
+
if (typeof obj === 'object') {
|
|
99
|
+
const result = {};
|
|
100
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
101
|
+
result[key] = redactSensitiveObject(value);
|
|
102
|
+
}
|
|
103
|
+
return result;
|
|
104
|
+
}
|
|
105
|
+
return obj;
|
|
106
|
+
}
|
|
107
|
+
const LOG_DIR = join(homedir(), '.skillsmith', 'logs');
|
|
108
|
+
/**
|
|
109
|
+
* Ensure log directory exists
|
|
110
|
+
*/
|
|
111
|
+
function ensureLogDir() {
|
|
112
|
+
if (!existsSync(LOG_DIR)) {
|
|
113
|
+
mkdirSync(LOG_DIR, { recursive: true });
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Format date for log filename
|
|
118
|
+
*/
|
|
119
|
+
function getLogFilename() {
|
|
120
|
+
const date = new Date();
|
|
121
|
+
const dateStr = date.toISOString().split('T')[0];
|
|
122
|
+
return join(LOG_DIR, 'mcp-server-' + dateStr + '.log');
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Format log entry
|
|
126
|
+
* SMI-883: Sanitizes message and details to prevent sensitive data leakage
|
|
127
|
+
*/
|
|
128
|
+
function formatLogEntry(level, message, details) {
|
|
129
|
+
const timestamp = new Date().toISOString();
|
|
130
|
+
// SMI-883: Redact sensitive data from message
|
|
131
|
+
const sanitizedMessage = redactSensitiveData(message);
|
|
132
|
+
let entry = '[' + timestamp + '] [' + level + '] ' + sanitizedMessage;
|
|
133
|
+
if (details !== undefined) {
|
|
134
|
+
try {
|
|
135
|
+
// SMI-883: Redact sensitive data from details object before serialization
|
|
136
|
+
const sanitizedDetails = redactSensitiveObject(details);
|
|
137
|
+
entry += '\n Details: ' + JSON.stringify(sanitizedDetails, null, 2).replace(/\n/g, '\n ');
|
|
138
|
+
}
|
|
139
|
+
catch {
|
|
140
|
+
entry += '\n Details: [Unable to serialize]';
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
return entry + '\n';
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Write log entry to file
|
|
147
|
+
*/
|
|
148
|
+
function writeLog(level, message, details) {
|
|
149
|
+
try {
|
|
150
|
+
ensureLogDir();
|
|
151
|
+
const entry = formatLogEntry(level, message, details);
|
|
152
|
+
appendFileSync(getLogFilename(), entry);
|
|
153
|
+
}
|
|
154
|
+
catch {
|
|
155
|
+
// Silently fail if unable to write logs
|
|
156
|
+
// Don't want logging failures to break the application
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Logger interface
|
|
161
|
+
*/
|
|
162
|
+
export const logger = {
|
|
163
|
+
info(message, details) {
|
|
164
|
+
writeLog('INFO', message, details);
|
|
165
|
+
},
|
|
166
|
+
warn(message, details) {
|
|
167
|
+
writeLog('WARN', message, details);
|
|
168
|
+
},
|
|
169
|
+
error(message, details) {
|
|
170
|
+
writeLog('ERROR', message, details);
|
|
171
|
+
},
|
|
172
|
+
debug(message, details) {
|
|
173
|
+
if (process.env.DEBUG) {
|
|
174
|
+
writeLog('DEBUG', message, details);
|
|
175
|
+
}
|
|
176
|
+
},
|
|
177
|
+
};
|
|
178
|
+
export default logger;
|
|
179
|
+
//# sourceMappingURL=logger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/logger.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"csp.test.d.ts","sourceRoot":"","sources":["../../../../src/middleware/__tests__/csp.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,389 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for Content Security Policy middleware and utilities
|
|
3
|
+
*/
|
|
4
|
+
import { describe, it, expect, beforeEach, vi } from 'vitest';
|
|
5
|
+
import { DEFAULT_CSP_DIRECTIVES, STRICT_CSP_DIRECTIVES, generateNonce, buildCspHeader, validateCspHeader, validateCspHeaderDetailed, cspMiddleware, getCspForEnvironment, } from '../csp.js';
|
|
6
|
+
describe('CSP Utilities', () => {
|
|
7
|
+
describe('generateNonce', () => {
|
|
8
|
+
it('should generate a nonce', () => {
|
|
9
|
+
const nonce = generateNonce();
|
|
10
|
+
expect(nonce).toBeDefined();
|
|
11
|
+
expect(typeof nonce).toBe('string');
|
|
12
|
+
});
|
|
13
|
+
it('should generate nonces of sufficient length', () => {
|
|
14
|
+
const nonce = generateNonce();
|
|
15
|
+
expect(nonce.length).toBeGreaterThanOrEqual(16);
|
|
16
|
+
});
|
|
17
|
+
it('should generate unique nonces', () => {
|
|
18
|
+
const nonce1 = generateNonce();
|
|
19
|
+
const nonce2 = generateNonce();
|
|
20
|
+
expect(nonce1).not.toBe(nonce2);
|
|
21
|
+
});
|
|
22
|
+
it('should generate valid base64 nonces', () => {
|
|
23
|
+
const nonce = generateNonce();
|
|
24
|
+
// Base64 can include A-Z, a-z, 0-9, +, /, and = for padding
|
|
25
|
+
expect(nonce).toMatch(/^[A-Za-z0-9+/]+=*$/);
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
describe('buildCspHeader', () => {
|
|
29
|
+
it('should build a basic CSP header', () => {
|
|
30
|
+
const directives = {
|
|
31
|
+
'default-src': ["'self'"],
|
|
32
|
+
'script-src': ["'self'"],
|
|
33
|
+
};
|
|
34
|
+
const header = buildCspHeader(directives);
|
|
35
|
+
expect(header).toContain("default-src 'self'");
|
|
36
|
+
expect(header).toContain("script-src 'self'");
|
|
37
|
+
});
|
|
38
|
+
it('should add nonce to script-src', () => {
|
|
39
|
+
const directives = {
|
|
40
|
+
'script-src': ["'self'"],
|
|
41
|
+
};
|
|
42
|
+
// Use valid base64 nonce (no hyphens)
|
|
43
|
+
const nonce = 'dGVzdG5vbmNlMTIz';
|
|
44
|
+
const header = buildCspHeader(directives, nonce);
|
|
45
|
+
expect(header).toContain(`'nonce-${nonce}'`);
|
|
46
|
+
});
|
|
47
|
+
it('should add nonce to style-src', () => {
|
|
48
|
+
const directives = {
|
|
49
|
+
'style-src': ["'self'"],
|
|
50
|
+
};
|
|
51
|
+
// Use valid base64 nonce (no hyphens)
|
|
52
|
+
const nonce = 'dGVzdG5vbmNlMTIz';
|
|
53
|
+
const header = buildCspHeader(directives, nonce);
|
|
54
|
+
expect(header).toContain(`'nonce-${nonce}'`);
|
|
55
|
+
});
|
|
56
|
+
it('should handle boolean directives', () => {
|
|
57
|
+
const directives = {
|
|
58
|
+
'upgrade-insecure-requests': true,
|
|
59
|
+
'block-all-mixed-content': true,
|
|
60
|
+
};
|
|
61
|
+
const header = buildCspHeader(directives);
|
|
62
|
+
expect(header).toContain('upgrade-insecure-requests');
|
|
63
|
+
expect(header).toContain('block-all-mixed-content');
|
|
64
|
+
});
|
|
65
|
+
it('should not include false boolean directives', () => {
|
|
66
|
+
const directives = {
|
|
67
|
+
'upgrade-insecure-requests': false,
|
|
68
|
+
};
|
|
69
|
+
const header = buildCspHeader(directives);
|
|
70
|
+
expect(header).not.toContain('upgrade-insecure-requests');
|
|
71
|
+
});
|
|
72
|
+
it('should handle multiple sources', () => {
|
|
73
|
+
const directives = {
|
|
74
|
+
'img-src': ["'self'", 'data:', 'https:'],
|
|
75
|
+
};
|
|
76
|
+
const header = buildCspHeader(directives);
|
|
77
|
+
expect(header).toContain("img-src 'self' data: https:");
|
|
78
|
+
});
|
|
79
|
+
it('should use DEFAULT_CSP_DIRECTIVES', () => {
|
|
80
|
+
const header = buildCspHeader(DEFAULT_CSP_DIRECTIVES);
|
|
81
|
+
expect(header).toContain("default-src 'self'");
|
|
82
|
+
expect(header).toContain("script-src 'self'");
|
|
83
|
+
expect(header).toContain("object-src 'none'");
|
|
84
|
+
expect(header).toContain('upgrade-insecure-requests');
|
|
85
|
+
});
|
|
86
|
+
it('should use STRICT_CSP_DIRECTIVES', () => {
|
|
87
|
+
const header = buildCspHeader(STRICT_CSP_DIRECTIVES);
|
|
88
|
+
expect(header).toContain("default-src 'none'");
|
|
89
|
+
expect(header).toContain("script-src 'self'");
|
|
90
|
+
expect(header).toContain("object-src 'none'");
|
|
91
|
+
});
|
|
92
|
+
it('should handle string directives like report-to', () => {
|
|
93
|
+
const directives = {
|
|
94
|
+
'default-src': ["'self'"],
|
|
95
|
+
'report-to': 'csp-endpoint',
|
|
96
|
+
};
|
|
97
|
+
const header = buildCspHeader(directives);
|
|
98
|
+
expect(header).toContain('report-to csp-endpoint');
|
|
99
|
+
});
|
|
100
|
+
it('should include all STRICT_CSP_DIRECTIVES values', () => {
|
|
101
|
+
const header = buildCspHeader(STRICT_CSP_DIRECTIVES);
|
|
102
|
+
expect(header).toContain("worker-src 'none'");
|
|
103
|
+
expect(header).toContain("form-action 'none'");
|
|
104
|
+
expect(header).toContain("frame-ancestors 'none'");
|
|
105
|
+
expect(header).toContain("base-uri 'none'");
|
|
106
|
+
expect(header).toContain("manifest-src 'self'");
|
|
107
|
+
expect(header).toContain("require-trusted-types-for 'script'");
|
|
108
|
+
});
|
|
109
|
+
it('should properly format nonce in script-src', () => {
|
|
110
|
+
const directives = {
|
|
111
|
+
'script-src': ["'self'"],
|
|
112
|
+
};
|
|
113
|
+
const nonce = 'abc123XYZ';
|
|
114
|
+
const header = buildCspHeader(directives, nonce);
|
|
115
|
+
expect(header).toBe("script-src 'self' 'nonce-abc123XYZ'");
|
|
116
|
+
});
|
|
117
|
+
});
|
|
118
|
+
describe('validateCspHeader', () => {
|
|
119
|
+
it('should validate a proper CSP header', () => {
|
|
120
|
+
const header = "default-src 'self'; script-src 'self'";
|
|
121
|
+
expect(validateCspHeader(header)).toBe(true);
|
|
122
|
+
});
|
|
123
|
+
it('should reject empty CSP', () => {
|
|
124
|
+
expect(validateCspHeader('')).toBe(false);
|
|
125
|
+
});
|
|
126
|
+
it('should reject non-string CSP', () => {
|
|
127
|
+
expect(validateCspHeader(null)).toBe(false);
|
|
128
|
+
expect(validateCspHeader(undefined)).toBe(false);
|
|
129
|
+
expect(validateCspHeader(123)).toBe(false);
|
|
130
|
+
});
|
|
131
|
+
it('should warn about unsafe-eval', () => {
|
|
132
|
+
const consoleSpy = vi.spyOn(console, 'warn').mockImplementation(() => { });
|
|
133
|
+
const header = "script-src 'self' 'unsafe-eval'";
|
|
134
|
+
validateCspHeader(header);
|
|
135
|
+
expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining('unsafe-eval'));
|
|
136
|
+
consoleSpy.mockRestore();
|
|
137
|
+
});
|
|
138
|
+
it('should warn about unsafe-inline without nonce', () => {
|
|
139
|
+
const consoleSpy = vi.spyOn(console, 'warn').mockImplementation(() => { });
|
|
140
|
+
const header = "script-src 'self' 'unsafe-inline'";
|
|
141
|
+
validateCspHeader(header);
|
|
142
|
+
expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining('unsafe-inline'));
|
|
143
|
+
consoleSpy.mockRestore();
|
|
144
|
+
});
|
|
145
|
+
it('should not warn about unsafe-inline with nonce', () => {
|
|
146
|
+
const consoleSpy = vi.spyOn(console, 'warn').mockImplementation(() => { });
|
|
147
|
+
const header = "script-src 'self' 'unsafe-inline' 'nonce-abc123'";
|
|
148
|
+
validateCspHeader(header);
|
|
149
|
+
expect(consoleSpy).not.toHaveBeenCalled();
|
|
150
|
+
consoleSpy.mockRestore();
|
|
151
|
+
});
|
|
152
|
+
it('should reject CSP without directives', () => {
|
|
153
|
+
const header = 'not a valid csp';
|
|
154
|
+
expect(validateCspHeader(header)).toBe(false);
|
|
155
|
+
});
|
|
156
|
+
it('should accept sandbox as a valid directive', () => {
|
|
157
|
+
const header = 'sandbox allow-scripts';
|
|
158
|
+
expect(validateCspHeader(header)).toBe(true);
|
|
159
|
+
});
|
|
160
|
+
});
|
|
161
|
+
describe('validateCspHeaderDetailed', () => {
|
|
162
|
+
it('should return detailed validation result for valid CSP', () => {
|
|
163
|
+
const header = "default-src 'self'; script-src 'self'";
|
|
164
|
+
const result = validateCspHeaderDetailed(header);
|
|
165
|
+
expect(result.valid).toBe(true);
|
|
166
|
+
expect(result.errors).toHaveLength(0);
|
|
167
|
+
});
|
|
168
|
+
it('should return error for empty CSP', () => {
|
|
169
|
+
const result = validateCspHeaderDetailed('');
|
|
170
|
+
expect(result.valid).toBe(false);
|
|
171
|
+
expect(result.errors).toContain('CSP header must be a non-empty string');
|
|
172
|
+
});
|
|
173
|
+
it('should warn about wildcard in script-src', () => {
|
|
174
|
+
const consoleSpy = vi.spyOn(console, 'warn').mockImplementation(() => { });
|
|
175
|
+
const header = "script-src 'self' *";
|
|
176
|
+
const result = validateCspHeaderDetailed(header);
|
|
177
|
+
expect(result.warnings).toContain('Wildcard (*) in script-src is overly permissive');
|
|
178
|
+
consoleSpy.mockRestore();
|
|
179
|
+
});
|
|
180
|
+
it('should warn about data: URI in script-src', () => {
|
|
181
|
+
const consoleSpy = vi.spyOn(console, 'warn').mockImplementation(() => { });
|
|
182
|
+
const header = "script-src 'self' data:";
|
|
183
|
+
const result = validateCspHeaderDetailed(header);
|
|
184
|
+
expect(result.warnings).toContain('data: URI in script-src allows XSS attacks');
|
|
185
|
+
consoleSpy.mockRestore();
|
|
186
|
+
});
|
|
187
|
+
it('should warn about missing default-src', () => {
|
|
188
|
+
const consoleSpy = vi.spyOn(console, 'warn').mockImplementation(() => { });
|
|
189
|
+
const header = "script-src 'self'";
|
|
190
|
+
const result = validateCspHeaderDetailed(header);
|
|
191
|
+
expect(result.warnings).toContain('Missing default-src - other directives may fall back to permissive defaults');
|
|
192
|
+
consoleSpy.mockRestore();
|
|
193
|
+
});
|
|
194
|
+
it('should include warning details for unsafe-eval', () => {
|
|
195
|
+
const consoleSpy = vi.spyOn(console, 'warn').mockImplementation(() => { });
|
|
196
|
+
const header = "default-src 'self'; script-src 'self' 'unsafe-eval'";
|
|
197
|
+
const result = validateCspHeaderDetailed(header);
|
|
198
|
+
// Updated warning message for per-directive validation
|
|
199
|
+
expect(result.warnings).toContain('unsafe-eval detected in script-src or default-src - allows arbitrary code execution');
|
|
200
|
+
consoleSpy.mockRestore();
|
|
201
|
+
});
|
|
202
|
+
it('should include warning details for unsafe-inline without nonce', () => {
|
|
203
|
+
const consoleSpy = vi.spyOn(console, 'warn').mockImplementation(() => { });
|
|
204
|
+
const header = "default-src 'self'; script-src 'self' 'unsafe-inline'";
|
|
205
|
+
const result = validateCspHeaderDetailed(header);
|
|
206
|
+
// Updated warning message for per-directive validation
|
|
207
|
+
expect(result.warnings).toContain('unsafe-inline without nonce in script-src - vulnerable to XSS');
|
|
208
|
+
consoleSpy.mockRestore();
|
|
209
|
+
});
|
|
210
|
+
it('should not warn about unsafe-inline when nonce is present', () => {
|
|
211
|
+
const consoleSpy = vi.spyOn(console, 'warn').mockImplementation(() => { });
|
|
212
|
+
const header = "default-src 'self'; script-src 'self' 'unsafe-inline' 'nonce-abc123'";
|
|
213
|
+
const result = validateCspHeaderDetailed(header);
|
|
214
|
+
// Updated warning message check
|
|
215
|
+
expect(result.warnings).not.toContain('unsafe-inline without nonce in script-src - vulnerable to XSS');
|
|
216
|
+
consoleSpy.mockRestore();
|
|
217
|
+
});
|
|
218
|
+
});
|
|
219
|
+
describe('cspMiddleware', () => {
|
|
220
|
+
let mockReq;
|
|
221
|
+
let mockRes;
|
|
222
|
+
let mockNext;
|
|
223
|
+
beforeEach(() => {
|
|
224
|
+
mockReq = {};
|
|
225
|
+
mockRes = {
|
|
226
|
+
setHeader: vi.fn(),
|
|
227
|
+
locals: {},
|
|
228
|
+
};
|
|
229
|
+
mockNext = vi.fn();
|
|
230
|
+
});
|
|
231
|
+
it('should set CSP header', () => {
|
|
232
|
+
const middleware = cspMiddleware();
|
|
233
|
+
middleware(mockReq, mockRes, mockNext);
|
|
234
|
+
expect(mockRes.setHeader).toHaveBeenCalledWith('Content-Security-Policy', expect.any(String));
|
|
235
|
+
});
|
|
236
|
+
it('should add nonce to response locals', () => {
|
|
237
|
+
const middleware = cspMiddleware();
|
|
238
|
+
middleware(mockReq, mockRes, mockNext);
|
|
239
|
+
expect(mockRes.locals.cspNonce).toBeDefined();
|
|
240
|
+
expect(typeof mockRes.locals.cspNonce).toBe('string');
|
|
241
|
+
});
|
|
242
|
+
it('should call next', () => {
|
|
243
|
+
const middleware = cspMiddleware();
|
|
244
|
+
middleware(mockReq, mockRes, mockNext);
|
|
245
|
+
expect(mockNext).toHaveBeenCalled();
|
|
246
|
+
});
|
|
247
|
+
it('should use custom directives', () => {
|
|
248
|
+
const customDirectives = {
|
|
249
|
+
'default-src': ["'none'"],
|
|
250
|
+
};
|
|
251
|
+
const middleware = cspMiddleware(customDirectives);
|
|
252
|
+
middleware(mockReq, mockRes, mockNext);
|
|
253
|
+
const cspHeader = mockRes.setHeader.mock.calls[0][1];
|
|
254
|
+
expect(cspHeader).toContain("default-src 'none'");
|
|
255
|
+
});
|
|
256
|
+
it('should create locals object if missing', () => {
|
|
257
|
+
mockRes.locals = undefined;
|
|
258
|
+
const middleware = cspMiddleware();
|
|
259
|
+
middleware(mockReq, mockRes, mockNext);
|
|
260
|
+
expect(mockRes.locals).toBeDefined();
|
|
261
|
+
expect(mockRes.locals.cspNonce).toBeDefined();
|
|
262
|
+
});
|
|
263
|
+
});
|
|
264
|
+
describe('getCspForEnvironment', () => {
|
|
265
|
+
it('should return strict CSP for production', () => {
|
|
266
|
+
const csp = getCspForEnvironment('production');
|
|
267
|
+
expect(csp['default-src']).toEqual(["'none'"]);
|
|
268
|
+
});
|
|
269
|
+
it('should return strict CSP by default', () => {
|
|
270
|
+
const csp = getCspForEnvironment();
|
|
271
|
+
expect(csp['default-src']).toEqual(["'none'"]);
|
|
272
|
+
});
|
|
273
|
+
it('should allow unsafe-eval for development', () => {
|
|
274
|
+
const csp = getCspForEnvironment('development');
|
|
275
|
+
expect(csp['script-src']).toContain("'unsafe-eval'");
|
|
276
|
+
});
|
|
277
|
+
it('should be permissive for test environment', () => {
|
|
278
|
+
const csp = getCspForEnvironment('test');
|
|
279
|
+
expect(csp['script-src']).toContain("'unsafe-inline'");
|
|
280
|
+
expect(csp['script-src']).toContain("'unsafe-eval'");
|
|
281
|
+
expect(csp['style-src']).toContain("'unsafe-inline'");
|
|
282
|
+
});
|
|
283
|
+
});
|
|
284
|
+
describe('Security Requirements', () => {
|
|
285
|
+
it('should not allow unsafe-eval in production', () => {
|
|
286
|
+
const csp = getCspForEnvironment('production');
|
|
287
|
+
const header = buildCspHeader(csp);
|
|
288
|
+
expect(header).not.toContain("'unsafe-eval'");
|
|
289
|
+
});
|
|
290
|
+
it('should not allow unsafe-inline in production', () => {
|
|
291
|
+
const csp = getCspForEnvironment('production');
|
|
292
|
+
const header = buildCspHeader(csp);
|
|
293
|
+
expect(header).not.toContain("'unsafe-inline'");
|
|
294
|
+
});
|
|
295
|
+
it('should block object-src in all environments', () => {
|
|
296
|
+
const prodCsp = getCspForEnvironment('production');
|
|
297
|
+
const devCsp = getCspForEnvironment('development');
|
|
298
|
+
const testCsp = getCspForEnvironment('test');
|
|
299
|
+
expect(prodCsp['object-src']).toEqual(["'none'"]);
|
|
300
|
+
expect(devCsp['object-src']).toEqual(["'none'"]);
|
|
301
|
+
expect(testCsp['object-src']).toEqual(["'none'"]);
|
|
302
|
+
});
|
|
303
|
+
it('should upgrade insecure requests in production', () => {
|
|
304
|
+
const csp = getCspForEnvironment('production');
|
|
305
|
+
expect(csp['upgrade-insecure-requests']).toBe(true);
|
|
306
|
+
});
|
|
307
|
+
it('should block mixed content in production', () => {
|
|
308
|
+
const csp = getCspForEnvironment('production');
|
|
309
|
+
expect(csp['block-all-mixed-content']).toBe(true);
|
|
310
|
+
});
|
|
311
|
+
it('should prevent frame embedding in production', () => {
|
|
312
|
+
const csp = getCspForEnvironment('production');
|
|
313
|
+
expect(csp['frame-ancestors']).toEqual(["'none'"]);
|
|
314
|
+
});
|
|
315
|
+
it('should restrict base-uri in production to prevent base tag injection', () => {
|
|
316
|
+
const csp = getCspForEnvironment('production');
|
|
317
|
+
expect(csp['base-uri']).toEqual(["'none'"]);
|
|
318
|
+
});
|
|
319
|
+
it('should include require-trusted-types-for in strict mode', () => {
|
|
320
|
+
expect(STRICT_CSP_DIRECTIVES['require-trusted-types-for']).toEqual(["'script'"]);
|
|
321
|
+
});
|
|
322
|
+
it('should restrict manifest-src in strict mode', () => {
|
|
323
|
+
expect(STRICT_CSP_DIRECTIVES['manifest-src']).toEqual(["'self'"]);
|
|
324
|
+
});
|
|
325
|
+
it('should block all frame-src in strict mode', () => {
|
|
326
|
+
expect(STRICT_CSP_DIRECTIVES['frame-src']).toEqual(["'none'"]);
|
|
327
|
+
});
|
|
328
|
+
it('should block all workers in strict mode', () => {
|
|
329
|
+
expect(STRICT_CSP_DIRECTIVES['worker-src']).toEqual(["'none'"]);
|
|
330
|
+
});
|
|
331
|
+
it('should have restrictive form-action in strict mode', () => {
|
|
332
|
+
expect(STRICT_CSP_DIRECTIVES['form-action']).toEqual(["'none'"]);
|
|
333
|
+
});
|
|
334
|
+
it('should generate cryptographically unique nonces', () => {
|
|
335
|
+
// Generate multiple nonces and ensure they are all unique
|
|
336
|
+
const nonces = new Set();
|
|
337
|
+
for (let i = 0; i < 100; i++) {
|
|
338
|
+
nonces.add(generateNonce());
|
|
339
|
+
}
|
|
340
|
+
expect(nonces.size).toBe(100);
|
|
341
|
+
});
|
|
342
|
+
it('should have nonces with sufficient entropy', () => {
|
|
343
|
+
const nonce = generateNonce();
|
|
344
|
+
// Base64 of 16 bytes = 24 characters (with padding)
|
|
345
|
+
// Without padding, it could be 22 characters
|
|
346
|
+
expect(nonce.length).toBeGreaterThanOrEqual(22);
|
|
347
|
+
});
|
|
348
|
+
});
|
|
349
|
+
describe('Directive Configuration', () => {
|
|
350
|
+
it('should include all required security directives in DEFAULT_CSP_DIRECTIVES', () => {
|
|
351
|
+
const requiredDirectives = [
|
|
352
|
+
'default-src',
|
|
353
|
+
'script-src',
|
|
354
|
+
'style-src',
|
|
355
|
+
'img-src',
|
|
356
|
+
'connect-src',
|
|
357
|
+
'frame-ancestors',
|
|
358
|
+
'base-uri',
|
|
359
|
+
'form-action',
|
|
360
|
+
];
|
|
361
|
+
for (const directive of requiredDirectives) {
|
|
362
|
+
expect(DEFAULT_CSP_DIRECTIVES).toHaveProperty(directive);
|
|
363
|
+
}
|
|
364
|
+
});
|
|
365
|
+
it('should include all required security directives in STRICT_CSP_DIRECTIVES', () => {
|
|
366
|
+
const requiredDirectives = [
|
|
367
|
+
'default-src',
|
|
368
|
+
'script-src',
|
|
369
|
+
'style-src',
|
|
370
|
+
'img-src',
|
|
371
|
+
'connect-src',
|
|
372
|
+
'frame-ancestors',
|
|
373
|
+
'base-uri',
|
|
374
|
+
'form-action',
|
|
375
|
+
'object-src',
|
|
376
|
+
'frame-src',
|
|
377
|
+
'worker-src',
|
|
378
|
+
];
|
|
379
|
+
for (const directive of requiredDirectives) {
|
|
380
|
+
expect(STRICT_CSP_DIRECTIVES).toHaveProperty(directive);
|
|
381
|
+
}
|
|
382
|
+
});
|
|
383
|
+
it('should have object-src set to none in both default and strict', () => {
|
|
384
|
+
expect(DEFAULT_CSP_DIRECTIVES['object-src']).toEqual(["'none'"]);
|
|
385
|
+
expect(STRICT_CSP_DIRECTIVES['object-src']).toEqual(["'none'"]);
|
|
386
|
+
});
|
|
387
|
+
});
|
|
388
|
+
});
|
|
389
|
+
//# sourceMappingURL=csp.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"csp.test.js","sourceRoot":"","sources":["../../../../src/middleware/__tests__/csp.test.ts"],"names":[],"mappings":"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"}
|