@peac/protocol 0.13.2 → 0.13.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/dist/_internal/legacy-path.d.ts +49 -0
  2. package/dist/_internal/legacy-path.d.ts.map +1 -0
  3. package/dist/_internal/record-core/bounded-validator.d.ts +65 -29
  4. package/dist/_internal/record-core/bounded-validator.d.ts.map +1 -1
  5. package/dist/_internal/record-core/validators/iat-not-yet-valid.d.ts +29 -0
  6. package/dist/_internal/record-core/validators/iat-not-yet-valid.d.ts.map +1 -0
  7. package/dist/_internal/record-core/validators/index.d.ts +7 -0
  8. package/dist/_internal/record-core/validators/index.d.ts.map +1 -1
  9. package/dist/_internal/record-core/validators/jose-typ-strictness.d.ts +39 -0
  10. package/dist/_internal/record-core/validators/jose-typ-strictness.d.ts.map +1 -0
  11. package/dist/_internal/record-core/validators/policy-binding.d.ts +33 -0
  12. package/dist/_internal/record-core/validators/policy-binding.d.ts.map +1 -0
  13. package/dist/_internal/record-core/validators/schema-parse.d.ts +42 -0
  14. package/dist/_internal/record-core/validators/schema-parse.d.ts.map +1 -0
  15. package/dist/_internal/record-core/validators/signature.d.ts +31 -0
  16. package/dist/_internal/record-core/validators/signature.d.ts.map +1 -0
  17. package/dist/_internal/record-core/validators/type-extension-enforcement.d.ts +42 -0
  18. package/dist/_internal/record-core/validators/type-extension-enforcement.d.ts.map +1 -0
  19. package/dist/_internal/record-core/validators/unknown-extension-grammar.d.ts +39 -0
  20. package/dist/_internal/record-core/validators/unknown-extension-grammar.d.ts.map +1 -0
  21. package/dist/_internal/test-helpers/candidate-runner.d.ts +52 -0
  22. package/dist/_internal/test-helpers/candidate-runner.d.ts.map +1 -0
  23. package/dist/_internal/test-helpers/parity-verdict.d.ts +35 -0
  24. package/dist/_internal/test-helpers/parity-verdict.d.ts.map +1 -1
  25. package/dist/index.cjs +195 -27
  26. package/dist/index.cjs.map +1 -1
  27. package/dist/index.mjs +195 -27
  28. package/dist/index.mjs.map +1 -1
  29. package/dist/issue.d.ts.map +1 -1
  30. package/dist/verify-local.cjs +163 -0
  31. package/dist/verify-local.cjs.map +1 -1
  32. package/dist/verify-local.d.ts.map +1 -1
  33. package/dist/verify-local.mjs +163 -0
  34. package/dist/verify-local.mjs.map +1 -1
  35. package/dist/verify.d.ts.map +1 -1
  36. package/package.json +4 -4
package/dist/index.mjs CHANGED
@@ -310,6 +310,127 @@ function validateExtensionBudgetInternal(extensions) {
310
310
  if (violations.length === 0) return ACCEPTED4;
311
311
  return { accepted: false, violations };
312
312
  }
