@peac/protocol 0.13.4 → 0.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -313,12 +313,26 @@ function validateExtensionBudgetInternal(extensions) {
313
313
  function validateSchemaParseInternal(payload) {
314
314
  const pr = parseReceiptClaims(payload);
315
315
  if (!pr.ok) {
316
- return { accepted: false, errorCode: pr.error.code };
316
+ return {
317
+ accepted: false,
318
+ errorCode: pr.error.code,
319
+ errorMessage: pr.error.message,
320
+ ...pr.error.issues !== void 0 && { errorIssues: pr.error.issues }
321
+ };
317
322
  }
318
323
  if (pr.wireVersion !== "0.2") {
319
- return { accepted: false, errorCode: "E_UNSUPPORTED_WIRE_VERSION" };
324
+ return {
325
+ accepted: false,
326
+ errorCode: "E_UNSUPPORTED_WIRE_VERSION",
327
+ errorMessage: `Unsupported wire version: ${pr.wireVersion}`
328
+ };
320
329
  }
321
- return { accepted: true, claims: pr.claims };
330
+ return {
331
+ accepted: true,
332
+ claims: pr.claims,
333
+ wireVersion: "0.2",
334
+ warnings: pr.warnings
335
+ };
322
336
  }
323
337
 
324
338
  // src/_internal/record-core/validators/jose-typ-strictness.ts
@@ -558,6 +572,86 @@ function runBoundedValidatorShadow(input) {
558
572
  warnings
559
573
  };
560
574
  }
