@socketsecurity/lib 6.0.7 → 6.0.9
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/CHANGELOG.md +42 -0
- package/README.md +1 -1
- package/dist/ai/agent-context.d.mts +103 -0
- package/dist/ai/agent-context.js +157 -0
- package/dist/ai/backends.d.mts +83 -0
- package/dist/ai/backends.js +173 -0
- package/dist/ai/credentials.d.mts +49 -0
- package/dist/ai/credentials.js +82 -0
- package/dist/ai/discover.d.mts +4 -0
- package/dist/ai/discover.js +1 -1
- package/dist/ai/exec.d.mts +52 -0
- package/dist/ai/exec.js +92 -0
- package/dist/ai/http.d.mts +132 -0
- package/dist/ai/http.js +130 -0
- package/dist/ai/profiles.d.mts +41 -6
- package/dist/ai/profiles.js +52 -10
- package/dist/ai/route.d.mts +82 -0
- package/dist/ai/route.js +171 -0
- package/dist/ai/spawn.d.mts +42 -2
- package/dist/ai/spawn.js +146 -33
- package/dist/ai/subagent-status.d.mts +48 -0
- package/dist/ai/subagent-status.js +57 -0
- package/dist/ai/tier.d.mts +60 -0
- package/dist/ai/tier.js +53 -0
- package/dist/ai/types.d.mts +25 -2
- package/dist/ai/worktree.js +4 -0
- package/dist/archives/tar.js +1 -1
- package/dist/archives/zip.js +2 -2
- package/dist/argv/parse.d.ts +19 -2
- package/dist/argv/parse.js +1 -1
- package/dist/arrays/join.js +4 -0
- package/dist/bin/find.js +4 -4
- package/dist/bin/prim.cjs +23322 -18018
- package/dist/bin/resolve.js +2 -2
- package/dist/cache/ttl/store.js +2 -2
- package/dist/cli/check-primordials.d.ts +8 -3
- package/dist/cli/check-primordials.js +4 -4
- package/dist/compression/_internal.js +1 -1
- package/dist/compression/brotli.d.ts +1 -2
- package/dist/compression/brotli.js +5 -1
- package/dist/compression/gzip.js +5 -1
- package/dist/config/layers.d.ts +53 -0
- package/dist/config/layers.js +83 -0
- package/dist/constants/packages.d.ts +3 -0
- package/dist/constants/packages.js +2 -1
- package/dist/constants/socket.d.ts +2 -6
- package/dist/constants/socket.js +12 -14
- package/dist/cover/code.js +2 -2
- package/dist/crypto/hash.d.ts +4 -1
- package/dist/crypto/hash.js +4 -1
- package/dist/dlx/arborist.js +13 -3
- package/dist/dlx/binary-cache.js +1 -1
- package/dist/dlx/binary-resolution.js +1 -1
- package/dist/dlx/detect.d.ts +8 -0
- package/dist/dlx/firewall.d.ts +8 -0
- package/dist/dlx/lockfile.js +5 -2
- package/dist/dlx/manifest.js +1 -1
- package/dist/dlx/package.js +4 -0
- package/dist/eco/cargo/parse-lockfile.d.ts +1 -2
- package/dist/eco/cargo/parse-lockfile.js +3 -3
- package/dist/eco/manifest/detect-format.js +1 -1
- package/dist/eco/npm/npm/parse-lockfile.d.ts +3 -4
- package/dist/eco/npm/npm/parse-lockfile.js +2 -2
- package/dist/eco/npm/parse-package-json.d.ts +11 -0
- package/dist/eco/npm/parse-package-json.js +1 -1
- package/dist/eco/npm/pnpm/parse-lockfile.d.ts +5 -3
- package/dist/eco/npm/pnpm/parse-lockfile.js +3 -3
- package/dist/eco/npm/yarnpkg/yarn/exec.js +1 -1
- package/dist/eco/npm/yarnpkg/yarn/parse-lockfile.d.ts +1 -2
- package/dist/eco/npm/yarnpkg/yarn/parse-lockfile.js +2 -2
- package/dist/env/proxy.js +1 -1
- package/dist/env/rewire.d.ts +6 -3
- package/dist/env/rewire.js +7 -8
- package/dist/env/socket.d.ts +7 -0
- package/dist/env/socket.js +10 -0
- package/dist/env/xdg.d.ts +17 -0
- package/dist/env/xdg.js +21 -1
- package/dist/errors/predicates.js +1 -1
- package/dist/errors/stack.js +1 -2
- package/dist/external/@npmcli/package-json.js +3455 -4881
- package/dist/external/@npmcli/promise-spawn.js +3 -1
- package/dist/external/@yarnpkg/extensions.js +1 -1
- package/dist/external/external-pack.js +1 -1
- package/dist/external/npm-pack.js +29164 -31799
- package/dist/external/pico-pack.js +4 -2
- package/dist/external/tar-fs.js +63 -16
- package/dist/external/which.js +3 -1
- package/dist/external-tools/bazel/asset-names.d.ts +1 -1
- package/dist/external-tools/bazel/asset-names.js +5 -2
- package/dist/external-tools/bazel/from-download.d.ts +1 -1
- package/dist/external-tools/bazel/from-download.js +5 -2
- package/dist/external-tools/bazel/resolve-bazel-version.js +4 -0
- package/dist/external-tools/bazel/resolve.d.ts +3 -3
- package/dist/external-tools/bazel/resolve.js +16 -8
- package/dist/external-tools/cdxgen/asset-names.d.ts +1 -1
- package/dist/external-tools/cdxgen/asset-names.js +5 -2
- package/dist/external-tools/cdxgen/from-download.d.ts +1 -1
- package/dist/external-tools/cdxgen/from-download.js +7 -4
- package/dist/external-tools/cdxgen/resolve.d.ts +3 -3
- package/dist/external-tools/cdxgen/resolve.js +16 -8
- package/dist/external-tools/from-download.d.ts +2 -2
- package/dist/external-tools/from-download.js +11 -5
- package/dist/external-tools/from-pip-venv.d.ts +1 -1
- package/dist/external-tools/from-pip-venv.js +12 -5
- package/dist/external-tools/janus/asset-names.d.ts +1 -1
- package/dist/external-tools/janus/asset-names.js +5 -2
- package/dist/external-tools/janus/from-download.d.ts +1 -1
- package/dist/external-tools/janus/from-download.js +5 -2
- package/dist/external-tools/janus/resolve.d.ts +3 -3
- package/dist/external-tools/janus/resolve.js +16 -8
- package/dist/external-tools/jre/asset-names.d.ts +1 -1
- package/dist/external-tools/jre/asset-names.js +5 -2
- package/dist/external-tools/jre/detect-platform-arch.js +1 -1
- package/dist/external-tools/jre/from-download.d.ts +1 -1
- package/dist/external-tools/jre/from-download.js +7 -4
- package/dist/external-tools/jre/from-java-home.js +2 -2
- package/dist/external-tools/jre/from-vfs.js +2 -2
- package/dist/external-tools/jre/resolve.d.ts +3 -3
- package/dist/external-tools/jre/resolve.js +16 -8
- package/dist/external-tools/manifest.d.ts +18 -0
- package/dist/external-tools/manifest.js +2 -2
- package/dist/external-tools/opengrep/asset-names.d.ts +1 -1
- package/dist/external-tools/opengrep/asset-names.js +5 -2
- package/dist/external-tools/opengrep/from-download.d.ts +1 -1
- package/dist/external-tools/opengrep/from-download.js +5 -2
- package/dist/external-tools/opengrep/resolve.d.ts +3 -3
- package/dist/external-tools/opengrep/resolve.js +16 -8
- package/dist/external-tools/python/asset-names.d.ts +1 -1
- package/dist/external-tools/python/asset-names.js +11 -4
- package/dist/external-tools/python/dlx.d.ts +3 -3
- package/dist/external-tools/python/dlx.js +20 -9
- package/dist/external-tools/python/from-download.d.ts +1 -1
- package/dist/external-tools/python/from-download.js +12 -5
- package/dist/external-tools/python/pin.js +6 -3
- package/dist/external-tools/python/pip-install.js +6 -3
- package/dist/external-tools/python/resolve.d.ts +3 -3
- package/dist/external-tools/python/resolve.js +19 -11
- package/dist/external-tools/python/uv-install.d.ts +89 -0
- package/dist/external-tools/python/uv-install.js +165 -0
- package/dist/external-tools/sbt/asset-names.d.ts +1 -1
- package/dist/external-tools/sbt/asset-names.js +5 -2
- package/dist/external-tools/sbt/from-download.d.ts +1 -1
- package/dist/external-tools/sbt/from-download.js +5 -2
- package/dist/external-tools/sbt/resolve.d.ts +3 -3
- package/dist/external-tools/sbt/resolve.js +16 -8
- package/dist/external-tools/skillspector/from-dlx.d.ts +1 -1
- package/dist/external-tools/skillspector/from-dlx.js +10 -3
- package/dist/external-tools/skillspector/from-uv.d.ts +30 -0
- package/dist/external-tools/skillspector/from-uv.js +56 -0
- package/dist/external-tools/skillspector/resolve.d.ts +20 -5
- package/dist/external-tools/skillspector/resolve.js +27 -6
- package/dist/external-tools/skillspector/types.d.ts +3 -1
- package/dist/external-tools/synp/asset-names.d.ts +1 -1
- package/dist/external-tools/synp/asset-names.js +6 -2
- package/dist/external-tools/synp/from-download.d.ts +1 -1
- package/dist/external-tools/synp/from-download.js +5 -2
- package/dist/external-tools/synp/resolve.d.ts +3 -3
- package/dist/external-tools/synp/resolve.js +16 -8
- package/dist/external-tools/trivy/asset-names.d.ts +1 -1
- package/dist/external-tools/trivy/asset-names.js +5 -2
- package/dist/external-tools/trivy/from-download.d.ts +1 -1
- package/dist/external-tools/trivy/from-download.js +7 -4
- package/dist/external-tools/trivy/resolve.d.ts +3 -3
- package/dist/external-tools/trivy/resolve.js +16 -8
- package/dist/external-tools/trufflehog/asset-names.d.ts +1 -1
- package/dist/external-tools/trufflehog/asset-names.js +5 -2
- package/dist/external-tools/trufflehog/from-download.d.ts +1 -1
- package/dist/external-tools/trufflehog/from-download.js +7 -4
- package/dist/external-tools/trufflehog/resolve.d.ts +3 -3
- package/dist/external-tools/trufflehog/resolve.js +16 -8
- package/dist/external-tools/uv/asset-names.d.ts +36 -0
- package/dist/external-tools/uv/asset-names.js +73 -0
- package/dist/external-tools/uv/from-download.d.ts +17 -0
- package/dist/external-tools/uv/from-download.js +50 -0
- package/dist/external-tools/uv/from-path.d.ts +5 -0
- package/dist/external-tools/uv/from-path.js +22 -0
- package/dist/external-tools/uv/from-vfs.d.ts +7 -0
- package/dist/external-tools/uv/from-vfs.js +26 -0
- package/dist/external-tools/uv/resolve.d.ts +25 -0
- package/dist/external-tools/uv/resolve.js +61 -0
- package/dist/external-tools/uv/types.d.ts +24 -0
- package/dist/external-tools/uv/types.js +2 -0
- package/dist/fleet/repo-config.d.ts +53 -0
- package/dist/fleet/repo-config.js +79 -0
- package/dist/fs/allowed-dirs-cache.d.ts +27 -1
- package/dist/fs/allowed-dirs-cache.js +39 -6
- package/dist/fs/copy.d.ts +88 -0
- package/dist/fs/copy.js +89 -0
- package/dist/fs/find.js +1 -1
- package/dist/fs/read-json-cache.d.ts +7 -0
- package/dist/fs/resolve-module.js +6 -2
- package/dist/fs/safe.js +1 -1
- package/dist/git/_internal.js +3 -3
- package/dist/git/repo.js +2 -4
- package/dist/git/staged.js +8 -0
- package/dist/git/tracked.d.ts +84 -0
- package/dist/git/tracked.js +163 -0
- package/dist/git/unstaged.js +8 -0
- package/dist/github/refs-graphql.js +4 -0
- package/dist/github/refs-rest.js +4 -0
- package/dist/globs/_internal.js +1 -1
- package/dist/globs/match.js +9 -1
- package/dist/globs/matcher.js +5 -1
- package/dist/http-request/browser.js +7 -3
- package/dist/http-request/checksum-file.js +1 -1
- package/dist/http-request/{browser-fetch.d.ts → fetch/browser.d.ts} +2 -2
- package/dist/http-request/{browser-fetch.js → fetch/browser.js} +4 -4
- package/dist/http-request/headers.js +1 -1
- package/dist/http-request/request-attempt.js +2 -2
- package/dist/http-request/user-agent.js +1 -1
- package/dist/integrity.d.ts +124 -71
- package/dist/integrity.js +168 -78
- package/dist/json/edit.js +38 -30
- package/dist/json/format.js +1 -1
- package/dist/logger/colors.d.ts +1 -2
- package/dist/logger/colors.js +2 -2
- package/dist/logger/symbols-builder.js +7 -8
- package/dist/logger/symbols.js +8 -8
- package/dist/native-messaging/install.d.ts +1 -1
- package/dist/native-messaging/install.js +7 -4
- package/dist/native-messaging/rate-limit.d.ts +7 -0
- package/dist/native-messaging/rate-limit.js +4 -0
- package/dist/node/async-hooks.js +1 -1
- package/dist/node/child-process.js +1 -1
- package/dist/node/crypto.js +1 -1
- package/dist/node/events.js +1 -1
- package/dist/node/fs-promises.js +1 -1
- package/dist/node/fs.d.ts +22 -6
- package/dist/node/fs.js +16 -3
- package/dist/node/http.js +1 -1
- package/dist/node/https.js +1 -1
- package/dist/node/module.d.ts +73 -2
- package/dist/node/module.js +97 -12
- package/dist/node/os.d.ts +10 -2
- package/dist/node/os.js +11 -4
- package/dist/node/path.d.ts +11 -2
- package/dist/node/path.js +17 -4
- package/dist/node/timers-promises.js +1 -1
- package/dist/node/url.js +1 -1
- package/dist/node/util.js +1 -1
- package/dist/objects/getters.js +1 -1
- package/dist/objects/mutate.js +2 -2
- package/dist/packages/edit-class.d.ts +2 -3
- package/dist/packages/edit-class.js +41 -35
- package/dist/packages/exports.js +4 -4
- package/dist/packages/fetch.js +1 -1
- package/dist/packages/isolation.js +2 -2
- package/dist/packages/licenses.js +2 -2
- package/dist/packages/manifest.d.ts +29 -0
- package/dist/packages/manifest.js +40 -4
- package/dist/packages/normalize.js +2 -2
- package/dist/packages/provenance.js +3 -3
- package/dist/packages/specs.js +1 -1
- package/dist/packages/tarball.js +4 -2
- package/dist/packages/types.d.ts +1 -2
- package/dist/paths/_internal.d.ts +1 -7
- package/dist/paths/_internal.js +9 -15
- package/dist/paths/conversion.js +1 -1
- package/dist/paths/dirnames.d.ts +1 -0
- package/dist/paths/dirnames.js +2 -0
- package/dist/paths/normalize.js +1 -1
- package/dist/paths/predicates.js +2 -1
- package/dist/paths/resolve.js +14 -19
- package/dist/paths/rewire.d.ts +5 -0
- package/dist/paths/socket.d.ts +137 -123
- package/dist/paths/socket.js +172 -131
- package/dist/perf/metrics.js +1 -1
- package/dist/perf/report.js +1 -1
- package/dist/primordials/process.d.ts +88 -0
- package/dist/primordials/process.js +132 -0
- package/dist/primordials/uncurry.d.ts +1 -2
- package/dist/process/spawn/child.js +8 -2
- package/dist/process/spawn/errors.js +1 -1
- package/dist/releases/github-archives.js +1 -1
- package/dist/releases/github-listing.d.ts +1 -2
- package/dist/schema/types.d.ts +3 -4
- package/dist/schema/validate.js +1 -1
- package/dist/secrets/broker.d.ts +35 -0
- package/dist/secrets/broker.js +72 -0
- package/dist/secrets/find.d.ts +8 -6
- package/dist/secrets/find.js +25 -5
- package/dist/secrets/keychain.d.ts +1 -1
- package/dist/secrets/linux.js +32 -44
- package/dist/secrets/macos.d.ts +1 -2
- package/dist/secrets/macos.js +20 -29
- package/dist/secrets/rc.d.ts +2 -2
- package/dist/secrets/rc.js +21 -13
- package/dist/secrets/socket-api-token.js +8 -0
- package/dist/secrets/windows.js +27 -33
- package/dist/shell/parse.d.ts +32 -0
- package/dist/shell/parse.js +60 -0
- package/dist/smol/detect.js +1 -1
- package/dist/smol/http.js +1 -1
- package/dist/smol/https.js +1 -1
- package/dist/smol/manifest.js +1 -1
- package/dist/smol/path.js +1 -1
- package/dist/smol/primordial.js +1 -1
- package/dist/smol/purl.js +1 -1
- package/dist/smol/versions.js +1 -1
- package/dist/smol/vfs.js +1 -1
- package/dist/sorts/_internal.d.ts +1 -2
- package/dist/sorts/_internal.js +2 -6
- package/dist/sorts/semver.js +2 -2
- package/dist/spinner/create-spinner-class.js +2 -2
- package/dist/spinner/spinner-internals.d.ts +1 -1
- package/dist/spinner/spinner-internals.js +9 -5
- package/dist/spinner/spinner.d.ts +4 -0
- package/dist/spinner/spinner.js +1 -1
- package/dist/stdio/progress.js +6 -2
- package/dist/stdio/prompts.d.ts +2 -10
- package/dist/stdio/prompts.js +11 -24
- package/dist/strings/format.js +1 -1
- package/dist/strings/search.js +1 -1
- package/dist/temporal/instant.js +2 -2
- package/dist/themes/context.d.ts +5 -3
- package/dist/themes/context.js +5 -6
- package/dist/url/assert-safe.d.ts +29 -0
- package/dist/url/assert-safe.js +54 -0
- package/dist/url/predicates.d.ts +31 -1
- package/dist/url/predicates.js +42 -1
- package/dist/url/types.d.ts +4 -0
- package/llms.txt +750 -0
- package/package.json +253 -125
package/dist/integrity.d.ts
CHANGED
|
@@ -1,18 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SRI-blessed hash algorithms. The W3C set; the prefix is part of the wire
|
|
3
|
+
* format, not a fleet convention.
|
|
4
|
+
*/
|
|
5
|
+
export type HashAlgorithm = 'sha256' | 'sha384' | 'sha512';
|
|
6
|
+
/**
|
|
7
|
+
* A cryptographic hash: an algorithm plus the digest in both encodings. Frozen,
|
|
8
|
+
* plain, self-describing — `h.algorithm` removes every "is this 256 or 512?"
|
|
9
|
+
* guess, and `h.hex` / `h.sri` are precomputed views (cheap transcodes of the
|
|
10
|
+
* digest, eager so the value stays serializable and structurally comparable).
|
|
11
|
+
*/
|
|
12
|
+
export interface Hash {
|
|
13
|
+
readonly algorithm: HashAlgorithm;
|
|
14
|
+
/**
|
|
15
|
+
* Lowercase hex digest (64 chars sha256, 96 sha384, 128 sha512).
|
|
16
|
+
*/
|
|
17
|
+
readonly hex: string;
|
|
18
|
+
/**
|
|
19
|
+
* W3C SRI string: `<algorithm>-<base64>`.
|
|
20
|
+
*/
|
|
21
|
+
readonly sri: string;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Anything a caller can hand verify/convert as "the expected hash": a parsed
|
|
25
|
+
* {@link Hash}, an SRI string, or a bare hex digest (algorithm inferred by
|
|
26
|
+
* length).
|
|
27
|
+
*/
|
|
28
|
+
export type HashInput = string | Hash;
|
|
1
29
|
/**
|
|
2
30
|
* Tagged union representing an expected hash.
|
|
3
31
|
*
|
|
4
|
-
* @
|
|
5
|
-
*
|
|
6
|
-
* 'sha256-NiCg/K+B7NOq7M1ZZZGdkNvJE/TQepbhHnyvwseFBUs='
|
|
7
|
-
*
|
|
8
|
-
* @example
|
|
9
|
-
* // Bare sha256 hex (sniffed as checksum):
|
|
10
|
-
* 'a1b2c3...'
|
|
11
|
-
*
|
|
12
|
-
* @example
|
|
13
|
-
* // Explicit:
|
|
14
|
-
* { type: 'integrity', value: 'sha512-...' }
|
|
15
|
-
* { type: 'checksum', value: 'a1b2c3...' }
|
|
32
|
+
* @deprecated Prefer {@link HashInput} + {@link parseHash}. Kept for the
|
|
33
|
+
* `integrity?: HashSpec` option fields across dlx / external-tools.
|
|
16
34
|
*/
|
|
17
35
|
export type HashSpec = string | {
|
|
18
36
|
type: 'integrity';
|
|
@@ -22,15 +40,16 @@ export type HashSpec = string | {
|
|
|
22
40
|
value: string;
|
|
23
41
|
};
|
|
24
42
|
/**
|
|
25
|
-
* Normalized internal form. Always an object.
|
|
43
|
+
* Normalized internal form of a {@link HashSpec}. Always an object.
|
|
26
44
|
*/
|
|
27
45
|
export interface NormalizedHash {
|
|
28
46
|
type: 'integrity' | 'checksum';
|
|
29
47
|
value: string;
|
|
30
48
|
}
|
|
31
49
|
/**
|
|
32
|
-
* Both hash formats for the same bytes
|
|
33
|
-
*
|
|
50
|
+
* Both pinned hash formats for the same bytes: the sha512 SRI we pin against
|
|
51
|
+
* and the sha256 hex upstream tools emit. Returned from downloads so callers
|
|
52
|
+
* record whichever their config uses.
|
|
34
53
|
*/
|
|
35
54
|
export interface ComputedHashes {
|
|
36
55
|
/**
|
|
@@ -43,7 +62,7 @@ export interface ComputedHashes {
|
|
|
43
62
|
checksum: string;
|
|
44
63
|
}
|
|
45
64
|
/**
|
|
46
|
-
* Parsed components of an integrity string.
|
|
65
|
+
* Parsed components of an SRI integrity string.
|
|
47
66
|
*/
|
|
48
67
|
export interface ParsedIntegrity {
|
|
49
68
|
/**
|
|
@@ -56,54 +75,64 @@ export interface ParsedIntegrity {
|
|
|
56
75
|
body: string;
|
|
57
76
|
}
|
|
58
77
|
/**
|
|
59
|
-
* Convert a
|
|
60
|
-
* Idempotent on integrity input — call this on user-supplied data without first
|
|
61
|
-
* sniffing the format.
|
|
78
|
+
* Convert a hex checksum to its SRI integrity form.
|
|
62
79
|
*
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
*
|
|
66
|
-
*
|
|
80
|
+
* @deprecated Prefer `parseHash(x).sri`, which is total across all algorithms
|
|
81
|
+
* and infers the algorithm from a bare hex digest. This shim defaults to
|
|
82
|
+
* `'sha256'` because it only relabels the hex bytes — it does NOT re-hash, so
|
|
83
|
+
* a sha512 label on a 256-bit digest would be a lie. Idempotent on SRI input.
|
|
84
|
+
*
|
|
85
|
+
* @throws TypeError when the input is neither a recognized SRI nor a hex
|
|
86
|
+
* digest.
|
|
87
|
+
*/
|
|
88
|
+
export declare function checksumToIntegrity(input: string, algorithm?: HashAlgorithm): string;
|
|
89
|
+
/**
|
|
90
|
+
* Compute a single {@link Hash} of `bytes`. Defaults to sha512 — the canonical
|
|
91
|
+
* trust string we pin against. Pass `'sha256'` for the upstream-interop digest.
|
|
67
92
|
*
|
|
68
93
|
* @example
|
|
69
94
|
* ;```typescript
|
|
70
|
-
*
|
|
71
|
-
*
|
|
72
|
-
* )
|
|
73
|
-
* // 'sha256-NiCg/K+B7NOq7M1ZZZGdkNvJE/TQepbhHnyvwseFBUs='
|
|
74
|
-
*
|
|
75
|
-
* checksumToIntegrity('sha256-NiCg/K+B7NOq7M1ZZZGdkNvJE/TQepbhHnyvwseFBUs=')
|
|
76
|
-
* // 'sha256-NiCg/K+B7NOq7M1ZZZGdkNvJE/TQepbhHnyvwseFBUs=' (idempotent)
|
|
95
|
+
* computeHash(bytes).sri // 'sha512-…' (pin this)
|
|
96
|
+
* computeHash(bytes, 'sha256').hex // '3620a0…' (compare to SHA256SUMS)
|
|
77
97
|
* ```
|
|
78
|
-
*
|
|
79
|
-
* @throws TypeError when the input is neither a recognized SRI nor a hex
|
|
80
|
-
* digest.
|
|
81
98
|
*/
|
|
82
|
-
export declare function
|
|
99
|
+
export declare function computeHash(bytes: NodeJS.ArrayBufferView, algorithm?: HashAlgorithm): Hash;
|
|
83
100
|
/**
|
|
84
|
-
* Compute both
|
|
85
|
-
*
|
|
101
|
+
* Compute both pinned formats for `bytes`: the sha512 SRI integrity and the
|
|
102
|
+
* sha256 hex checksum. Use when a config records both (e.g.
|
|
103
|
+
* `external-tools.json`, dlx lockfiles).
|
|
86
104
|
*/
|
|
87
105
|
export declare function computeHashes(bytes: Buffer): ComputedHashes;
|
|
88
106
|
/**
|
|
89
|
-
*
|
|
90
|
-
*
|
|
107
|
+
* Compare two hashes for equality, ENCODING-agnostically. Parses both and —
|
|
108
|
+
* only when they share an algorithm — timing-safe compares the digests.
|
|
91
109
|
*
|
|
92
|
-
*
|
|
93
|
-
*
|
|
94
|
-
*
|
|
110
|
+
* Returns false when the algorithms differ. A sha512 and a sha256 are different
|
|
111
|
+
* functions of the same bytes: their digests are unrelated values, so they can
|
|
112
|
+
* never be "equal", and you CANNOT derive or check one against the other
|
|
113
|
+
* without the original bytes. To confirm a sha256 and a sha512 describe the
|
|
114
|
+
* same content, hash the bytes both ways (`computeHashes`) or `verifyHash` the
|
|
115
|
+
* bytes against each — there is no hash-to-hash shortcut across algorithms.
|
|
116
|
+
*
|
|
117
|
+
* What this DOES solve is the cross-ENCODING case that bites string `===`: a
|
|
118
|
+
* sha256 SRI and the same sha256 hex compare equal here.
|
|
95
119
|
*
|
|
96
120
|
* @example
|
|
97
121
|
* ;```typescript
|
|
98
|
-
*
|
|
99
|
-
*
|
|
100
|
-
*
|
|
101
|
-
* integrityToChecksum(
|
|
102
|
-
* '3620a0fcaf81ecd3aaeccd5965919d90dbc913f4d07a96e11e7cafc2c785054b',
|
|
103
|
-
* )
|
|
104
|
-
* // '3620a0fcaf81ecd3aaeccd5965919d90dbc913f4d07a96e11e7cafc2c785054b' (idempotent)
|
|
122
|
+
* equalHashes('sha256-NiCg…', '3620a0fc…') // true (same digest, SRI vs hex)
|
|
123
|
+
* equalHashes('sha512-…', '3620a0fc…') // false (different algorithms)
|
|
105
124
|
* ```
|
|
106
125
|
*
|
|
126
|
+
* @throws TypeError when either input is not a recognized hash.
|
|
127
|
+
*/
|
|
128
|
+
export declare function equalHashes(a: HashInput, b: HashInput): boolean;
|
|
129
|
+
/**
|
|
130
|
+
* Convert an SRI integrity string to its hex checksum form.
|
|
131
|
+
*
|
|
132
|
+
* @deprecated Prefer `parseHash(x).hex`, which is total across all algorithms.
|
|
133
|
+
* This shim is sha256-only (throws on sha384 / sha512) to preserve its
|
|
134
|
+
* historical "checksums are sha256" contract. Idempotent on hex input.
|
|
135
|
+
*
|
|
107
136
|
* @throws TypeError when the input is neither a recognized SRI nor a hex
|
|
108
137
|
* checksum, or when the input is a non-sha256 SRI.
|
|
109
138
|
*/
|
|
@@ -112,49 +141,73 @@ export declare function integrityToChecksum(input: string): string;
|
|
|
112
141
|
* True when `s` is a sha256 hex checksum (exactly 64 hex chars).
|
|
113
142
|
*/
|
|
114
143
|
export declare function isChecksum(s: string): boolean;
|
|
144
|
+
/**
|
|
145
|
+
* True when `s` is a bare hex digest of a recognized length (sha256 / sha384 /
|
|
146
|
+
* sha512).
|
|
147
|
+
*/
|
|
148
|
+
export declare function isHex(s: string): boolean;
|
|
115
149
|
/**
|
|
116
150
|
* True when `s` is a W3C SRI integrity string: `sha(256|384|512)-<base64>`.
|
|
117
151
|
*/
|
|
118
152
|
export declare function isIntegrity(s: string): boolean;
|
|
153
|
+
/**
|
|
154
|
+
* Build a frozen {@link Hash} from an algorithm and a hex digest. The internal
|
|
155
|
+
* constructor — trusts its inputs (lowercases the hex, computes the SRI view);
|
|
156
|
+
* use {@link parseHash} for untrusted strings, which validates first.
|
|
157
|
+
*/
|
|
158
|
+
export declare function makeHash(algorithm: HashAlgorithm, hex: string): Hash;
|
|
119
159
|
/**
|
|
120
160
|
* Normalize a {@link HashSpec} to its canonical `{ type, value }` form.
|
|
121
161
|
*
|
|
122
|
-
*
|
|
123
|
-
*
|
|
124
|
-
* - Bare string of 64 hex chars → checksum.
|
|
125
|
-
* - Anything else throws TypeError.
|
|
162
|
+
* @deprecated Prefer {@link parseHash}, which returns an algorithm-tagged
|
|
163
|
+
* {@link Hash}. Kept for callers that branch on integrity-vs-checksum type.
|
|
126
164
|
*
|
|
127
165
|
* @throws TypeError if the string is not a recognized format, or if an explicit
|
|
128
166
|
* object's value doesn't match its declared type.
|
|
129
167
|
*/
|
|
130
168
|
export declare function normalizeHash(spec: HashSpec): NormalizedHash;
|
|
131
169
|
/**
|
|
132
|
-
*
|
|
133
|
-
*
|
|
170
|
+
* Parse any {@link HashInput} into a canonical {@link Hash}. The one entry
|
|
171
|
+
* point for untrusted input — validates shape + length, then freezes.
|
|
134
172
|
*
|
|
135
|
-
* @
|
|
136
|
-
*
|
|
137
|
-
*
|
|
138
|
-
*
|
|
139
|
-
*
|
|
173
|
+
* - A {@link Hash} object is re-canonicalized from its `algorithm` + `hex`.
|
|
174
|
+
* - An SRI string carries its algorithm in the prefix (the body length is checked
|
|
175
|
+
* against it).
|
|
176
|
+
* - A bare hex digest infers the algorithm from its length (64 / 96 / 128).
|
|
177
|
+
*
|
|
178
|
+
* @throws TypeError when the input is not a recognized SRI or hex digest, or
|
|
179
|
+
* when an SRI body's length doesn't match its declared algorithm.
|
|
180
|
+
*/
|
|
181
|
+
export declare function parseHash(input: HashInput): Hash;
|
|
182
|
+
/**
|
|
183
|
+
* Split an SRI integrity string into its `{ algorithm, body }` components.
|
|
184
|
+
* `body` is the base64-encoded digest.
|
|
140
185
|
*
|
|
141
186
|
* @throws Error when the input is not a valid SRI integrity string.
|
|
142
187
|
*/
|
|
143
188
|
export declare function parseIntegrity(sri: string): ParsedIntegrity;
|
|
144
189
|
/**
|
|
145
|
-
* Verify
|
|
146
|
-
*
|
|
147
|
-
*
|
|
148
|
-
*
|
|
149
|
-
*
|
|
190
|
+
* Verify `bytes` against an expected hash. Reads the algorithm the expected
|
|
191
|
+
* hash declares, computes only that digest, and compares with
|
|
192
|
+
* `crypto.timingSafeEqual` — so any encoding (hex / SRI / {@link Hash}) and any
|
|
193
|
+
* algorithm (sha256 / sha384 / sha512) verifies without the caller reconciling
|
|
194
|
+
* formats first.
|
|
195
|
+
*
|
|
196
|
+
* @throws HashMismatchError when the recomputed digest doesn't match.
|
|
197
|
+
* @throws TypeError when `expected` is not a recognized hash.
|
|
150
198
|
*/
|
|
151
|
-
export declare function verifyHash(
|
|
199
|
+
export declare function verifyHash(bytes: NodeJS.ArrayBufferView, expected: HashInput): void;
|
|
152
200
|
/**
|
|
153
|
-
* Thrown when an expected hash doesn't match the computed hash of the
|
|
154
|
-
*
|
|
201
|
+
* Thrown when an expected hash doesn't match the computed hash of the verified
|
|
202
|
+
* bytes. Carries both sides (as {@link Hash}) for diagnostics.
|
|
155
203
|
*/
|
|
156
|
-
export declare class
|
|
157
|
-
readonly expected:
|
|
158
|
-
readonly actual:
|
|
159
|
-
constructor(expected:
|
|
204
|
+
export declare class HashMismatchError extends Error {
|
|
205
|
+
readonly expected: Hash;
|
|
206
|
+
readonly actual: Hash;
|
|
207
|
+
constructor(expected: Hash, actual: Hash);
|
|
160
208
|
}
|
|
209
|
+
/**
|
|
210
|
+
* @deprecated Renamed to {@link HashMismatchError}. Alias kept for callers that
|
|
211
|
+
* catch the old name.
|
|
212
|
+
*/
|
|
213
|
+
export declare const DlxHashMismatchError: typeof HashMismatchError;
|
package/dist/integrity.js
CHANGED
|
@@ -5,94 +5,129 @@ const require_runtime = require('./_virtual/_rolldown/runtime.js');
|
|
|
5
5
|
const require_crypto_hash = require('./crypto/hash.js');
|
|
6
6
|
const require_primordials_buffer = require('./primordials/buffer.js');
|
|
7
7
|
const require_primordials_error = require('./primordials/error.js');
|
|
8
|
+
const require_primordials_object = require('./primordials/object.js');
|
|
9
|
+
const require_primordials_string = require('./primordials/string.js');
|
|
8
10
|
let node_crypto = require("node:crypto");
|
|
9
11
|
node_crypto = require_runtime.__toESM(node_crypto);
|
|
10
12
|
|
|
11
13
|
//#region src/integrity.ts
|
|
12
14
|
/**
|
|
13
|
-
* @file Integrity + checksum helpers.
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
* `
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
15
|
+
* @file Integrity + checksum helpers. One concept — a {@link Hash} (algorithm +
|
|
16
|
+
* digest) — in two encodings:
|
|
17
|
+
*
|
|
18
|
+
* - **hex** — lowercase hex digest (`shasum -a 256` / GitHub `SHA256SUMS`).
|
|
19
|
+
* - **sri** — W3C Subresource Integrity `sha(256|384|512)-<base64>` (npm
|
|
20
|
+
* `dist.integrity`, the `<script integrity>` attribute). Both are views of
|
|
21
|
+
* the same digest. The algorithm is EXPLICIT on every `Hash` — never
|
|
22
|
+
* inferred from which function produced it or sniffed from a string's
|
|
23
|
+
* shape. `verifyHash(bytes, expected)` honors whatever algorithm the
|
|
24
|
+
* expected hash declares, so a sha256 `SHA256SUMS` digest and a sha512 npm
|
|
25
|
+
* integrity both "just verify" with no manual conversion. Role split (see
|
|
26
|
+
* `docs/hash-algorithms.md`, unchanged): we PIN sha512 (`computeHash`
|
|
27
|
+
* default, `computeHashes().integrity`); sha256 is the upstream-interop
|
|
28
|
+
* shape (`fetchChecksumFile`, `computeHashes().checksum`). The two only
|
|
29
|
+
* meet at verify-upstream-256 → pin-512. Algorithms are never flipped —
|
|
30
|
+
* relabeling a 256-bit digest as sha512 would be a lie, and you can't
|
|
31
|
+
* re-hash without the bytes. "SSRI" is just another name for Subresource
|
|
32
|
+
* Integrity — only this module should mention it, inside `parseIntegrity`.
|
|
28
33
|
*/
|
|
29
34
|
const INTEGRITY_RE = /^(sha(?:256|384|512))-([A-Za-z0-9+/]+=*)$/;
|
|
35
|
+
const HEX_RE = /^[a-f0-9]+$/i;
|
|
30
36
|
const CHECKSUM_RE = /^[a-f0-9]{64}$/i;
|
|
37
|
+
const ALGORITHM_HEX_LENGTH = {
|
|
38
|
+
sha256: 64,
|
|
39
|
+
sha384: 96,
|
|
40
|
+
sha512: 128
|
|
41
|
+
};
|
|
42
|
+
const HEX_LENGTH_TO_ALGORITHM = {
|
|
43
|
+
64: "sha256",
|
|
44
|
+
96: "sha384",
|
|
45
|
+
128: "sha512"
|
|
46
|
+
};
|
|
31
47
|
/**
|
|
32
|
-
* Convert a
|
|
33
|
-
* Idempotent on integrity input — call this on user-supplied data without first
|
|
34
|
-
* sniffing the format.
|
|
35
|
-
*
|
|
36
|
-
* The default algorithm is `'sha256'` because that's the fleet's checksum
|
|
37
|
-
* convention; pass an explicit algorithm if you have a hex digest from `sha384`
|
|
38
|
-
* or `sha512` (the function does not verify hex length against the algorithm —
|
|
39
|
-
* caller's responsibility).
|
|
40
|
-
*
|
|
41
|
-
* @example
|
|
42
|
-
* ;```typescript
|
|
43
|
-
* checksumToIntegrity(
|
|
44
|
-
* '3620a0fcaf81ecd3aaeccd5965919d90dbc913f4d07a96e11e7cafc2c785054b',
|
|
45
|
-
* )
|
|
46
|
-
* // 'sha256-NiCg/K+B7NOq7M1ZZZGdkNvJE/TQepbhHnyvwseFBUs='
|
|
48
|
+
* Convert a hex checksum to its SRI integrity form.
|
|
47
49
|
*
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
*
|
|
50
|
+
* @deprecated Prefer `parseHash(x).sri`, which is total across all algorithms
|
|
51
|
+
* and infers the algorithm from a bare hex digest. This shim defaults to
|
|
52
|
+
* `'sha256'` because it only relabels the hex bytes — it does NOT re-hash, so
|
|
53
|
+
* a sha512 label on a 256-bit digest would be a lie. Idempotent on SRI input.
|
|
51
54
|
*
|
|
52
55
|
* @throws TypeError when the input is neither a recognized SRI nor a hex
|
|
53
56
|
* digest.
|
|
54
57
|
*/
|
|
55
58
|
function checksumToIntegrity(input, algorithm = "sha256") {
|
|
56
59
|
if (isIntegrity(input)) return input;
|
|
57
|
-
if (
|
|
58
|
-
return
|
|
60
|
+
if (!HEX_RE.test(input)) throw new require_primordials_error.TypeErrorCtor(`checksumToIntegrity: expected a hex digest or SRI string, got: ${input}`);
|
|
61
|
+
return makeHash(algorithm, input).sri;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Compute a single {@link Hash} of `bytes`. Defaults to sha512 — the canonical
|
|
65
|
+
* trust string we pin against. Pass `'sha256'` for the upstream-interop digest.
|
|
66
|
+
*
|
|
67
|
+
* @example
|
|
68
|
+
* ;```typescript
|
|
69
|
+
* computeHash(bytes).sri // 'sha512-…' (pin this)
|
|
70
|
+
* computeHash(bytes, 'sha256').hex // '3620a0…' (compare to SHA256SUMS)
|
|
71
|
+
* ```
|
|
72
|
+
*/
|
|
73
|
+
function computeHash(bytes, algorithm = "sha512") {
|
|
74
|
+
return makeHash(algorithm, require_crypto_hash.hash(algorithm, bytes, "hex"));
|
|
59
75
|
}
|
|
60
76
|
/**
|
|
61
|
-
* Compute both
|
|
62
|
-
*
|
|
77
|
+
* Compute both pinned formats for `bytes`: the sha512 SRI integrity and the
|
|
78
|
+
* sha256 hex checksum. Use when a config records both (e.g.
|
|
79
|
+
* `external-tools.json`, dlx lockfiles).
|
|
63
80
|
*/
|
|
64
81
|
function computeHashes(bytes) {
|
|
65
82
|
return {
|
|
66
|
-
integrity:
|
|
67
|
-
checksum:
|
|
83
|
+
integrity: computeHash(bytes, "sha512").sri,
|
|
84
|
+
checksum: computeHash(bytes, "sha256").hex
|
|
68
85
|
};
|
|
69
86
|
}
|
|
70
87
|
/**
|
|
71
|
-
*
|
|
72
|
-
*
|
|
88
|
+
* Compare two hashes for equality, ENCODING-agnostically. Parses both and —
|
|
89
|
+
* only when they share an algorithm — timing-safe compares the digests.
|
|
73
90
|
*
|
|
74
|
-
*
|
|
75
|
-
*
|
|
76
|
-
*
|
|
91
|
+
* Returns false when the algorithms differ. A sha512 and a sha256 are different
|
|
92
|
+
* functions of the same bytes: their digests are unrelated values, so they can
|
|
93
|
+
* never be "equal", and you CANNOT derive or check one against the other
|
|
94
|
+
* without the original bytes. To confirm a sha256 and a sha512 describe the
|
|
95
|
+
* same content, hash the bytes both ways (`computeHashes`) or `verifyHash` the
|
|
96
|
+
* bytes against each — there is no hash-to-hash shortcut across algorithms.
|
|
97
|
+
*
|
|
98
|
+
* What this DOES solve is the cross-ENCODING case that bites string `===`: a
|
|
99
|
+
* sha256 SRI and the same sha256 hex compare equal here.
|
|
77
100
|
*
|
|
78
101
|
* @example
|
|
79
102
|
* ;```typescript
|
|
80
|
-
*
|
|
81
|
-
*
|
|
82
|
-
*
|
|
83
|
-
* integrityToChecksum(
|
|
84
|
-
* '3620a0fcaf81ecd3aaeccd5965919d90dbc913f4d07a96e11e7cafc2c785054b',
|
|
85
|
-
* )
|
|
86
|
-
* // '3620a0fcaf81ecd3aaeccd5965919d90dbc913f4d07a96e11e7cafc2c785054b' (idempotent)
|
|
103
|
+
* equalHashes('sha256-NiCg…', '3620a0fc…') // true (same digest, SRI vs hex)
|
|
104
|
+
* equalHashes('sha512-…', '3620a0fc…') // false (different algorithms)
|
|
87
105
|
* ```
|
|
88
106
|
*
|
|
107
|
+
* @throws TypeError when either input is not a recognized hash.
|
|
108
|
+
*/
|
|
109
|
+
function equalHashes(a, b) {
|
|
110
|
+
const aHash = parseHash(a);
|
|
111
|
+
const bHash = parseHash(b);
|
|
112
|
+
if (aHash.algorithm !== bHash.algorithm) return false;
|
|
113
|
+
const aBuf = require_primordials_buffer.BufferFrom(aHash.hex, "hex");
|
|
114
|
+
const bBuf = require_primordials_buffer.BufferFrom(bHash.hex, "hex");
|
|
115
|
+
return aBuf.length === bBuf.length && node_crypto.default.timingSafeEqual(aBuf, bBuf);
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Convert an SRI integrity string to its hex checksum form.
|
|
119
|
+
*
|
|
120
|
+
* @deprecated Prefer `parseHash(x).hex`, which is total across all algorithms.
|
|
121
|
+
* This shim is sha256-only (throws on sha384 / sha512) to preserve its
|
|
122
|
+
* historical "checksums are sha256" contract. Idempotent on hex input.
|
|
123
|
+
*
|
|
89
124
|
* @throws TypeError when the input is neither a recognized SRI nor a hex
|
|
90
125
|
* checksum, or when the input is a non-sha256 SRI.
|
|
91
126
|
*/
|
|
92
127
|
function integrityToChecksum(input) {
|
|
93
128
|
if (isChecksum(input)) return input;
|
|
94
129
|
const parsed = parseIntegrity(input);
|
|
95
|
-
if (parsed.algorithm !== "sha256") throw new require_primordials_error.TypeErrorCtor(`integrityToChecksum: ${parsed.algorithm} integrity has no 64-hex-char checksum form — checksums are sha256-only by fleet convention.`);
|
|
130
|
+
if (parsed.algorithm !== "sha256") throw new require_primordials_error.TypeErrorCtor(`integrityToChecksum: ${parsed.algorithm} integrity has no 64-hex-char checksum form — checksums are sha256-only by fleet convention. Use parseHash(x).hex for any algorithm.`);
|
|
96
131
|
return require_primordials_buffer.BufferPrototypeToString(require_primordials_buffer.BufferFrom(parsed.body, "base64"), "hex");
|
|
97
132
|
}
|
|
98
133
|
/**
|
|
@@ -102,18 +137,36 @@ function isChecksum(s) {
|
|
|
102
137
|
return CHECKSUM_RE.test(s);
|
|
103
138
|
}
|
|
104
139
|
/**
|
|
140
|
+
* True when `s` is a bare hex digest of a recognized length (sha256 / sha384 /
|
|
141
|
+
* sha512).
|
|
142
|
+
*/
|
|
143
|
+
function isHex(s) {
|
|
144
|
+
return HEX_RE.test(s) && HEX_LENGTH_TO_ALGORITHM[s.length] !== void 0;
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
105
147
|
* True when `s` is a W3C SRI integrity string: `sha(256|384|512)-<base64>`.
|
|
106
148
|
*/
|
|
107
149
|
function isIntegrity(s) {
|
|
108
150
|
return INTEGRITY_RE.test(s);
|
|
109
151
|
}
|
|
110
152
|
/**
|
|
153
|
+
* Build a frozen {@link Hash} from an algorithm and a hex digest. The internal
|
|
154
|
+
* constructor — trusts its inputs (lowercases the hex, computes the SRI view);
|
|
155
|
+
* use {@link parseHash} for untrusted strings, which validates first.
|
|
156
|
+
*/
|
|
157
|
+
function makeHash(algorithm, hex) {
|
|
158
|
+
const lowerHex = require_primordials_string.StringPrototypeToLowerCase(hex);
|
|
159
|
+
return require_primordials_object.ObjectFreeze({
|
|
160
|
+
algorithm,
|
|
161
|
+
hex: lowerHex,
|
|
162
|
+
sri: `${algorithm}-${require_primordials_buffer.BufferPrototypeToString(require_primordials_buffer.BufferFrom(lowerHex, "hex"), "base64")}`
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
111
166
|
* Normalize a {@link HashSpec} to its canonical `{ type, value }` form.
|
|
112
167
|
*
|
|
113
|
-
*
|
|
114
|
-
*
|
|
115
|
-
* - Bare string of 64 hex chars → checksum.
|
|
116
|
-
* - Anything else throws TypeError.
|
|
168
|
+
* @deprecated Prefer {@link parseHash}, which returns an algorithm-tagged
|
|
169
|
+
* {@link Hash}. Kept for callers that branch on integrity-vs-checksum type.
|
|
117
170
|
*
|
|
118
171
|
* @throws TypeError if the string is not a recognized format, or if an explicit
|
|
119
172
|
* object's value doesn't match its declared type.
|
|
@@ -148,14 +201,37 @@ function normalizeHash(spec) {
|
|
|
148
201
|
throw new require_primordials_error.TypeErrorCtor(`normalizeHash: unrecognized hash format. Expected SRI integrity ("sha(256|384|512)-<base64>") or sha256 hex checksum (64 hex chars), got: ${spec}`);
|
|
149
202
|
}
|
|
150
203
|
/**
|
|
151
|
-
*
|
|
152
|
-
*
|
|
204
|
+
* Parse any {@link HashInput} into a canonical {@link Hash}. The one entry
|
|
205
|
+
* point for untrusted input — validates shape + length, then freezes.
|
|
153
206
|
*
|
|
154
|
-
* @
|
|
155
|
-
*
|
|
156
|
-
*
|
|
157
|
-
*
|
|
158
|
-
*
|
|
207
|
+
* - A {@link Hash} object is re-canonicalized from its `algorithm` + `hex`.
|
|
208
|
+
* - An SRI string carries its algorithm in the prefix (the body length is checked
|
|
209
|
+
* against it).
|
|
210
|
+
* - A bare hex digest infers the algorithm from its length (64 / 96 / 128).
|
|
211
|
+
*
|
|
212
|
+
* @throws TypeError when the input is not a recognized SRI or hex digest, or
|
|
213
|
+
* when an SRI body's length doesn't match its declared algorithm.
|
|
214
|
+
*/
|
|
215
|
+
function parseHash(input) {
|
|
216
|
+
if (typeof input === "object" && input !== null) return makeHash(input.algorithm, input.hex);
|
|
217
|
+
const sriMatch = INTEGRITY_RE.exec(input);
|
|
218
|
+
if (sriMatch) {
|
|
219
|
+
const algorithm = sriMatch[1];
|
|
220
|
+
const hex = require_primordials_buffer.BufferPrototypeToString(require_primordials_buffer.BufferFrom(sriMatch[2], "base64"), "hex");
|
|
221
|
+
const expectedLength = ALGORITHM_HEX_LENGTH[algorithm];
|
|
222
|
+
if (hex.length !== expectedLength) throw new require_primordials_error.TypeErrorCtor(`parseHash: ${algorithm} SRI body decodes to ${hex.length} hex chars, expected ${expectedLength}: ${input}`);
|
|
223
|
+
return makeHash(algorithm, hex);
|
|
224
|
+
}
|
|
225
|
+
if (HEX_RE.test(input)) {
|
|
226
|
+
const algorithm = HEX_LENGTH_TO_ALGORITHM[input.length];
|
|
227
|
+
if (algorithm === void 0) throw new require_primordials_error.TypeErrorCtor(`parseHash: hex digest is ${input.length} chars; expected 64 (sha256), 96 (sha384), or 128 (sha512): ${input}`);
|
|
228
|
+
return makeHash(algorithm, input);
|
|
229
|
+
}
|
|
230
|
+
throw new require_primordials_error.TypeErrorCtor(`parseHash: expected an SRI string ("sha(256|384|512)-<base64>") or a hex digest, got: ${input}`);
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* Split an SRI integrity string into its `{ algorithm, body }` components.
|
|
234
|
+
* `body` is the base64-encoded digest.
|
|
159
235
|
*
|
|
160
236
|
* @throws Error when the input is not a valid SRI integrity string.
|
|
161
237
|
*/
|
|
@@ -168,41 +244,55 @@ function parseIntegrity(sri) {
|
|
|
168
244
|
};
|
|
169
245
|
}
|
|
170
246
|
/**
|
|
171
|
-
* Verify
|
|
172
|
-
*
|
|
247
|
+
* Verify `bytes` against an expected hash. Reads the algorithm the expected
|
|
248
|
+
* hash declares, computes only that digest, and compares with
|
|
249
|
+
* `crypto.timingSafeEqual` — so any encoding (hex / SRI / {@link Hash}) and any
|
|
250
|
+
* algorithm (sha256 / sha384 / sha512) verifies without the caller reconciling
|
|
251
|
+
* formats first.
|
|
173
252
|
*
|
|
174
|
-
* @throws
|
|
175
|
-
*
|
|
253
|
+
* @throws HashMismatchError when the recomputed digest doesn't match.
|
|
254
|
+
* @throws TypeError when `expected` is not a recognized hash.
|
|
176
255
|
*/
|
|
177
|
-
function verifyHash(
|
|
178
|
-
const
|
|
179
|
-
const
|
|
180
|
-
const
|
|
181
|
-
|
|
256
|
+
function verifyHash(bytes, expected) {
|
|
257
|
+
const expectedHash = parseHash(expected);
|
|
258
|
+
const actualHash = computeHash(bytes, expectedHash.algorithm);
|
|
259
|
+
const expectedBuf = require_primordials_buffer.BufferFrom(expectedHash.hex, "hex");
|
|
260
|
+
const actualBuf = require_primordials_buffer.BufferFrom(actualHash.hex, "hex");
|
|
261
|
+
if (expectedBuf.length !== actualBuf.length || !node_crypto.default.timingSafeEqual(expectedBuf, actualBuf)) throw new HashMismatchError(expectedHash, actualHash);
|
|
182
262
|
}
|
|
183
263
|
/**
|
|
184
|
-
* Thrown when an expected hash doesn't match the computed hash of the
|
|
185
|
-
*
|
|
264
|
+
* Thrown when an expected hash doesn't match the computed hash of the verified
|
|
265
|
+
* bytes. Carries both sides (as {@link Hash}) for diagnostics.
|
|
186
266
|
*/
|
|
187
|
-
var
|
|
267
|
+
var HashMismatchError = class extends Error {
|
|
188
268
|
expected;
|
|
189
269
|
actual;
|
|
190
270
|
constructor(expected, actual) {
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
this.name = "DlxHashMismatchError";
|
|
271
|
+
super(`Hash mismatch (${expected.algorithm}): expected ${expected.sri}, got ${actual.sri}`);
|
|
272
|
+
this.name = "HashMismatchError";
|
|
194
273
|
this.expected = expected;
|
|
195
274
|
this.actual = actual;
|
|
196
275
|
}
|
|
197
276
|
};
|
|
277
|
+
/**
|
|
278
|
+
* @deprecated Renamed to {@link HashMismatchError}. Alias kept for callers that
|
|
279
|
+
* catch the old name.
|
|
280
|
+
*/
|
|
281
|
+
const DlxHashMismatchError = HashMismatchError;
|
|
198
282
|
|
|
199
283
|
//#endregion
|
|
200
284
|
exports.DlxHashMismatchError = DlxHashMismatchError;
|
|
285
|
+
exports.HashMismatchError = HashMismatchError;
|
|
201
286
|
exports.checksumToIntegrity = checksumToIntegrity;
|
|
287
|
+
exports.computeHash = computeHash;
|
|
202
288
|
exports.computeHashes = computeHashes;
|
|
289
|
+
exports.equalHashes = equalHashes;
|
|
203
290
|
exports.integrityToChecksum = integrityToChecksum;
|
|
204
291
|
exports.isChecksum = isChecksum;
|
|
292
|
+
exports.isHex = isHex;
|
|
205
293
|
exports.isIntegrity = isIntegrity;
|
|
294
|
+
exports.makeHash = makeHash;
|
|
206
295
|
exports.normalizeHash = normalizeHash;
|
|
296
|
+
exports.parseHash = parseHash;
|
|
207
297
|
exports.parseIntegrity = parseIntegrity;
|
|
208
298
|
exports.verifyHash = verifyHash;
|