@peac/net-node 0.12.6
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 +190 -0
- package/README.md +736 -0
- package/dist/codes.d.ts +47 -0
- package/dist/codes.d.ts.map +1 -0
- package/dist/codes.js +53 -0
- package/dist/codes.js.map +1 -0
- package/dist/constants.d.ts +39 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +39 -0
- package/dist/constants.js.map +1 -0
- package/dist/evidence-utils.d.ts +49 -0
- package/dist/evidence-utils.d.ts.map +1 -0
- package/dist/evidence-utils.js +109 -0
- package/dist/evidence-utils.js.map +1 -0
- package/dist/impl.d.ts +331 -0
- package/dist/impl.d.ts.map +1 -0
- package/dist/impl.js +1188 -0
- package/dist/impl.js.map +1 -0
- package/dist/index.d.ts +772 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1121 -0
- package/dist/index.js.map +1 -0
- package/dist/internal.d.ts +28 -0
- package/dist/internal.d.ts.map +1 -0
- package/dist/internal.js +59 -0
- package/dist/internal.js.map +1 -0
- package/dist/receipt-resolver.d.ts +65 -0
- package/dist/receipt-resolver.d.ts.map +1 -0
- package/dist/receipt-resolver.js +140 -0
- package/dist/receipt-resolver.js.map +1 -0
- package/dist/receipt-url-middleware.d.ts +87 -0
- package/dist/receipt-url-middleware.d.ts.map +1 -0
- package/dist/receipt-url-middleware.js +141 -0
- package/dist/receipt-url-middleware.js.map +1 -0
- package/dist/ssrf.d.ts +114 -0
- package/dist/ssrf.d.ts.map +1 -0
- package/dist/ssrf.js +214 -0
- package/dist/ssrf.js.map +1 -0
- package/dist/testing.d.ts +65 -0
- package/dist/testing.d.ts.map +1 -0
- package/dist/testing.js +103 -0
- package/dist/testing.js.map +1 -0
- package/package.json +79 -0
package/dist/codes.d.ts
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Error codes for @peac/net-node
|
|
3
|
+
*
|
|
4
|
+
* Single source of truth for all error codes used in this package.
|
|
5
|
+
* Both index.ts (public API) and impl.ts (internal) import from here.
|
|
6
|
+
*
|
|
7
|
+
* STABILITY: These identifiers are part of the public API surface.
|
|
8
|
+
* Consumers may log, alert, or persist these codes. Changes to code
|
|
9
|
+
* values are breaking changes and require a major version bump.
|
|
10
|
+
*
|
|
11
|
+
* @module @peac/net-node
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* All error codes for safeFetch operations
|
|
15
|
+
*
|
|
16
|
+
* These codes are designed for audit-clean logging:
|
|
17
|
+
* - Each failure mode has a distinct code
|
|
18
|
+
* - Codes follow E_NET_* namespace
|
|
19
|
+
* - Reason suffix indicates specific cause for mixed scenarios
|
|
20
|
+
*/
|
|
21
|
+
export declare const SAFE_FETCH_ERROR_CODES: {
|
|
22
|
+
readonly E_SSRF_URL_REJECTED: "E_NET_SSRF_URL_REJECTED";
|
|
23
|
+
readonly E_SSRF_DNS_RESOLVED_PRIVATE: "E_NET_SSRF_DNS_RESOLVED_PRIVATE";
|
|
24
|
+
readonly E_SSRF_ALL_IPS_BLOCKED: "E_NET_SSRF_ALL_IPS_BLOCKED";
|
|
25
|
+
readonly E_SSRF_REDIRECT_BLOCKED: "E_NET_SSRF_REDIRECT_BLOCKED";
|
|
26
|
+
readonly E_SSRF_TOO_MANY_REDIRECTS: "E_NET_SSRF_TOO_MANY_REDIRECTS";
|
|
27
|
+
readonly E_SSRF_ALLOWCIDRS_ACK_REQUIRED: "E_NET_SSRF_ALLOWCIDRS_ACK_REQUIRED";
|
|
28
|
+
readonly E_SSRF_IPV6_ZONE_ID: "E_NET_SSRF_IPV6_ZONE_ID";
|
|
29
|
+
readonly E_SSRF_INVALID_HOST: "E_NET_SSRF_INVALID_HOST";
|
|
30
|
+
readonly E_SSRF_MIXED_DNS_BLOCKED: "E_NET_SSRF_MIXED_DNS_BLOCKED";
|
|
31
|
+
readonly E_SSRF_MIXED_DNS_ACK_MISSING: "E_NET_SSRF_MIXED_DNS_ACK_MISSING";
|
|
32
|
+
readonly E_SSRF_DANGEROUS_PORT: "E_NET_SSRF_DANGEROUS_PORT";
|
|
33
|
+
readonly E_SSRF_DANGEROUS_PORT_ACK_MISSING: "E_NET_SSRF_DANGEROUS_PORT_ACK_MISSING";
|
|
34
|
+
readonly E_TENANT_KEY_MISSING: "E_NET_TENANT_KEY_MISSING";
|
|
35
|
+
readonly E_DNS_RESOLUTION_FAILED: "E_NET_DNS_RESOLUTION_FAILED";
|
|
36
|
+
readonly E_REQUEST_TIMEOUT: "E_NET_REQUEST_TIMEOUT";
|
|
37
|
+
readonly E_DNS_TIMEOUT: "E_NET_DNS_TIMEOUT";
|
|
38
|
+
readonly E_CONNECT_TIMEOUT: "E_NET_CONNECT_TIMEOUT";
|
|
39
|
+
readonly E_HEADERS_TIMEOUT: "E_NET_HEADERS_TIMEOUT";
|
|
40
|
+
readonly E_BODY_TIMEOUT: "E_NET_BODY_TIMEOUT";
|
|
41
|
+
readonly E_NETWORK_ERROR: "E_NET_NETWORK_ERROR";
|
|
42
|
+
readonly E_METHOD_NOT_ALLOWED: "E_NET_METHOD_NOT_ALLOWED";
|
|
43
|
+
readonly E_RESPONSE_TOO_LARGE: "E_NET_RESPONSE_TOO_LARGE";
|
|
44
|
+
readonly E_PARSE_ERROR: "E_NET_PARSE_ERROR";
|
|
45
|
+
};
|
|
46
|
+
export type SafeFetchErrorCode = (typeof SAFE_FETCH_ERROR_CODES)[keyof typeof SAFE_FETCH_ERROR_CODES];
|
|
47
|
+
//# sourceMappingURL=codes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codes.d.ts","sourceRoot":"","sources":["../src/codes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH;;;;;;;GAOG;AACH,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;CA+BzB,CAAC;AAEX,MAAM,MAAM,kBAAkB,GAC5B,CAAC,OAAO,sBAAsB,CAAC,CAAC,MAAM,OAAO,sBAAsB,CAAC,CAAC"}
|
package/dist/codes.js
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Error codes for @peac/net-node
|
|
3
|
+
*
|
|
4
|
+
* Single source of truth for all error codes used in this package.
|
|
5
|
+
* Both index.ts (public API) and impl.ts (internal) import from here.
|
|
6
|
+
*
|
|
7
|
+
* STABILITY: These identifiers are part of the public API surface.
|
|
8
|
+
* Consumers may log, alert, or persist these codes. Changes to code
|
|
9
|
+
* values are breaking changes and require a major version bump.
|
|
10
|
+
*
|
|
11
|
+
* @module @peac/net-node
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* All error codes for safeFetch operations
|
|
15
|
+
*
|
|
16
|
+
* These codes are designed for audit-clean logging:
|
|
17
|
+
* - Each failure mode has a distinct code
|
|
18
|
+
* - Codes follow E_NET_* namespace
|
|
19
|
+
* - Reason suffix indicates specific cause for mixed scenarios
|
|
20
|
+
*/
|
|
21
|
+
export const SAFE_FETCH_ERROR_CODES = {
|
|
22
|
+
// SSRF errors
|
|
23
|
+
E_SSRF_URL_REJECTED: 'E_NET_SSRF_URL_REJECTED',
|
|
24
|
+
E_SSRF_DNS_RESOLVED_PRIVATE: 'E_NET_SSRF_DNS_RESOLVED_PRIVATE',
|
|
25
|
+
E_SSRF_ALL_IPS_BLOCKED: 'E_NET_SSRF_ALL_IPS_BLOCKED',
|
|
26
|
+
E_SSRF_REDIRECT_BLOCKED: 'E_NET_SSRF_REDIRECT_BLOCKED',
|
|
27
|
+
E_SSRF_TOO_MANY_REDIRECTS: 'E_NET_SSRF_TOO_MANY_REDIRECTS',
|
|
28
|
+
E_SSRF_ALLOWCIDRS_ACK_REQUIRED: 'E_NET_SSRF_ALLOWCIDRS_ACK_REQUIRED',
|
|
29
|
+
E_SSRF_IPV6_ZONE_ID: 'E_NET_SSRF_IPV6_ZONE_ID',
|
|
30
|
+
E_SSRF_INVALID_HOST: 'E_NET_SSRF_INVALID_HOST',
|
|
31
|
+
// P0.2: Mixed DNS audit-clean reason codes
|
|
32
|
+
E_SSRF_MIXED_DNS_BLOCKED: 'E_NET_SSRF_MIXED_DNS_BLOCKED',
|
|
33
|
+
E_SSRF_MIXED_DNS_ACK_MISSING: 'E_NET_SSRF_MIXED_DNS_ACK_MISSING',
|
|
34
|
+
// Port security
|
|
35
|
+
E_SSRF_DANGEROUS_PORT: 'E_NET_SSRF_DANGEROUS_PORT',
|
|
36
|
+
E_SSRF_DANGEROUS_PORT_ACK_MISSING: 'E_NET_SSRF_DANGEROUS_PORT_ACK_MISSING',
|
|
37
|
+
// Evidence configuration
|
|
38
|
+
E_TENANT_KEY_MISSING: 'E_NET_TENANT_KEY_MISSING',
|
|
39
|
+
// Network errors
|
|
40
|
+
E_DNS_RESOLUTION_FAILED: 'E_NET_DNS_RESOLUTION_FAILED',
|
|
41
|
+
E_REQUEST_TIMEOUT: 'E_NET_REQUEST_TIMEOUT',
|
|
42
|
+
// P1.3: Phase-specific timeout codes for audit trail
|
|
43
|
+
E_DNS_TIMEOUT: 'E_NET_DNS_TIMEOUT',
|
|
44
|
+
E_CONNECT_TIMEOUT: 'E_NET_CONNECT_TIMEOUT',
|
|
45
|
+
E_HEADERS_TIMEOUT: 'E_NET_HEADERS_TIMEOUT',
|
|
46
|
+
E_BODY_TIMEOUT: 'E_NET_BODY_TIMEOUT',
|
|
47
|
+
E_NETWORK_ERROR: 'E_NET_NETWORK_ERROR',
|
|
48
|
+
// Method/size errors
|
|
49
|
+
E_METHOD_NOT_ALLOWED: 'E_NET_METHOD_NOT_ALLOWED',
|
|
50
|
+
E_RESPONSE_TOO_LARGE: 'E_NET_RESPONSE_TOO_LARGE',
|
|
51
|
+
E_PARSE_ERROR: 'E_NET_PARSE_ERROR',
|
|
52
|
+
};
|
|
53
|
+
//# sourceMappingURL=codes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codes.js","sourceRoot":"","sources":["../src/codes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG;IACpC,cAAc;IACd,mBAAmB,EAAE,yBAAyB;IAC9C,2BAA2B,EAAE,iCAAiC;IAC9D,sBAAsB,EAAE,4BAA4B;IACpD,uBAAuB,EAAE,6BAA6B;IACtD,yBAAyB,EAAE,+BAA+B;IAC1D,8BAA8B,EAAE,oCAAoC;IACpE,mBAAmB,EAAE,yBAAyB;IAC9C,mBAAmB,EAAE,yBAAyB;IAC9C,2CAA2C;IAC3C,wBAAwB,EAAE,8BAA8B;IACxD,4BAA4B,EAAE,kCAAkC;IAChE,gBAAgB;IAChB,qBAAqB,EAAE,2BAA2B;IAClD,iCAAiC,EAAE,uCAAuC;IAC1E,yBAAyB;IACzB,oBAAoB,EAAE,0BAA0B;IAChD,iBAAiB;IACjB,uBAAuB,EAAE,6BAA6B;IACtD,iBAAiB,EAAE,uBAAuB;IAC1C,qDAAqD;IACrD,aAAa,EAAE,mBAAmB;IAClC,iBAAiB,EAAE,uBAAuB;IAC1C,iBAAiB,EAAE,uBAAuB;IAC1C,cAAc,EAAE,oBAAoB;IACpC,eAAe,EAAE,qBAAqB;IACtC,qBAAqB;IACrB,oBAAoB,EAAE,0BAA0B;IAChD,oBAAoB,EAAE,0BAA0B;IAChD,aAAa,EAAE,mBAAmB;CAC1B,CAAC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Constants for @peac/net-node
|
|
3
|
+
*
|
|
4
|
+
* Single source of truth for schema versions and configuration constants.
|
|
5
|
+
* Both index.ts (public API) and impl.ts (internal) import from here.
|
|
6
|
+
*
|
|
7
|
+
* STABILITY: Schema version strings are part of the public API surface.
|
|
8
|
+
* Evidence producers persist these in receipts. Changes to version
|
|
9
|
+
* strings indicate wire format changes and follow semver semantics.
|
|
10
|
+
*
|
|
11
|
+
* @module @peac/net-node
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* Event schema version for forward compatibility
|
|
15
|
+
*
|
|
16
|
+
* Events are emitted during fetch lifecycle for audit logging.
|
|
17
|
+
* Increment minor for additive changes, major for breaking changes.
|
|
18
|
+
* @since v0.10.x
|
|
19
|
+
*/
|
|
20
|
+
export declare const SAFE_FETCH_EVENT_SCHEMA_VERSION: "peac-safe-fetch-event/0.1";
|
|
21
|
+
/**
|
|
22
|
+
* Evidence schema version for forward compatibility
|
|
23
|
+
*
|
|
24
|
+
* Evidence is the portable, signed-ready artifact returned by safeFetch.
|
|
25
|
+
* This is separate from event schema because evidence and events serve
|
|
26
|
+
* different purposes and may evolve independently.
|
|
27
|
+
*
|
|
28
|
+
* Increment minor for additive changes, major for breaking changes.
|
|
29
|
+
* @since v0.10.x
|
|
30
|
+
*/
|
|
31
|
+
export declare const SAFE_FETCH_EVIDENCE_SCHEMA_VERSION: "peac-safe-fetch-evidence/0.1";
|
|
32
|
+
/**
|
|
33
|
+
* P1.4: Bounded audit queue configuration
|
|
34
|
+
*
|
|
35
|
+
* Maximum number of pending audit events before new events are dropped.
|
|
36
|
+
* This prevents microtask blowup if events are generated faster than processed.
|
|
37
|
+
*/
|
|
38
|
+
export declare const MAX_PENDING_AUDIT_EVENTS: 1000;
|
|
39
|
+
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH;;;;;;GAMG;AACH,eAAO,MAAM,+BAA+B,EAAG,2BAAoC,CAAC;AAEpF;;;;;;;;;GASG;AACH,eAAO,MAAM,kCAAkC,EAAG,8BAAuC,CAAC;AAE1F;;;;;GAKG;AACH,eAAO,MAAM,wBAAwB,EAAG,IAAa,CAAC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Constants for @peac/net-node
|
|
3
|
+
*
|
|
4
|
+
* Single source of truth for schema versions and configuration constants.
|
|
5
|
+
* Both index.ts (public API) and impl.ts (internal) import from here.
|
|
6
|
+
*
|
|
7
|
+
* STABILITY: Schema version strings are part of the public API surface.
|
|
8
|
+
* Evidence producers persist these in receipts. Changes to version
|
|
9
|
+
* strings indicate wire format changes and follow semver semantics.
|
|
10
|
+
*
|
|
11
|
+
* @module @peac/net-node
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* Event schema version for forward compatibility
|
|
15
|
+
*
|
|
16
|
+
* Events are emitted during fetch lifecycle for audit logging.
|
|
17
|
+
* Increment minor for additive changes, major for breaking changes.
|
|
18
|
+
* @since v0.10.x
|
|
19
|
+
*/
|
|
20
|
+
export const SAFE_FETCH_EVENT_SCHEMA_VERSION = 'peac-safe-fetch-event/0.1';
|
|
21
|
+
/**
|
|
22
|
+
* Evidence schema version for forward compatibility
|
|
23
|
+
*
|
|
24
|
+
* Evidence is the portable, signed-ready artifact returned by safeFetch.
|
|
25
|
+
* This is separate from event schema because evidence and events serve
|
|
26
|
+
* different purposes and may evolve independently.
|
|
27
|
+
*
|
|
28
|
+
* Increment minor for additive changes, major for breaking changes.
|
|
29
|
+
* @since v0.10.x
|
|
30
|
+
*/
|
|
31
|
+
export const SAFE_FETCH_EVIDENCE_SCHEMA_VERSION = 'peac-safe-fetch-evidence/0.1';
|
|
32
|
+
/**
|
|
33
|
+
* P1.4: Bounded audit queue configuration
|
|
34
|
+
*
|
|
35
|
+
* Maximum number of pending audit events before new events are dropped.
|
|
36
|
+
* This prevents microtask blowup if events are generated faster than processed.
|
|
37
|
+
*/
|
|
38
|
+
export const MAX_PENDING_AUDIT_EVENTS = 1000;
|
|
39
|
+
//# sourceMappingURL=constants.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,+BAA+B,GAAG,2BAAoC,CAAC;AAEpF;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,kCAAkC,GAAG,8BAAuC,CAAC;AAE1F;;;;;GAKG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG,IAAa,CAAC"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Evidence Utilities for @peac/net-node
|
|
3
|
+
*
|
|
4
|
+
* This module contains shared utilities used by both the main entry (index.ts)
|
|
5
|
+
* and internal modules (internal.ts). Breaking these out prevents circular
|
|
6
|
+
* dependencies and makes the module graph simpler.
|
|
7
|
+
*
|
|
8
|
+
* @internal
|
|
9
|
+
* @module @peac/net-node/evidence-utils
|
|
10
|
+
*/
|
|
11
|
+
import { MAX_PENDING_AUDIT_EVENTS } from './constants.js';
|
|
12
|
+
export { MAX_PENDING_AUDIT_EVENTS };
|
|
13
|
+
/**
|
|
14
|
+
* Canonicalize a value according to RFC 8785 (JSON Canonicalization Scheme)
|
|
15
|
+
*
|
|
16
|
+
* Key ordering is lexicographic by Unicode code point (UTF-16 code units).
|
|
17
|
+
* This matches JavaScript's default string comparison.
|
|
18
|
+
*
|
|
19
|
+
* IMPORTANT: This function produces deterministic output suitable for
|
|
20
|
+
* cryptographic hashing. The output is cross-platform consistent.
|
|
21
|
+
*
|
|
22
|
+
* @param value - Any JSON-serializable value
|
|
23
|
+
* @returns Canonical JSON string
|
|
24
|
+
*/
|
|
25
|
+
export declare function jcsCanonicalizeValue(value: unknown): string;
|
|
26
|
+
/**
|
|
27
|
+
* Canonicalize evidence object using RFC 8785 JCS
|
|
28
|
+
*
|
|
29
|
+
* This is the first step in computing an evidence digest.
|
|
30
|
+
* The output is a deterministic JSON string.
|
|
31
|
+
*
|
|
32
|
+
* @param evidence - Evidence object (SafeFetchEvidence or SafeFetchEvidenceCore)
|
|
33
|
+
* @returns Canonical JSON string
|
|
34
|
+
*/
|
|
35
|
+
export declare function canonicalizeEvidence(evidence: Record<string, unknown>): string;
|
|
36
|
+
/**
|
|
37
|
+
* Compute SHA-256 digest of evidence using JCS canonicalization
|
|
38
|
+
*
|
|
39
|
+
* Returns a 0x-prefixed lowercase hex string, consistent with other
|
|
40
|
+
* PEAC cryptographic identifiers (EAS anchors, IP hashes).
|
|
41
|
+
*
|
|
42
|
+
* Self-omission rule: If the evidence includes digest fields, they are
|
|
43
|
+
* stripped before computing the digest to avoid circularity.
|
|
44
|
+
*
|
|
45
|
+
* @param evidence - Evidence object with optional digest fields
|
|
46
|
+
* @returns 0x-prefixed SHA-256 hex digest
|
|
47
|
+
*/
|
|
48
|
+
export declare function computeEvidenceDigest(evidence: Record<string, unknown>): string;
|
|
49
|
+
//# sourceMappingURL=evidence-utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"evidence-utils.d.ts","sourceRoot":"","sources":["../src/evidence-utils.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAKH,OAAO,EAAE,wBAAwB,EAAE,MAAM,gBAAgB,CAAC;AAG1D,OAAO,EAAE,wBAAwB,EAAE,CAAC;AAkBpC;;;;;;;;;;;GAWG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CA4B3D;AAMD;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAE9E;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAM/E"}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Evidence Utilities for @peac/net-node
|
|
3
|
+
*
|
|
4
|
+
* This module contains shared utilities used by both the main entry (index.ts)
|
|
5
|
+
* and internal modules (internal.ts). Breaking these out prevents circular
|
|
6
|
+
* dependencies and makes the module graph simpler.
|
|
7
|
+
*
|
|
8
|
+
* @internal
|
|
9
|
+
* @module @peac/net-node/evidence-utils
|
|
10
|
+
*/
|
|
11
|
+
import { createHash } from 'crypto';
|
|
12
|
+
// Import constants from single source of truth
|
|
13
|
+
import { MAX_PENDING_AUDIT_EVENTS } from './constants.js';
|
|
14
|
+
// Re-export for backwards compatibility
|
|
15
|
+
export { MAX_PENDING_AUDIT_EVENTS };
|
|
16
|
+
// -----------------------------------------------------------------------------
|
|
17
|
+
// JCS Canonicalization (RFC 8785)
|
|
18
|
+
// -----------------------------------------------------------------------------
|
|
19
|
+
/**
|
|
20
|
+
* Check if a value is a plain object (prototype is Object.prototype or null)
|
|
21
|
+
*
|
|
22
|
+
* This excludes Date, RegExp, Map, Set, and other non-JSON-serializable objects.
|
|
23
|
+
* @internal
|
|
24
|
+
*/
|
|
25
|
+
function isPlainObject(value) {
|
|
26
|
+
if (value === null || typeof value !== 'object')
|
|
27
|
+
return false;
|
|
28
|
+
const proto = Object.getPrototypeOf(value);
|
|
29
|
+
return proto === Object.prototype || proto === null;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Canonicalize a value according to RFC 8785 (JSON Canonicalization Scheme)
|
|
33
|
+
*
|
|
34
|
+
* Key ordering is lexicographic by Unicode code point (UTF-16 code units).
|
|
35
|
+
* This matches JavaScript's default string comparison.
|
|
36
|
+
*
|
|
37
|
+
* IMPORTANT: This function produces deterministic output suitable for
|
|
38
|
+
* cryptographic hashing. The output is cross-platform consistent.
|
|
39
|
+
*
|
|
40
|
+
* @param value - Any JSON-serializable value
|
|
41
|
+
* @returns Canonical JSON string
|
|
42
|
+
*/
|
|
43
|
+
export function jcsCanonicalizeValue(value) {
|
|
44
|
+
if (value === null)
|
|
45
|
+
return 'null';
|
|
46
|
+
if (typeof value === 'boolean')
|
|
47
|
+
return value ? 'true' : 'false';
|
|
48
|
+
if (typeof value === 'number') {
|
|
49
|
+
// Handle special cases per ES2015 spec
|
|
50
|
+
if (Object.is(value, -0))
|
|
51
|
+
return '0';
|
|
52
|
+
if (!Number.isFinite(value)) {
|
|
53
|
+
throw new Error('JCS does not support Infinity or NaN');
|
|
54
|
+
}
|
|
55
|
+
return String(value);
|
|
56
|
+
}
|
|
57
|
+
if (typeof value === 'string') {
|
|
58
|
+
// Use JSON.stringify for proper escaping
|
|
59
|
+
return JSON.stringify(value);
|
|
60
|
+
}
|
|
61
|
+
if (Array.isArray(value)) {
|
|
62
|
+
const elements = value.map(jcsCanonicalizeValue);
|
|
63
|
+
return '[' + elements.join(',') + ']';
|
|
64
|
+
}
|
|
65
|
+
if (isPlainObject(value)) {
|
|
66
|
+
// Sort keys lexicographically (Unicode code point order)
|
|
67
|
+
const keys = Object.keys(value).sort();
|
|
68
|
+
const pairs = keys
|
|
69
|
+
.filter((k) => value[k] !== undefined)
|
|
70
|
+
.map((k) => JSON.stringify(k) + ':' + jcsCanonicalizeValue(value[k]));
|
|
71
|
+
return '{' + pairs.join(',') + '}';
|
|
72
|
+
}
|
|
73
|
+
throw new Error(`Cannot canonicalize value of type ${typeof value}`);
|
|
74
|
+
}
|
|
75
|
+
// -----------------------------------------------------------------------------
|
|
76
|
+
// Evidence Canonicalization and Digest
|
|
77
|
+
// -----------------------------------------------------------------------------
|
|
78
|
+
/**
|
|
79
|
+
* Canonicalize evidence object using RFC 8785 JCS
|
|
80
|
+
*
|
|
81
|
+
* This is the first step in computing an evidence digest.
|
|
82
|
+
* The output is a deterministic JSON string.
|
|
83
|
+
*
|
|
84
|
+
* @param evidence - Evidence object (SafeFetchEvidence or SafeFetchEvidenceCore)
|
|
85
|
+
* @returns Canonical JSON string
|
|
86
|
+
*/
|
|
87
|
+
export function canonicalizeEvidence(evidence) {
|
|
88
|
+
return jcsCanonicalizeValue(evidence);
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Compute SHA-256 digest of evidence using JCS canonicalization
|
|
92
|
+
*
|
|
93
|
+
* Returns a 0x-prefixed lowercase hex string, consistent with other
|
|
94
|
+
* PEAC cryptographic identifiers (EAS anchors, IP hashes).
|
|
95
|
+
*
|
|
96
|
+
* Self-omission rule: If the evidence includes digest fields, they are
|
|
97
|
+
* stripped before computing the digest to avoid circularity.
|
|
98
|
+
*
|
|
99
|
+
* @param evidence - Evidence object with optional digest fields
|
|
100
|
+
* @returns 0x-prefixed SHA-256 hex digest
|
|
101
|
+
*/
|
|
102
|
+
export function computeEvidenceDigest(evidence) {
|
|
103
|
+
// Strip digest fields if present (self-omission rule)
|
|
104
|
+
const { evidence_digest, evidence_alg, canonicalization, ...core } = evidence;
|
|
105
|
+
const canonical = canonicalizeEvidence(core);
|
|
106
|
+
const hash = createHash('sha256').update(canonical, 'utf8').digest('hex');
|
|
107
|
+
return `0x${hash}`;
|
|
108
|
+
}
|
|
109
|
+
//# sourceMappingURL=evidence-utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"evidence-utils.js","sourceRoot":"","sources":["../src/evidence-utils.ts"],"names":[],"mappings":"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"}
|