@astrasyncai/verification-gateway 2.0.0 → 2.0.1

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 (91) hide show
  1. package/dist/adapter-interface/interface.d.mts +2 -2
  2. package/dist/adapter-interface/interface.d.ts +2 -2
  3. package/dist/adapters/express.d.mts +2 -2
  4. package/dist/adapters/express.d.ts +2 -2
  5. package/dist/adapters/express.js +118 -5
  6. package/dist/adapters/express.js.map +1 -1
  7. package/dist/adapters/express.mjs +118 -5
  8. package/dist/adapters/express.mjs.map +1 -1
  9. package/dist/adapters/nextjs.d.mts +2 -2
  10. package/dist/adapters/nextjs.d.ts +2 -2
  11. package/dist/adapters/nextjs.js +189 -9
  12. package/dist/adapters/nextjs.js.map +1 -1
  13. package/dist/adapters/nextjs.mjs +189 -9
  14. package/dist/adapters/nextjs.mjs.map +1 -1
  15. package/dist/adapters/sdk.d.mts +2 -2
  16. package/dist/adapters/sdk.d.ts +2 -2
  17. package/dist/adapters/sdk.js +1 -0
  18. package/dist/adapters/sdk.js.map +1 -1
  19. package/dist/adapters/sdk.mjs +1 -0
  20. package/dist/adapters/sdk.mjs.map +1 -1
  21. package/dist/agent/index.d.mts +2 -2
  22. package/dist/agent/index.d.ts +2 -2
  23. package/dist/browser/background.d.mts +2 -0
  24. package/dist/browser/background.d.ts +2 -0
  25. package/dist/browser/background.js +4090 -0
  26. package/dist/browser/background.js.map +1 -0
  27. package/dist/browser/background.mjs +4088 -0
  28. package/dist/browser/background.mjs.map +1 -0
  29. package/dist/browser/browser-adapter.d.mts +10 -6
  30. package/dist/browser/browser-adapter.d.ts +10 -6
  31. package/dist/browser/browser-adapter.js +16 -5
  32. package/dist/browser/browser-adapter.js.map +1 -1
  33. package/dist/browser/browser-adapter.mjs +14 -4
  34. package/dist/browser/browser-adapter.mjs.map +1 -1
  35. package/dist/cli/index.d.mts +2 -2
  36. package/dist/cli/index.d.ts +2 -2
  37. package/dist/cli/index.js +1 -1
  38. package/dist/cli/index.js.map +1 -1
  39. package/dist/cli/index.mjs +1 -1
  40. package/dist/cli/index.mjs.map +1 -1
  41. package/dist/cursor/cursor-adapter.d.mts +3 -4
  42. package/dist/cursor/cursor-adapter.d.ts +3 -4
  43. package/dist/cursor/cursor-adapter.js.map +1 -1
  44. package/dist/cursor/cursor-adapter.mjs.map +1 -1
  45. package/dist/cursor/extension.d.mts +27 -0
  46. package/dist/cursor/extension.d.ts +27 -0
  47. package/dist/cursor/extension.js +4057 -0
  48. package/dist/cursor/extension.js.map +1 -0
  49. package/dist/cursor/extension.mjs +4029 -0
  50. package/dist/cursor/extension.mjs.map +1 -0
  51. package/dist/{express-DIEyq1Tz.d.ts → express-Bcl-uBUE.d.ts} +1 -1
  52. package/dist/{express-Cp4eg77F.d.mts → express-CtwDIZyF.d.mts} +1 -1
  53. package/dist/gateway/gateway.d.mts +2 -2
  54. package/dist/gateway/gateway.d.ts +2 -2
  55. package/dist/gateway/gateway.js +17 -17
  56. package/dist/gateway/gateway.js.map +1 -1
  57. package/dist/gateway/gateway.mjs +11 -18
  58. package/dist/gateway/gateway.mjs.map +1 -1
  59. package/dist/git-trigger/git-hooks.d.mts +2 -2
  60. package/dist/git-trigger/git-hooks.d.ts +2 -2
  61. package/dist/git-trigger/git-hooks.js +1 -2
  62. package/dist/git-trigger/git-hooks.js.map +1 -1
  63. package/dist/git-trigger/git-hooks.mjs +1 -9
  64. package/dist/git-trigger/git-hooks.mjs.map +1 -1
  65. package/dist/{index-CoLebmwv.d.mts → index-B1ThcGZl.d.mts} +1 -1
  66. package/dist/{index-BhTbGU-o.d.mts → index-BY8yQ8N8.d.mts} +1 -1
  67. package/dist/{index-Bhfxq9xI.d.ts → index-CtYSYwn3.d.ts} +1 -1
  68. package/dist/{index-CNkmHmpi.d.ts → index-DnoXfdFd.d.ts} +1 -1
  69. package/dist/index.d.mts +7 -7
  70. package/dist/index.d.ts +7 -7
  71. package/dist/index.js +201 -14
  72. package/dist/index.js.map +1 -1
  73. package/dist/index.mjs +201 -14
  74. package/dist/index.mjs.map +1 -1
  75. package/dist/local-evaluator/evaluator.d.mts +2 -2
  76. package/dist/local-evaluator/evaluator.d.ts +2 -2
  77. package/dist/local-evaluator/evaluator.js.map +1 -1
  78. package/dist/local-evaluator/evaluator.mjs.map +1 -1
  79. package/dist/{nextjs-_C_FcJY5.d.mts → nextjs-BQyMCSx_.d.mts} +1 -1
  80. package/dist/{nextjs-Cag7libc.d.ts → nextjs-CEldnIJ9.d.ts} +1 -1
  81. package/dist/{sdk-DAJahT3p.d.mts → sdk-BhvuJSrH.d.mts} +1 -1
  82. package/dist/{sdk-CMPDFUjo.d.ts → sdk-BlyVSC_S.d.ts} +1 -1
  83. package/dist/transport/index.d.mts +2 -2
  84. package/dist/transport/index.d.ts +2 -2
  85. package/dist/{types-Ce2mFJkO.d.ts → types-79qS7aON.d.ts} +2 -2
  86. package/dist/{types-Bf8pML07.d.mts → types-CxQwJKbd.d.mts} +17 -2
  87. package/dist/{types-Bf8pML07.d.ts → types-CxQwJKbd.d.ts} +17 -2
  88. package/dist/{types-BvpGdsv1.d.mts → types-jJnPXStc.d.mts} +2 -2
  89. package/dist/ui/index.d.mts +1 -1
  90. package/dist/ui/index.d.ts +1 -1
  91. package/package.json +3 -2
