@vibesdotdev/security 0.0.0-stage → 1.0.0-rc.4
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/LICENSE +18 -0
- package/README.md +109 -2
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +2 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/plugin.d.ts +15 -0
- package/dist/cli/plugin.d.ts.map +1 -0
- package/dist/cli/plugin.js +25 -0
- package/dist/cli/plugin.js.map +1 -0
- package/dist/cli/read-lockfile.d.ts +4 -0
- package/dist/cli/read-lockfile.d.ts.map +1 -0
- package/dist/cli/read-lockfile.js +74 -0
- package/dist/cli/read-lockfile.js.map +1 -0
- package/dist/cli/report-output.d.ts +20 -0
- package/dist/cli/report-output.d.ts.map +1 -0
- package/dist/cli/report-output.js +27 -0
- package/dist/cli/report-output.js.map +1 -0
- package/dist/cli/shield.cli-group.descriptor.d.ts +9 -0
- package/dist/cli/shield.cli-group.descriptor.d.ts.map +1 -0
- package/dist/cli/shield.cli-group.descriptor.js +16 -0
- package/dist/cli/shield.cli-group.descriptor.js.map +1 -0
- package/dist/cli/shield.deps.cli-group.descriptor.d.ts +9 -0
- package/dist/cli/shield.deps.cli-group.descriptor.d.ts.map +1 -0
- package/dist/cli/shield.deps.cli-group.descriptor.js +17 -0
- package/dist/cli/shield.deps.cli-group.descriptor.js.map +1 -0
- package/dist/cli/shield.deps.gate.descriptor.d.ts +10 -0
- package/dist/cli/shield.deps.gate.descriptor.d.ts.map +1 -0
- package/dist/cli/shield.deps.gate.descriptor.js +25 -0
- package/dist/cli/shield.deps.gate.descriptor.js.map +1 -0
- package/dist/cli/shield.deps.gate.impl.consumer.d.ts +18 -0
- package/dist/cli/shield.deps.gate.impl.consumer.d.ts.map +1 -0
- package/dist/cli/shield.deps.gate.impl.consumer.js +42 -0
- package/dist/cli/shield.deps.gate.impl.consumer.js.map +1 -0
- package/dist/cli/shield.deps.scan.descriptor.d.ts +10 -0
- package/dist/cli/shield.deps.scan.descriptor.d.ts.map +1 -0
- package/dist/cli/shield.deps.scan.descriptor.js +25 -0
- package/dist/cli/shield.deps.scan.descriptor.js.map +1 -0
- package/dist/cli/shield.deps.scan.impl.consumer.d.ts +16 -0
- package/dist/cli/shield.deps.scan.impl.consumer.d.ts.map +1 -0
- package/dist/cli/shield.deps.scan.impl.consumer.js +35 -0
- package/dist/cli/shield.deps.scan.impl.consumer.js.map +1 -0
- package/dist/helpers/constant-time.d.ts +18 -0
- package/dist/helpers/constant-time.d.ts.map +1 -0
- package/dist/helpers/constant-time.js +49 -0
- package/dist/helpers/constant-time.js.map +1 -0
- package/dist/helpers/filename-sanitizer.d.ts +2 -0
- package/dist/helpers/filename-sanitizer.d.ts.map +1 -0
- package/dist/helpers/filename-sanitizer.js +18 -0
- package/dist/helpers/filename-sanitizer.js.map +1 -0
- package/dist/helpers/forwardable-auth-headers.d.ts +8 -0
- package/dist/helpers/forwardable-auth-headers.d.ts.map +1 -0
- package/dist/helpers/forwardable-auth-headers.js +44 -0
- package/dist/helpers/forwardable-auth-headers.js.map +1 -0
- package/dist/helpers/index.d.ts +7 -0
- package/dist/helpers/index.d.ts.map +1 -0
- package/dist/helpers/index.js +7 -0
- package/dist/helpers/index.js.map +1 -0
- package/dist/helpers/ip-range.d.ts +3 -0
- package/dist/helpers/ip-range.d.ts.map +1 -0
- package/dist/helpers/ip-range.js +55 -0
- package/dist/helpers/ip-range.js.map +1 -0
- package/dist/helpers/mime-classifier.d.ts +3 -0
- package/dist/helpers/mime-classifier.d.ts.map +1 -0
- package/dist/helpers/mime-classifier.js +29 -0
- package/dist/helpers/mime-classifier.js.map +1 -0
- package/dist/helpers/pattern-matcher.d.ts +13 -0
- package/dist/helpers/pattern-matcher.d.ts.map +1 -0
- package/dist/helpers/pattern-matcher.js +29 -0
- package/dist/helpers/pattern-matcher.js.map +1 -0
- package/dist/implementations/cli-types.d.ts +2 -0
- package/dist/implementations/cli-types.d.ts.map +1 -0
- package/dist/implementations/cli-types.js +2 -0
- package/dist/implementations/cli-types.js.map +1 -0
- package/dist/implementations/encryption.d.ts +21 -0
- package/dist/implementations/encryption.d.ts.map +1 -0
- package/dist/implementations/encryption.js +154 -0
- package/dist/implementations/encryption.js.map +1 -0
- package/dist/implementations/errors.d.ts +17 -0
- package/dist/implementations/errors.d.ts.map +1 -0
- package/dist/implementations/errors.js +23 -0
- package/dist/implementations/errors.js.map +1 -0
- package/dist/implementations/keys.d.ts +24 -0
- package/dist/implementations/keys.d.ts.map +1 -0
- package/dist/implementations/keys.js +114 -0
- package/dist/implementations/keys.js.map +1 -0
- package/dist/implementations/redaction-admission.d.ts +24 -0
- package/dist/implementations/redaction-admission.d.ts.map +1 -0
- package/dist/implementations/redaction-admission.js +44 -0
- package/dist/implementations/redaction-admission.js.map +1 -0
- package/dist/implementations/redaction.d.ts +32 -0
- package/dist/implementations/redaction.d.ts.map +1 -0
- package/dist/implementations/redaction.js +47 -0
- package/dist/implementations/redaction.js.map +1 -0
- package/dist/implementations/redactor.inprocess.impl.d.ts +30 -0
- package/dist/implementations/redactor.inprocess.impl.d.ts.map +1 -0
- package/dist/implementations/redactor.inprocess.impl.js +26 -0
- package/dist/implementations/redactor.inprocess.impl.js.map +1 -0
- package/dist/implementations/redactor.subprocess.impl.d.ts +25 -0
- package/dist/implementations/redactor.subprocess.impl.d.ts.map +1 -0
- package/dist/implementations/redactor.subprocess.impl.js +42 -0
- package/dist/implementations/redactor.subprocess.impl.js.map +1 -0
- package/dist/implementations/scanner.impl.d.ts +7 -0
- package/dist/implementations/scanner.impl.d.ts.map +1 -0
- package/dist/implementations/scanner.impl.js +166 -0
- package/dist/implementations/scanner.impl.js.map +1 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +11 -0
- package/dist/index.js.map +1 -0
- package/dist/kinds/auditor.kind.d.ts +31 -0
- package/dist/kinds/auditor.kind.d.ts.map +1 -0
- package/dist/kinds/auditor.kind.js +48 -0
- package/dist/kinds/auditor.kind.js.map +1 -0
- package/dist/kinds/dep-scanner.kind.d.ts +27 -0
- package/dist/kinds/dep-scanner.kind.d.ts.map +1 -0
- package/dist/kinds/dep-scanner.kind.js +29 -0
- package/dist/kinds/dep-scanner.kind.js.map +1 -0
- package/dist/kinds/freshness-policy.kind.d.ts +34 -0
- package/dist/kinds/freshness-policy.kind.d.ts.map +1 -0
- package/dist/kinds/freshness-policy.kind.js +47 -0
- package/dist/kinds/freshness-policy.kind.js.map +1 -0
- package/dist/kinds/index.d.ts +9 -0
- package/dist/kinds/index.d.ts.map +1 -0
- package/dist/kinds/index.js +9 -0
- package/dist/kinds/index.js.map +1 -0
- package/dist/kinds/ioc-feed.kind.d.ts +35 -0
- package/dist/kinds/ioc-feed.kind.d.ts.map +1 -0
- package/dist/kinds/ioc-feed.kind.js +36 -0
- package/dist/kinds/ioc-feed.kind.js.map +1 -0
- package/dist/kinds/policy.kind.d.ts +42 -0
- package/dist/kinds/policy.kind.d.ts.map +1 -0
- package/dist/kinds/policy.kind.js +23 -0
- package/dist/kinds/policy.kind.js.map +1 -0
- package/dist/kinds/redactor.kind.d.ts +30 -0
- package/dist/kinds/redactor.kind.d.ts.map +1 -0
- package/dist/kinds/redactor.kind.js +25 -0
- package/dist/kinds/redactor.kind.js.map +1 -0
- package/dist/kinds/scanner.kind.d.ts +35 -0
- package/dist/kinds/scanner.kind.d.ts.map +1 -0
- package/dist/kinds/scanner.kind.js +26 -0
- package/dist/kinds/scanner.kind.js.map +1 -0
- package/dist/schemas/AuditEvent.d.ts +30 -0
- package/dist/schemas/AuditEvent.d.ts.map +1 -0
- package/dist/schemas/AuditEvent.js +17 -0
- package/dist/schemas/AuditEvent.js.map +1 -0
- package/dist/schemas/RedactionRule.d.ts +16 -0
- package/dist/schemas/RedactionRule.d.ts.map +1 -0
- package/dist/schemas/RedactionRule.js +10 -0
- package/dist/schemas/RedactionRule.js.map +1 -0
- package/dist/schemas/SecurityPolicy.d.ts +21 -0
- package/dist/schemas/SecurityPolicy.d.ts.map +1 -0
- package/dist/schemas/SecurityPolicy.js +9 -0
- package/dist/schemas/SecurityPolicy.js.map +1 -0
- package/dist/schemas/ThreatReport.d.ts +25 -0
- package/dist/schemas/ThreatReport.d.ts.map +1 -0
- package/dist/schemas/ThreatReport.js +14 -0
- package/dist/schemas/ThreatReport.js.map +1 -0
- package/dist/schemas/contracts/auditor.d.ts +68 -0
- package/dist/schemas/contracts/auditor.d.ts.map +1 -0
- package/dist/schemas/contracts/auditor.js +13 -0
- package/dist/schemas/contracts/auditor.js.map +1 -0
- package/dist/schemas/contracts/card.d.ts +106 -0
- package/dist/schemas/contracts/card.d.ts.map +1 -0
- package/dist/schemas/contracts/card.js +73 -0
- package/dist/schemas/contracts/card.js.map +1 -0
- package/dist/schemas/contracts/dep-scanner.d.ts +91 -0
- package/dist/schemas/contracts/dep-scanner.d.ts.map +1 -0
- package/dist/schemas/contracts/dep-scanner.js +27 -0
- package/dist/schemas/contracts/dep-scanner.js.map +1 -0
- package/dist/schemas/contracts/freshness-policy.d.ts +99 -0
- package/dist/schemas/contracts/freshness-policy.d.ts.map +1 -0
- package/dist/schemas/contracts/freshness-policy.js +31 -0
- package/dist/schemas/contracts/freshness-policy.js.map +1 -0
- package/dist/schemas/contracts/ioc-feed.d.ts +85 -0
- package/dist/schemas/contracts/ioc-feed.d.ts.map +1 -0
- package/dist/schemas/contracts/ioc-feed.js +28 -0
- package/dist/schemas/contracts/ioc-feed.js.map +1 -0
- package/dist/schemas/contracts/misc.d.ts +11 -0
- package/dist/schemas/contracts/misc.d.ts.map +1 -0
- package/dist/schemas/contracts/misc.js +4 -0
- package/dist/schemas/contracts/misc.js.map +1 -0
- package/dist/schemas/contracts/policy.d.ts +93 -0
- package/dist/schemas/contracts/policy.d.ts.map +1 -0
- package/dist/schemas/contracts/policy.js +25 -0
- package/dist/schemas/contracts/policy.js.map +1 -0
- package/dist/schemas/contracts/redactor.d.ts +99 -0
- package/dist/schemas/contracts/redactor.d.ts.map +1 -0
- package/dist/schemas/contracts/redactor.js +34 -0
- package/dist/schemas/contracts/redactor.js.map +1 -0
- package/dist/schemas/contracts/scanner.d.ts +112 -0
- package/dist/schemas/contracts/scanner.d.ts.map +1 -0
- package/dist/schemas/contracts/scanner.js +40 -0
- package/dist/schemas/contracts/scanner.js.map +1 -0
- package/dist/schemas/contracts/widget.d.ts +19 -0
- package/dist/schemas/contracts/widget.d.ts.map +1 -0
- package/dist/schemas/contracts/widget.js +10 -0
- package/dist/schemas/contracts/widget.js.map +1 -0
- package/dist/schemas/encryption.d.ts +25 -0
- package/dist/schemas/encryption.d.ts.map +1 -0
- package/dist/schemas/encryption.js +35 -0
- package/dist/schemas/encryption.js.map +1 -0
- package/dist/schemas/index.d.ts +6 -0
- package/dist/schemas/index.d.ts.map +1 -0
- package/dist/schemas/index.js +6 -0
- package/dist/schemas/index.js.map +1 -0
- package/dist/schemas/policy.d.ts +2 -0
- package/dist/schemas/policy.d.ts.map +1 -0
- package/dist/schemas/policy.js +2 -0
- package/dist/schemas/policy.js.map +1 -0
- package/dist/schemas/redactor.d.ts +2 -0
- package/dist/schemas/redactor.d.ts.map +1 -0
- package/dist/schemas/redactor.js +2 -0
- package/dist/schemas/redactor.js.map +1 -0
- package/dist/schemas/report-event.d.ts +29 -0
- package/dist/schemas/report-event.d.ts.map +1 -0
- package/dist/schemas/report-event.js +19 -0
- package/dist/schemas/report-event.js.map +1 -0
- package/dist/schemas/scanner.d.ts +2 -0
- package/dist/schemas/scanner.d.ts.map +1 -0
- package/dist/schemas/scanner.js +2 -0
- package/dist/schemas/scanner.js.map +1 -0
- package/dist/security-client/index.d.ts +3 -0
- package/dist/security-client/index.d.ts.map +1 -0
- package/dist/security-client/index.js +2 -0
- package/dist/security-client/index.js.map +1 -0
- package/dist/security-client/security-client.d.ts +34 -0
- package/dist/security-client/security-client.d.ts.map +1 -0
- package/dist/security-client/security-client.js +54 -0
- package/dist/security-client/security-client.js.map +1 -0
- package/dist/security.consumer.plugin.d.ts +3 -0
- package/dist/security.consumer.plugin.d.ts.map +1 -0
- package/dist/security.consumer.plugin.js +28 -0
- package/dist/security.consumer.plugin.js.map +1 -0
- package/dist/security.plugin.d.ts +16 -0
- package/dist/security.plugin.d.ts.map +1 -0
- package/dist/security.plugin.js +78 -0
- package/dist/security.plugin.js.map +1 -0
- package/dist/svelte/index.d.ts +3 -0
- package/dist/svelte/index.d.ts.map +1 -0
- package/dist/svelte/index.js +2 -0
- package/dist/svelte/security-svelte.plugin.d.ts +3 -0
- package/dist/svelte/security-svelte.plugin.d.ts.map +1 -0
- package/dist/svelte/security-svelte.plugin.js +38 -0
- package/dist/svelte/styles.css +8 -0
- package/dist/svelte/tool-widgets/SecurityToolCard.svelte +140 -0
- package/dist/svelte/tool-widgets/SecurityToolCard.svelte.d.ts +5 -0
- package/dist/svelte/tool-widgets/SecurityToolCard.svelte.d.ts.map +1 -0
- package/dist/svelte/tool-widgets/index.d.ts +2 -0
- package/dist/svelte/tool-widgets/index.d.ts.map +1 -0
- package/dist/svelte/tool-widgets/index.js +6 -0
- package/dist/tools/check-policy/check-policy.descriptor.d.ts +37 -0
- package/dist/tools/check-policy/check-policy.descriptor.d.ts.map +1 -0
- package/dist/tools/check-policy/check-policy.descriptor.js +21 -0
- package/dist/tools/check-policy/check-policy.descriptor.js.map +1 -0
- package/dist/tools/check-policy/check-policy.impl.consumer.d.ts +7 -0
- package/dist/tools/check-policy/check-policy.impl.consumer.d.ts.map +1 -0
- package/dist/tools/check-policy/check-policy.impl.consumer.js +21 -0
- package/dist/tools/check-policy/check-policy.impl.consumer.js.map +1 -0
- package/dist/tools/check-policy/index.d.ts +3 -0
- package/dist/tools/check-policy/index.d.ts.map +1 -0
- package/dist/tools/check-policy/index.js +2 -0
- package/dist/tools/check-policy/index.js.map +1 -0
- package/dist/tools/check-policy/schemas.d.ts +23 -0
- package/dist/tools/check-policy/schemas.d.ts.map +1 -0
- package/dist/tools/check-policy/schemas.js +13 -0
- package/dist/tools/check-policy/schemas.js.map +1 -0
- package/dist/tools/index.d.ts +10 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +6 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/redact-output/index.d.ts +3 -0
- package/dist/tools/redact-output/index.d.ts.map +1 -0
- package/dist/tools/redact-output/index.js +2 -0
- package/dist/tools/redact-output/index.js.map +1 -0
- package/dist/tools/redact-output/redact-output.descriptor.d.ts +42 -0
- package/dist/tools/redact-output/redact-output.descriptor.d.ts.map +1 -0
- package/dist/tools/redact-output/redact-output.descriptor.js +21 -0
- package/dist/tools/redact-output/redact-output.descriptor.js.map +1 -0
- package/dist/tools/redact-output/redact-output.impl.consumer.d.ts +7 -0
- package/dist/tools/redact-output/redact-output.impl.consumer.d.ts.map +1 -0
- package/dist/tools/redact-output/redact-output.impl.consumer.js +18 -0
- package/dist/tools/redact-output/redact-output.impl.consumer.js.map +1 -0
- package/dist/tools/redact-output/schemas.d.ts +28 -0
- package/dist/tools/redact-output/schemas.d.ts.map +1 -0
- package/dist/tools/redact-output/schemas.js +13 -0
- package/dist/tools/redact-output/schemas.js.map +1 -0
- package/dist/tools/report-event/index.d.ts +3 -0
- package/dist/tools/report-event/index.d.ts.map +1 -0
- package/dist/tools/report-event/index.js +2 -0
- package/dist/tools/report-event/index.js.map +1 -0
- package/dist/tools/report-event/report-event.descriptor.d.ts +43 -0
- package/dist/tools/report-event/report-event.descriptor.d.ts.map +1 -0
- package/dist/tools/report-event/report-event.descriptor.js +21 -0
- package/dist/tools/report-event/report-event.descriptor.js.map +1 -0
- package/dist/tools/report-event/report-event.impl.consumer.d.ts +24 -0
- package/dist/tools/report-event/report-event.impl.consumer.d.ts.map +1 -0
- package/dist/tools/report-event/report-event.impl.consumer.js +61 -0
- package/dist/tools/report-event/report-event.impl.consumer.js.map +1 -0
- package/dist/tools/report-event/schemas.d.ts +2 -0
- package/dist/tools/report-event/schemas.d.ts.map +1 -0
- package/dist/tools/report-event/schemas.js +3 -0
- package/dist/tools/report-event/schemas.js.map +1 -0
- package/dist/tools/scan-input/index.d.ts +3 -0
- package/dist/tools/scan-input/index.d.ts.map +1 -0
- package/dist/tools/scan-input/index.js +2 -0
- package/dist/tools/scan-input/index.js.map +1 -0
- package/dist/tools/scan-input/scan-input.descriptor.d.ts +49 -0
- package/dist/tools/scan-input/scan-input.descriptor.d.ts.map +1 -0
- package/dist/tools/scan-input/scan-input.descriptor.js +21 -0
- package/dist/tools/scan-input/scan-input.descriptor.js.map +1 -0
- package/dist/tools/scan-input/scan-input.impl.consumer.d.ts +7 -0
- package/dist/tools/scan-input/scan-input.impl.consumer.d.ts.map +1 -0
- package/dist/tools/scan-input/scan-input.impl.consumer.js +22 -0
- package/dist/tools/scan-input/scan-input.impl.consumer.js.map +1 -0
- package/dist/tools/scan-input/schemas.d.ts +36 -0
- package/dist/tools/scan-input/schemas.d.ts.map +1 -0
- package/dist/tools/scan-input/schemas.js +15 -0
- package/dist/tools/scan-input/schemas.js.map +1 -0
- package/dist/tools/security-tool-card.d.ts +13 -0
- package/dist/tools/security-tool-card.d.ts.map +1 -0
- package/dist/tools/security-tool-card.js +171 -0
- package/dist/tools/security-tool-card.js.map +1 -0
- package/dist/tools/security.docs.descriptor.d.ts +17 -0
- package/dist/tools/security.docs.descriptor.d.ts.map +1 -0
- package/dist/tools/security.docs.descriptor.js +49 -0
- package/dist/tools/security.docs.descriptor.js.map +1 -0
- package/dist/tui/index.d.ts +2 -0
- package/dist/tui/index.d.ts.map +1 -0
- package/dist/tui/index.js +2 -0
- package/dist/tui/index.js.map +1 -0
- package/dist/tui/security-tui.plugin.d.ts +3 -0
- package/dist/tui/security-tui.plugin.d.ts.map +1 -0
- package/dist/tui/security-tui.plugin.js +31 -0
- package/dist/tui/security-tui.plugin.js.map +1 -0
- package/dist/tui/tool-widgets/SecurityToolWidget.impl.consumer.d.ts +5 -0
- package/dist/tui/tool-widgets/SecurityToolWidget.impl.consumer.d.ts.map +1 -0
- package/dist/tui/tool-widgets/SecurityToolWidget.impl.consumer.js +37 -0
- package/dist/tui/tool-widgets/SecurityToolWidget.impl.consumer.js.map +1 -0
- package/docs/host-boundary.md +186 -0
- package/docs/scanner-work.md +29 -0
- package/package.json +245 -4
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shield Deps Scan CLI Command Implementation (consumer)
|
|
3
|
+
*
|
|
4
|
+
* Resolves the registered `security/dep-scanner` service, scans the given
|
|
5
|
+
* lockfile, and prints the DepScanReport as JSON.
|
|
6
|
+
*
|
|
7
|
+
* Output and diagnostics go through the handed runtime's host text output (see
|
|
8
|
+
* `./report-output.ts`), and the exit code is requested rather than taken, so a
|
|
9
|
+
* CI gate's stdout is never truncated.
|
|
10
|
+
*/
|
|
11
|
+
import * as z from 'zod/v4';
|
|
12
|
+
import { requestCLIExit } from '@vibesdotdev/cli/providers';
|
|
13
|
+
import { readLockfile } from "./read-lockfile.js";
|
|
14
|
+
import { writeDepScanReport, writeDiagnostic } from "./report-output.js";
|
|
15
|
+
export default {
|
|
16
|
+
async execute(args, opts, context) {
|
|
17
|
+
const parsedPath = z.string().min(1).safeParse(args.path);
|
|
18
|
+
const { runtime } = context;
|
|
19
|
+
if (!parsedPath.success) {
|
|
20
|
+
await writeDiagnostic(runtime, 'shield deps scan: missing required <path> argument');
|
|
21
|
+
requestCLIExit(2);
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
const path = parsedPath.data;
|
|
25
|
+
if (!runtime.hasKind('security/dep-scanner') || runtime.query('security/dep-scanner').enabled().descriptors().length === 0) {
|
|
26
|
+
await writeDiagnostic(runtime, 'shield deps scan: no dep scanner registered');
|
|
27
|
+
requestCLIExit(2);
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
const scanner = await runtime.query('security/dep-scanner').enabled().resolve();
|
|
31
|
+
const manifest = await readLockfile(runtime, path);
|
|
32
|
+
await writeDepScanReport(runtime, await scanner.scan(manifest));
|
|
33
|
+
},
|
|
34
|
+
};
|
|
35
|
+
//# sourceMappingURL=shield.deps.scan.impl.consumer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shield.deps.scan.impl.consumer.js","sourceRoot":"","sources":["../../src/cli/shield.deps.scan.impl.consumer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,CAAC,MAAM,QAAQ,CAAC;AAC5B,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAE5D,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAGzE,eAAe;IACd,KAAK,CAAC,OAAO,CAAC,IAAkD,EAAE,IAAkD,EAAE,OAAwC;QAC7J,MAAM,UAAU,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC1D,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC;QAC5B,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC;YACzB,MAAM,eAAe,CAAC,OAAO,EAAE,oDAAoD,CAAC,CAAC;YACrF,cAAc,CAAC,CAAC,CAAC,CAAC;YAClB,OAAO;QACR,CAAC;QACD,MAAM,IAAI,GAAG,UAAU,CAAC,IAAI,CAAC;QAE7B,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,sBAAsB,CAAC,IAAI,OAAO,CAAC,KAAK,CAAC,sBAAsB,CAAC,CAAC,OAAO,EAAE,CAAC,WAAW,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC5H,MAAM,eAAe,CAAC,OAAO,EAAE,6CAA6C,CAAC,CAAC;YAC9E,cAAc,CAAC,CAAC,CAAC,CAAC;YAClB,OAAO;QACR,CAAC;QAED,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,KAAK,CAA0C,sBAAsB,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,CAAC;QACzH,MAAM,QAAQ,GAAG,MAAM,YAAY,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QACnD,MAAM,kBAAkB,CAAC,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;IACjE,CAAC;CACD,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Constant-time string equality for secrets and tokens.
|
|
3
|
+
*
|
|
4
|
+
* Does not short-circuit on length mismatch (length is still observable for
|
|
5
|
+
* empty/unequal sizes via total work, but the matched-prefix length of the
|
|
6
|
+
* secret is not leaked via early exit). Runtime-agnostic — no Node `crypto`
|
|
7
|
+
* or Buffer — so it is safe on workerd and browsers.
|
|
8
|
+
*
|
|
9
|
+
* Prefer this over local copies of `timingSafeEqual` / `tokensMatch` that
|
|
10
|
+
* early-return on `a.length !== b.length`.
|
|
11
|
+
*/
|
|
12
|
+
export declare function constantTimeEqual(a: string, b: string): boolean;
|
|
13
|
+
/**
|
|
14
|
+
* Constant-time equality for equal-or-unequal byte arrays (hashes, digests).
|
|
15
|
+
* Same length-oracle discipline as {@link constantTimeEqual}.
|
|
16
|
+
*/
|
|
17
|
+
export declare function constantTimeEqualBytes(a: Uint8Array, b: Uint8Array): boolean;
|
|
18
|
+
//# sourceMappingURL=constant-time.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constant-time.d.ts","sourceRoot":"","sources":["../../src/helpers/constant-time.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAmB/D;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,UAAU,GAAG,OAAO,CAY5E"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Constant-time string equality for secrets and tokens.
|
|
3
|
+
*
|
|
4
|
+
* Does not short-circuit on length mismatch (length is still observable for
|
|
5
|
+
* empty/unequal sizes via total work, but the matched-prefix length of the
|
|
6
|
+
* secret is not leaked via early exit). Runtime-agnostic — no Node `crypto`
|
|
7
|
+
* or Buffer — so it is safe on workerd and browsers.
|
|
8
|
+
*
|
|
9
|
+
* Prefer this over local copies of `timingSafeEqual` / `tokensMatch` that
|
|
10
|
+
* early-return on `a.length !== b.length`.
|
|
11
|
+
*/
|
|
12
|
+
export function constantTimeEqual(a, b) {
|
|
13
|
+
const aBytes = new TextEncoder().encode(a);
|
|
14
|
+
const bBytes = new TextEncoder().encode(b);
|
|
15
|
+
// Mismatched length is a guaranteed non-match, but still iterate so
|
|
16
|
+
// timing does not reveal the matched-prefix length of either string.
|
|
17
|
+
let mismatch = aBytes.length === bBytes.length ? 0 : 1;
|
|
18
|
+
const len = aBytes.length;
|
|
19
|
+
// When b is empty, avoid modulo-by-zero; any non-empty a already mismatches.
|
|
20
|
+
if (bBytes.length === 0) {
|
|
21
|
+
return len === 0 && mismatch === 0;
|
|
22
|
+
}
|
|
23
|
+
for (let i = 0; i < len; i++) {
|
|
24
|
+
mismatch |= aBytes[i] ^ bBytes[i % bBytes.length];
|
|
25
|
+
}
|
|
26
|
+
// Also walk remaining b bytes when a is shorter so work scales with both.
|
|
27
|
+
for (let i = len; i < bBytes.length; i++) {
|
|
28
|
+
mismatch |= bBytes[i];
|
|
29
|
+
}
|
|
30
|
+
return mismatch === 0;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Constant-time equality for equal-or-unequal byte arrays (hashes, digests).
|
|
34
|
+
* Same length-oracle discipline as {@link constantTimeEqual}.
|
|
35
|
+
*/
|
|
36
|
+
export function constantTimeEqualBytes(a, b) {
|
|
37
|
+
let mismatch = a.length === b.length ? 0 : 1;
|
|
38
|
+
if (b.length === 0) {
|
|
39
|
+
return a.length === 0 && mismatch === 0;
|
|
40
|
+
}
|
|
41
|
+
for (let i = 0; i < a.length; i++) {
|
|
42
|
+
mismatch |= a[i] ^ b[i % b.length];
|
|
43
|
+
}
|
|
44
|
+
for (let i = a.length; i < b.length; i++) {
|
|
45
|
+
mismatch |= b[i];
|
|
46
|
+
}
|
|
47
|
+
return mismatch === 0;
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=constant-time.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constant-time.js","sourceRoot":"","sources":["../../src/helpers/constant-time.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,MAAM,UAAU,iBAAiB,CAAC,CAAS,EAAE,CAAS;IACrD,MAAM,MAAM,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IAC3C,MAAM,MAAM,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IAC3C,oEAAoE;IACpE,qEAAqE;IACrE,IAAI,QAAQ,GAAG,MAAM,CAAC,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACvD,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC;IAC1B,6EAA6E;IAC7E,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,GAAG,KAAK,CAAC,IAAI,QAAQ,KAAK,CAAC,CAAC;IACpC,CAAC;IACD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;QAC9B,QAAQ,IAAI,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;IACnD,CAAC;IACD,0EAA0E;IAC1E,KAAK,IAAI,CAAC,GAAG,GAAG,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAC1C,QAAQ,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC;IACvB,CAAC;IACD,OAAO,QAAQ,KAAK,CAAC,CAAC;AACvB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,sBAAsB,CAAC,CAAa,EAAE,CAAa;IAClE,IAAI,QAAQ,GAAG,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC7C,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACpB,OAAO,CAAC,CAAC,MAAM,KAAK,CAAC,IAAI,QAAQ,KAAK,CAAC,CAAC;IACzC,CAAC;IACD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACnC,QAAQ,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC;IACpC,CAAC;IACD,KAAK,IAAI,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAC1C,QAAQ,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IACD,OAAO,QAAQ,KAAK,CAAC,CAAC;AACvB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"filename-sanitizer.d.ts","sourceRoot":"","sources":["../../src/helpers/filename-sanitizer.ts"],"names":[],"mappings":"AAGA,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,SAAM,GAAG,MAAM,CAaxE"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
const FORBIDDEN_PUNCTUATION = '<>:"/\\|?*';
|
|
2
|
+
const RESERVED_NAMES = /^(con|prn|aux|nul|com[0-9]|lpt[0-9])(\.|$)/i;
|
|
3
|
+
export function sanitizeFilename(name, replacement = '_') {
|
|
4
|
+
let sanitized = '';
|
|
5
|
+
for (let i = 0; i < name.length; i++) {
|
|
6
|
+
const ch = name[i] ?? '';
|
|
7
|
+
const code = name.charCodeAt(i);
|
|
8
|
+
if (code <= 0x1f || FORBIDDEN_PUNCTUATION.includes(ch)) {
|
|
9
|
+
sanitized += replacement;
|
|
10
|
+
}
|
|
11
|
+
else {
|
|
12
|
+
sanitized += ch;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
sanitized = sanitized.replace(RESERVED_NAMES, replacement);
|
|
16
|
+
return sanitized.trim().slice(0, 255);
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=filename-sanitizer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"filename-sanitizer.js","sourceRoot":"","sources":["../../src/helpers/filename-sanitizer.ts"],"names":[],"mappings":"AAAA,MAAM,qBAAqB,GAAG,YAAY,CAAC;AAC3C,MAAM,cAAc,GAAG,6CAA6C,CAAC;AAErE,MAAM,UAAU,gBAAgB,CAAC,IAAY,EAAE,WAAW,GAAG,GAAG;IAC/D,IAAI,SAAS,GAAG,EAAE,CAAC;IACnB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,MAAM,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QACzB,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;QAChC,IAAI,IAAI,IAAI,IAAI,IAAI,qBAAqB,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC;YACxD,SAAS,IAAI,WAAW,CAAC;QAC1B,CAAC;aAAM,CAAC;YACP,SAAS,IAAI,EAAE,CAAC;QACjB,CAAC;IACF,CAAC;IACD,SAAS,GAAG,SAAS,CAAC,OAAO,CAAC,cAAc,EAAE,WAAW,CAAC,CAAC;IAC3D,OAAO,SAAS,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;AACvC,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ForwardableAuthHeaders } from '../schemas/contracts/misc.ts';
|
|
2
|
+
export type { ForwardableAuthHeaders } from '../schemas/contracts/misc.ts';
|
|
3
|
+
/**
|
|
4
|
+
* Select only credentials that a verified surface may forward to another Vibes
|
|
5
|
+
* app. Unrelated cookies and malformed bearer values never cross an app boundary.
|
|
6
|
+
*/
|
|
7
|
+
export declare function selectForwardableAuthHeaders(headers: Record<string, string> | undefined): ForwardableAuthHeaders;
|
|
8
|
+
//# sourceMappingURL=forwardable-auth-headers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"forwardable-auth-headers.d.ts","sourceRoot":"","sources":["../../src/helpers/forwardable-auth-headers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,8BAA8B,CAAC;AAC3E,YAAY,EAAE,sBAAsB,EAAE,MAAM,8BAA8B,CAAC;AAe3E;;;GAGG;AACH,wBAAgB,4BAA4B,CAC3C,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,GACzC,sBAAsB,CAwBxB"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
const FORWARDABLE_AUTH_COOKIES = new Set([
|
|
2
|
+
'vibes.jwt',
|
|
3
|
+
'better-auth.session_token',
|
|
4
|
+
'__Secure-better-auth.session_token',
|
|
5
|
+
'__Host-better-auth.session_token'
|
|
6
|
+
]);
|
|
7
|
+
function readHeader(headers, name) {
|
|
8
|
+
if (!headers)
|
|
9
|
+
return undefined;
|
|
10
|
+
const entry = Object.entries(headers).find(([key]) => key.toLowerCase() === name);
|
|
11
|
+
const value = entry?.[1]?.trim();
|
|
12
|
+
return value && !/[\r\n]/.test(value) ? value : undefined;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Select only credentials that a verified surface may forward to another Vibes
|
|
16
|
+
* app. Unrelated cookies and malformed bearer values never cross an app boundary.
|
|
17
|
+
*/
|
|
18
|
+
export function selectForwardableAuthHeaders(headers) {
|
|
19
|
+
const authorization = readHeader(headers, 'authorization');
|
|
20
|
+
const jwt = authorization?.match(/^Bearer\s+(\S+)$/i)?.[1];
|
|
21
|
+
const rawCookie = readHeader(headers, 'cookie');
|
|
22
|
+
const cookies = [];
|
|
23
|
+
if (rawCookie) {
|
|
24
|
+
for (const part of rawCookie.split(';')) {
|
|
25
|
+
const separator = part.indexOf('=');
|
|
26
|
+
if (separator <= 0)
|
|
27
|
+
continue;
|
|
28
|
+
const name = part.slice(0, separator).trim();
|
|
29
|
+
const value = part.slice(separator + 1).trim();
|
|
30
|
+
if (FORWARDABLE_AUTH_COOKIES.has(name) && value.length > 0 && !/[;\r\n]/.test(value)) {
|
|
31
|
+
cookies.push(`${name}=${value}`);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
const result = {};
|
|
36
|
+
if (cookies.length > 0) {
|
|
37
|
+
result.cookie = cookies.join('; ');
|
|
38
|
+
}
|
|
39
|
+
if (jwt) {
|
|
40
|
+
result.jwt = jwt;
|
|
41
|
+
}
|
|
42
|
+
return result;
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=forwardable-auth-headers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"forwardable-auth-headers.js","sourceRoot":"","sources":["../../src/helpers/forwardable-auth-headers.ts"],"names":[],"mappings":"AAEA,MAAM,wBAAwB,GAAG,IAAI,GAAG,CAAC;IACxC,WAAW;IACX,2BAA2B;IAC3B,oCAAoC;IACpC,kCAAkC;CAClC,CAAC,CAAC;AAEH,SAAS,UAAU,CAAC,OAA2C,EAAE,IAAY;IAC5E,IAAI,CAAC,OAAO;QAAE,OAAO,SAAS,CAAC;IAC/B,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,WAAW,EAAE,KAAK,IAAI,CAAC,CAAC;IAClF,MAAM,KAAK,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC;IACjC,OAAO,KAAK,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;AAC3D,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,4BAA4B,CAC3C,OAA2C;IAE3C,MAAM,aAAa,GAAG,UAAU,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC;IAC3D,MAAM,GAAG,GAAG,aAAa,EAAE,KAAK,CAAC,mBAAmB,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAC3D,MAAM,SAAS,GAAG,UAAU,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IAChD,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,IAAI,SAAS,EAAE,CAAC;QACf,KAAK,MAAM,IAAI,IAAI,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;YACzC,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;YACpC,IAAI,SAAS,IAAI,CAAC;gBAAE,SAAS;YAC7B,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,IAAI,EAAE,CAAC;YAC7C,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;YAC/C,IAAI,wBAAwB,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;gBACtF,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,IAAI,KAAK,EAAE,CAAC,CAAC;YAClC,CAAC;QACF,CAAC;IACF,CAAC;IACD,MAAM,MAAM,GAA2B,EAAE,CAAC;IAC1C,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxB,MAAM,CAAC,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACpC,CAAC;IACD,IAAI,GAAG,EAAE,CAAC;QACT,MAAM,CAAC,GAAG,GAAG,GAAG,CAAC;IAClB,CAAC;IACD,OAAO,MAAM,CAAC;AACf,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { matchesPattern, findMatches } from './pattern-matcher.ts';
|
|
2
|
+
export { isIpInRange, isIpPrivate } from './ip-range.ts';
|
|
3
|
+
export { extensionToMime, mimeToExtensions } from './mime-classifier.ts';
|
|
4
|
+
export { sanitizeFilename } from './filename-sanitizer.ts';
|
|
5
|
+
export { constantTimeEqual, constantTimeEqualBytes } from './constant-time.ts';
|
|
6
|
+
export { selectForwardableAuthHeaders, type ForwardableAuthHeaders } from './forwardable-auth-headers.ts';
|
|
7
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/helpers/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnE,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AACzD,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACzE,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAC/E,OAAO,EACN,4BAA4B,EAC5B,KAAK,sBAAsB,EAC3B,MAAM,+BAA+B,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { matchesPattern, findMatches } from "./pattern-matcher.js";
|
|
2
|
+
export { isIpInRange, isIpPrivate } from "./ip-range.js";
|
|
3
|
+
export { extensionToMime, mimeToExtensions } from "./mime-classifier.js";
|
|
4
|
+
export { sanitizeFilename } from "./filename-sanitizer.js";
|
|
5
|
+
export { constantTimeEqual, constantTimeEqualBytes } from "./constant-time.js";
|
|
6
|
+
export { selectForwardableAuthHeaders } from "./forwardable-auth-headers.js";
|
|
7
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/helpers/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnE,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AACzD,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACzE,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAC/E,OAAO,EACN,4BAA4B,EAE5B,MAAM,+BAA+B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ip-range.d.ts","sourceRoot":"","sources":["../../src/helpers/ip-range.ts"],"names":[],"mappings":"AAyCA,wBAAgB,WAAW,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAQ3E;AAED,wBAAgB,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAQ/C"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import * as z from 'zod/v4';
|
|
2
|
+
/**
|
|
3
|
+
* IPv4 dotted-quad membership.
|
|
4
|
+
*
|
|
5
|
+
* A range check is a decision about an address a caller did not choose, so it
|
|
6
|
+
* only ever matches an address it could read. Anything that is not four decimal
|
|
7
|
+
* octets in 0-255 — an empty string, `garbage`, `1.2.3`, a hex or octal literal,
|
|
8
|
+
* a value with surrounding space — is in no range at all. Coercing such a value
|
|
9
|
+
* to `0.0.0.0` would report it as a member of any range that starts there.
|
|
10
|
+
*/
|
|
11
|
+
const OCTET_PATTERN = /^(?:0|[1-9][0-9]{0,2})$/;
|
|
12
|
+
const DOTTED_QUAD_SCHEMA = z.string().superRefine((address, context) => {
|
|
13
|
+
const octets = address.split('.');
|
|
14
|
+
if (octets.length !== 4) {
|
|
15
|
+
context.addIssue({
|
|
16
|
+
code: 'custom',
|
|
17
|
+
message: 'An IPv4 address is exactly four dot-separated octets'
|
|
18
|
+
});
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
for (const [index, octet] of octets.entries()) {
|
|
22
|
+
if (!OCTET_PATTERN.test(octet) || Number(octet) > 255) {
|
|
23
|
+
context.addIssue({
|
|
24
|
+
code: 'custom',
|
|
25
|
+
path: [index],
|
|
26
|
+
message: `Octet ${index} is not a decimal number in 0-255`
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
/** The address as a 32-bit number, or undefined when it is not a dotted quad. */
|
|
32
|
+
function ipToNumber(ip) {
|
|
33
|
+
if (!DOTTED_QUAD_SCHEMA.safeParse(ip).success)
|
|
34
|
+
return undefined;
|
|
35
|
+
const [first, second, third, fourth] = ip.split('.').map(Number);
|
|
36
|
+
return ((first << 24) | (second << 16) | (third << 8) | fourth) >>> 0;
|
|
37
|
+
}
|
|
38
|
+
export function isIpInRange(ip, start, end) {
|
|
39
|
+
const address = ipToNumber(ip);
|
|
40
|
+
const from = ipToNumber(start);
|
|
41
|
+
const to = ipToNumber(end);
|
|
42
|
+
// An address or a bound that does not parse is in no range. A membership
|
|
43
|
+
// question about a value the matcher could not read has no true answer.
|
|
44
|
+
if (address === undefined || from === undefined || to === undefined)
|
|
45
|
+
return false;
|
|
46
|
+
return address >= from && address <= to;
|
|
47
|
+
}
|
|
48
|
+
export function isIpPrivate(ip) {
|
|
49
|
+
return (isIpInRange(ip, '10.0.0.0', '10.255.255.255') ||
|
|
50
|
+
isIpInRange(ip, '172.16.0.0', '172.31.255.255') ||
|
|
51
|
+
isIpInRange(ip, '192.168.0.0', '192.168.255.255') ||
|
|
52
|
+
ip === '127.0.0.1' ||
|
|
53
|
+
ip === '::1');
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=ip-range.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ip-range.js","sourceRoot":"","sources":["../../src/helpers/ip-range.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,QAAQ,CAAC;AAE5B;;;;;;;;GAQG;AAEH,MAAM,aAAa,GAAG,yBAAyB,CAAC;AAEhD,MAAM,kBAAkB,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,WAAW,CAAC,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE;IACtE,MAAM,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAClC,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,CAAC,QAAQ,CAAC;YAChB,IAAI,EAAE,QAAQ;YACd,OAAO,EAAE,sDAAsD;SAC/D,CAAC,CAAC;QACH,OAAO;IACR,CAAC;IACD,KAAK,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,EAAE,EAAE,CAAC;QAC/C,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,KAAK,CAAC,GAAG,GAAG,EAAE,CAAC;YACvD,OAAO,CAAC,QAAQ,CAAC;gBAChB,IAAI,EAAE,QAAQ;gBACd,IAAI,EAAE,CAAC,KAAK,CAAC;gBACb,OAAO,EAAE,SAAS,KAAK,mCAAmC;aAC1D,CAAC,CAAC;QACJ,CAAC;IACF,CAAC;AACF,CAAC,CAAC,CAAC;AAEH,iFAAiF;AACjF,SAAS,UAAU,CAAC,EAAU;IAC7B,IAAI,CAAC,kBAAkB,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,OAAO;QAAE,OAAO,SAAS,CAAC;IAChE,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACjE,OAAO,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC,GAAG,CAAC,MAAM,IAAI,EAAE,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;AACvE,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,EAAU,EAAE,KAAa,EAAE,GAAW;IACjE,MAAM,OAAO,GAAG,UAAU,CAAC,EAAE,CAAC,CAAC;IAC/B,MAAM,IAAI,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;IAC/B,MAAM,EAAE,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC;IAC3B,yEAAyE;IACzE,wEAAwE;IACxE,IAAI,OAAO,KAAK,SAAS,IAAI,IAAI,KAAK,SAAS,IAAI,EAAE,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC;IAClF,OAAO,OAAO,IAAI,IAAI,IAAI,OAAO,IAAI,EAAE,CAAC;AACzC,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,EAAU;IACrC,OAAO,CACN,WAAW,CAAC,EAAE,EAAE,UAAU,EAAE,gBAAgB,CAAC;QAC7C,WAAW,CAAC,EAAE,EAAE,YAAY,EAAE,gBAAgB,CAAC;QAC/C,WAAW,CAAC,EAAE,EAAE,aAAa,EAAE,iBAAiB,CAAC;QACjD,EAAE,KAAK,WAAW;QAClB,EAAE,KAAK,KAAK,CACZ,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mime-classifier.d.ts","sourceRoot":"","sources":["../../src/helpers/mime-classifier.ts"],"names":[],"mappings":"AAcA,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAO1D;AAID,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAKvD"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
const MIME_MAP = {
|
|
2
|
+
'text/plain': ['txt', 'md', 'csv'],
|
|
3
|
+
'text/html': ['html', 'htm'],
|
|
4
|
+
'application/json': ['json'],
|
|
5
|
+
'image/png': ['png'],
|
|
6
|
+
'image/jpeg': ['jpg', 'jpeg'],
|
|
7
|
+
'application/pdf': ['pdf'],
|
|
8
|
+
'text/css': ['css'],
|
|
9
|
+
'text/javascript': ['js', 'mjs'],
|
|
10
|
+
'application/typescript': ['ts', 'mts'],
|
|
11
|
+
'text/xml': ['xml'],
|
|
12
|
+
'application/xml': ['xml'],
|
|
13
|
+
};
|
|
14
|
+
export function extensionToMime(ext) {
|
|
15
|
+
for (const [mime, exts] of Object.entries(MIME_MAP)) {
|
|
16
|
+
if (exts.includes(ext.toLowerCase())) {
|
|
17
|
+
return mime;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
const EXTENSION_LOOKUP = new Map(Object.entries(MIME_MAP));
|
|
23
|
+
export function mimeToExtensions(mime) {
|
|
24
|
+
// A copy: the table is module state, and handing a caller the live array
|
|
25
|
+
// would let one `push` rewrite the classifier for every later caller.
|
|
26
|
+
const extensions = EXTENSION_LOOKUP.get(mime);
|
|
27
|
+
return extensions === undefined ? [] : [...extensions];
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=mime-classifier.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mime-classifier.js","sourceRoot":"","sources":["../../src/helpers/mime-classifier.ts"],"names":[],"mappings":"AAAA,MAAM,QAAQ,GAAG;IAChB,YAAY,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,CAAC;IAClC,WAAW,EAAE,CAAC,MAAM,EAAE,KAAK,CAAC;IAC5B,kBAAkB,EAAE,CAAC,MAAM,CAAC;IAC5B,WAAW,EAAE,CAAC,KAAK,CAAC;IACpB,YAAY,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC;IAC7B,iBAAiB,EAAE,CAAC,KAAK,CAAC;IAC1B,UAAU,EAAE,CAAC,KAAK,CAAC;IACnB,iBAAiB,EAAE,CAAC,IAAI,EAAE,KAAK,CAAC;IAChC,wBAAwB,EAAE,CAAC,IAAI,EAAE,KAAK,CAAC;IACvC,UAAU,EAAE,CAAC,KAAK,CAAC;IACnB,iBAAiB,EAAE,CAAC,KAAK,CAAC;CACS,CAAC;AAErC,MAAM,UAAU,eAAe,CAAC,GAAW;IAC1C,KAAK,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;QACrD,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,EAAE,CAAC;YACtC,OAAO,IAAI,CAAC;QACb,CAAC;IACF,CAAC;IACD,OAAO,IAAI,CAAC;AACb,CAAC;AAED,MAAM,gBAAgB,GAAG,IAAI,GAAG,CAAmB,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;AAE7E,MAAM,UAAU,gBAAgB,CAAC,IAAY;IAC5C,yEAAyE;IACzE,sEAAsE;IACtE,MAAM,UAAU,GAAG,gBAAgB,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC9C,OAAO,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC;AACxD,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pattern matching over untrusted text.
|
|
3
|
+
*
|
|
4
|
+
* Both entry points work on a copy of the caller's `RegExp`. A `/g` or `/y`
|
|
5
|
+
* pattern carries `lastIndex` between calls, so matching the caller's own
|
|
6
|
+
* object would make a repeated identical question alternate between answers.
|
|
7
|
+
*/
|
|
8
|
+
export declare function matchesPattern(input: string, pattern: RegExp): boolean;
|
|
9
|
+
export declare function findMatches(input: string, pattern: RegExp): Array<{
|
|
10
|
+
match: string;
|
|
11
|
+
index: number;
|
|
12
|
+
}>;
|
|
13
|
+
//# sourceMappingURL=pattern-matcher.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pattern-matcher.d.ts","sourceRoot":"","sources":["../../src/helpers/pattern-matcher.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAOH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAEtE;AAED,wBAAgB,WAAW,CAC1B,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,GACb,KAAK,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CAYzC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pattern matching over untrusted text.
|
|
3
|
+
*
|
|
4
|
+
* Both entry points work on a copy of the caller's `RegExp`. A `/g` or `/y`
|
|
5
|
+
* pattern carries `lastIndex` between calls, so matching the caller's own
|
|
6
|
+
* object would make a repeated identical question alternate between answers.
|
|
7
|
+
*/
|
|
8
|
+
/** A copy of `pattern`, so the caller's `lastIndex` can never leak between calls. */
|
|
9
|
+
function copyPattern(pattern) {
|
|
10
|
+
return new RegExp(pattern.source, pattern.flags);
|
|
11
|
+
}
|
|
12
|
+
export function matchesPattern(input, pattern) {
|
|
13
|
+
return copyPattern(pattern).test(input);
|
|
14
|
+
}
|
|
15
|
+
export function findMatches(input, pattern) {
|
|
16
|
+
const results = [];
|
|
17
|
+
const re = copyPattern(pattern);
|
|
18
|
+
let match;
|
|
19
|
+
while ((match = re.exec(input)) !== null) {
|
|
20
|
+
results.push({ match: match[0], index: match.index });
|
|
21
|
+
// A zero-length match leaves `lastIndex` where it already was, so a
|
|
22
|
+
// pattern that can match empty would spin on the same index forever.
|
|
23
|
+
// Advancing one code unit past it is what makes the walk terminate.
|
|
24
|
+
if (match[0].length === 0)
|
|
25
|
+
re.lastIndex = match.index + 1;
|
|
26
|
+
}
|
|
27
|
+
return results;
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=pattern-matcher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pattern-matcher.js","sourceRoot":"","sources":["../../src/helpers/pattern-matcher.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,qFAAqF;AACrF,SAAS,WAAW,CAAC,OAAe;IACnC,OAAO,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC;AAClD,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,KAAa,EAAE,OAAe;IAC5D,OAAO,WAAW,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AACzC,CAAC;AAED,MAAM,UAAU,WAAW,CAC1B,KAAa,EACb,OAAe;IAEf,MAAM,OAAO,GAA4C,EAAE,CAAC;IAC5D,MAAM,EAAE,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC;IAChC,IAAI,KAA6B,CAAC;IAClC,OAAO,CAAC,KAAK,GAAG,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;QAC1C,OAAO,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC;QACtD,oEAAoE;QACpE,qEAAqE;QACrE,oEAAoE;QACpE,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,KAAK,CAAC;YAAE,EAAE,CAAC,SAAS,GAAG,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC;IAC3D,CAAC;IACD,OAAO,OAAO,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli-types.d.ts","sourceRoot":"","sources":["../../src/implementations/cli-types.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,uBAAuB,EAAE,yBAAyB,EAAE,MAAM,sCAAsC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli-types.js","sourceRoot":"","sources":["../../src/implementations/cli-types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { type EncryptionKeyRuntime } from './keys.ts';
|
|
2
|
+
export { boundEncryptionKeyHex, readOrCreateKeyFile, resolveEncryptionKeyHexForBase, SECRET_ENCRYPTION_KEY_CREDENTIAL } from './keys.ts';
|
|
3
|
+
import { type EncryptedSecret } from '../schemas/encryption.ts';
|
|
4
|
+
export declare function encryptStringWithKey(data: string, keyHex: string): Uint8Array;
|
|
5
|
+
export declare function decryptToStringWithKey(data: Uint8Array, keyHex: string): string;
|
|
6
|
+
export declare function generateEncryptionKey(): string;
|
|
7
|
+
export declare class SecretEncryption {
|
|
8
|
+
private readonly runtime;
|
|
9
|
+
constructor(runtime: EncryptionKeyRuntime);
|
|
10
|
+
private key;
|
|
11
|
+
encryptBytes(data: Uint8Array): Promise<Uint8Array>;
|
|
12
|
+
decryptBytes(encrypted: Uint8Array): Promise<Uint8Array>;
|
|
13
|
+
encryptString(data: string): Promise<Uint8Array>;
|
|
14
|
+
decryptToString(data: Uint8Array): Promise<string>;
|
|
15
|
+
encrypt(value: string): Promise<EncryptedSecret>;
|
|
16
|
+
decrypt(data: EncryptedSecret): Promise<string>;
|
|
17
|
+
encryptForStorage(value: string): Promise<string>;
|
|
18
|
+
decryptFromStorage(stored: string): Promise<string>;
|
|
19
|
+
static generateKey(): string;
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=encryption.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"encryption.d.ts","sourceRoot":"","sources":["../../src/implementations/encryption.ts"],"names":[],"mappings":"AAEA,OAAO,EAA2B,KAAK,oBAAoB,EAAE,MAAM,WAAW,CAAC;AAC/E,OAAO,EACN,qBAAqB,EACrB,mBAAmB,EACnB,8BAA8B,EAC9B,gCAAgC,EAChC,MAAM,WAAW,CAAC;AACnB,OAAO,EAA8G,KAAK,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAuG5K,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,UAAU,CAE7E;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAE/E;AA8BD,wBAAgB,qBAAqB,IAAI,MAAM,CAE9C;AAED,qBAAa,gBAAgB;IAChB,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAAP,OAAO,EAAE,oBAAoB;IAE1D,OAAO,CAAC,GAAG;IAIL,YAAY,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;IAInD,YAAY,CAAC,SAAS,EAAE,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;IAIxD,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAIhD,eAAe,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC;IAIlD,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC;IAIhD,OAAO,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC;IAI/C,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAKjD,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAWzD,MAAM,CAAC,WAAW,IAAI,MAAM;CAG5B"}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import { fromHex, toHex, fromBase64, toBase64 } from '@vibesdotdev/crypto/encoding';
|
|
2
|
+
import { CapabilityError, CaughtFailureSchema } from '@vibesdotdev/kernel';
|
|
3
|
+
import { resolveEncryptionKeyHex } from "./keys.js";
|
|
4
|
+
export { boundEncryptionKeyHex, readOrCreateKeyFile, resolveEncryptionKeyHexForBase, SECRET_ENCRYPTION_KEY_CREDENTIAL } from "./keys.js";
|
|
5
|
+
import { parseEncryptionKey, parseCiphertext, BinaryCiphertextSchema, EncryptedSecretSchema, StoredCiphertextSchema } from "../schemas/encryption.js";
|
|
6
|
+
const ALGORITHM = 'aes-256-gcm';
|
|
7
|
+
const IV_LENGTH = 16;
|
|
8
|
+
const TAG_LENGTH = 16;
|
|
9
|
+
const KEY_LENGTH = 32;
|
|
10
|
+
const STORAGE_AAD = new TextEncoder().encode('secret');
|
|
11
|
+
let _nodeCrypto = null;
|
|
12
|
+
function nodeCrypto() {
|
|
13
|
+
if (_nodeCrypto)
|
|
14
|
+
return _nodeCrypto;
|
|
15
|
+
const loaded = globalThis.process?.getBuiltinModule?.('node:crypto');
|
|
16
|
+
if (!loaded) {
|
|
17
|
+
throw new CapabilityError('node:crypto is unavailable in this runtime.', 'UNAVAILABLE', {
|
|
18
|
+
reason: 'crypto-unavailable',
|
|
19
|
+
retryable: false
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
_nodeCrypto = loaded;
|
|
23
|
+
return loaded;
|
|
24
|
+
}
|
|
25
|
+
function keyFromHex(hex) {
|
|
26
|
+
return fromHex(parseEncryptionKey(hex));
|
|
27
|
+
}
|
|
28
|
+
const runtimeKeys = new WeakMap();
|
|
29
|
+
/** One key resolution per runtime; a refused resolution is not cached, so a later bind is seen. */
|
|
30
|
+
function keyFor(runtime) {
|
|
31
|
+
let key = runtimeKeys.get(runtime);
|
|
32
|
+
if (!key) {
|
|
33
|
+
key = resolveEncryptionKeyHex(runtime).then(keyFromHex);
|
|
34
|
+
runtimeKeys.set(runtime, key);
|
|
35
|
+
key.catch(() => {
|
|
36
|
+
if (runtimeKeys.get(runtime) === key)
|
|
37
|
+
runtimeKeys.delete(runtime);
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
return key;
|
|
41
|
+
}
|
|
42
|
+
function concatBytes(...parts) {
|
|
43
|
+
const result = new Uint8Array(parts.reduce((length, part) => length + part.byteLength, 0));
|
|
44
|
+
let offset = 0;
|
|
45
|
+
for (const part of parts) {
|
|
46
|
+
result.set(part, offset);
|
|
47
|
+
offset += part.byteLength;
|
|
48
|
+
}
|
|
49
|
+
return result;
|
|
50
|
+
}
|
|
51
|
+
function encryptBytesWith(key, data) {
|
|
52
|
+
const { createCipheriv, randomBytes } = nodeCrypto();
|
|
53
|
+
const iv = randomBytes(IV_LENGTH);
|
|
54
|
+
const cipher = createCipheriv(ALGORITHM, key, iv);
|
|
55
|
+
return concatBytes(iv, cipher.update(data), cipher.final(), cipher.getAuthTag());
|
|
56
|
+
}
|
|
57
|
+
function ciphertextInvalid(cause) {
|
|
58
|
+
return new CapabilityError('The encrypted data failed authentication: it is malformed, truncated or tampered with.', 'INVALID_INPUT', { reason: 'ciphertext-invalid', retryable: false, cause: CaughtFailureSchema.parse(cause) });
|
|
59
|
+
}
|
|
60
|
+
function decryptBytesWith(key, encrypted) {
|
|
61
|
+
parseCiphertext(BinaryCiphertextSchema, encrypted);
|
|
62
|
+
const driver = nodeCrypto();
|
|
63
|
+
const iv = encrypted.slice(0, IV_LENGTH);
|
|
64
|
+
const tag = encrypted.slice(encrypted.byteLength - TAG_LENGTH);
|
|
65
|
+
const ciphertext = encrypted.slice(IV_LENGTH, encrypted.byteLength - TAG_LENGTH);
|
|
66
|
+
try {
|
|
67
|
+
const decipher = driver.createDecipheriv(ALGORITHM, key, iv);
|
|
68
|
+
decipher.setAuthTag(tag);
|
|
69
|
+
return concatBytes(decipher.update(ciphertext), decipher.final());
|
|
70
|
+
}
|
|
71
|
+
catch (error) {
|
|
72
|
+
throw ciphertextInvalid(error);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
export function encryptStringWithKey(data, keyHex) {
|
|
76
|
+
return encryptBytesWith(keyFromHex(keyHex), new TextEncoder().encode(data));
|
|
77
|
+
}
|
|
78
|
+
export function decryptToStringWithKey(data, keyHex) {
|
|
79
|
+
return new TextDecoder().decode(decryptBytesWith(keyFromHex(keyHex), data));
|
|
80
|
+
}
|
|
81
|
+
function encryptSecretWith(key, value) {
|
|
82
|
+
const { createCipheriv, randomBytes } = nodeCrypto();
|
|
83
|
+
const iv = randomBytes(IV_LENGTH);
|
|
84
|
+
const cipher = createCipheriv(ALGORITHM, key, iv);
|
|
85
|
+
cipher.setAAD(STORAGE_AAD);
|
|
86
|
+
const encrypted = concatBytes(cipher.update(new TextEncoder().encode(value)), cipher.final());
|
|
87
|
+
const tag = cipher.getAuthTag();
|
|
88
|
+
return {
|
|
89
|
+
iv: toBase64(iv),
|
|
90
|
+
tag: toBase64(tag),
|
|
91
|
+
encrypted: toBase64(encrypted)
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
function decryptSecretWith(key, data) {
|
|
95
|
+
data = parseCiphertext(EncryptedSecretSchema, data);
|
|
96
|
+
const driver = nodeCrypto();
|
|
97
|
+
try {
|
|
98
|
+
const decipher = driver.createDecipheriv(ALGORITHM, key, fromBase64(data.iv));
|
|
99
|
+
decipher.setAAD(STORAGE_AAD);
|
|
100
|
+
decipher.setAuthTag(fromBase64(data.tag));
|
|
101
|
+
return decipher.update(fromBase64(data.encrypted), undefined, 'utf8') + decipher.final('utf8');
|
|
102
|
+
}
|
|
103
|
+
catch (error) {
|
|
104
|
+
throw ciphertextInvalid(error);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
export function generateEncryptionKey() {
|
|
108
|
+
return toHex(nodeCrypto().randomBytes(KEY_LENGTH));
|
|
109
|
+
}
|
|
110
|
+
export class SecretEncryption {
|
|
111
|
+
runtime;
|
|
112
|
+
constructor(runtime) {
|
|
113
|
+
this.runtime = runtime;
|
|
114
|
+
}
|
|
115
|
+
key() {
|
|
116
|
+
return keyFor(this.runtime);
|
|
117
|
+
}
|
|
118
|
+
async encryptBytes(data) {
|
|
119
|
+
return encryptBytesWith(await this.key(), data);
|
|
120
|
+
}
|
|
121
|
+
async decryptBytes(encrypted) {
|
|
122
|
+
return decryptBytesWith(await this.key(), encrypted);
|
|
123
|
+
}
|
|
124
|
+
async encryptString(data) {
|
|
125
|
+
return this.encryptBytes(new TextEncoder().encode(data));
|
|
126
|
+
}
|
|
127
|
+
async decryptToString(data) {
|
|
128
|
+
return new TextDecoder().decode(await this.decryptBytes(data));
|
|
129
|
+
}
|
|
130
|
+
async encrypt(value) {
|
|
131
|
+
return encryptSecretWith(await this.key(), value);
|
|
132
|
+
}
|
|
133
|
+
async decrypt(data) {
|
|
134
|
+
return decryptSecretWith(await this.key(), data);
|
|
135
|
+
}
|
|
136
|
+
async encryptForStorage(value) {
|
|
137
|
+
const secret = encryptSecretWith(await this.key(), value);
|
|
138
|
+
return `${secret.iv}:${secret.tag}:${secret.encrypted}`;
|
|
139
|
+
}
|
|
140
|
+
async decryptFromStorage(stored) {
|
|
141
|
+
parseCiphertext(StoredCiphertextSchema, stored);
|
|
142
|
+
const [iv, tag, encrypted, ...extra] = stored.split(':');
|
|
143
|
+
if (iv === undefined || tag === undefined || encrypted === undefined || extra.length > 0) {
|
|
144
|
+
throw new CapabilityError('Invalid encrypted value format', 'INVALID_INPUT', {
|
|
145
|
+
reason: 'ciphertext-invalid'
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
return decryptSecretWith(await this.key(), { iv, tag, encrypted });
|
|
149
|
+
}
|
|
150
|
+
static generateKey() {
|
|
151
|
+
return generateEncryptionKey();
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
//# sourceMappingURL=encryption.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"encryption.js","sourceRoot":"","sources":["../../src/implementations/encryption.ts"],"names":[],"mappings":"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"}
|