313
+ function validateSchemaParseInternal(payload) {
314
+ const pr = parseReceiptClaims(payload);
315
+ if (!pr.ok) {
316
+ return { accepted: false, errorCode: pr.error.code };
317
+ }
318
+ if (pr.wireVersion !== "0.2") {
319
+ return { accepted: false, errorCode: "E_UNSUPPORTED_WIRE_VERSION" };
320
+ }
321
+ return { accepted: true, claims: pr.claims };
322
+ }
323
+
324
+ // src/_internal/record-core/validators/jose-typ-strictness.ts
325
+ var ACCEPTED_NO_WARN = { accepted: true };
326
+ var ACCEPTED_TYP_MISSING = {
327
+ accepted: true,
328
+ warnings: [{ code: "typ_missing" }]
329
+ };
330
+ var REJECTED_INVALID_FORMAT = {
331
+ accepted: false,
332
+ errorCode: "E_INVALID_FORMAT"
333
+ };
334
+ function validateJoseTypStrictnessInternal(typ, strictness) {
335
+ const present = typeof typ === "string" && typ.length > 0;
336
+ if (present) return ACCEPTED_NO_WARN;
337
+ if (strictness === "strict") return REJECTED_INVALID_FORMAT;
338
+ return ACCEPTED_TYP_MISSING;
339
+ }
340
+
341
+ // src/_internal/record-core/validators/iat-not-yet-valid.ts
342
+ var ACCEPTED5 = { accepted: true };
343
+ var REJECTED2 = {
344
+ accepted: false,
345
+ errorCode: "E_NOT_YET_VALID"
346
+ };
347
+ function validateIatNotYetValidInternal(iat, now, maxClockSkew) {
348
+ if (iat > now + maxClockSkew) return REJECTED2;
349
+ return ACCEPTED5;
350
+ }
351
+ function validatePolicyBindingInternal(receiptPolicyDigest, localPolicyDigest) {
352
+ if (receiptPolicyDigest === void 0 || localPolicyDigest === void 0) {
353
+ return { accepted: true, status: "unavailable" };
354
+ }
355
+ const status = verifyPolicyBinding(receiptPolicyDigest, localPolicyDigest);
356
+ if (status === "failed") {
357
+ return { accepted: false, errorCode: "E_POLICY_BINDING_FAILED", status };
358
+ }
359
+ return { accepted: true, status };
360
+ }
361
+ var ACCEPTED_EMPTY = {
362
+ accepted: true,
363
+ warnings: []
364
+ };
365
+ function escapeJsonPointer(token) {
366
+ return token.replace(/~/g, "~0").replace(/\//g, "~1");
367
+ }
368
+ function validateUnknownExtensionGrammarInternal(extensions) {
369
+ if (extensions === void 0) return ACCEPTED_EMPTY;
370
+ const keys = Object.keys(extensions);
371
+ if (keys.length === 0) return ACCEPTED_EMPTY;
372
+ const warnings = [];
373
+ for (const key of keys) {
374
+ if (!REGISTERED_EXTENSION_GROUP_KEYS.has(key) && isValidExtensionKey(key)) {
375
+ warnings.push({
376
+ code: "unknown_extension_preserved",
377
+ pointer: `/extensions/${escapeJsonPointer(key)}`
378
+ });
379
+ }
380
+ }
381
+ return { accepted: true, warnings };
382
+ }
383
+
384
+ // src/type-extension-check.ts
385
+ function checkTypeExtensionMapping(kind, type, extensions, typeToExtensionMap, registeredExtensionGroupKeys) {
386
+ if (kind === "challenge") {
387
+ return { status: "skip" };
388
+ }
389
+ const expectedGroup = typeToExtensionMap.get(type);
390
+ if (expectedGroup === void 0) {
391
+ return { status: "skip" };
392
+ }
393
+ if (extensions !== void 0 && Object.prototype.hasOwnProperty.call(extensions, expectedGroup)) {
394
+ return { status: "ok" };
395
+ }
396
+ const presentRegistered = [];
397
+ if (extensions !== void 0) {
398
+ for (const key of Object.keys(extensions)) {
399
+ if (key !== expectedGroup && registeredExtensionGroupKeys.has(key)) {
400
+ presentRegistered.push(key);
401
+ }
402
+ }
403
+ }
404
+ return {
405
+ status: presentRegistered.length > 0 ? "mismatch" : "missing",
406
+ expected_extension_group: expectedGroup,
407
+ present_registered_extension_groups: presentRegistered
408
+ };
409
+ }
410
+
411
+ // src/_internal/record-core/validators/type-extension-enforcement.ts
412
+ var ACCEPTED_NO_WARN2 = { accepted: true };
413
+ function validateTypeExtensionEnforcementInternal(kind, type, extensions, strictness) {
414
+ const result = checkTypeExtensionMapping(
415
+ kind,
416
+ type,
417
+ extensions,
418
+ TYPE_TO_EXTENSION_MAP,
419
+ REGISTERED_EXTENSION_GROUP_KEYS
420
+ );
421
+ if (result.status === "ok" || result.status === "skip") {
422
+ return ACCEPTED_NO_WARN2;
423
+ }
424
+ if (strictness === "strict") {
425
+ const errorCode = result.status === "missing" ? "E_EXTENSION_GROUP_REQUIRED" : "E_EXTENSION_GROUP_MISMATCH";
426
+ return { accepted: false, errorCode, pointer: "/type" };
427
+ }
428
+ const warningCode = result.status === "missing" ? "extension_group_missing" : "extension_group_mismatch";
429
+ return {
430
+ accepted: true,
431
+ warnings: [{ code: warningCode, pointer: "/type" }]
432
+ };
433
+ }
313
434
 
314
435
  // src/_internal/record-core/bounded-validator.ts
315
436
  function runBoundedValidatorShadow(input) {
@@ -369,6 +490,68 @@ function runBoundedValidatorShadow(input) {
369
490
  violations.push({ layer: "extension-budget", code: v.code, path: v.path });
370
491
  }
371
492
  }
493
+ if (input.fullClaims !== void 0) {
494
+ const schemaRes = validateSchemaParseInternal(input.fullClaims);
495
+ if (!schemaRes.accepted && schemaRes.errorCode !== void 0) {
496
+ violations.push({ layer: "schema-parse", code: schemaRes.errorCode });
497
+ }
498
+ }
499
+ if (input.header !== void 0 && input.strictness !== void 0) {
500
+ const typRes = validateJoseTypStrictnessInternal(input.header.typ, input.strictness);
501
+ if (!typRes.accepted) {
502
+ violations.push({ layer: "jose-typ-strictness", code: typRes.errorCode });
503
+ } else if (typRes.warnings) {
504
+ for (const w of typRes.warnings) {
505
+ warnings.push({ layer: "jose-typ-strictness", code: w.code });
506
+ }
507
+ }
508
+ }
509
+ if (input.maxClockSkew !== void 0) {
510
+ const iatRes = validateIatNotYetValidInternal(input.claims.iat, input.now, input.maxClockSkew);
511
+ if (!iatRes.accepted && iatRes.errorCode !== void 0) {
512
+ violations.push({ layer: "iat-not-yet-valid", code: iatRes.errorCode });
513
+ }
514
+ }
515
+ if (input.receiptPolicyDigest !== void 0 && input.localPolicyDigest !== void 0) {
516
+ const policyRes = validatePolicyBindingInternal(
517
+ input.receiptPolicyDigest,
518
+ input.localPolicyDigest
519
+ );
520
+ if (!policyRes.accepted && policyRes.errorCode !== void 0) {
521
+ violations.push({ layer: "policy-binding", code: policyRes.errorCode });
522
+ }
523
+ }
524
+ const unknownExtRes = validateUnknownExtensionGrammarInternal(input.claims.extensions);
525
+ for (const w of unknownExtRes.warnings) {
526
+ warnings.push({
527
+ layer: "unknown-extension-grammar",
528
+ code: w.code,
529
+ path: w.pointer
530
+ });
531
+ }
532
+ if (input.strictness !== void 0) {
533
+ const enforceRes = validateTypeExtensionEnforcementInternal(
534
+ input.claims.kind,
535
+ input.claims.type,
536
+ input.claims.extensions,
537
+ input.strictness
538
+ );
539
+ if (!enforceRes.accepted) {
540
+ violations.push({
541
+ layer: "type-extension-enforcement",
542
+ code: enforceRes.errorCode,
543
+ path: enforceRes.pointer
544
+ });
545
+ } else if (enforceRes.warnings) {
546
+ for (const w of enforceRes.warnings) {
547
+ warnings.push({
548
+ layer: "type-extension-enforcement",
549
+ code: w.code,
550
+ path: w.pointer
551
+ });
552
+ }
553
+ }
554
+ }
372
555
  return {
373
556
  accepted: violations.length === 0,
374
557
  violations,
@@ -594,6 +777,14 @@ function pruneStale() {
594
777
  while (SHADOW_LOG.length > 0 && SHADOW_LOG[0].timestamp < cutoffIso) SHADOW_LOG.shift();
595
778
  }
596
779
 
780
+ // src/_internal/legacy-path.ts
781
+ function readLegacyPathFlag(options) {
782
+ if (options?._internal?.legacyPath === true) return true;
783
+ if (typeof process === "undefined" || process === null) return false;
784
+ const env = process.env;
785
+ return env?.PEAC_INTERNAL_LEGACY_PATH === "1";
786
+ }
787
+
597
788
  // src/_internal/shadow-observe.ts
598
789
  function realObservationForIssue() {
599
790
  return EMPTY_ACCEPTED;
@@ -804,6 +995,7 @@ async function issue(options) {
804
995
  return issueWire02(options);
805
996
  }
806
997
  async function issueWire02(options) {
998
+ void readLegacyPathFlag(options);
807
999
  if (!isCanonicalIss(options.iss)) {
808
1000
  throw new IssueError({
809
1001
  code: "E_ISS_NOT_CANONICAL",
@@ -1918,6 +2110,8 @@ function jwkToPublicKey(jwk) {
1918
2110
  return new Uint8Array(xBytes);
1919
2111
  }
1920
2112
  async function verifyReceipt(optionsOrJws) {
2113
+ const legacyPathOptions = typeof optionsOrJws === "string" ? void 0 : optionsOrJws;
2114
+ void readLegacyPathFlag(legacyPathOptions);
1921
2115
  const receiptJws = typeof optionsOrJws === "string" ? optionsOrJws : optionsOrJws.receiptJws;
1922
2116
  const inputSnapshot = typeof optionsOrJws === "string" ? void 0 : optionsOrJws.subject_snapshot;
1923
2117
  const telemetry = typeof optionsOrJws === "string" ? void 0 : optionsOrJws.telemetry;
@@ -2051,33 +2245,6 @@ async function verifyReceipt(optionsOrJws) {
2051
2245
  }
2052
2246
  }
2053
2247
 
2054
- // src/type-extension-check.ts
2055
- function checkTypeExtensionMapping(kind, type, extensions, typeToExtensionMap, registeredExtensionGroupKeys) {
2056
- if (kind === "challenge") {
2057
- return { status: "skip" };
2058
- }
2059
- const expectedGroup = typeToExtensionMap.get(type);
2060
- if (expectedGroup === void 0) {
2061
- return { status: "skip" };
2062
- }
2063
- if (extensions !== void 0 && Object.prototype.hasOwnProperty.call(extensions, expectedGroup)) {
2064
- return { status: "ok" };
2065
- }
2066
- const presentRegistered = [];
2067
- if (extensions !== void 0) {
2068
- for (const key of Object.keys(extensions)) {
2069
- if (key !== expectedGroup && registeredExtensionGroupKeys.has(key)) {
2070
- presentRegistered.push(key);
2071
- }
2072
- }
2073
- }
2074
- return {
2075
- status: presentRegistered.length > 0 ? "mismatch" : "missing",
2076
- expected_extension_group: expectedGroup,
2077
- present_registered_extension_groups: presentRegistered
2078
- };
2079
- }
2080
-
2081
2248
  // src/_internal/record-core/shadow-hook.ts
2082
2249
  function maybeRunShadowValidation(input) {
2083
2250
  return void 0;
@@ -2109,6 +2276,7 @@ function sanitizeParseIssues(issues) {
2109
2276
  }));
2110
2277
  }
2111
2278
  async function verifyLocal(jws, publicKey, options = {}) {
2279
+ void readLegacyPathFlag(options);
2112
2280
  const {
2113
2281
  issuer,
2114
2282
  subjectUri,