575
+ var MAX_SANITIZED_ISSUES = 25;
576
+ function sanitizeIssues(issues) {
577
+ if (!Array.isArray(issues)) return void 0;
578
+ return issues.slice(0, MAX_SANITIZED_ISSUES).map((issue2) => {
579
+ const candidate = issue2;
580
+ const path = Array.isArray(candidate.path) ? candidate.path.map(
581
+ (segment) => typeof segment === "string" || typeof segment === "number" ? String(segment) : ""
582
+ ).join(".") : "";
583
+ const message = typeof candidate.message === "string" ? candidate.message : String(candidate.message ?? issue2);
584
+ return { path, message };
585
+ });
586
+ }
587
+ function runBoundedValidationGate(input) {
588
+ if (input.surface === "issueWire02") {
589
+ return runIssueWire02(input.payload);
590
+ }
591
+ return runVerifyLocal(input.payload);
592
+ }
593
+ function runIssueWire02(payload) {
594
+ const schemaRes = validateSchemaParseInternal(payload);
595
+ if (!schemaRes.accepted) {
596
+ const firstIssueMessage = schemaRes.errorIssues?.[0]?.message;
597
+ return {
598
+ ok: false,
599
+ code: "E_INVALID_FORMAT",
600
+ message: `Wire 0.2 claims schema validation failed: ${firstIssueMessage ?? "unknown"}`
601
+ };
602
+ }
603
+ return { ok: true };
604
+ }
605
+ function runVerifyLocal(payload) {
606
+ const kernelRes = validateKernelConstraints(payload);
607
+ if (!kernelRes.valid) {
608
+ const v = kernelRes.violations[0];
609
+ return {
610
+ ok: false,
611
+ code: "E_CONSTRAINT_VIOLATION",
612
+ message: `Kernel constraint violated: ${v.constraint} (actual: ${v.actual}, limit: ${v.limit})`
613
+ };
614
+ }
615
+ const schemaRes = validateSchemaParseInternal(payload);
616
+ if (!schemaRes.accepted) {
617
+ if (schemaRes.errorCode === "E_UNSUPPORTED_WIRE_VERSION") {
618
+ return {
619
+ ok: false,
620
+ code: "E_UNSUPPORTED_WIRE_VERSION",
621
+ message: "Wire 0.1 receipts are not supported. Re-issue as Wire 0.2 using issue()."
622
+ };
623
+ }
624
+ const sanitized = sanitizeIssues(schemaRes.errorIssues);
625
+ const details = {};
626
+ if (schemaRes.errorCode !== void 0) {
627
+ Object.assign(details, { parse_code: schemaRes.errorCode });
628
+ }
629
+ if (sanitized !== void 0) {
630
+ Object.assign(details, { issues: sanitized });
631
+ }
632
+ return {
633
+ ok: false,
634
+ code: "E_INVALID_FORMAT",
635
+ message: `Receipt schema validation failed: ${schemaRes.errorMessage ?? "unknown"}`,
636
+ ...Object.keys(details).length > 0 && { details }
637
+ };
638
+ }
639
+ if (schemaRes.wireVersion !== "0.2" || schemaRes.claims === void 0) {
640
+ return {
641
+ ok: false,
642
+ code: "E_UNSUPPORTED_WIRE_VERSION",
643
+ message: "Wire 0.1 receipts are not supported. Re-issue as Wire 0.2 using issue()."
644
+ };
645
+ }
646
+ return {
647
+ ok: true,
648
+ parsed: {
649
+ wireVersion: "0.2",
650
+ claims: schemaRes.claims,
651
+ parserWarnings: schemaRes.warnings ?? []
652
+ }
653
+ };
654
+ }
561
655
  var SECRET_PATTERNS = [
562
656
  // Compact JWS / JWT (header.payload.signature with eyJ-prefixed header).
563
657
  /eyJ[A-Za-z0-9_-]{20,}\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+/g,
@@ -995,7 +1089,7 @@ async function issue(options) {
995
1089
  return issueWire02(options);
996
1090
  }
997
1091
  async function issueWire02(options) {
998
- void readLegacyPathFlag(options);
1092
+ const legacyPath = readLegacyPathFlag(options);
999
1093
  if (!isCanonicalIss(options.iss)) {
1000
1094
  throw new IssueError({
1001
1095
  code: "E_ISS_NOT_CANONICAL",
@@ -1024,22 +1118,39 @@ async function issueWire02(options) {
1024
1118
  ...options.policy !== void 0 && { policy: options.policy },
1025
1119
  ...options.extensions !== void 0 && { extensions: options.extensions }
1026
1120
  };
1027
- const parseResult = Wire02ClaimsSchema.safeParse(claims);
1028
- if (!parseResult.success) {
1029
- const firstIssue = parseResult.error.issues[0];
1030
- throw new IssueError({
1031
- code: "E_INVALID_FORMAT",
1032
- category: "validation",
1033
- severity: "error",
1034
- retryable: false,
1035
- http_status: 400,
1036
- details: {
1037
- message: `Wire 0.2 claims schema validation failed: ${firstIssue?.message ?? "unknown"}`
1038
- }
1121
+ if (legacyPath) {
1122
+ const parseResult = Wire02ClaimsSchema.safeParse(claims);
1123
+ if (!parseResult.success) {
1124
+ const firstIssue = parseResult.error.issues[0];
1125
+ throw new IssueError({
1126
+ code: "E_INVALID_FORMAT",
1127
+ category: "validation",
1128
+ severity: "error",
1129
+ retryable: false,
1130
+ http_status: 400,
1131
+ details: {
1132
+ message: `Wire 0.2 claims schema validation failed: ${firstIssue?.message ?? "unknown"}`
1133
+ }
1134
+ });
1135
+ }
1136
+ } else {
1137
+ const gateResult = runBoundedValidationGate({
1138
+ surface: "issueWire02",
1139
+ payload: claims
1039
1140
  });
1141
+ if (!gateResult.ok) {
1142
+ throw new IssueError({
1143
+ code: gateResult.code,
1144
+ category: "validation",
1145
+ severity: "error",
1146
+ retryable: false,
1147
+ http_status: 400,
1148
+ details: { message: gateResult.message }
1149
+ });
1150
+ }
1040
1151
  }
1041
1152
  const jws = await defaultCodec.encode(claims, options.privateKey, options.kid);
1042
- if (isShadowEnabled(options)) {
1153
+ if (legacyPath && isShadowEnabled(options)) {
1043
1154
  scheduleShadow({
1044
1155
  call: "issue",
1045
1156
  realResult: realObservationForIssue(),
@@ -2276,7 +2387,7 @@ function sanitizeParseIssues(issues) {
2276
2387
  }));
2277
2388
  }
2278
2389
  async function verifyLocal(jws, publicKey, options = {}) {
2279
- void readLegacyPathFlag(options);
2390
+ const legacyPath = readLegacyPathFlag(options);
2280
2391
  const {
2281
2392
  issuer,
2282
2393
  subjectUri,
@@ -2309,22 +2420,56 @@ async function verifyLocal(jws, publicKey, options = {}) {
2309
2420
  message: "JWS typ header is absent; accepted in interop mode"
2310
2421
  });
2311
2422
  }
2312
- const constraintResult = validateKernelConstraints(result.payload);
2313
- if (!constraintResult.valid) {
2314
- const v = constraintResult.violations[0];
2315
- return {
2316
- valid: false,
2317
- code: "E_CONSTRAINT_VIOLATION",
2318
- message: `Kernel constraint violated: ${v.constraint} (actual: ${v.actual}, limit: ${v.limit})`
2319
- };
2320
- }
2321
- const pr = parseReceiptClaims(result.payload);
2322
- if (!pr.ok) {
2323
- return {
2324
- valid: false,
2325
- code: "E_INVALID_FORMAT",
2326
- message: `Receipt schema validation failed: ${pr.error.message}`,
2327
- details: { parse_code: pr.error.code, issues: sanitizeParseIssues(pr.error.issues) }
2423
+ let pr;
2424
+ if (legacyPath) {
2425
+ const constraintResult = validateKernelConstraints(result.payload);
2426
+ if (!constraintResult.valid) {
2427
+ const v = constraintResult.violations[0];
2428
+ return {
2429
+ valid: false,
2430
+ code: "E_CONSTRAINT_VIOLATION",
2431
+ message: `Kernel constraint violated: ${v.constraint} (actual: ${v.actual}, limit: ${v.limit})`
2432
+ };
2433
+ }
2434
+ const parsed = parseReceiptClaims(result.payload);
2435
+ if (!parsed.ok) {
2436
+ return {
2437
+ valid: false,
2438
+ code: "E_INVALID_FORMAT",
2439
+ message: `Receipt schema validation failed: ${parsed.error.message}`,
2440
+ details: {
2441
+ parse_code: parsed.error.code,
2442
+ issues: sanitizeParseIssues(parsed.error.issues)
2443
+ }
2444
+ };
2445
+ }
2446
+ pr = parsed;
2447
+ } else {
2448
+ const gateResult = runBoundedValidationGate({
2449
+ surface: "verifyLocal",
2450
+ payload: result.payload
2451
+ });
2452
+ if (!gateResult.ok) {
2453
+ return {
2454
+ valid: false,
2455
+ code: gateResult.code,
2456
+ message: gateResult.message,
2457
+ ...gateResult.details !== void 0 && { details: gateResult.details }
2458
+ };
2459
+ }
2460
+ const parsedFromGate = gateResult.parsed;
2461
+ if (parsedFromGate === void 0) {
2462
+ return {
2463
+ valid: false,
2464
+ code: "E_INTERNAL",
2465
+ message: "Bounded validation gate accepted without surfacing parsed claims"
2466
+ };
2467
+ }
2468
+ pr = {
2469
+ ok: true,
2470
+ wireVersion: parsedFromGate.wireVersion,
2471
+ warnings: parsedFromGate.parserWarnings,
2472
+ claims: parsedFromGate.claims
2328
2473
  };
2329
2474
  }
2330
2475
  if (pr.wireVersion === "0.2") {
@@ -2441,7 +2586,7 @@ async function verifyLocal(jws, publicKey, options = {}) {
2441
2586
  ...callerBindings?.documents !== void 0 && callerBindings.documents.length > 0 && { documents: callerBindings.documents }
2442
2587
  };
2443
2588
  const sortedWarnings = sortWarnings(accumulatedWarnings);
2444
- if (isShadowEnabled(options)) {
2589
+ if (legacyPath && isShadowEnabled(options)) {
2445
2590
  const headerSnapshot = { ...result.header };
2446
2591
  scheduleShadow({
2447
2592
  call: "verifyLocal",