package/dist/index.mjs CHANGED
@@ -228,6 +228,7 @@ async function callVerifyAccessAPI(config, request) {
228
228
  if (requestData.subAgentDepth !== void 0) body.subAgentDepth = requestData.subAgentDepth;
229
229
  if (requestData.enableRuntimeChallenge) body.enableRuntimeChallenge = requestData.enableRuntimeChallenge;
230
230
  if (requestData.createSession) body.createSession = requestData.createSession;
231
+ if (requestData.durationRequired) body.durationRequired = requestData.durationRequired;
231
232
  if (requestData.counterpartyType) body.counterpartyType = requestData.counterpartyType;
232
233
  if (requestData.counterpartyUrl) body.counterpartyUrl = requestData.counterpartyUrl;
233
234
  if (requestData.runtimeChallengeOptions) body.runtimeChallengeOptions = requestData.runtimeChallengeOptions;
@@ -401,6 +402,24 @@ async function recordDecision(config, sessionId, decision, reason) {
401
402
  }).catch(() => {
402
403
  });
403
404
  }
405
+ async function reportUnregisteredAttempt(config, data) {
406
+ const apiBaseUrl = config.apiBaseUrl || DEFAULT_CONFIG.apiBaseUrl;
407
+ await fetch(`${apiBaseUrl}/verification-activity/unregistered-attempt`, {
408
+ method: "POST",
409
+ headers: { "Content-Type": "application/json" },
410
+ body: JSON.stringify(data)
411
+ }).catch(() => {
412
+ });
413
+ }
414
+ async function reportCounterpartyPreCheckFailure(config, data) {
415
+ const apiBaseUrl = config.apiBaseUrl || DEFAULT_CONFIG.apiBaseUrl;
416
+ await fetch(`${apiBaseUrl}/verification-activity/counterparty-pre-check-failure`, {
417
+ method: "POST",
418
+ headers: { "Content-Type": "application/json" },
419
+ body: JSON.stringify(data)
420
+ }).catch(() => {
421
+ });
422
+ }
404
423
  async function quickVerify(config, credentials) {
405
424
  const result = await verify(config, {
406
425
  credentials,
@@ -482,6 +501,54 @@ function extractHttpCredentials(headers) {
482
501
  return credentials;
483
502
  }
484
503
 
504
+ // src/pdlss-pre-check.ts
505
+ function performCounterpartyPreCheck(routeConfig, astraCreds, purpose) {
506
+ const failures = [];
507
+ if (routeConfig.allowedPurposes && routeConfig.allowedPurposes.length > 0 && purpose) {
508
+ if (!routeConfig.allowedPurposes.includes(purpose)) {
509
+ failures.push({
510
+ field: "purpose",
511
+ requested: purpose,
512
+ limit: routeConfig.allowedPurposes,
513
+ message: `Purpose "${purpose}" is not in the allowed list: [${routeConfig.allowedPurposes.join(", ")}]`
514
+ });
515
+ }
516
+ }
517
+ if (routeConfig.requiredPurposes && routeConfig.requiredPurposes.length > 0 && purpose) {
518
+ if (!routeConfig.requiredPurposes.includes(purpose)) {
519
+ failures.push({
520
+ field: "purpose",
521
+ requested: purpose,
522
+ limit: routeConfig.requiredPurposes,
523
+ message: `Purpose "${purpose}" is not in the required list: [${routeConfig.requiredPurposes.join(", ")}]`
524
+ });
525
+ }
526
+ }
527
+ if (routeConfig.maxDuration && astraCreds?.pdlss?.duration?.maxSessionDuration) {
528
+ const requested = astraCreds.pdlss.duration.maxSessionDuration;
529
+ if (requested > routeConfig.maxDuration) {
530
+ failures.push({
531
+ field: "duration",
532
+ requested,
533
+ limit: routeConfig.maxDuration,
534
+ message: `Requested duration ${requested}s exceeds maximum ${routeConfig.maxDuration}s`
535
+ });
536
+ }
537
+ }
538
+ if (routeConfig.allowedJurisdictions && routeConfig.allowedJurisdictions.length > 0 && astraCreds?.pdlss?.scope?.jurisdiction) {
539
+ const requested = astraCreds.pdlss.scope.jurisdiction;
540
+ if (!routeConfig.allowedJurisdictions.includes(requested)) {
541
+ failures.push({
542
+ field: "jurisdiction",
543
+ requested,
544
+ limit: routeConfig.allowedJurisdictions,
545
+ message: `Jurisdiction "${requested}" is not in the allowed list: [${routeConfig.allowedJurisdictions.join(", ")}]`
546
+ });
547
+ }
548
+ }
549
+ return failures;
550
+ }
551
+
485
552
  // src/adapters/express.ts
486
553
  function defaultExtractCredentials(req) {
487
554
  return extractCredentials(
@@ -493,6 +560,12 @@ function extractAstraSyncCredentials(req) {
493
560
  return extractHttpCredentials(req.headers);
494
561
  }
495
562
  function defaultExtractPurpose(req) {
563
+ const astraPurpose = req.headers["x-astra-purpose"];
564
+ if (astraPurpose) {
565
+ const value = Array.isArray(astraPurpose) ? astraPurpose[0] : astraPurpose;
566
+ const category = value.split(":")[0];
567
+ return category;
568
+ }
496
569
  const purposeHeader = req.headers["x-purpose"] || req.headers["X-Purpose"];
497
570
  if (purposeHeader) {
498
571
  return Array.isArray(purposeHeader) ? purposeHeader[0] : purposeHeader;
@@ -502,14 +575,14 @@ function defaultExtractPurpose(req) {
502
575
  }
503
576
  switch (req.method) {
504
577
  case "GET":
505
- return "read";
578
+ return "read_data";
506
579
  case "POST":
507
- return "create";
580
+ return "write_data";
508
581
  case "PUT":
509
582
  case "PATCH":
510
- return "update";
583
+ return "write_data";
511
584
  case "DELETE":
512
- return "delete";
585
+ return "delete_data";
513
586
  default:
514
587
  return "general";
515
588
  }
@@ -546,6 +619,7 @@ function createMiddleware(options) {
546
619
  skipPaths = [],
547
620
  onDenied = defaultOnDenied,
548
621
  recordDecisions,
622
+ enableRuntimeChallenge = true,
549
623
  ...config
550
624
  } = options;
551
625
  return async (req, res, next) => {
@@ -563,6 +637,16 @@ function createMiddleware(options) {
563
637
  }
564
638
  const credentials = customExtractCredentials ? customExtractCredentials(req) : defaultExtractCredentials(req);
565
639
  if (!hasCredentials(credentials) && routeConfig.minAccessLevel !== "guidance") {
640
+ const counterpartyUrl2 = config.counterpartyUrl || `${req.protocol}://${req.get("host")}`;
641
+ reportUnregisteredAttempt(config, {
642
+ counterpartyUrl: counterpartyUrl2,
643
+ counterpartyType: config.counterpartyType || "api",
644
+ sourceIp: req.ip,
645
+ userAgent: req.headers["user-agent"],
646
+ requestPath: req.path,
647
+ requestMethod: req.method
648
+ }).catch(() => {
649
+ });
566
650
  const result2 = {
567
651
  verified: false,
568
652
  accessLevel: "none",
@@ -579,7 +663,34 @@ function createMiddleware(options) {
579
663
  return;
580
664
  }
581
665
  const purpose = customExtractPurpose ? customExtractPurpose(req) : defaultExtractPurpose(req);
666
+ const astraCreds = extractAstraSyncCredentials(req);
582
667
  const counterpartyUrl = config.counterpartyUrl || `${req.protocol}://${req.get("host")}`;
668
+ const preCheckFailures = performCounterpartyPreCheck(routeConfig, astraCreds, purpose);
669
+ if (preCheckFailures.length > 0) {
670
+ const result2 = {
671
+ verified: false,
672
+ accessLevel: "none",
673
+ denialReasons: preCheckFailures.map((f) => f.message),
674
+ guidance: {
675
+ message: "Request exceeds counterparty-defined PDLSS limits.",
676
+ registrationUrl: `${config.apiBaseUrl?.replace("/api", "")}/register`,
677
+ documentationUrl: `${config.apiBaseUrl?.replace("/api", "")}/docs/pdlss`
678
+ },
679
+ verifiedAt: /* @__PURE__ */ new Date()
680
+ };
681
+ req.agentVerification = result2;
682
+ reportCounterpartyPreCheckFailure(config, {
683
+ agentId: astraCreds?.agentId || credentials.astraId || "unknown",
684
+ counterpartyUrl,
685
+ counterpartyType: config.counterpartyType || "api",
686
+ failures: preCheckFailures,
687
+ requestPath: req.path,
688
+ requestMethod: req.method
689
+ }).catch(() => {
690
+ });
691
+ onDenied(result2, req, res);
692
+ return;
693
+ }
583
694
  const shouldRecordDecisions = recordDecisions !== false;
584
695
  const result = await verify(config, {
585
696
  credentials,
@@ -590,7 +701,9 @@ function createMiddleware(options) {
590
701
  userAgent: req.headers["user-agent"],
591
702
  createSession: shouldRecordDecisions,
592
703
  counterpartyUrl,
593
- counterpartyType: config.counterpartyType || "api"
704
+ counterpartyType: config.counterpartyType || "api",
705
+ enableRuntimeChallenge,
706
+ durationRequired: astraCreds?.pdlss?.duration?.maxSessionDuration
594
707
  });
595
708
  req.agentVerification = result;
596
709
  const sessionId = result.sessionId;
@@ -685,17 +798,32 @@ function findRouteConfig2(routes, path, method) {
685
798
  return methodMatches && pathMatches;
686
799
  });
687
800
  }
688
- function inferPurpose(method) {
689
- switch (method.toUpperCase()) {
801
+ function extractAstraSyncCredentialsFromNextRequest(request) {
802
+ const headers = {};
803
+ request.headers.forEach((value, key) => {
804
+ headers[key] = value;
805
+ });
806
+ return extractHttpCredentials(headers);
807
+ }
808
+ function extractPurpose(request) {
809
+ const astraPurpose = request.headers.get("x-astra-purpose");
810
+ if (astraPurpose) {
811
+ return astraPurpose.split(":")[0];
812
+ }
813
+ const purposeHeader = request.headers.get("x-purpose");
814
+ if (purposeHeader) {
815
+ return purposeHeader;
816
+ }
817
+ switch (request.method.toUpperCase()) {
690
818
  case "GET":
691
- return "read";
819
+ return "read_data";
692
820
  case "POST":
693
- return "create";
821
+ return "write_data";
694
822
  case "PUT":
695
823
  case "PATCH":
696
- return "update";
824
+ return "write_data";
697
825
  case "DELETE":
698
- return "delete";
826
+ return "delete_data";
699
827
  default:
700
828
  return "general";
701
829
  }
@@ -847,7 +975,7 @@ function generateCommerceShieldHtml(result, options) {
847
975
  `.trim();
848
976
  }
849
977
  function createMiddleware2(options) {
850
- const { routes = [], skipPaths = [], showCommerceShield = true, ...config } = options;
978
+ const { routes = [], skipPaths = [], showCommerceShield = true, enableRuntimeChallenge = true, ...config } = options;
851
979
  return async function middleware(request) {
852
980
  const { NextResponse } = await import("next/server");
853
981
  const pathname = request.nextUrl.pathname;
@@ -864,6 +992,16 @@ function createMiddleware2(options) {
864
992
  }
865
993
  const credentials = extractCredentialsFromNextRequest(request);
866
994
  if (!hasCredentials(credentials) && routeConfig.minAccessLevel !== "guidance") {
995
+ const counterpartyUrl2 = config.counterpartyUrl || request.nextUrl.origin;
996
+ reportUnregisteredAttempt(config, {
997
+ counterpartyUrl: counterpartyUrl2,
998
+ counterpartyType: config.counterpartyType || "website",
999
+ sourceIp: request.headers.get("x-forwarded-for") || request.headers.get("x-real-ip") || void 0,
1000
+ userAgent: request.headers.get("user-agent") || void 0,
1001
+ requestPath: pathname,
1002
+ requestMethod: request.method
1003
+ }).catch(() => {
1004
+ });
867
1005
  const result2 = {
868
1006
  verified: false,
869
1007
  accessLevel: "none",
@@ -901,7 +1039,54 @@ function createMiddleware2(options) {
901
1039
  return NextResponse.redirect(new URL(registerUrl, request.url));
902
1040
  }
903
1041
  const counterpartyUrl = config.counterpartyUrl || request.nextUrl.origin;
904
- const purpose = request.headers.get("x-purpose") || inferPurpose(request.method);
1042
+ const purpose = extractPurpose(request);
1043
+ const astraCreds = extractAstraSyncCredentialsFromNextRequest(request);
1044
+ const preCheckFailures = performCounterpartyPreCheck(routeConfig, astraCreds, purpose);
1045
+ if (preCheckFailures.length > 0) {
1046
+ const preCheckResult = {
1047
+ verified: false,
1048
+ accessLevel: "none",
1049
+ denialReasons: preCheckFailures.map((f) => f.message),
1050
+ guidance: {
1051
+ message: "Request exceeds counterparty-defined PDLSS limits.",
1052
+ registrationUrl: `${config.apiBaseUrl?.replace("/api", "")}/register`,
1053
+ documentationUrl: `${config.apiBaseUrl?.replace("/api", "")}/docs/pdlss`
1054
+ },
1055
+ verifiedAt: /* @__PURE__ */ new Date()
1056
+ };
1057
+ reportCounterpartyPreCheckFailure(config, {
1058
+ agentId: astraCreds?.agentId || credentials.astraId || "unknown",
1059
+ counterpartyUrl,
1060
+ counterpartyType: config.counterpartyType || "website",
1061
+ failures: preCheckFailures,
1062
+ requestPath: pathname,
1063
+ requestMethod: request.method
1064
+ }).catch(() => {
1065
+ });
1066
+ if (pathname.startsWith("/api/")) {
1067
+ return NextResponse.json(
1068
+ {
1069
+ success: false,
1070
+ error: {
1071
+ code: "PDLSS_PRE_CHECK_FAILED",
1072
+ message: preCheckResult.denialReasons?.[0] || "PDLSS pre-check failed",
1073
+ guidance: preCheckResult.guidance
1074
+ }
1075
+ },
1076
+ { status: 403 }
1077
+ );
1078
+ }
1079
+ if (showCommerceShield) {
1080
+ return new NextResponse(generateCommerceShieldHtml(preCheckResult, options), {
1081
+ status: 200,
1082
+ headers: {
1083
+ "Content-Type": "text/html",
1084
+ "X-AstraSync-Verification": "commerce-shield"
1085
+ }
1086
+ });
1087
+ }
1088
+ return NextResponse.redirect(new URL("/unauthorized", request.url));
1089
+ }
905
1090
  const result = await verify(config, {
906
1091
  credentials,
907
1092
  purpose,
@@ -910,7 +1095,9 @@ function createMiddleware2(options) {
910
1095
  clientIp: request.headers.get("x-forwarded-for")?.split(",")[0]?.trim() || void 0,
911
1096
  userAgent: request.headers.get("user-agent") || void 0,
912
1097
  counterpartyUrl,
913
- counterpartyType: config.counterpartyType || "website"
1098
+ counterpartyType: config.counterpartyType || "website",
1099
+ enableRuntimeChallenge,
1100
+ durationRequired: astraCreds?.pdlss?.duration?.maxSessionDuration
914
1101
  });
915
1102
  if (!hasMinimumAccess(result.accessLevel, routeConfig.minAccessLevel)) {
916
1103
  if (pathname.startsWith("/api/")) {