@suveren/gateway 0.19.5 → 0.20.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.
Files changed (46) hide show
  1. package/content/integrations/crm.json +1 -1
  2. package/content/integrations/deploy-github.json +1 -1
  3. package/content/integrations/erp.json +1 -1
  4. package/content/integrations/mail.json +1 -1
  5. package/content/integrations/records.json +1 -1
  6. package/dist/control-plane/index.mjs +21 -13
  7. package/dist/mcp-server/{chunk-ZRRZFGRL.mjs → chunk-APIQIEUA.mjs} +39 -27
  8. package/dist/mcp-server/http.mjs +308 -97
  9. package/dist/mcp-server/report-verify-cli.mjs +1 -1
  10. package/dist/ui/assets/index-1gCMlbLl.js +116 -0
  11. package/dist/ui/index.html +1 -1
  12. package/node_modules/@hap/core/README.md +92 -29
  13. package/node_modules/@hap/core/dist/index.d.mts +614 -593
  14. package/node_modules/@hap/core/dist/index.d.ts +614 -593
  15. package/node_modules/@hap/core/dist/index.js +774 -749
  16. package/node_modules/@hap/core/dist/index.mjs +744 -724
  17. package/node_modules/@hap/core/package.json +1 -1
  18. package/node_modules/@hap/core/src/base64url.ts +39 -0
  19. package/node_modules/@hap/core/src/commitment-modes.ts +0 -21
  20. package/node_modules/@hap/core/src/errors.ts +76 -0
  21. package/node_modules/@hap/core/src/frame.ts +47 -178
  22. package/node_modules/@hap/core/src/gatekeeper.ts +219 -600
  23. package/node_modules/@hap/core/src/identity.ts +9 -12
  24. package/node_modules/@hap/core/src/index.ts +8 -4
  25. package/node_modules/@hap/core/src/mandate.ts +177 -166
  26. package/node_modules/@hap/core/src/owner-signature.ts +282 -0
  27. package/node_modules/@hap/core/src/profile.ts +234 -0
  28. package/node_modules/@hap/core/src/ticket.ts +148 -0
  29. package/node_modules/@hap/core/src/types.ts +191 -344
  30. package/node_modules/@hap/core/src/versions.ts +47 -0
  31. package/package.json +2 -2
  32. package/profiles/calendar/0.6.profile.json +191 -0
  33. package/profiles/charge/0.6.profile.json +211 -0
  34. package/profiles/customers/0.9.profile.json +182 -0
  35. package/profiles/delegation/0.3.profile.json +118 -0
  36. package/profiles/deploy/0.11.profile.json +177 -0
  37. package/profiles/email/0.8.profile.json +226 -0
  38. package/profiles/index.json +12 -1
  39. package/profiles/publish/0.6.profile.json +187 -0
  40. package/profiles/purchase/0.7.profile.json +235 -0
  41. package/profiles/records/0.6.profile.json +118 -0
  42. package/profiles/reporting/0.3.profile.json +98 -0
  43. package/profiles/sales/0.4.profile.json +291 -0
  44. package/dist/ui/assets/index-Du68zJhH.js +0 -116
  45. package/node_modules/@hap/core/src/attestation.ts +0 -173
  46. package/node_modules/@hap/core/src/receipt.ts +0 -74
@@ -6,7 +6,7 @@
6
6
  "icon": "users",
7
7
  "profile": "customers",
8
8
  "npmPackage": "@humanagencyp/crm-mcp",
