@substrat-run/kernel 0.142.0 → 0.144.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 (169) hide show
  1. package/dist/attachment-extractor.d.ts +0 -9
  2. package/dist/attachment-extractor.d.ts.map +1 -1
  3. package/dist/attachment-extractor.js +2 -2
  4. package/dist/attachment-extractor.js.map +1 -1
  5. package/dist/attachment-text.d.ts +0 -5
  6. package/dist/attachment-text.d.ts.map +1 -1
  7. package/dist/attachment-text.js +0 -4
  8. package/dist/attachment-text.js.map +1 -1
  9. package/dist/attribution.d.ts +0 -7
  10. package/dist/attribution.d.ts.map +1 -1
  11. package/dist/attribution.js +0 -7
  12. package/dist/attribution.js.map +1 -1
  13. package/dist/audit-outcome.d.ts +60 -2
  14. package/dist/audit-outcome.d.ts.map +1 -1
  15. package/dist/audit-outcome.js +63 -3
  16. package/dist/audit-outcome.js.map +1 -1
  17. package/dist/capability.d.ts +20 -13
  18. package/dist/capability.d.ts.map +1 -1
  19. package/dist/capability.js +76 -16
  20. package/dist/capability.js.map +1 -1
  21. package/dist/connector-calls.d.ts +0 -5
  22. package/dist/connector-calls.d.ts.map +1 -1
  23. package/dist/connector-calls.js +1 -1
  24. package/dist/connector-calls.js.map +1 -1
  25. package/dist/denial-query.d.ts +0 -14
  26. package/dist/denial-query.d.ts.map +1 -1
  27. package/dist/denial-query.js +1 -1
  28. package/dist/denial-query.js.map +1 -1
  29. package/dist/derived-handlers.d.ts +17 -0
  30. package/dist/derived-handlers.d.ts.map +1 -0
  31. package/dist/derived-handlers.js +198 -0
  32. package/dist/derived-handlers.js.map +1 -0
  33. package/dist/entity-binding.d.ts +121 -0
  34. package/dist/entity-binding.d.ts.map +1 -0
  35. package/dist/entity-binding.js +235 -0
  36. package/dist/entity-binding.js.map +1 -0
  37. package/dist/entity-grant-shape.d.ts +127 -12
  38. package/dist/entity-grant-shape.d.ts.map +1 -1
  39. package/dist/entity-grant-shape.js +399 -137
  40. package/dist/entity-grant-shape.js.map +1 -1
  41. package/dist/entity-grant.d.ts +5 -7
  42. package/dist/entity-grant.d.ts.map +1 -1
  43. package/dist/entity-grant.js +6 -7
  44. package/dist/entity-grant.js.map +1 -1
  45. package/dist/entity-state.d.ts +0 -17
  46. package/dist/entity-state.d.ts.map +1 -1
  47. package/dist/entity-state.js +2 -2
  48. package/dist/entity-state.js.map +1 -1
  49. package/dist/entity-trash.d.ts +2 -2
  50. package/dist/entity-trash.d.ts.map +1 -1
  51. package/dist/entity-trash.js +6 -6
  52. package/dist/entity-trash.js.map +1 -1
  53. package/dist/grant-scoped-read.d.ts +0 -2
  54. package/dist/grant-scoped-read.d.ts.map +1 -1
  55. package/dist/grant-scoped-read.js +2 -2
  56. package/dist/grant-scoped-read.js.map +1 -1
  57. package/dist/index.d.ts +53 -55
  58. package/dist/index.d.ts.map +1 -1
  59. package/dist/index.js +51 -53
  60. package/dist/index.js.map +1 -1
  61. package/dist/job-run.d.ts +0 -39
  62. package/dist/job-run.d.ts.map +1 -1
  63. package/dist/job-run.js +6 -6
  64. package/dist/job-run.js.map +1 -1
  65. package/dist/list-index.d.ts +0 -45
  66. package/dist/list-index.d.ts.map +1 -1
  67. package/dist/list-index.js +2 -39
  68. package/dist/list-index.js.map +1 -1
  69. package/dist/membership-executor.d.ts +2 -1
  70. package/dist/membership-executor.d.ts.map +1 -1
  71. package/dist/membership-executor.js +1 -1
  72. package/dist/membership-executor.js.map +1 -1
  73. package/dist/migration-digest.d.ts +0 -12
  74. package/dist/migration-digest.d.ts.map +1 -1
  75. package/dist/migration-digest.js +1 -1
  76. package/dist/migration-digest.js.map +1 -1
  77. package/dist/module-erasure.d.ts +2 -1
  78. package/dist/module-erasure.d.ts.map +1 -1
  79. package/dist/module-erasure.js +12 -1
  80. package/dist/module-erasure.js.map +1 -1
  81. package/dist/module-operations.d.ts +146 -0
  82. package/dist/module-operations.d.ts.map +1 -0
  83. package/dist/module-operations.js +174 -0
  84. package/dist/module-operations.js.map +1 -0
  85. package/dist/peer.d.ts +0 -2
  86. package/dist/peer.d.ts.map +1 -1
  87. package/dist/peer.js +0 -4
  88. package/dist/peer.js.map +1 -1
  89. package/dist/platform-request-query.d.ts +6 -6
  90. package/dist/platform-request-query.d.ts.map +1 -1
  91. package/dist/platform-request-query.js +23 -7
  92. package/dist/platform-request-query.js.map +1 -1
  93. package/dist/platform-sweep.d.ts +26 -2
  94. package/dist/platform-sweep.d.ts.map +1 -1
  95. package/dist/platform-sweep.js +6 -2
  96. package/dist/platform-sweep.js.map +1 -1
  97. package/dist/refusal-query.d.ts +0 -11
  98. package/dist/refusal-query.d.ts.map +1 -1
  99. package/dist/refusal-query.js +1 -1
  100. package/dist/refusal-query.js.map +1 -1
  101. package/dist/refusals.d.ts +1 -3
  102. package/dist/refusals.d.ts.map +1 -1
  103. package/dist/refusals.js +0 -2
  104. package/dist/refusals.js.map +1 -1
  105. package/dist/row-decode.d.ts +16 -1
  106. package/dist/row-decode.d.ts.map +1 -1
  107. package/dist/row-decode.js +18 -6
  108. package/dist/row-decode.js.map +1 -1
  109. package/dist/scope-copy-ledger.d.ts +0 -2
  110. package/dist/scope-copy-ledger.d.ts.map +1 -1
  111. package/dist/scope-copy-ledger.js +1 -1
  112. package/dist/scope-copy-ledger.js.map +1 -1
  113. package/dist/scope-host.d.ts +47 -101
  114. package/dist/scope-host.d.ts.map +1 -1
  115. package/dist/scope-host.js +0 -17
  116. package/dist/scope-host.js.map +1 -1
  117. package/dist/scope-lifecycle.d.ts +0 -21
  118. package/dist/scope-lifecycle.d.ts.map +1 -1
  119. package/dist/scope-lifecycle.js +1 -1
  120. package/dist/scope-lifecycle.js.map +1 -1
  121. package/dist/scope-role-admin.d.ts +0 -6
  122. package/dist/scope-role-admin.d.ts.map +1 -1
  123. package/dist/scope-role-admin.js +1 -1
  124. package/dist/scope-role-admin.js.map +1 -1
  125. package/dist/search-index.d.ts +0 -23
  126. package/dist/search-index.d.ts.map +1 -1
  127. package/dist/search-index.js +2 -24
  128. package/dist/search-index.js.map +1 -1
  129. package/dist/spine-restore.d.ts +0 -22
  130. package/dist/spine-restore.d.ts.map +1 -1
  131. package/dist/spine-restore.js +2 -2
  132. package/dist/spine-restore.js.map +1 -1
  133. package/dist/sql-identifier.d.ts +3 -0
  134. package/dist/sql-identifier.d.ts.map +1 -1
  135. package/dist/sql-identifier.js +2 -0
  136. package/dist/sql-identifier.js.map +1 -1
  137. package/dist/sql-limits.d.ts +4 -0
  138. package/dist/sql-limits.d.ts.map +1 -1
  139. package/dist/sql-limits.js +4 -0
  140. package/dist/sql-limits.js.map +1 -1
  141. package/dist/subject-redaction.d.ts +0 -38
  142. package/dist/subject-redaction.d.ts.map +1 -1
  143. package/dist/subject-redaction.js +4 -4
  144. package/dist/subject-redaction.js.map +1 -1
  145. package/dist/system-switch-record.d.ts +0 -4
  146. package/dist/system-switch-record.d.ts.map +1 -1
  147. package/dist/system-switch-record.js +2 -2
  148. package/dist/system-switch-record.js.map +1 -1
  149. package/dist/system-switch.d.ts +5 -23
  150. package/dist/system-switch.d.ts.map +1 -1
  151. package/dist/system-switch.js +8 -1
  152. package/dist/system-switch.js.map +1 -1
  153. package/dist/table-ownership.d.ts +0 -32
  154. package/dist/table-ownership.d.ts.map +1 -1
  155. package/dist/table-ownership.js +5 -5
  156. package/dist/table-ownership.js.map +1 -1
  157. package/dist/testing.d.ts +17 -0
  158. package/dist/testing.d.ts.map +1 -0
  159. package/dist/testing.js +15 -0
  160. package/dist/testing.js.map +1 -0
  161. package/dist/vertical-events.d.ts +1 -7
  162. package/dist/vertical-events.d.ts.map +1 -1
  163. package/dist/vertical-events.js +2 -10
  164. package/dist/vertical-events.js.map +1 -1
  165. package/package.json +6 -2
  166. package/dist/connect-state.d.ts +0 -103
  167. package/dist/connect-state.d.ts.map +0 -1
  168. package/dist/connect-state.js +0 -128
  169. package/dist/connect-state.js.map +0 -1
