@peac/protocol 0.10.8 → 0.10.10
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 +1 -1
- package/dist/discovery.d.ts.map +1 -1
- package/dist/index.cjs +2694 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.mjs +2612 -0
- package/dist/index.mjs.map +1 -0
- package/dist/issue.d.ts +3 -0
- package/dist/issue.d.ts.map +1 -1
- package/dist/telemetry.d.ts +43 -0
- package/dist/telemetry.d.ts.map +1 -1
- package/dist/transport-profiles.d.ts.map +1 -1
- package/dist/verification-report.d.ts.map +1 -1
- package/dist/verifier-types.d.ts +42 -2
- package/dist/verifier-types.d.ts.map +1 -1
- package/dist/verify-local.cjs +164 -0
- package/dist/verify-local.cjs.map +1 -0
- package/dist/verify-local.d.ts +61 -4
- package/dist/verify-local.d.ts.map +1 -1
- package/dist/verify-local.mjs +160 -0
- package/dist/verify-local.mjs.map +1 -0
- package/dist/verify.d.ts +3 -0
- package/dist/verify.d.ts.map +1 -1
- package/package.json +20 -14
- package/dist/crypto-utils.js +0 -21
- package/dist/crypto-utils.js.map +0 -1
- package/dist/discovery.js +0 -405
- package/dist/discovery.js.map +0 -1
- package/dist/headers.js +0 -110
- package/dist/headers.js.map +0 -1
- package/dist/index.js +0 -44
- package/dist/index.js.map +0 -1
- package/dist/issue.js +0 -208
- package/dist/issue.js.map +0 -1
- package/dist/pointer-fetch.js +0 -305
- package/dist/pointer-fetch.js.map +0 -1
- package/dist/ssrf-safe-fetch.js +0 -671
- package/dist/ssrf-safe-fetch.js.map +0 -1
- package/dist/telemetry.js +0 -18
- package/dist/telemetry.js.map +0 -1
- package/dist/transport-profiles.js +0 -424
- package/dist/transport-profiles.js.map +0 -1
- package/dist/verification-report.js +0 -322
- package/dist/verification-report.js.map +0 -1
- package/dist/verifier-core.js +0 -578
- package/dist/verifier-core.js.map +0 -1
- package/dist/verifier-types.js +0 -161
- package/dist/verifier-types.js.map +0 -1
- package/dist/verify-local.js +0 -189
- package/dist/verify-local.js.map +0 -1
- package/dist/verify.js +0 -202
- package/dist/verify.js.map +0 -1
package/dist/issue.js
DELETED
|
@@ -1,208 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* Receipt issuance
|
|
4
|
-
* Validates input, generates UUIDv7 rid, and signs with Ed25519
|
|
5
|
-
*/
|
|
6
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
-
exports.IssueError = void 0;
|
|
8
|
-
exports.issue = issue;
|
|
9
|
-
exports.issueJws = issueJws;
|
|
10
|
-
const uuidv7_1 = require("uuidv7");
|
|
11
|
-
const crypto_1 = require("@peac/crypto");
|
|
12
|
-
const zod_1 = require("zod");
|
|
13
|
-
const schema_1 = require("@peac/schema");
|
|
14
|
-
const telemetry_1 = require("@peac/telemetry");
|
|
15
|
-
const telemetry_js_1 = require("./telemetry.js");
|
|
16
|
-
/**
|
|
17
|
-
* Error thrown during receipt issuance
|
|
18
|
-
*
|
|
19
|
-
* Wraps a structured PEACError for programmatic handling.
|
|
20
|
-
*/
|
|
21
|
-
class IssueError extends Error {
|
|
22
|
-
/** Structured error details */
|
|
23
|
-
peacError;
|
|
24
|
-
constructor(peacError) {
|
|
25
|
-
const details = peacError.details;
|
|
26
|
-
super(details?.message ?? peacError.code);
|
|
27
|
-
this.name = 'IssueError';
|
|
28
|
-
this.peacError = peacError;
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
exports.IssueError = IssueError;
|
|
32
|
-
/**
|
|
33
|
-
* Issue a PEAC receipt
|
|
34
|
-
*
|
|
35
|
-
* @param options - Receipt options
|
|
36
|
-
* @returns Issue result with JWS and optional subject_snapshot
|
|
37
|
-
* @throws IssueError if evidence contains non-JSON-safe values
|
|
38
|
-
*/
|
|
39
|
-
async function issue(options) {
|
|
40
|
-
// Validate URLs
|
|
41
|
-
if (!options.iss.startsWith('https://')) {
|
|
42
|
-
throw new Error('Issuer URL must start with https://');
|
|
43
|
-
}
|
|
44
|
-
if (!options.aud.startsWith('https://')) {
|
|
45
|
-
throw new Error('Audience URL must start with https://');
|
|
46
|
-
}
|
|
47
|
-
if (options.subject && !options.subject.startsWith('https://')) {
|
|
48
|
-
throw new Error('Subject URI must start with https://');
|
|
49
|
-
}
|
|
50
|
-
// Validate currency code
|
|
51
|
-
if (!/^[A-Z]{3}$/.test(options.cur)) {
|
|
52
|
-
throw new Error('Currency must be ISO 4217 uppercase (e.g., USD)');
|
|
53
|
-
}
|
|
54
|
-
// Validate amount
|
|
55
|
-
if (!Number.isInteger(options.amt) || options.amt < 0) {
|
|
56
|
-
throw new Error('Amount must be a non-negative integer');
|
|
57
|
-
}
|
|
58
|
-
// Validate expiry (if provided)
|
|
59
|
-
if (options.exp !== undefined) {
|
|
60
|
-
if (!Number.isInteger(options.exp) || options.exp < 0) {
|
|
61
|
-
throw new Error('Expiry must be a non-negative integer');
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
// Normalize and validate purpose (v0.9.24+)
|
|
65
|
-
let purposeDeclared;
|
|
66
|
-
if (options.purpose !== undefined) {
|
|
67
|
-
// Normalize to array
|
|
68
|
-
const rawPurposes = Array.isArray(options.purpose) ? options.purpose : [options.purpose];
|
|
69
|
-
// Validate each token
|
|
70
|
-
const invalidTokens = [];
|
|
71
|
-
for (const token of rawPurposes) {
|
|
72
|
-
if (!(0, schema_1.isValidPurposeToken)(token)) {
|
|
73
|
-
invalidTokens.push(token);
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
if (invalidTokens.length > 0) {
|
|
77
|
-
throw new Error(`Invalid purpose tokens: ${invalidTokens.join(', ')}`);
|
|
78
|
-
}
|
|
79
|
-
// Check for explicit 'undeclared' which is invalid on wire
|
|
80
|
-
if (rawPurposes.includes('undeclared')) {
|
|
81
|
-
throw new Error("Explicit 'undeclared' is not a valid purpose token (internal-only)");
|
|
82
|
-
}
|
|
83
|
-
purposeDeclared = rawPurposes;
|
|
84
|
-
}
|
|
85
|
-
// Validate purpose_enforced (must be canonical)
|
|
86
|
-
if (options.purpose_enforced !== undefined) {
|
|
87
|
-
if (!(0, schema_1.isCanonicalPurpose)(options.purpose_enforced)) {
|
|
88
|
-
throw new Error(`purpose_enforced must be a canonical purpose, got: ${options.purpose_enforced}`);
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
// Validate purpose_reason
|
|
92
|
-
if (options.purpose_reason !== undefined) {
|
|
93
|
-
if (!(0, schema_1.isValidPurposeReason)(options.purpose_reason)) {
|
|
94
|
-
throw new Error(`Invalid purpose_reason: ${options.purpose_reason}`);
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
// Validate workflow_context (v0.10.2+)
|
|
98
|
-
if (options.workflow_context !== undefined) {
|
|
99
|
-
if (!(0, schema_1.isValidWorkflowContext)(options.workflow_context)) {
|
|
100
|
-
throw new IssueError((0, schema_1.createWorkflowContextInvalidError)('Does not conform to WorkflowContextSchema'));
|
|
101
|
-
}
|
|
102
|
-
if (!(0, schema_1.hasValidDagSemantics)(options.workflow_context)) {
|
|
103
|
-
// Determine specific reason
|
|
104
|
-
const ctx = options.workflow_context;
|
|
105
|
-
const isSelfParent = ctx.parent_step_ids.includes(ctx.step_id);
|
|
106
|
-
const hasDuplicates = new Set(ctx.parent_step_ids).size !== ctx.parent_step_ids.length;
|
|
107
|
-
const reason = isSelfParent ? 'self_parent' : hasDuplicates ? 'duplicate_parent' : 'cycle';
|
|
108
|
-
throw new IssueError((0, schema_1.createWorkflowDagInvalidError)(reason));
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
// Generate UUIDv7 for receipt ID
|
|
112
|
-
const rid = (0, uuidv7_1.uuidv7)();
|
|
113
|
-
// Get current timestamp
|
|
114
|
-
const iat = Math.floor(Date.now() / 1000);
|
|
115
|
-
// Build receipt claims
|
|
116
|
-
const claims = {
|
|
117
|
-
iss: options.iss,
|
|
118
|
-
aud: options.aud,
|
|
119
|
-
iat,
|
|
120
|
-
rid,
|
|
121
|
-
amt: options.amt,
|
|
122
|
-
cur: options.cur,
|
|
123
|
-
payment: {
|
|
124
|
-
rail: options.rail,
|
|
125
|
-
reference: options.reference,
|
|
126
|
-
amount: options.amt,
|
|
127
|
-
currency: options.cur,
|
|
128
|
-
asset: options.asset ?? options.cur, // Default asset to currency for backward compatibility
|
|
129
|
-
env: options.env ?? 'test', // Default to test environment for backward compatibility
|
|
130
|
-
evidence: options.evidence ?? {}, // Default to empty object for backward compatibility
|
|
131
|
-
...(options.network && { network: options.network }),
|
|
132
|
-
...(options.facilitator_ref && { facilitator_ref: options.facilitator_ref }),
|
|
133
|
-
...(options.idempotency_key && { idempotency_key: options.idempotency_key }),
|
|
134
|
-
...(options.metadata && { metadata: options.metadata }),
|
|
135
|
-
},
|
|
136
|
-
...(options.exp && { exp: options.exp }),
|
|
137
|
-
...(options.subject && { subject: { uri: options.subject } }),
|
|
138
|
-
// Build extensions (merge user-provided ext with workflow_context)
|
|
139
|
-
...((options.ext || options.workflow_context) && {
|
|
140
|
-
ext: {
|
|
141
|
-
...options.ext,
|
|
142
|
-
...(options.workflow_context && {
|
|
143
|
-
[schema_1.WORKFLOW_EXTENSION_KEY]: options.workflow_context,
|
|
144
|
-
}),
|
|
145
|
-
},
|
|
146
|
-
}),
|
|
147
|
-
// Purpose claims (v0.9.24+)
|
|
148
|
-
...(purposeDeclared && { purpose_declared: purposeDeclared }),
|
|
149
|
-
...(options.purpose_enforced && { purpose_enforced: options.purpose_enforced }),
|
|
150
|
-
...(options.purpose_reason && { purpose_reason: options.purpose_reason }),
|
|
151
|
-
};
|
|
152
|
-
// Validate claims with Zod - map evidence errors to typed error
|
|
153
|
-
try {
|
|
154
|
-
schema_1.ReceiptClaims.parse(claims);
|
|
155
|
-
}
|
|
156
|
-
catch (err) {
|
|
157
|
-
if (err instanceof zod_1.ZodError) {
|
|
158
|
-
// Check if any error path touches evidence
|
|
159
|
-
const evidenceIssue = err.issues.find((issue) => issue.path.some((p) => p === 'evidence' || p === 'payment'));
|
|
160
|
-
if (evidenceIssue && evidenceIssue.path.includes('evidence')) {
|
|
161
|
-
const peacError = (0, schema_1.createEvidenceNotJsonError)(evidenceIssue.message, evidenceIssue.path);
|
|
162
|
-
throw new IssueError(peacError);
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
throw err;
|
|
166
|
-
}
|
|
167
|
-
// Validate subject_snapshot if provided (v0.9.17+)
|
|
168
|
-
// This validates schema and logs advisory PII warning if applicable
|
|
169
|
-
const validatedSnapshot = (0, schema_1.validateSubjectSnapshot)(options.subject_snapshot);
|
|
170
|
-
// Track start time for telemetry
|
|
171
|
-
const startTime = performance.now();
|
|
172
|
-
// Sign with Ed25519
|
|
173
|
-
const jws = await (0, crypto_1.sign)(claims, options.privateKey, options.kid);
|
|
174
|
-
// Emit telemetry (no-throw guard)
|
|
175
|
-
const p = telemetry_1.providerRef.current;
|
|
176
|
-
if (p) {
|
|
177
|
-
try {
|
|
178
|
-
const durationMs = performance.now() - startTime;
|
|
179
|
-
p.onReceiptIssued({
|
|
180
|
-
receiptHash: (0, telemetry_js_1.hashReceipt)(jws),
|
|
181
|
-
issuer: options.iss,
|
|
182
|
-
kid: options.kid,
|
|
183
|
-
durationMs,
|
|
184
|
-
});
|
|
185
|
-
}
|
|
186
|
-
catch {
|
|
187
|
-
// Telemetry MUST NOT break core flow
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
return {
|
|
191
|
-
jws,
|
|
192
|
-
...(validatedSnapshot && { subject_snapshot: validatedSnapshot }),
|
|
193
|
-
};
|
|
194
|
-
}
|
|
195
|
-
/**
|
|
196
|
-
* Issue a PEAC receipt and return just the JWS string
|
|
197
|
-
*
|
|
198
|
-
* Convenience wrapper for common header-centric flows where only the JWS is needed.
|
|
199
|
-
* For access to validated subject_snapshot, use issue() instead.
|
|
200
|
-
*
|
|
201
|
-
* @param options - Receipt options
|
|
202
|
-
* @returns JWS compact serialization
|
|
203
|
-
*/
|
|
204
|
-
async function issueJws(options) {
|
|
205
|
-
const result = await issue(options);
|
|
206
|
-
return result.jws;
|
|
207
|
-
}
|
|
208
|
-
//# sourceMappingURL=issue.js.map
|
package/dist/issue.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"issue.js","sourceRoot":"","sources":["../src/issue.ts"],"names":[],"mappings":"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"}
|
package/dist/pointer-fetch.js
DELETED
|
@@ -1,305 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* PEAC Pointer Fetch with Digest Verification
|
|
4
|
-
*
|
|
5
|
-
* Implements secure receipt fetching via pointers per TRANSPORT-PROFILES.md:
|
|
6
|
-
* - SSRF-safe fetch
|
|
7
|
-
* - SHA-256 digest verification
|
|
8
|
-
* - Size limits
|
|
9
|
-
*
|
|
10
|
-
* @packageDocumentation
|
|
11
|
-
*/
|
|
12
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
-
exports.fetchPointerWithDigest = fetchPointerWithDigest;
|
|
14
|
-
exports.verifyAndFetchPointer = verifyAndFetchPointer;
|
|
15
|
-
const crypto_1 = require("@peac/crypto");
|
|
16
|
-
const kernel_1 = require("@peac/kernel");
|
|
17
|
-
const ssrf_safe_fetch_js_1 = require("./ssrf-safe-fetch.js");
|
|
18
|
-
// ---------------------------------------------------------------------------
|
|
19
|
-
// Error Mapping
|
|
20
|
-
// ---------------------------------------------------------------------------
|
|
21
|
-
/**
|
|
22
|
-
* Map SSRF error reason to pointer error reason
|
|
23
|
-
*/
|
|
24
|
-
function mapSsrfError(ssrfError) {
|
|
25
|
-
const reason = ssrfError.reason;
|
|
26
|
-
switch (reason) {
|
|
27
|
-
case 'not_https':
|
|
28
|
-
case 'private_ip':
|
|
29
|
-
case 'loopback':
|
|
30
|
-
case 'link_local':
|
|
31
|
-
case 'dns_failure':
|
|
32
|
-
case 'cross_origin_redirect':
|
|
33
|
-
return {
|
|
34
|
-
ok: false,
|
|
35
|
-
reason: 'pointer_fetch_blocked',
|
|
36
|
-
errorCode: 'E_VERIFY_POINTER_FETCH_BLOCKED',
|
|
37
|
-
message: ssrfError.message,
|
|
38
|
-
};
|
|
39
|
-
case 'timeout':
|
|
40
|
-
return {
|
|
41
|
-
ok: false,
|
|
42
|
-
reason: 'pointer_fetch_timeout',
|
|
43
|
-
errorCode: 'E_VERIFY_POINTER_FETCH_TIMEOUT',
|
|
44
|
-
message: ssrfError.message,
|
|
45
|
-
};
|
|
46
|
-
case 'response_too_large':
|
|
47
|
-
return {
|
|
48
|
-
ok: false,
|
|
49
|
-
reason: 'pointer_fetch_too_large',
|
|
50
|
-
errorCode: 'E_VERIFY_POINTER_FETCH_TOO_LARGE',
|
|
51
|
-
message: ssrfError.message,
|
|
52
|
-
};
|
|
53
|
-
default:
|
|
54
|
-
return {
|
|
55
|
-
ok: false,
|
|
56
|
-
reason: 'pointer_fetch_failed',
|
|
57
|
-
errorCode: 'E_VERIFY_POINTER_FETCH_FAILED',
|
|
58
|
-
message: ssrfError.message,
|
|
59
|
-
};
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
// ---------------------------------------------------------------------------
|
|
63
|
-
// Pointer Fetch
|
|
64
|
-
// ---------------------------------------------------------------------------
|
|
65
|
-
/**
|
|
66
|
-
* Fetch a receipt via pointer with digest verification
|
|
67
|
-
*
|
|
68
|
-
* Per TRANSPORT-PROFILES.md:
|
|
69
|
-
* - Fetch the URL using SSRF-safe fetch
|
|
70
|
-
* - Compute SHA-256 digest of response
|
|
71
|
-
* - Verify digest matches expected value from header
|
|
72
|
-
* - Return receipt only if digest matches
|
|
73
|
-
*
|
|
74
|
-
* @param options - Pointer fetch options
|
|
75
|
-
* @returns Fetch result
|
|
76
|
-
*/
|
|
77
|
-
async function fetchPointerWithDigest(options) {
|
|
78
|
-
const { url, expectedDigest, fetchOptions = {} } = options;
|
|
79
|
-
// Validate expected digest format
|
|
80
|
-
const hexRegex = /^[0-9a-f]{64}$/;
|
|
81
|
-
if (!hexRegex.test(expectedDigest)) {
|
|
82
|
-
return {
|
|
83
|
-
ok: false,
|
|
84
|
-
reason: 'pointer_fetch_failed',
|
|
85
|
-
errorCode: 'E_VERIFY_POINTER_FETCH_FAILED',
|
|
86
|
-
message: 'Invalid expected digest: must be 64 lowercase hex characters',
|
|
87
|
-
};
|
|
88
|
-
}
|
|
89
|
-
// Validate URL is HTTPS (pre-check before fetch)
|
|
90
|
-
try {
|
|
91
|
-
const parsedUrl = new URL(url);
|
|
92
|
-
if (parsedUrl.protocol !== 'https:') {
|
|
93
|
-
return {
|
|
94
|
-
ok: false,
|
|
95
|
-
reason: 'pointer_fetch_blocked',
|
|
96
|
-
errorCode: 'E_VERIFY_POINTER_FETCH_BLOCKED',
|
|
97
|
-
message: 'Pointer URL must use HTTPS',
|
|
98
|
-
};
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
catch {
|
|
102
|
-
return {
|
|
103
|
-
ok: false,
|
|
104
|
-
reason: 'pointer_fetch_failed',
|
|
105
|
-
errorCode: 'E_VERIFY_POINTER_FETCH_FAILED',
|
|
106
|
-
message: 'Invalid pointer URL',
|
|
107
|
-
};
|
|
108
|
-
}
|
|
109
|
-
// Fetch with SSRF protection and DoS bounds
|
|
110
|
-
// - Size cap: maxReceiptBytes (prevents memory exhaustion)
|
|
111
|
-
// - No redirects: prevents redirect-based SSRF (pointer URL must be direct)
|
|
112
|
-
// - Timeout: prevents slow-loris style attacks
|
|
113
|
-
const fetchResult = await (0, ssrf_safe_fetch_js_1.ssrfSafeFetch)(url, {
|
|
114
|
-
...fetchOptions,
|
|
115
|
-
maxBytes: kernel_1.VERIFIER_LIMITS.maxReceiptBytes,
|
|
116
|
-
allowRedirects: false, // Pointer URL must be direct - no redirects
|
|
117
|
-
timeoutMs: fetchOptions?.timeoutMs ?? kernel_1.VERIFIER_LIMITS.fetchTimeoutMs,
|
|
118
|
-
headers: {
|
|
119
|
-
Accept: 'application/jose, application/json, text/plain',
|
|
120
|
-
...fetchOptions.headers,
|
|
121
|
-
},
|
|
122
|
-
});
|
|
123
|
-
if (!fetchResult.ok) {
|
|
124
|
-
return mapSsrfError(fetchResult);
|
|
125
|
-
}
|
|
126
|
-
const receipt = fetchResult.body;
|
|
127
|
-
// Validate Content-Type if present (warn but don't reject for interoperability)
|
|
128
|
-
// Expected: application/jose, application/json, or text/plain
|
|
129
|
-
const contentType = fetchResult.contentType;
|
|
130
|
-
const expectedContentTypes = ['application/jose', 'application/json', 'text/plain'];
|
|
131
|
-
const contentTypeWarning = contentType && !expectedContentTypes.some((expected) => contentType.startsWith(expected))
|
|
132
|
-
? `Unexpected Content-Type: ${contentType}; expected application/jose, application/json, or text/plain`
|
|
133
|
-
: undefined;
|
|
134
|
-
// Validate: reject empty body
|
|
135
|
-
if (!receipt || receipt.trim().length === 0) {
|
|
136
|
-
return {
|
|
137
|
-
ok: false,
|
|
138
|
-
reason: 'malformed_receipt',
|
|
139
|
-
errorCode: 'E_VERIFY_MALFORMED_RECEIPT',
|
|
140
|
-
message: 'Pointer target returned empty content',
|
|
141
|
-
};
|
|
142
|
-
}
|
|
143
|
-
// Validate: content must look like JWS compact serialization (3 dot-separated segments)
|
|
144
|
-
const jwsValidation = validateJwsCompactStructure(receipt);
|
|
145
|
-
if (!jwsValidation.valid) {
|
|
146
|
-
return {
|
|
147
|
-
ok: false,
|
|
148
|
-
reason: 'malformed_receipt',
|
|
149
|
-
errorCode: 'E_VERIFY_MALFORMED_RECEIPT',
|
|
150
|
-
message: jwsValidation.message,
|
|
151
|
-
};
|
|
152
|
-
}
|
|
153
|
-
// Compute digest of fetched content (hash the raw string bytes)
|
|
154
|
-
const actualDigest = await (0, crypto_1.sha256Hex)(receipt);
|
|
155
|
-
// Verify digest matches
|
|
156
|
-
if (actualDigest !== expectedDigest) {
|
|
157
|
-
return {
|
|
158
|
-
ok: false,
|
|
159
|
-
reason: 'pointer_digest_mismatch',
|
|
160
|
-
errorCode: 'E_VERIFY_POINTER_DIGEST_MISMATCH',
|
|
161
|
-
message: 'Fetched receipt digest does not match expected digest',
|
|
162
|
-
actualDigest,
|
|
163
|
-
expectedDigest,
|
|
164
|
-
};
|
|
165
|
-
}
|
|
166
|
-
return {
|
|
167
|
-
ok: true,
|
|
168
|
-
receipt,
|
|
169
|
-
actualDigest,
|
|
170
|
-
digestMatched: true,
|
|
171
|
-
contentType: fetchResult.contentType,
|
|
172
|
-
...(contentTypeWarning && { contentTypeWarning }),
|
|
173
|
-
};
|
|
174
|
-
}
|
|
175
|
-
/**
|
|
176
|
-
* Validate that a string looks like JWS compact serialization
|
|
177
|
-
*
|
|
178
|
-
* A valid JWS compact has exactly 3 dot-separated base64url segments.
|
|
179
|
-
*
|
|
180
|
-
* @param value - String to validate
|
|
181
|
-
* @returns Validation result
|
|
182
|
-
*/
|
|
183
|
-
function validateJwsCompactStructure(value) {
|
|
184
|
-
const segments = value.split('.');
|
|
185
|
-
if (segments.length !== 3) {
|
|
186
|
-
return {
|
|
187
|
-
valid: false,
|
|
188
|
-
message: `Invalid JWS compact serialization: expected 3 segments, got ${segments.length}`,
|
|
189
|
-
};
|
|
190
|
-
}
|
|
191
|
-
// All segments must be non-empty and contain only base64url characters
|
|
192
|
-
const base64urlRegex = /^[A-Za-z0-9_-]+$/;
|
|
193
|
-
for (let i = 0; i < segments.length; i++) {
|
|
194
|
-
const segment = segments[i];
|
|
195
|
-
if (segment.length === 0) {
|
|
196
|
-
return {
|
|
197
|
-
valid: false,
|
|
198
|
-
message: `Invalid JWS compact serialization: segment ${i + 1} is empty`,
|
|
199
|
-
};
|
|
200
|
-
}
|
|
201
|
-
if (!base64urlRegex.test(segment)) {
|
|
202
|
-
return {
|
|
203
|
-
valid: false,
|
|
204
|
-
message: `Invalid JWS compact serialization: segment ${i + 1} contains invalid characters`,
|
|
205
|
-
};
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
return { valid: true };
|
|
209
|
-
}
|
|
210
|
-
/**
|
|
211
|
-
* Parse pointer header key=value pairs (ReDoS-safe)
|
|
212
|
-
*
|
|
213
|
-
* Handles both quoted and unquoted values without complex regex alternation.
|
|
214
|
-
*/
|
|
215
|
-
function parsePointerHeader(input) {
|
|
216
|
-
const params = {};
|
|
217
|
-
let i = 0;
|
|
218
|
-
const len = input.length;
|
|
219
|
-
while (i < len) {
|
|
220
|
-
// Skip whitespace and commas
|
|
221
|
-
while (i < len && (input[i] === ' ' || input[i] === ',' || input[i] === '\t')) {
|
|
222
|
-
i++;
|
|
223
|
-
}
|
|
224
|
-
if (i >= len)
|
|
225
|
-
break;
|
|
226
|
-
// Parse key (word characters only)
|
|
227
|
-
const keyStart = i;
|
|
228
|
-
while (i < len && /\w/.test(input[i])) {
|
|
229
|
-
i++;
|
|
230
|
-
}
|
|
231
|
-
const key = input.slice(keyStart, i);
|
|
232
|
-
if (!key)
|
|
233
|
-
break;
|
|
234
|
-
// Skip whitespace before '='
|
|
235
|
-
while (i < len && input[i] === ' ')
|
|
236
|
-
i++;
|
|
237
|
-
// Expect '='
|
|
238
|
-
if (i >= len || input[i] !== '=')
|
|
239
|
-
break;
|
|
240
|
-
i++; // skip '='
|
|
241
|
-
// Skip whitespace after '='
|
|
242
|
-
while (i < len && input[i] === ' ')
|
|
243
|
-
i++;
|
|
244
|
-
// Parse value (quoted or unquoted)
|
|
245
|
-
let value;
|
|
246
|
-
if (input[i] === '"') {
|
|
247
|
-
// Quoted value - find closing quote
|
|
248
|
-
i++; // skip opening quote
|
|
249
|
-
const valueStart = i;
|
|
250
|
-
while (i < len && input[i] !== '"') {
|
|
251
|
-
i++;
|
|
252
|
-
}
|
|
253
|
-
value = input.slice(valueStart, i);
|
|
254
|
-
if (i < len)
|
|
255
|
-
i++; // skip closing quote
|
|
256
|
-
}
|
|
257
|
-
else {
|
|
258
|
-
// Unquoted value - read until comma or whitespace
|
|
259
|
-
const valueStart = i;
|
|
260
|
-
while (i < len && input[i] !== ',' && input[i] !== ' ' && input[i] !== '\t') {
|
|
261
|
-
i++;
|
|
262
|
-
}
|
|
263
|
-
value = input.slice(valueStart, i);
|
|
264
|
-
}
|
|
265
|
-
params[key] = value;
|
|
266
|
-
}
|
|
267
|
-
return params;
|
|
268
|
-
}
|
|
269
|
-
/**
|
|
270
|
-
* Verify a pointer header and fetch the receipt
|
|
271
|
-
*
|
|
272
|
-
* Combines parsing and fetching in a single operation.
|
|
273
|
-
*
|
|
274
|
-
* @param pointerHeader - PEAC-Receipt-Pointer header value
|
|
275
|
-
* @param fetchOptions - Optional SSRF fetch options
|
|
276
|
-
* @returns Fetch result
|
|
277
|
-
*/
|
|
278
|
-
async function verifyAndFetchPointer(pointerHeader, fetchOptions) {
|
|
279
|
-
// Parse pointer header (RFC 8941 dictionary format)
|
|
280
|
-
// Format: sha256="<hex>", url="<url>"
|
|
281
|
-
// Using explicit parsing to avoid ReDoS in regex alternation
|
|
282
|
-
const params = parsePointerHeader(pointerHeader);
|
|
283
|
-
if (!params.sha256) {
|
|
284
|
-
return {
|
|
285
|
-
ok: false,
|
|
286
|
-
reason: 'pointer_fetch_failed',
|
|
287
|
-
errorCode: 'E_VERIFY_POINTER_FETCH_FAILED',
|
|
288
|
-
message: 'PEAC-Receipt-Pointer missing sha256 parameter',
|
|
289
|
-
};
|
|
290
|
-
}
|
|
291
|
-
if (!params.url) {
|
|
292
|
-
return {
|
|
293
|
-
ok: false,
|
|
294
|
-
reason: 'pointer_fetch_failed',
|
|
295
|
-
errorCode: 'E_VERIFY_POINTER_FETCH_FAILED',
|
|
296
|
-
message: 'PEAC-Receipt-Pointer missing url parameter',
|
|
297
|
-
};
|
|
298
|
-
}
|
|
299
|
-
return fetchPointerWithDigest({
|
|
300
|
-
url: params.url,
|
|
301
|
-
expectedDigest: params.sha256,
|
|
302
|
-
fetchOptions,
|
|
303
|
-
});
|
|
304
|
-
}
|
|
305
|
-
//# sourceMappingURL=pointer-fetch.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"pointer-fetch.js","sourceRoot":"","sources":["../src/pointer-fetch.ts"],"names":[],"mappings":"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"}
|