9
- "npmVersion": "1.2.0",
9
+ "npmVersion": "1.3.0",
10
10
  "mcp": {
11
11
  "command": "crm-mcp",
12
12
  "args": []
@@ -6,7 +6,7 @@
6
6
  "icon": "wrench",
7
7
  "profile": "deploy",
8
8
  "npmPackage": "@humanagencyp/deploy-mcp",
9
- "npmVersion": "0.4.2",
9
+ "npmVersion": "0.5.0",
10
10
  "mcp": {
11
11
  "command": "deploy-mcp",
12
12
  "args": []
@@ -6,7 +6,7 @@
6
6
  "icon": "briefcase",
7
7
  "profile": "sales",
8
8
  "npmPackage": "@humanagencyp/erp-mcp",
9
- "npmVersion": "0.4.0",
9
+ "npmVersion": "0.5.0",
10
10
  "mcp": {
11
11
  "command": "erp-mcp",
12
12
  "args": [],
@@ -6,7 +6,7 @@
6
6
  "icon": "mail",
7
7
  "profile": "email",
8
8
  "npmPackage": "@humanagencyp/email-mcp",
9
- "npmVersion": "0.2.0",
9
+ "npmVersion": "0.3.0",
10
10
  "mcp": {
11
11
  "command": "email-mcp",
12
12
  "args": []
@@ -6,7 +6,7 @@
6
6
  "icon": "file-text",
7
7
  "profile": "records",
8
8
  "npmPackage": "@humanagencyp/records-mcp",
9
- "npmVersion": "1.0.4",
9
+ "npmVersion": "1.1.0",
10
10
  "personalDefault": true,
11
11
  "mcp": {
12
12
  "command": "records-mcp",
@@ -3347,7 +3347,7 @@ function createEvidenceExportRouter(spUrl, vault2, dataDir, lockAsTlsMismatch2)
3347
3347
  try {
3348
3348
  const pin = readPairing(dataDir);
3349
3349
  const { res: asRes } = await fetchAs(
3350
- `${spUrl}/api/receipts/export`,
3350
+ `${spUrl}/api/tickets/export`,
3351
3351
  { headers: { Cookie: cookie }, signal: controller.signal },
3352
3352
  {
3353
3353
  enforce: resolvePinTls(dataDir),
@@ -3406,7 +3406,10 @@ function createEvidenceExportRouter(spUrl, vault2, dataDir, lockAsTlsMismatch2)
3406
3406
 
3407
3407
  // src/routes/evidence.ts
3408
3408
  import { Router as Router10 } from "express";
3409
- import { verifyReceiptSignature } from "@hap/core";
3409
+ import { verifyTicketSignature, encodeDidKey } from "@hap/core";
3410
+ function issuerFromPublicKeyHex(publicKeyHex) {
3411
+ return encodeDidKey(Buffer.from(publicKeyHex, "hex"));
3412
+ }
3410
3413
  async function verifyAll(receipts) {
3411
3414
  const out = {};
3412
3415
  for (const raw of receipts) {
@@ -3418,7 +3421,7 @@ async function verifyAll(receipts) {
3418
3421
  continue;
3419
3422
  }
3420
3423
  try {
3421
- await verifyReceiptSignature(e.receipt, e.asPublicKey);
3424
+ await verifyTicketSignature(e.receipt, { trustedIssuers: [issuerFromPublicKeyHex(e.asPublicKey)] });
3422
3425
  out[id] = "valid";
3423
3426
  } catch {
3424
3427
  out[id] = "invalid";
@@ -3927,11 +3930,13 @@ import { timingSafeEqual as timingSafeEqual3, randomUUID } from "crypto";
3927
3930
  import {
3928
3931
  allowedCommitmentModes,
3929
3932
  computeBoundsHash,
3930
- computeContextHash,
3933
+ computeScopeHash,
3931
3934
  computeIntentHash,
3935
+ computeProfileHash,
3932
3936
  isCommitmentModeAllowed,
3933
3937
  validateBoundsParams,
3934
- validateContextParams
3938
+ validateScopeParams,
3939
+ PROTOCOL_VERSION
3935
3940
  } from "@hap/core";
3936
3941
  var MandateRefused = class extends Error {
3937
3942
  };
@@ -3971,8 +3976,8 @@ function approverPubkeys(body) {
3971
3976
  }
3972
3977
  async function delegationWorkspace(deps, groups) {
3973
3978
  const personal = groups.find((g) => g.isPersonal);
3974
- const mine = await deps.as("GET", "/api/attestations/mine?status=active");
3975
- const rows = mine.status === 200 ? mine.body?.attestations ?? [] : [];
3979
+ const mine = await deps.as("GET", "/api/mandates/mine?status=active");
3980
+ const rows = mine.status === 200 ? mine.body?.mandates ?? [] : [];
3976
3981
  const ids = new Set(rows.filter((r) => r.profileId && shortOf(r.profileId) === "delegation" && r.groupId).map((r) => r.groupId));
3977
3982
  const found = groups.filter((g) => ids.has(g.id));
3978
3983
  if (found.length === 0) return personal;
@@ -4011,7 +4016,7 @@ async function planMandate(req, deps) {
4011
4016
  }
4012
4017
  }
4013
4018
  const context = scalarRecord("scope", req.scope);
4014
- errors.push(...validateContextParams(context, profile).errors);
4019
+ errors.push(...validateScopeParams(context, profile).errors);
4015
4020
  if (errors.length) refuse(`The mandate does not fit profile ${profile.id}: ${errors.join(" ")}`);
4016
4021
  if (!isCommitmentModeAllowed(profile, req.mode)) {
4017
4022
  refuse(`Profile ${profile.id} allows mode ${allowedCommitmentModes(profile).join(" or ") || "none"}, not "${req.mode}".`);
@@ -4041,7 +4046,7 @@ async function createMandate(req, deps) {
4041
4046
  const plan = await planMandate(req, deps);
4042
4047
  const user = deps.user;
4043
4048
  const boundsHash = computeBoundsHash(plan.bounds, plan.profile);
4044
- const contextHash = computeContextHash(plan.context, plan.profile);
4049
+ const scopeHash = computeScopeHash(plan.context, plan.profile);
4045
4050
  const intentHash = computeIntentHash(plan.intent);
4046
4051
  const ecHash = computeIntentHash(JSON.stringify({ profile: plan.profile.id, domain: plan.domain, group: plan.groupId }));
4047
4052
  let enc;
@@ -4054,14 +4059,17 @@ async function createMandate(req, deps) {
4054
4059
  if (recipients.length > 0) enc = await deps.encrypt(plan.intent, recipients);
4055
4060
  }
4056
4061
  const authorizationId = deps.newAuthorizationId();
4057
- const res = await deps.as("POST", "/api/as/attest", {
4062
+ const res = await deps.as("POST", "/api/as/mandate", {
4058
4063
  authorization_id: authorizationId,
4059
4064
  profile_id: plan.profile.id,
4065
+ profile_hash: computeProfileHash(plan.profile),
4066
+ supported_versions: [PROTOCOL_VERSION],
4060
4067
  bounds: plan.bounds,
4061
4068
  bounds_hash: boundsHash,
4062
- context_hash: contextHash,
4069
+ scope_hash: scopeHash,
4063
4070
  domain: plan.domain,
4064
4071
  did: user.did,
4072
+ mandate_owners: [{ did: user.did }],
4065
4073
  gate_content_hashes: { intent: intentHash },
4066
4074
  execution_context_hash: ecHash,
4067
4075
  group_id: plan.groupId,
@@ -4078,7 +4086,7 @@ async function createMandate(req, deps) {
4078
4086
  refuse(`The Authority Server refused the mandate: ${why}`);
4079
4087
  }
4080
4088
  try {
4081
- await deps.deliverGateContent({ authorizationId, boundsHash, contextHash, context: plan.context, gateContent: { intent: plan.intent } });
4089
+ await deps.deliverGateContent({ authorizationId, boundsHash, contextHash: scopeHash, context: plan.context, gateContent: { intent: plan.intent } });
4082
4090
  } catch (err) {
4083
4091
  await deps.as("POST", `/api/authorizations/${encodeURIComponent(authorizationId)}/revoke`, {
4084
4092
  reason: "Auto-revoked: gate content delivery failed"
@@ -4960,7 +4968,7 @@ app.use(
4960
4968
  const url = req.url ?? "";
4961
4969
  if (method !== "POST" && method !== "DELETE") return;
4962
4970
  const path = url.split("?")[0];
4963
- if (method === "POST" && path === "/api/as/attest" || method === "POST" && /^\/api\/attestations\/[^/]+\/revoke$/.test(path) || method === "POST" && /^\/api\/authorizations\/[^/]+\/delete$/.test(path)) {
4971
+ if (method === "POST" && path === "/api/as/mandate" || method === "POST" && /^\/api\/attestations\/[^/]+\/revoke$/.test(path) || method === "POST" && /^\/api\/authorizations\/[^/]+\/(revoke|delete)$/.test(path)) {
4964
4972
  eventBus.emit("attestation-changed");
4965
4973
  void resyncGates().catch(() => {
4966
4974
  });
@@ -1053,7 +1053,7 @@ function renderReportHtml(rawHtml, elements, opts = {}) {
1053
1053
  }
1054
1054
 
1055
1055
  // src/lib/report/export-report.ts
1056
- import { decodeAttestationBlob, getProfile as getProfile2 } from "@hap/core";
1056
+ import { decodeMandateBlob, getProfile as getProfile2 } from "@hap/core";
1057
1057
  function processTimeZone() {
1058
1058
  try {
1059
1059
  const tz = Intl.DateTimeFormat().resolvedOptions().timeZone;
@@ -1074,7 +1074,7 @@ function disclosedNames(blobs) {
1074
1074
  const names = /* @__PURE__ */ new Map();
1075
1075
  for (const blob of blobs) {
1076
1076
  try {
1077
- for (const sub of decodeAttestationBlob(blob).payload.subjects ?? []) {
1077
+ for (const sub of decodeMandateBlob(blob).payload.subjects ?? []) {
1078
1078
  if (sub.assurance === "high" && sub.disclose?.name) {
1079
1079
  if (!names.has(sub.did)) names.set(sub.did, /* @__PURE__ */ new Set());
1080
1080
  names.get(sub.did).add(sub.disclose.name);
@@ -1089,7 +1089,7 @@ function firstOwnerDids(auth) {
1089
1089
  const blob = auth?.attestations[0]?.blob;
1090
1090
  if (!blob) return [];
1091
1091
  try {
1092
- return decodeAttestationBlob(blob).payload.resolved_owners ?? [];
1092
+ return (decodeMandateBlob(blob).payload.mandate_owners ?? []).map((o) => o.did);
1093
1093
  } catch {
1094
1094
  return [];
1095
1095
  }
@@ -1267,10 +1267,16 @@ function isExportBundle(v) {
1267
1267
 
1268
1268
  // src/lib/report/verify-export.ts
1269
1269
  import { Parser as Parser2 } from "htmlparser2";
1270
- import { verifyReceiptSignature as verifyReceiptSignature2, verifyAttestationSignature as verifyAttestationSignature4, decodeAttestationBlob as decodeAttestationBlob5, computeBoundsHash } from "@hap/core";
1270
+ import { verifyTicketSignature as verifyTicketSignature2, verifyMandateSignature as verifyMandateSignature4, decodeMandateBlob as decodeMandateBlob5, computeBoundsHash } from "@hap/core";
1271
+
1272
+ // src/lib/issuer-from-hex.ts
1273
+ import { encodeDidKey } from "@hap/core";
1274
+ function issuerFromPublicKeyHex(publicKeyHex) {
1275
+ return encodeDidKey(Buffer.from(publicKeyHex, "hex"));
1276
+ }
1271
1277
 
1272
1278
  // src/lib/report/verify-drawn.ts
1273
- import { computeIntentHash, decodeAttestationBlob as decodeAttestationBlob4, verifyAttestationSignature as verifyAttestationSignature3 } from "@hap/core";
1279
+ import { computeIntentHash, decodeMandateBlob as decodeMandateBlob4, verifyMandateSignature as verifyMandateSignature3 } from "@hap/core";
1274
1280
 
1275
1281
  // src/lib/report/metric-resolvers.ts
1276
1282
  var METRIC_KINDS = [
@@ -1335,10 +1341,10 @@ function computeMetric(kind, cases, refusalTimes = []) {
1335
1341
  }
1336
1342
 
1337
1343
  // src/lib/report/ticket-resolvers.ts
1338
- import { verifyReceiptSignature, verifyAttestationSignature as verifyAttestationSignature2, decodeAttestationBlob as decodeAttestationBlob3 } from "@hap/core";
1344
+ import { verifyTicketSignature, verifyMandateSignature as verifyMandateSignature2, decodeMandateBlob as decodeMandateBlob3 } from "@hap/core";
1339
1345
 
1340
1346
  // src/lib/report/identity.ts
1341
- import { decodeAttestationBlob as decodeAttestationBlob2, verifyAttestationSignature } from "@hap/core";
1347
+ import { decodeMandateBlob as decodeMandateBlob2, verifyMandateSignature } from "@hap/core";
1342
1348
  var cache = /* @__PURE__ */ new WeakMap();
1343
1349
  function cacheKey(archive) {
1344
1350
  const auths = archive.getAuthorizations();
@@ -1353,14 +1359,13 @@ async function build(archive) {
1353
1359
  if (!key2) continue;
1354
1360
  for (const att of auth.attestations) {
1355
1361
  try {
1356
- const attestation = decodeAttestationBlob2(att.blob);
1357
- await verifyAttestationSignature(attestation, key2);
1358
- for (const s of attestation.payload.subjects ?? []) {
1362
+ const mandate = decodeMandateBlob2(att.blob);
1363
+ await verifyMandateSignature(mandate, { trustedIssuers: [issuerFromPublicKeyHex(key2)] });
1364
+ for (const s of mandate.payload.subjects ?? []) {
1359
1365
  if (s.assurance === "high" && s.disclose?.name && !names.has(s.did)) names.set(s.did, s.disclose.name);
1360
1366
  }
1361
- for (const rd of attestation.payload.resolved_domains ?? []) {
1362
- if (rd?.domain && rd?.did && !domainDids.has(rd.domain)) domainDids.set(rd.domain, rd.did);
1363
- }
1367
+ const ownerDid = mandate.payload.mandate_owners?.[0]?.did;
1368
+ if (att.domain && ownerDid && !domainDids.has(att.domain)) domainDids.set(att.domain, ownerDid);
1364
1369
  } catch {
1365
1370
  }
1366
1371
  }
@@ -1486,7 +1491,9 @@ async function checkTicket(archive, ticketId2) {
1486
1491
  return { ok: false, reason: `Ticket "${ticketId2}" has no archived Authority Server key to verify it against.`, entry };
1487
1492
  }
1488
1493
  try {
1489
- await verifyReceiptSignature(entry.receipt, entry.asPublicKey);
1494
+ await verifyTicketSignature(entry.receipt, {
1495
+ trustedIssuers: [issuerFromPublicKeyHex(entry.asPublicKey)]
1496
+ });
1490
1497
  } catch (err) {
1491
1498
  return {
1492
1499
  ok: false,
@@ -1583,11 +1590,13 @@ async function resolveMandateElement(archive, ticketRef) {
1583
1590
  const firstBlob = auth.attestations[0]?.blob;
1584
1591
  if (firstBlob && check.entry.asPublicKey) {
1585
1592
  try {
1586
- const attestation = decodeAttestationBlob3(firstBlob);
1587
- await verifyAttestationSignature2(attestation, check.entry.asPublicKey);
1588
- mode = attestation.payload.commitment_mode;
1589
- const dids = attestation.payload.resolved_owners ?? [];
1590
- const subjects = attestation.payload.subjects ?? [];
1593
+ const mandate = decodeMandateBlob3(firstBlob);
1594
+ await verifyMandateSignature2(mandate, {
1595
+ trustedIssuers: [issuerFromPublicKeyHex(check.entry.asPublicKey)]
1596
+ });
1597
+ mode = mandate.payload.commitment_mode;
1598
+ const dids = (mandate.payload.mandate_owners ?? []).map((o) => o.did);
1599
+ const subjects = mandate.payload.subjects ?? [];
1591
1600
  ownersRaw = dids;
1592
1601
  const dir = await getIdentityDirectory(archive);
1593
1602
  owners = dids.map((did) => {
@@ -1787,9 +1796,9 @@ function checkDocumentReproduces(bundle, documentHtml) {
1787
1796
  }
1788
1797
  async function verifiedPayload(blob, publicKeyHex) {
1789
1798
  try {
1790
- const att = decodeAttestationBlob4(blob);
1791
- await verifyAttestationSignature3(att, publicKeyHex);
1792
- return att.payload;
1799
+ const mandate = decodeMandateBlob4(blob);
1800
+ await verifyMandateSignature3(mandate, { trustedIssuers: [issuerFromPublicKeyHex(publicKeyHex)] });
1801
+ return mandate.payload;
1793
1802
  } catch {
1794
1803
  return null;
1795
1804
  }
@@ -1996,7 +2005,7 @@ function checkMandateFields(ctx, att, m, r, box, prefix) {
1996
2005
  }
1997
2006
  }
1998
2007
  function checkOwners(att, payload, labels, box, prefix) {
1999
- const dids = payload.resolved_owners ?? [];
2008
+ const dids = (payload.mandate_owners ?? []).map((o) => o.did);
2000
2009
  if (labels.length !== dids.length) {
2001
2010
  box.mismatches.push(`${prefix}owner: the box shows ${labels.length} owner(s), the signed mandate names ${dids.length}.`);
2002
2011
  return;
@@ -2243,8 +2252,8 @@ async function checkAttestations(auth, publicKeyHex) {
2243
2252
  }
2244
2253
  for (const att of auth.attestations) {
2245
2254
  try {
2246
- const attestation = decodeAttestationBlob5(att.blob);
2247
- await verifyAttestationSignature4(attestation, publicKeyHex);
2255
+ const mandate = decodeMandateBlob5(att.blob);
2256
+ await verifyMandateSignature4(mandate, { trustedIssuers: [issuerFromPublicKeyHex(publicKeyHex)] });
2248
2257
  } catch (err) {
2249
2258
  return { valid: false, error: err instanceof Error ? err.message : String(err) };
2250
2259
  }
@@ -2263,7 +2272,9 @@ async function verifyExportBundle(bundle, opts = {}) {
2263
2272
  continue;
2264
2273
  }
2265
2274
  try {
2266
- await verifyReceiptSignature2(receipt, bundle.authorityServer.publicKeyHex);
2275
+ await verifyTicketSignature2(receipt, {
2276
+ trustedIssuers: [issuerFromPublicKeyHex(bundle.authorityServer.publicKeyHex)]
2277
+ });
2267
2278
  tickets.push({ ticketId: id, referenced: referencedIds.has(id), present: true, signatureValid: true });
2268
2279
  } catch (err) {
2269
2280
  tickets.push({
@@ -2283,7 +2294,7 @@ async function verifyExportBundle(bundle, opts = {}) {
2283
2294
  if (auth.boundsHash) hashes.push({ from: "the mandate record", value: auth.boundsHash, signed: false });
2284
2295
  for (const att of auth.attestations) {
2285
2296
  try {
2286
- const bh = decodeAttestationBlob5(att.blob).payload.bounds_hash;
2297
+ const bh = decodeMandateBlob5(att.blob).payload.bounds_hash;
2287
2298
  if (bh) hashes.push({ from: "the signed attestation", value: bh, signed: attestationValid });
2288
2299
  } catch {
2289
2300
  }
@@ -2379,6 +2390,7 @@ function resolveKeyConfirmation(actualKeyHex, opts) {
2379
2390
  export {
2380
2391
  readPairing,
2381
2392
  fingerprintOf,
2393
+ issuerFromPublicKeyHex,
2382
2394
  REPORT_ELEMENTS,
2383
2395
  REPORT_BRIEF,
2384
2396
  sanitizeReport,