@@ -1,128 +0,0 @@
1
- /**
2
- * The signed state of a PLATFORM-MINTED provider consent round (connections.md §3.5.3).
3
- *
4
- * §3.5.1 settled how an OAuth connection is authorized: the act originates in-scope, a
5
- * signed state token carries the proof, and the host-side callback effects the write
6
- * stamped with the principal from that state. The dashboard's connect link is one
7
- * instance of it. This is the second: a tenant admin working inside a VERTICAL — a
8
- * bookkeeping bureau connecting a client company, with no dashboard account and no
9
- * reason to have one — presses Connect on the vertical's own screen, and the vertical's
10
- * operation is the permission-checked act.
11
- *
12
- * **Why an in-session claim carries no link row.** The dashboard's connect link is minted,
13
- * mailed, and clicked days later by someone else, so it is a row: single-use, revocable, and
14
- * dead when the minting admin loses access. A vertical-minted round is clicked in-session by
15
- * the person who just pressed the button, so the row would be state nobody reads. What
16
- * replaces it is the expiry — minutes, not a week — and the account leg of the connection
17
- * key: a replayed round re-consents the SAME company, which the store rotates in place
18
- * rather than duplicating (#1267). The consent code itself is single-use at the provider.
19
- * A vertical's MAILED link is the other case again, and carries a row: `linkId`, below.
20
- *
21
- * **Why the kernel.** Two workers hold the halves — the control plane mints (it owns the
22
- * directory the vertical is re-derived from), the dashboard verifies (it owns the one
23
- * `redirect_uri` registered with the provider) — and a MAC that two deployments must agree
24
- * on is exactly the thing that must not be written twice. It sits beside `platform-call.ts`
25
- * for the same reason that does: both answer "did this really come from the platform".
26
- *
27
- * Web Crypto only, so this file is testable in Node and runs unchanged in workerd.
28
- */
29
- /** Thrown when a claim cannot be minted — never when one fails to verify (that is `null`). */
30
- export class ConnectStateError extends Error {
31
- constructor(message) {
32
- super(message);
33
- this.name = 'ConnectStateError';
34
- }
35
- }
36
- /**
37
- * The purpose label, and the `:v1` is the key-derivation version. Signing key is
38
- * HKDF(PLATFORM_SECRET, info = this), so a token minted here can never verify anywhere
39
- * else the platform secret is presented — `/internal/provision` and the two relays
40
- * compare the secret raw, and a MAC family shared with them would let a signature minted
41
- * for one be replayed as the other wherever the shapes overlap (the same trap #968 fixed
42
- * inside the dashboard).
43
- */
44
- export const CONNECT_STATE_PURPOSE = 'substrat-platform:connect-state:v1';
45
- const enc = (s) => new TextEncoder().encode(s);
46
- const b64url = (bytes) => {
47
- let s = '';
48
- for (const b of bytes)
49
- s += String.fromCharCode(b);
50
- return btoa(s).replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
51
- };
52
- const b64urlToBytes = (s) => {
53
- const padded = s.replace(/-/g, '+').replace(/_/g, '/') + '='.repeat((4 - (s.length % 4)) % 4);
54
- const raw = atob(padded);
55
- const out = new Uint8Array(raw.length);
56
- for (let i = 0; i < raw.length; i++)
57
- out[i] = raw.charCodeAt(i);
58
- return out;
59
- };
60
- /** HKDF-SHA-256(ikm = the platform secret, info = the purpose) → an HMAC-SHA-256 key. */
61
- async function stateKey(platformSecret) {
62
- const ikm = await crypto.subtle.importKey('raw', enc(platformSecret), 'HKDF', false, ['deriveKey']);
63
- return crypto.subtle.deriveKey({ name: 'HKDF', hash: 'SHA-256', salt: enc('substrat-platform'), info: enc(CONNECT_STATE_PURPOSE) }, ikm, { name: 'HMAC', hash: 'SHA-256', length: 256 }, false, ['sign', 'verify']);
64
- }
65
- /**
66
- * `<base64url(JSON claim)>.<base64url(HMAC)>`.
67
- *
68
- * Refuses an unset secret rather than signing with `''` — the same law
69
- * `assertPlatformCall` states: an unset secret is a failure, not a bypass. A token
70
- * signed under the empty string would verify for anyone who guessed that it was.
71
- */
72
- export async function signConnectState(platformSecret, claim) {
73
- if (!platformSecret) {
74
- throw new ConnectStateError('cannot mint a connect state: PLATFORM_SECRET is unset on this deployment');
75
- }
76
- const body = b64url(enc(JSON.stringify(claim)));
77
- const sig = new Uint8Array(await crypto.subtle.sign('HMAC', await stateKey(platformSecret), enc(body)));
78
- return `${body}.${b64url(sig)}`;
79
- }
80
- /**
81
- * The claim if the signature verifies under this deployment's platform secret and `exp`
82
- * is still ahead of `now`; `null` for everything else — a forgery, a token minted with
83
- * the raw secret, an expired round, a malformed string. One `null` for every failure on
84
- * purpose: the caller renders one refusal, and a distinguishable error is an oracle.
85
- *
86
- * An unset secret verifies nothing (never throws): a deployment holding no platform
87
- * secret has no platform-minted rounds to accept.
88
- */
89
- export async function verifyConnectState(platformSecret, token, now) {
90
- if (!platformSecret || !token)
91
- return null;
92
- const parts = token.split('.');
93
- if (parts.length !== 2)
94
- return null;
95
- const [body, sig] = parts;
96
- if (!body || !sig)
97
- return null;
98
- let ok = false;
99
- try {
100
- ok = await crypto.subtle.verify('HMAC', await stateKey(platformSecret), b64urlToBytes(sig), enc(body));
101
- }
102
- catch {
103
- return null;
104
- }
105
- if (!ok)
106
- return null;
107
- try {
108
- const claim = JSON.parse(new TextDecoder().decode(b64urlToBytes(body)));
109
- if (typeof claim.exp !== 'number' || claim.exp <= now)
110
- return null;
111
- // A verified signature proves the platform minted it; it does not prove the shape,
112
- // and a claim missing one of these would reach the store as `undefined` — which is
113
- // how a credential lands under the wrong key rather than not at all.
114
- for (const field of ['tenantId', 'scopeId', 'vertical', 'provider', 'principal']) {
115
- if (typeof claim[field] !== 'string' || !claim[field])
116
- return null;
117
- }
118
- // A link round with a malformed row reference would read as an in-session round — the
119
- // one kind the callback spends nothing for — so it is refused, never downgraded.
120
- if (claim.linkId !== undefined && (typeof claim.linkId !== 'string' || !claim.linkId))
121
- return null;
122
- return claim;
123
- }
124
- catch {
125
- return null;
126
- }
127
- }
128
- //# sourceMappingURL=connect-state.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"connect-state.js","sourceRoot":"","sources":["../src/connect-state.ts"],"names":[],"mappings":"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"}