@tinycloud/node-sdk 3.2.6-beta.6 → 3.3.0-beta.11

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 (43) hide show
  1. package/dist/{WasmKeyProvider-DEdSyQ0I.d.cts → TinyCloudNode-CcNh20QX.d.cts} +181 -286
  2. package/dist/{WasmKeyProvider-DEdSyQ0I.d.ts → TinyCloudNode-CcNh20QX.d.ts} +181 -286
  3. package/dist/WasmKeyProvider-5Ee7fcAw.d.cts +217 -0
  4. package/dist/WasmKeyProvider-5Ee7fcAw.d.ts +217 -0
  5. package/dist/authority-Cwotwza3.d.cts +118 -0
  6. package/dist/authority-D_u9a7Wl.d.ts +118 -0
  7. package/dist/core.cjs +401 -168
  8. package/dist/core.cjs.map +1 -1
  9. package/dist/core.d.cts +37 -4
  10. package/dist/core.d.ts +37 -4
  11. package/dist/core.js +408 -176
  12. package/dist/core.js.map +1 -1
  13. package/dist/gated-network-BEF2XSTC.d.cts +16 -0
  14. package/dist/gated-network-BEF2XSTC.d.ts +16 -0
  15. package/dist/index.cjs +2735 -545
  16. package/dist/index.cjs.map +1 -1
  17. package/dist/index.d.cts +35 -89
  18. package/dist/index.d.ts +35 -89
  19. package/dist/index.js +2730 -545
  20. package/dist/index.js.map +1 -1
  21. package/dist/replication/authority.cjs +153 -15
  22. package/dist/replication/authority.cjs.map +1 -1
  23. package/dist/replication/authority.d.cts +4 -1
  24. package/dist/replication/authority.d.ts +4 -1
  25. package/dist/replication/authority.js +147 -14
  26. package/dist/replication/authority.js.map +1 -1
  27. package/dist/replication/gated-network.cjs +90 -0
  28. package/dist/replication/gated-network.cjs.map +1 -0
  29. package/dist/replication/gated-network.d.cts +2 -0
  30. package/dist/replication/gated-network.d.ts +2 -0
  31. package/dist/replication/gated-network.js +65 -0
  32. package/dist/replication/gated-network.js.map +1 -0
  33. package/dist/replication/runtime.cjs +84 -6
  34. package/dist/replication/runtime.cjs.map +1 -1
  35. package/dist/replication/runtime.d.cts +2 -1
  36. package/dist/replication/runtime.d.ts +2 -1
  37. package/dist/replication/runtime.js +84 -6
  38. package/dist/replication/runtime.js.map +1 -1
  39. package/dist/{runtime-B5P5SRpC.d.ts → runtime-D1o9Eybt.d.cts} +14 -3
  40. package/dist/{runtime-B5P5SRpC.d.cts → runtime-v62FzQHz.d.ts} +14 -3
  41. package/package.json +14 -4
  42. package/dist/authority-DDGtccBK.d.cts +0 -96
  43. package/dist/authority-DDGtccBK.d.ts +0 -96
@@ -21,28 +21,40 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
21
21
  var authority_exports = {};
22
22
  __export(authority_exports, {
23
23
  AUTHORITY_EXPIRY_MARGIN_MS: () => AUTHORITY_EXPIRY_MARGIN_MS,
24
+ assertRenewalParent: () => assertRenewalParent,
24
25
  assertValidReplicationConfig: () => assertValidReplicationConfig,
25
26
  augmentSignInEntriesWithReplication: () => augmentSignInEntriesWithReplication,
26
27
  createReplicationAuthority: () => createReplicationAuthority,
28
+ establishReplicaSessionStamp: () => establishReplicaSessionStamp,
27
29
  hasUnrestrictedGetCoverage: () => hasUnrestrictedGetCoverage,
30
+ mintNodeReplicationGrant: () => mintNodeReplicationGrant,
28
31
  replicationScopeFromSignedSession: () => replicationScopeFromSignedSession,
32
+ reportReplicaDenial: () => reportReplicaDenial,
33
+ restoreReplicaSessionStamp: () => restoreReplicaSessionStamp,
29
34
  ucanAttCovers: () => ucanAttCovers,
30
- ucanAttUnconstrainedFor: () => ucanAttUnconstrainedFor
35
+ ucanAttUnconstrainedFor: () => ucanAttUnconstrainedFor,
36
+ verifiedOwnerConsentAnchor: () => verifiedOwnerConsentAnchor
31
37
  });
32
38
  module.exports = __toCommonJS(authority_exports);
39
+ var import_siwe = require("siwe");
33
40
  var import_sdk_core2 = require("@tinycloud/sdk-core");
34
41
  var import_replica = require("@tinycloud/replica");
35
42
 
36
43
  // src/replication/config.ts
44
+ var import_grantPolicyConstants = require("@tinycloud/sdk-services/kv/replication/grantPolicyConstants");
37
45
  var import_prefix = require("@tinycloud/sdk-services/kv/replication/prefix");
38
46
  function assertValidReplicationConfig(replication) {
39
- if (replication === void 0 || replication.enabled !== true) return;
47
+ if (replication === void 0 || !replication.enabled) return;
40
48
  if (replication.storage === void 0 || replication.storage === null) {
41
49
  throw new TypeError("replication.enabled requires replication.storage");
42
50
  }
43
51
  if (!Array.isArray(replication.prefixes) || replication.prefixes.length === 0) {
44
52
  throw new TypeError("replication.prefixes must be a non-empty array");
45
53
  }
54
+ const grantTtlMs = replication.grantTtlMs;
55
+ if (grantTtlMs !== void 0 && (!Number.isFinite(grantTtlMs) || grantTtlMs <= 0 || grantTtlMs > import_grantPolicyConstants.MAX_GRANT_TTL_MS)) {
56
+ throw new TypeError(`replication.grantTtlMs must be a positive number of milliseconds no greater than ${import_grantPolicyConstants.MAX_GRANT_TTL_MS}`);
57
+ }
46
58
  for (const prefix of replication.prefixes) {
47
59
  try {
48
60
  (0, import_prefix.assertFolderPrefix)(prefix);
@@ -116,9 +128,83 @@ function augmentSignInEntriesWithReplication(input) {
116
128
 
117
129
  // src/replication/authority.ts
118
130
  var parseUcanGrant = import_replica.parseUcanGrant;
131
+ function reportReplicaDenial(result, reason, onEvent, context) {
132
+ if (result.status !== "denied" && result.status !== "deleted" && result.status !== "marker") return;
133
+ const event = {
134
+ type: "replication.lifecycle",
135
+ at: (/* @__PURE__ */ new Date()).toISOString(),
136
+ reason,
137
+ action: result.status === "denied" ? "denied" : result.status === "deleted" ? "database_deleted" : "marker_set",
138
+ ...result.status === "denied" ? { partitions: result.intents } : {},
139
+ ...result.status === "marker" ? { code: result.code } : {}
140
+ };
141
+ try {
142
+ onEvent?.(event);
143
+ } catch {
144
+ }
145
+ const { type, ...data } = event;
146
+ try {
147
+ context?.emit(type, data);
148
+ } catch {
149
+ }
150
+ }
119
151
  var KV_GET2 = import_sdk_core2.KV.GET;
120
152
  var KV_SYNC2 = import_sdk_core2.KV.SYNC;
121
153
  var KV_SERVICE2 = "tinycloud.kv";
154
+ function verifiedOwnerConsentAnchor(session, wasmBindings, exactVerifiedRecap) {
155
+ if (typeof session.siwe !== "string" || typeof session.signature !== "string" || typeof session.address !== "string" || typeof session.chainId !== "number") return null;
156
+ try {
157
+ const verified = wasmBindings.validatePersistedSession?.({
158
+ delegationHeader: session.delegationHeader,
159
+ delegationCid: session.delegationCid,
160
+ spaceId: session.spaceId,
161
+ jwk: session.jwk,
162
+ address: session.address,
163
+ chainId: session.chainId,
164
+ siwe: session.siwe,
165
+ signature: session.signature
166
+ });
167
+ if (!verified || !Number.isSafeInteger(Date.parse(verified.expiresAt ?? ""))) return null;
168
+ const signedIssuedAt = new import_siwe.SiweMessage(session.siwe).issuedAt;
169
+ if (typeof signedIssuedAt !== "string") return null;
170
+ const issuedAt = Date.parse(signedIssuedAt);
171
+ if (!Number.isSafeInteger(issuedAt) || issuedAt < 0) return null;
172
+ const granted = exactVerifiedRecap(verified).filter((entry) => entry.space === session.spaceId && entry.service === "kv").map((entry) => ({ ...entry, service: "tinycloud.kv" }));
173
+ const coversGetAndSync = granted.some((entry) => (0, import_sdk_core2.isCapabilitySubset)([{
174
+ service: "tinycloud.kv",
175
+ space: session.spaceId,
176
+ path: entry.path,
177
+ actions: [import_sdk_core2.KV.GET, import_sdk_core2.KV.SYNC]
178
+ }], granted).subset);
179
+ return coversGetAndSync ? { at: issuedAt, source: "siwe" } : null;
180
+ } catch {
181
+ return null;
182
+ }
183
+ }
184
+ function establishReplicaSessionStamp(storage, principal, anchor) {
185
+ if (storage.kind === "indexeddb" && storage.lifecycle?.kind === "indexeddb") {
186
+ return storage.lifecycle.establishSessionStamp(principal, { consentAnchor: anchor });
187
+ }
188
+ if (storage.kind === "sqlite" && storage.lifecycle?.kind === "file") {
189
+ return storage.lifecycle.establishSessionStamp(principal, { consentAnchor: anchor });
190
+ }
191
+ throw Object.assign(new Error("Replica sign-in requires its platform lifecycle gate."), {
192
+ code: "REPLICA_GATED",
193
+ gate: "gate_unavailable"
194
+ });
195
+ }
196
+ function restoreReplicaSessionStamp(storage, principal, persisted) {
197
+ if (storage.kind === "indexeddb" && storage.lifecycle?.kind === "indexeddb") {
198
+ return storage.lifecycle.restoreSessionStamp(principal, persisted);
199
+ }
200
+ if (storage.kind === "sqlite" && storage.lifecycle?.kind === "file") {
201
+ return storage.lifecycle.restoreSessionStamp(principal, persisted);
202
+ }
203
+ throw Object.assign(new Error("Replica restore requires its platform lifecycle gate."), {
204
+ code: "REPLICA_GATED",
205
+ gate: "gate_unavailable"
206
+ });
207
+ }
122
208
  function replicationEntries(spaceId, prefix) {
123
209
  return [{
124
210
  service: KV_SERVICE2,
@@ -166,6 +252,20 @@ function ucanAttCovers(att, space, prefix, ability, options) {
166
252
  function ucanAttUnconstrainedFor(att, space, prefix) {
167
253
  return ucanAttCovers(att, space, prefix, KV_GET2) && ucanAttCovers(att, space, prefix, KV_SYNC2);
168
254
  }
255
+ async function mintNodeReplicationGrant(deviceDid, entries, options, renewalSession, node) {
256
+ if (options?.renewalOnly && !renewalSession) throw new Error("replication renewal lost its owner session");
257
+ const delegateOptions = options?.renewalOnly ? {
258
+ expiry: options.expiryMs,
259
+ onPrepared: async (prepared) => {
260
+ assertRenewalParent(prepared.delegationHeader.Authorization, renewalSession);
261
+ }
262
+ } : options?.expiryMs === void 0 ? void 0 : { expiry: options.expiryMs };
263
+ const result = await node.delegateTo((0, import_sdk_core2.principalDid)(deviceDid), entries, delegateOptions);
264
+ return {
265
+ ucan: result.delegation.delegationHeader.Authorization,
266
+ expiresAt: result.delegation.expiry.getTime()
267
+ };
268
+ }
169
269
  var AUTHORITY_EXPIRY_MARGIN_MS = 6e4;
170
270
  function replicationScopeFromSignedSession(input) {
171
271
  let grant;
@@ -184,9 +284,28 @@ function replicationScopeFromSignedSession(input) {
184
284
  }
185
285
  return void 0;
186
286
  }
287
+ function assertRenewalParent(authorization, session) {
288
+ const grant = parseUcanGrant(authorization);
289
+ if (grant.issuer !== session.verificationMethod.split("#", 1)[0] || grant.prf.length !== 1 || grant.prf[0] !== session.delegationCid) {
290
+ throw Object.assign(new Error("replication renewal requires the bound owner session parent"), { refused: "NOT_COVERED" });
291
+ }
292
+ }
187
293
  function createReplicationAuthority(host) {
188
- const planOrRefusal = (entries) => {
189
- const plan = host.planDelegation(entries);
294
+ const boundSession = host.replicationSession();
295
+ let verifiedAnchor = null;
296
+ try {
297
+ const candidate = boundSession && host.verifiedConsentAnchor?.(boundSession);
298
+ if (candidate && Number.isFinite(candidate.at) && candidate.source !== "first_install") {
299
+ verifiedAnchor = { at: candidate.at, source: candidate.source };
300
+ }
301
+ } catch {
302
+ }
303
+ const activeSession = () => {
304
+ const session = host.replicationSession();
305
+ return session !== void 0 && session === boundSession ? session : void 0;
306
+ };
307
+ const planOrRefusal = (entries, expiryMs) => {
308
+ const plan = host.planDelegation(entries, expiryMs === void 0 ? void 0 : { expiry: expiryMs });
190
309
  if ("refused" in plan) return plan;
191
310
  return { path: plan.path, parentCid: plan.parentCid, expiresAt: plan.expiresAt };
192
311
  };
@@ -198,12 +317,20 @@ function createReplicationAuthority(host) {
198
317
  };
199
318
  const authority = {
200
319
  get sessionOnly() {
201
- const session = host.replicationSession();
202
- return session !== void 0 && session.siwe === void 0;
320
+ const session = activeSession();
321
+ return session === void 0 || session.siwe === void 0;
322
+ },
323
+ consentAnchor() {
324
+ return activeSession() ? verifiedAnchor : null;
325
+ },
326
+ get canRenew() {
327
+ const session = activeSession();
328
+ return verifiedAnchor?.source === "siwe" && session !== void 0 && session.siwe !== void 0;
203
329
  },
204
330
  sessionGrant(prefix) {
205
- const session = host.replicationSession();
331
+ const session = activeSession();
206
332
  if (session === void 0) return { refused: "SESSION_EXPIRING" };
333
+ if (verifiedAnchor === null && session.siwe !== void 0) return { refused: "NOT_COVERED" };
207
334
  const siweExpiry = session.siwe ? host.siweExpiration(session.siwe)?.getTime() : void 0;
208
335
  if (siweExpiry !== void 0 && siweExpiry <= Date.now() + AUTHORITY_EXPIRY_MARGIN_MS) {
209
336
  return { refused: "SESSION_EXPIRING" };
@@ -231,8 +358,9 @@ function createReplicationAuthority(host) {
231
358
  };
232
359
  },
233
360
  plan(prefix) {
234
- const session = host.replicationSession();
361
+ const session = activeSession();
235
362
  if (session === void 0) return { refused: "SESSION_EXPIRING" };
363
+ if (verifiedAnchor === null) return { refused: "NOT_COVERED" };
236
364
  const sessionGrant = this.sessionGrant(prefix);
237
365
  if (!("refused" in sessionGrant)) {
238
366
  const signed = signedSessionGrant(session);
@@ -246,23 +374,27 @@ function createReplicationAuthority(host) {
246
374
  if (authority.sessionOnly) return sessionGrant;
247
375
  return planOrRefusal(replicationEntries(session.spaceId, prefix));
248
376
  },
249
- async mint(deviceDid, prefix, signal) {
250
- if (authority.sessionOnly) throw new Error("compact delegate sessions cannot mint device grants");
251
- const session = host.replicationSession();
252
- if (session === void 0) throw new Error("replication mint without a session");
377
+ async mint(deviceDid, prefix, signal, options) {
378
+ const session = activeSession();
379
+ if (session === void 0) throw new Error("replication mint without the bound session");
380
+ if (session.siwe === void 0) throw new Error("compact delegate sessions cannot mint device grants");
381
+ if (verifiedAnchor?.source !== "siwe") throw new Error("replication mint requires verified owner consent");
253
382
  const entries = replicationEntries(session.spaceId, prefix);
254
- const plan = planOrRefusal(entries);
383
+ const plan = planOrRefusal(entries, options?.expiryMs);
255
384
  if ("refused" in plan) {
256
385
  throw Object.assign(
257
386
  new Error(`replication authority refused the mint: ${plan.refused}`),
258
387
  { refused: plan.refused }
259
388
  );
260
389
  }
390
+ if (options?.renewalOnly && plan.path !== "session") {
391
+ throw Object.assign(new Error("replication renewal requires a session parent"), { refused: "NOT_COVERED" });
392
+ }
261
393
  signal.throwIfAborted();
262
394
  const minted = await new Promise((resolve, reject) => {
263
395
  const onAbort = () => reject(signal.reason ?? new Error("replication mint aborted"));
264
396
  signal.addEventListener("abort", onAbort, { once: true });
265
- host.mintDelegation(deviceDid, entries).then(
397
+ host.mintDelegation(deviceDid, entries, options).then(
266
398
  (result) => {
267
399
  signal.removeEventListener("abort", onAbort);
268
400
  resolve(result);
@@ -281,12 +413,18 @@ function createReplicationAuthority(host) {
281
413
  // Annotate the CommonJS export names for ESM import in node:
282
414
  0 && (module.exports = {
283
415
  AUTHORITY_EXPIRY_MARGIN_MS,
416
+ assertRenewalParent,
284
417
  assertValidReplicationConfig,
285
418
  augmentSignInEntriesWithReplication,
286
419
  createReplicationAuthority,
420
+ establishReplicaSessionStamp,
287
421
  hasUnrestrictedGetCoverage,
422
+ mintNodeReplicationGrant,
288
423
  replicationScopeFromSignedSession,
424
+ reportReplicaDenial,
425
+ restoreReplicaSessionStamp,
289
426
  ucanAttCovers,
290
- ucanAttUnconstrainedFor
427
+ ucanAttUnconstrainedFor,
428
+ verifiedOwnerConsentAnchor
291
429
  });
292
430
  //# sourceMappingURL=authority.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/replication/authority.ts","../../src/replication/config.ts","../../src/replication/authority-sign-in.ts"],"sourcesContent":["/**\n * Replication authority (TC-858, plan v3 §4).\n *\n * `ReplicationAuthority` answers, per configured prefix, whether this node's\n * session can back a local replica: the session UCAN itself (delegate\n * posture), a child UCAN minted through `delegateTo`, or nothing (the\n * controller then reports `grant_missing` and reads from the network).\n *\n * The unrestricted-authority rule is enforced here, before any network work:\n * a prefix covered only by a caveated `get`/`sync` refuses with\n * `CAVEATED_AUTHORITY` — on the session path, the runtime-grant path, and on\n * any reuse of an installed grant (the adapter marks every grant's\n * `unconstrained` flag; the controller enforces it on reuse).\n */\n\nimport {\n actionContains,\n KV,\n canonicalizeRecapCaveats,\n isCapabilitySubset,\n parseSpaceUri,\n type PermissionEntry,\n type TinyCloudSession,\n} from \"@tinycloud/sdk-core\";\nimport {\n type AuthorityRefusal,\n type ReplicaDevice,\n type ReplicationAuthority,\n} from \"@tinycloud/sdk-services\";\nimport type { ReplicaRuntime } from \"./replica-contract\";\n// @ts-ignore -- node-sdk builds before replica declarations; keep the literal import for bundlers.\nimport { parseUcanGrant as replicaParseUcanGrant } from \"@tinycloud/replica\";\nconst parseUcanGrant = replicaParseUcanGrant as ReplicaRuntime[\"parseUcanGrant\"];\nexport { assertValidReplicationConfig } from \"./config\";\nexport { augmentSignInEntriesWithReplication, hasUnrestrictedGetCoverage } from \"./authority-sign-in\";\n\nconst KV_GET = KV.GET;\nconst KV_SYNC = KV.SYNC;\nconst KV_SERVICE = \"tinycloud.kv\";\n\n/** The delegation the replication grant delegates: get + sync on one folder prefix. */\nfunction replicationEntries(spaceId: string, prefix: string): PermissionEntry[] {\n return [{\n service: KV_SERVICE,\n space: spaceId,\n path: prefix === \"/\" ? \"\" : prefix,\n actions: [KV_GET, KV_SYNC],\n }];\n}\n\n\n\n\n/**\n * The signed UCAN attenuation (`att`: resource → ability → caveat branches).\n * Only array branch sets are known; anything else is treated as constrained —\n * fail closed, never assume unconstrained.\n */\nfunction caveatBranchesUnconstrained(value: unknown): boolean {\n if (value === undefined || value === null) return true;\n if (typeof value === \"object\" && !Array.isArray(value) && Object.keys(value).length === 0) {\n return true;\n }\n if (!Array.isArray(value)) return false;\n try {\n return (\n canonicalizeRecapCaveats(value as Record<string, unknown>[]) ===\n canonicalizeRecapCaveats(undefined)\n );\n } catch {\n return false;\n }\n}\n\n/** The KV path a signed UCAN resource names in `space`, like replica's `kvPathIn`. */\nfunction kvPathInResource(resource: string, space: string): string | undefined {\n for (const root of [`${space}/kv`, `tinycloud://${space}/kv`]) {\n if (resource === root || resource === `${root}/`) return \"/\";\n }\n for (const base of [`${space}/kv/`, `tinycloud://${space}/kv/`]) {\n if (resource.startsWith(base)) return resource.slice(base.length);\n }\n return undefined;\n\n}\n/**\n * Whether the signed `att` grants `ability` over the folder prefix, with\n * unrestricted authority unless explicitly asked to ignore caveats.\n */\nexport function ucanAttCovers(\n att: Record<string, Record<string, unknown>>,\n space: string,\n prefix: string,\n ability: string,\n options?: { ignoreCaveats?: boolean },\n): boolean {\n for (const [resource, abilities] of Object.entries(att)) {\n const path = kvPathInResource(resource, space);\n if (path === undefined) continue;\n for (const [granted, caveats] of Object.entries(abilities)) {\n if (!actionContains(granted, ability)) continue;\n if (!isCapabilitySubset(\n [{ service: KV_SERVICE, space, path: prefix, actions: [ability] }],\n [{ service: KV_SERVICE, space, path, actions: [granted] }],\n ).subset) continue;\n if (options?.ignoreCaveats === true || caveatBranchesUnconstrained(caveats)) return true;\n }\n }\n return false;\n}\n\n/** `unconstrained` for `ReplicaGrantInfo` (§2.1): get AND sync on the prefix carry no caveats. */\nexport function ucanAttUnconstrainedFor(\n att: Record<string, Record<string, unknown>>,\n space: string,\n prefix: string,\n): boolean {\n return (\n ucanAttCovers(att, space, prefix, KV_GET) &&\n ucanAttCovers(att, space, prefix, KV_SYNC)\n );\n}\n\nexport interface DelegationPlanResult {\n path: \"session\" | \"runtime\";\n parentCid: string;\n expiresAt: number;\n}\n\n/**\n * The `TinyCloudNode` internals the authority needs. `planDelegation` is the\n * pure extraction of `delegateTo`'s parent selection (§4.3), so `plan` and\n * `mint` can never disagree about which parent or expiry a delegation gets.\n */\nexport type ReplicationAuthoritySession = Pick<\n TinyCloudSession,\n \"delegationHeader\" | \"delegationCid\" | \"spaceId\" | \"verificationMethod\" | \"jwk\"\n> & Partial<Pick<TinyCloudSession, \"siwe\">>;\n\nexport interface ReplicationAuthorityHost {\n replicationSession(): ReplicationAuthoritySession | undefined;\n /** The SIWE \"Expiration Time\" of the session — the delegateTo delegation cap. */\n siweExpiration(siwe: string): Date | undefined;\n planDelegation(\n entries: PermissionEntry[],\n options?: { expiry?: string | number },\n ): ({ grant?: unknown } & DelegationPlanResult) | AuthorityRefusal;\n mintDelegation(\n deviceDid: string,\n entries: PermissionEntry[],\n ): Promise<{ ucan: string; expiresAt: number }>;\n}\n\n/** Milliseconds of validity a session or parent must have left for authority reuse (delegateTo's margin). */\nexport const AUTHORITY_EXPIRY_MARGIN_MS = 60_000;\n\n\n/** Verify a compact session delegation before using any persisted space metadata. */\nexport function replicationScopeFromSignedSession(input: {\n delegationHeader: { Authorization: string };\n delegationCid: string;\n verificationMethod: string;\n persistedSpace: string;\n}): { space: string; principal: string } | undefined {\n let grant: ReturnType<typeof parseUcanGrant>;\n try {\n grant = parseUcanGrant(input.delegationHeader.Authorization);\n } catch {\n return undefined;\n }\n const bareDid = (value: string): string => value.split(\"#\", 1)[0]!;\n if (\n grant.cid !== input.delegationCid ||\n bareDid(grant.audience) !== bareDid(input.verificationMethod)\n ) return undefined;\n for (const resource of Object.keys(grant.att)) {\n const space = resource.match(/^(?:tinycloud:\\/\\/)?(.+?)\\/kv(?:\\/|$)/)?.[1];\n if (space !== input.persistedSpace) continue;\n const owner = parseSpaceUri(space);\n if (owner?.owner && owner.address && owner.chainId) return { space, principal: owner.owner };\n }\n return undefined;\n}\nexport function createReplicationAuthority(host: ReplicationAuthorityHost): ReplicationAuthority {\n const planOrRefusal = (entries: PermissionEntry[]): DelegationPlanResult | AuthorityRefusal => {\n const plan = host.planDelegation(entries);\n if (\"refused\" in plan) return plan;\n return { path: plan.path, parentCid: plan.parentCid, expiresAt: plan.expiresAt };\n };\n const sessionAudience = (value: string): string => value.split(\"#\", 1)[0]!;\n const signedSessionGrant = (session: ReplicationAuthoritySession) => {\n const grant = parseUcanGrant(session.delegationHeader.Authorization);\n if (\n grant.cid !== session.delegationCid ||\n sessionAudience(grant.audience) !== sessionAudience(session.verificationMethod)\n ) return undefined;\n return grant;\n };\n const authority: ReplicationAuthority = {\n get sessionOnly() {\n const session = host.replicationSession();\n return session !== undefined && session.siwe === undefined;\n },\n sessionGrant(prefix: string): { ucan: string; device: ReplicaDevice } | AuthorityRefusal {\n const session = host.replicationSession();\n if (session === undefined) return { refused: \"SESSION_EXPIRING\" };\n const siweExpiry = session.siwe ? host.siweExpiration(session.siwe)?.getTime() : undefined;\n if (siweExpiry !== undefined && siweExpiry <= Date.now() + AUTHORITY_EXPIRY_MARGIN_MS) {\n return { refused: \"SESSION_EXPIRING\" };\n }\n let grant: ReturnType<typeof parseUcanGrant>;\n try {\n const verified = signedSessionGrant(session);\n if (!verified) return { refused: \"NOT_COVERED\" };\n grant = verified;\n } catch {\n return { refused: \"NOT_COVERED\" };\n }\n const tokenExpiry = grant.expiresAt === null ? undefined : grant.expiresAt * 1000;\n if (tokenExpiry === undefined || tokenExpiry <= Date.now() + AUTHORITY_EXPIRY_MARGIN_MS) {\n return { refused: \"SESSION_EXPIRING\" };\n }\n const covered = ucanAttCovers(grant.att, session.spaceId, prefix, KV_GET, { ignoreCaveats: true }) &&\n ucanAttCovers(grant.att, session.spaceId, prefix, KV_SYNC, { ignoreCaveats: true });\n if (!covered) return { refused: \"NOT_COVERED\" };\n if (!ucanAttUnconstrainedFor(grant.att, session.spaceId, prefix)) {\n return { refused: \"CAVEATED_AUTHORITY\" };\n }\n return {\n ucan: grant.jwt,\n device: { did: session.verificationMethod, jwk: session.jwk },\n };\n },\n plan(prefix: string): DelegationPlanResult | AuthorityRefusal {\n const session = host.replicationSession();\n if (session === undefined) return { refused: \"SESSION_EXPIRING\" };\n const sessionGrant = this.sessionGrant(prefix);\n if (!(\"refused\" in sessionGrant)) {\n const signed = signedSessionGrant(session);\n if (!signed || signed.expiresAt === null) return { refused: \"NOT_COVERED\" };\n return {\n path: \"session\",\n parentCid: session.delegationCid,\n expiresAt: signed.expiresAt * 1000,\n };\n }\n if (authority.sessionOnly) return sessionGrant;\n return planOrRefusal(replicationEntries(session.spaceId, prefix));\n },\n async mint(\n deviceDid: string,\n prefix: string,\n signal: AbortSignal,\n ): Promise<{ ucan: string; parentCid: string; expiresAt: number }> {\n if (authority.sessionOnly) throw new Error(\"compact delegate sessions cannot mint device grants\");\n const session = host.replicationSession();\n if (session === undefined) throw new Error(\"replication mint without a session\");\n const entries = replicationEntries(session.spaceId, prefix);\n const plan = planOrRefusal(entries);\n if (\"refused\" in plan) {\n throw Object.assign(\n new Error(`replication authority refused the mint: ${plan.refused}`),\n { refused: plan.refused },\n );\n }\n signal.throwIfAborted();\n const minted = await new Promise<{ ucan: string; expiresAt: number }>((resolve, reject) => {\n const onAbort = (): void => reject(signal.reason ?? new Error(\"replication mint aborted\"));\n signal.addEventListener(\"abort\", onAbort, { once: true });\n host.mintDelegation(deviceDid, entries).then(\n (result) => {\n signal.removeEventListener(\"abort\", onAbort);\n resolve(result);\n },\n (error: unknown) => {\n signal.removeEventListener(\"abort\", onAbort);\n reject(error instanceof Error ? error : new Error(String(error)));\n },\n );\n });\n return { ucan: minted.ucan, parentCid: plan.parentCid, expiresAt: minted.expiresAt };\n },\n };\n return authority;\n}\n","import { assertFolderPrefix as assertPureFolderPrefix, kvPrefixCovers } from \"@tinycloud/sdk-services/kv/replication/prefix\";\nimport type { ReplicationOptions } from \"@tinycloud/sdk-core\";\n\n/** Constructor-time validation; the space-dependent secrets check runs at sign-in and open. */\nexport function assertValidReplicationConfig(\n replication: (ReplicationOptions & { storage?: unknown }) | undefined,\n): void {\n if (replication === undefined || replication.enabled !== true) return;\n if (replication.storage === undefined || replication.storage === null) {\n throw new TypeError(\"replication.enabled requires replication.storage\");\n }\n if (!Array.isArray(replication.prefixes) || replication.prefixes.length === 0) {\n throw new TypeError(\"replication.prefixes must be a non-empty array\");\n }\n for (const prefix of replication.prefixes) {\n try {\n assertPureFolderPrefix(prefix);\n } catch (error) {\n throw new TypeError(error instanceof Error ? error.message : String(error));\n }\n }\n for (const [index, prefix] of replication.prefixes.entries()) {\n for (const other of replication.prefixes.slice(index + 1)) {\n if (kvPrefixCovers(prefix, other) || kvPrefixCovers(other, prefix)) {\n throw new TypeError(\n `replication.prefixes must not overlap: ${JSON.stringify(prefix)} and ${JSON.stringify(other)}`,\n );\n }\n }\n if ((prefix === \"/\" || prefix.split(\"/\", 1)[0] === \"vault\") && replication.allowSecrets !== true) {\n throw new TypeError(\n `replication prefix ${JSON.stringify(prefix)} overlaps the vault namespace; pass allowSecrets to opt in`,\n );\n }\n }\n}\n","import {\n KV,\n isCapabilitySubset,\n type PermissionEntry,\n type ReplicationOptions,\n} from \"@tinycloud/sdk-core\";\nimport { requiresSecretsOptIn } from \"@tinycloud/sdk-services\";\nimport { assertFolderPrefix } from \"@tinycloud/sdk-services/kv/replication/prefix\";\n\nconst KV_GET = KV.GET;\nconst KV_SYNC = KV.SYNC;\nconst KV_SERVICE = \"tinycloud.kv\";\n\nexport function hasUnrestrictedGetCoverage(\n entries: readonly PermissionEntry[],\n spaceId: string,\n prefix: string,\n): boolean {\n return isCapabilitySubset(\n [{ service: KV_SERVICE, space: spaceId, path: prefix, actions: [KV_GET] }],\n [...entries],\n ).subset;\n}\n\nexport function augmentSignInEntriesWithReplication(input: {\n entries: readonly PermissionEntry[];\n primarySpaceId: string;\n replication?: Pick<ReplicationOptions, \"prefixes\" | \"allowSecrets\">;\n}): PermissionEntry[] {\n const out: PermissionEntry[] = [];\n const replication = input.replication;\n if (replication === undefined) return out;\n const eligiblePaths: string[] = [];\n for (const prefix of replication.prefixes) {\n assertFolderPrefix(prefix);\n const path = prefix === \"/\" ? \"\" : prefix;\n if (\n requiresSecretsOptIn(input.primarySpaceId, prefix) &&\n replication.allowSecrets !== true\n ) {\n continue;\n }\n if (!hasUnrestrictedGetCoverage(input.entries, input.primarySpaceId, path)) {\n continue;\n }\n eligiblePaths.push(path);\n }\n if (\n eligiblePaths.length === replication.prefixes.length &&\n eligiblePaths.length > 0 &&\n hasUnrestrictedGetCoverage(input.entries, input.primarySpaceId, \"\")\n ) {\n return [{\n service: KV_SERVICE,\n space: input.primarySpaceId,\n path: \"\",\n actions: [KV_GET, KV_SYNC],\n }];\n }\n for (const path of eligiblePaths) {\n out.push({\n service: KV_SERVICE,\n space: input.primarySpaceId,\n path,\n actions: [KV_GET, KV_SYNC],\n });\n }\n return out;\n}\n"],"mappings":"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","names":["import_sdk_core","assertPureFolderPrefix","import_prefix","replicaParseUcanGrant","KV_GET","KV_SYNC","KV_SERVICE"]}
1
+ {"version":3,"sources":["../../src/replication/authority.ts","../../src/replication/config.ts","../../src/replication/authority-sign-in.ts"],"sourcesContent":["/**\n * Replication authority (TC-858, plan v3 §4).\n *\n * `ReplicationAuthority` answers, per configured prefix, whether this node's\n * session can back a local replica: the session UCAN itself (delegate\n * posture), a child UCAN minted through `delegateTo`, or nothing (the\n * controller then reports `grant_missing` and reads from the network).\n *\n * The unrestricted-authority rule is enforced here, before any network work:\n * a prefix covered only by a caveated `get`/`sync` refuses with\n * `CAVEATED_AUTHORITY` — on the session path, the runtime-grant path, and on\n * any reuse of an installed grant (the adapter marks every grant's\n * `unconstrained` flag; the controller enforces it on reuse).\n */\nimport { SiweMessage } from \"siwe\";\n\nimport {\n actionContains,\n KV,\n canonicalizeRecapCaveats,\n isCapabilitySubset,\n principalDid,\n parseSpaceUri,\n type PermissionEntry,\n type IWasmBindings,\n type WasmRecapEntry,\n type TinyCloudSession,\n type KVReplicaStorage,\n type ServiceContext,\n type ReplicationOptions,\n} from \"@tinycloud/sdk-core\";\nimport {\n type AuthorityRefusal,\n type ReplicaConsentAnchor,\n type ReplicaDevice,\n type ReplicationAuthority,\n type ReplicationEvent,\n} from \"@tinycloud/sdk-services\";\nimport type { ReplicaDenyInput, ReplicaSessionStamp } from \"@tinycloud/sdk-services/kv/replication\";\nimport type { DelegateToOptions, DelegateToResult, TinyCloudNode } from \"../TinyCloudNode\";\nimport type { ReplicaRuntime } from \"./replica-contract\";\n// @ts-ignore -- node-sdk builds before replica declarations; keep the literal import for bundlers.\nimport { parseUcanGrant as replicaParseUcanGrant } from \"@tinycloud/replica\";\nconst parseUcanGrant = replicaParseUcanGrant as ReplicaRuntime[\"parseUcanGrant\"];\nexport { assertValidReplicationConfig } from \"./config\";\nexport { augmentSignInEntriesWithReplication, hasUnrestrictedGetCoverage } from \"./authority-sign-in\";\n\n/** Report a completed deny from the already-loaded authority; delivery was revoked synchronously. */\nexport function reportReplicaDenial(\n result: { status: string; code?: string; intents?: number },\n reason: ReplicaDenyInput[\"reason\"],\n onEvent: ReplicationOptions[\"onEvent\"],\n context?: ServiceContext,\n): void {\n if (result.status !== \"denied\" && result.status !== \"deleted\" && result.status !== \"marker\") return;\n const event: Extract<ReplicationEvent, { type: \"replication.lifecycle\" }> = {\n type: \"replication.lifecycle\",\n at: new Date().toISOString(),\n reason,\n action: result.status === \"denied\" ? \"denied\" : result.status === \"deleted\" ? \"database_deleted\" : \"marker_set\",\n ...(result.status === \"denied\" ? { partitions: result.intents } : {}),\n ...(result.status === \"marker\" ? { code: result.code } : {}),\n };\n try { onEvent?.(event); } catch { /* Observability cannot undo committed denial. */ }\n const { type, ...data } = event;\n try { context?.emit(type, data); } catch { /* Observability cannot undo committed denial. */ }\n}\n\nconst KV_GET = KV.GET;\nconst KV_SYNC = KV.SYNC;\nconst KV_SERVICE = \"tinycloud.kv\";\n\n/** The verified owner proof is signed, finite, exact-space, and uncaveated on one get+sync scope. */\nexport function verifiedOwnerConsentAnchor(\n session: TinyCloudSession,\n wasmBindings: Pick<IWasmBindings, \"validatePersistedSession\">,\n exactVerifiedRecap: (verified: { verifiedRecap?: unknown }) => WasmRecapEntry[],\n): ReplicaConsentAnchor | null {\n if (typeof session.siwe !== \"string\" || typeof session.signature !== \"string\" ||\n typeof session.address !== \"string\" || typeof session.chainId !== \"number\") return null;\n try {\n const verified = wasmBindings.validatePersistedSession?.({\n delegationHeader: session.delegationHeader,\n delegationCid: session.delegationCid,\n spaceId: session.spaceId,\n jwk: session.jwk,\n address: session.address,\n chainId: session.chainId,\n siwe: session.siwe,\n signature: session.signature,\n });\n if (!verified || !Number.isSafeInteger(Date.parse(verified.expiresAt ?? \"\"))) return null;\n const signedIssuedAt = new SiweMessage(session.siwe).issuedAt;\n if (typeof signedIssuedAt !== \"string\") return null;\n const issuedAt = Date.parse(signedIssuedAt);\n if (!Number.isSafeInteger(issuedAt) || issuedAt < 0) return null;\n const granted = exactVerifiedRecap(verified)\n .filter((entry) => entry.space === session.spaceId && entry.service === \"kv\")\n .map((entry) => ({ ...entry, service: \"tinycloud.kv\" }));\n const coversGetAndSync = granted.some((entry) => isCapabilitySubset([{\n service: \"tinycloud.kv\",\n space: session.spaceId,\n path: entry.path,\n actions: [KV.GET, KV.SYNC],\n }], granted).subset);\n return coversGetAndSync ? { at: issuedAt, source: \"siwe\" } : null;\n } catch {\n return null;\n }\n}\n\n/** Fresh sign-in only: the lifecycle creates keys; restore never calls this. */\nexport function establishReplicaSessionStamp(\n storage: KVReplicaStorage,\n principal: string,\n anchor: ReplicaConsentAnchor,\n): Promise<ReplicaSessionStamp> {\n if (storage.kind === \"indexeddb\" && storage.lifecycle?.kind === \"indexeddb\") {\n return storage.lifecycle.establishSessionStamp(principal, { consentAnchor: anchor });\n }\n if (storage.kind === \"sqlite\" && storage.lifecycle?.kind === \"file\") {\n return storage.lifecycle.establishSessionStamp(principal, { consentAnchor: anchor });\n }\n throw Object.assign(new Error(\"Replica sign-in requires its platform lifecycle gate.\"), {\n code: \"REPLICA_GATED\" as const, gate: \"gate_unavailable\" as const,\n });\n}\n\n/** Existing persisted stamp only: never manufactures an authority on restore. */\nexport function restoreReplicaSessionStamp(\n storage: KVReplicaStorage,\n principal: string,\n persisted: ReplicaSessionStamp | undefined,\n): Promise<ReplicaSessionStamp> {\n if (storage.kind === \"indexeddb\" && storage.lifecycle?.kind === \"indexeddb\") {\n return storage.lifecycle.restoreSessionStamp(principal, persisted);\n }\n if (storage.kind === \"sqlite\" && storage.lifecycle?.kind === \"file\") {\n return storage.lifecycle.restoreSessionStamp(principal, persisted);\n }\n throw Object.assign(new Error(\"Replica restore requires its platform lifecycle gate.\"), {\n code: \"REPLICA_GATED\" as const, gate: \"gate_unavailable\" as const,\n });\n}\n\n/** The delegation the replication grant delegates: get + sync on one folder prefix. */\nfunction replicationEntries(spaceId: string, prefix: string): PermissionEntry[] {\n return [{\n service: KV_SERVICE,\n space: spaceId,\n path: prefix === \"/\" ? \"\" : prefix,\n actions: [KV_GET, KV_SYNC],\n }];\n}\n\n\n\n\n/**\n * The signed UCAN attenuation (`att`: resource → ability → caveat branches).\n * Only array branch sets are known; anything else is treated as constrained —\n * fail closed, never assume unconstrained.\n */\nfunction caveatBranchesUnconstrained(value: unknown): boolean {\n if (value === undefined || value === null) return true;\n if (typeof value === \"object\" && !Array.isArray(value) && Object.keys(value).length === 0) {\n return true;\n }\n if (!Array.isArray(value)) return false;\n try {\n return (\n canonicalizeRecapCaveats(value as Record<string, unknown>[]) ===\n canonicalizeRecapCaveats(undefined)\n );\n } catch {\n return false;\n }\n}\n\n/** The KV path a signed UCAN resource names in `space`, like replica's `kvPathIn`. */\nfunction kvPathInResource(resource: string, space: string): string | undefined {\n for (const root of [`${space}/kv`, `tinycloud://${space}/kv`]) {\n if (resource === root || resource === `${root}/`) return \"/\";\n }\n for (const base of [`${space}/kv/`, `tinycloud://${space}/kv/`]) {\n if (resource.startsWith(base)) return resource.slice(base.length);\n }\n return undefined;\n\n}\n/**\n * Whether the signed `att` grants `ability` over the folder prefix, with\n * unrestricted authority unless explicitly asked to ignore caveats.\n */\nexport function ucanAttCovers(\n att: Record<string, Record<string, unknown>>,\n space: string,\n prefix: string,\n ability: string,\n options?: { ignoreCaveats?: boolean },\n): boolean {\n for (const [resource, abilities] of Object.entries(att)) {\n const path = kvPathInResource(resource, space);\n if (path === undefined) continue;\n for (const [granted, caveats] of Object.entries(abilities)) {\n if (!actionContains(granted, ability)) continue;\n if (!isCapabilitySubset(\n [{ service: KV_SERVICE, space, path: prefix, actions: [ability] }],\n [{ service: KV_SERVICE, space, path, actions: [granted] }],\n ).subset) continue;\n if (options?.ignoreCaveats === true || caveatBranchesUnconstrained(caveats)) return true;\n }\n }\n return false;\n}\n\n/** `unconstrained` for `ReplicaGrantInfo` (§2.1): get AND sync on the prefix carry no caveats. */\nexport function ucanAttUnconstrainedFor(\n att: Record<string, Record<string, unknown>>,\n space: string,\n prefix: string,\n): boolean {\n return (\n ucanAttCovers(att, space, prefix, KV_GET) &&\n ucanAttCovers(att, space, prefix, KV_SYNC)\n );\n}\n\nexport interface DelegationPlanResult {\n path: \"session\" | \"runtime\";\n parentCid: string;\n expiresAt: number;\n}\n\n/**\n * The `TinyCloudNode` internals the authority needs. `planDelegation` is the\n * pure extraction of `delegateTo`'s parent selection (§4.3), so `plan` and\n * `mint` can never disagree about which parent or expiry a delegation gets.\n */\nexport type ReplicationAuthoritySession = Pick<\n TinyCloudSession,\n \"delegationHeader\" | \"delegationCid\" | \"spaceId\" | \"verificationMethod\" | \"jwk\"\n> & Partial<Pick<TinyCloudSession, \"siwe\" | \"signature\" | \"address\" | \"chainId\">>;\n\nexport interface ReplicationAuthorityHost {\n replicationSession(): ReplicationAuthoritySession | undefined;\n /** Validated owner proof only; never infer consent from a compact child UCAN. */\n verifiedConsentAnchor?(session: ReplicationAuthoritySession): ReplicaConsentAnchor | null;\n /** The SIWE \"Expiration Time\" of the session — the delegateTo delegation cap. */\n siweExpiration(siwe: string): Date | undefined;\n planDelegation(\n entries: PermissionEntry[],\n options?: { expiry?: string | number },\n ): ({ grant?: unknown } & DelegationPlanResult) | AuthorityRefusal;\n mintDelegation(\n deviceDid: string,\n entries: PermissionEntry[],\n options?: { expiryMs?: number; renewalOnly?: boolean },\n ): Promise<{ ucan: string; expiresAt: number }>;\n}\n\n/** Delegate a replica grant only through the selected owner parent for silent renewal. */\nexport async function mintNodeReplicationGrant(\n deviceDid: string,\n entries: PermissionEntry[],\n options: { expiryMs?: number; renewalOnly?: boolean } | undefined,\n renewalSession: ReplicationAuthoritySession | undefined,\n node: Pick<TinyCloudNode, \"delegateTo\">,\n): Promise<{ ucan: string; expiresAt: number }> {\n if (options?.renewalOnly && !renewalSession) throw new Error(\"replication renewal lost its owner session\");\n const delegateOptions: DelegateToOptions | undefined = options?.renewalOnly ? {\n expiry: options.expiryMs,\n onPrepared: async (prepared) => {\n assertRenewalParent(prepared.delegationHeader.Authorization, renewalSession!);\n },\n } : options?.expiryMs === undefined ? undefined : { expiry: options.expiryMs };\n const result: DelegateToResult = await node.delegateTo(principalDid(deviceDid), entries, delegateOptions);\n return {\n ucan: result.delegation.delegationHeader.Authorization,\n expiresAt: result.delegation.expiry.getTime(),\n };\n}\n\n/** Milliseconds of validity a session or parent must have left for authority reuse (delegateTo's margin). */\nexport const AUTHORITY_EXPIRY_MARGIN_MS = 60_000;\n\n\n/** Verify a compact session delegation before using any persisted space metadata. */\nexport function replicationScopeFromSignedSession(input: {\n delegationHeader: { Authorization: string };\n delegationCid: string;\n verificationMethod: string;\n persistedSpace: string;\n}): { space: string; principal: string } | undefined {\n let grant: ReturnType<typeof parseUcanGrant>;\n try {\n grant = parseUcanGrant(input.delegationHeader.Authorization);\n } catch {\n return undefined;\n }\n const bareDid = (value: string): string => value.split(\"#\", 1)[0]!;\n if (\n grant.cid !== input.delegationCid ||\n bareDid(grant.audience) !== bareDid(input.verificationMethod)\n ) return undefined;\n for (const resource of Object.keys(grant.att)) {\n const space = resource.match(/^(?:tinycloud:\\/\\/)?(.+?)\\/kv(?:\\/|$)/)?.[1];\n if (space !== input.persistedSpace) continue;\n const owner = parseSpaceUri(space);\n if (owner?.owner && owner.address && owner.chainId) return { space, principal: owner.owner };\n }\n return undefined;\n}\n/** Runs before host activation; a replan cannot silently switch a renewal to a runtime parent. */\nexport function assertRenewalParent(authorization: string, session: ReplicationAuthoritySession): void {\n const grant = parseUcanGrant(authorization);\n if (\n grant.issuer !== session.verificationMethod.split(\"#\", 1)[0] ||\n grant.prf.length !== 1 ||\n grant.prf[0] !== session.delegationCid\n ) {\n throw Object.assign(new Error(\"replication renewal requires the bound owner session parent\"), { refused: \"NOT_COVERED\" as const });\n }\n}\n\nexport function createReplicationAuthority(host: ReplicationAuthorityHost): ReplicationAuthority {\n const boundSession = host.replicationSession();\n let verifiedAnchor: ReplicaConsentAnchor | null = null;\n try {\n const candidate = boundSession && host.verifiedConsentAnchor?.(boundSession);\n if (candidate && Number.isFinite(candidate.at) && candidate.source !== \"first_install\") {\n verifiedAnchor = { at: candidate.at, source: candidate.source };\n }\n } catch {\n // Network sessions remain usable when the optional replica proof cannot be verified.\n }\n const activeSession = (): ReplicationAuthoritySession | undefined => {\n const session = host.replicationSession();\n return session !== undefined && session === boundSession ? session : undefined;\n };\n const planOrRefusal = (entries: PermissionEntry[], expiryMs?: number): DelegationPlanResult | AuthorityRefusal => {\n const plan = host.planDelegation(entries, expiryMs === undefined ? undefined : { expiry: expiryMs });\n if (\"refused\" in plan) return plan;\n return { path: plan.path, parentCid: plan.parentCid, expiresAt: plan.expiresAt };\n };\n const sessionAudience = (value: string): string => value.split(\"#\", 1)[0]!;\n const signedSessionGrant = (session: ReplicationAuthoritySession) => {\n const grant = parseUcanGrant(session.delegationHeader.Authorization);\n if (\n grant.cid !== session.delegationCid ||\n sessionAudience(grant.audience) !== sessionAudience(session.verificationMethod)\n ) return undefined;\n return grant;\n };\n const authority: ReplicationAuthority = {\n get sessionOnly() {\n const session = activeSession();\n return session === undefined || session.siwe === undefined;\n },\n consentAnchor(): ReplicaConsentAnchor | null {\n return activeSession() ? verifiedAnchor : null;\n },\n get canRenew() {\n const session = activeSession();\n return verifiedAnchor?.source === \"siwe\" && session !== undefined && session.siwe !== undefined;\n },\n sessionGrant(prefix: string): { ucan: string; device: ReplicaDevice } | AuthorityRefusal {\n const session = activeSession();\n if (session === undefined) return { refused: \"SESSION_EXPIRING\" };\n // A compact session proves current signed coverage, not consent to install or mint.\n if (verifiedAnchor === null && session.siwe !== undefined) return { refused: \"NOT_COVERED\" };\n const siweExpiry = session.siwe ? host.siweExpiration(session.siwe)?.getTime() : undefined;\n if (siweExpiry !== undefined && siweExpiry <= Date.now() + AUTHORITY_EXPIRY_MARGIN_MS) {\n return { refused: \"SESSION_EXPIRING\" };\n }\n let grant: ReturnType<typeof parseUcanGrant>;\n try {\n const verified = signedSessionGrant(session);\n if (!verified) return { refused: \"NOT_COVERED\" };\n grant = verified;\n } catch {\n return { refused: \"NOT_COVERED\" };\n }\n const tokenExpiry = grant.expiresAt === null ? undefined : grant.expiresAt * 1000;\n if (tokenExpiry === undefined || tokenExpiry <= Date.now() + AUTHORITY_EXPIRY_MARGIN_MS) {\n return { refused: \"SESSION_EXPIRING\" };\n }\n const covered = ucanAttCovers(grant.att, session.spaceId, prefix, KV_GET, { ignoreCaveats: true }) &&\n ucanAttCovers(grant.att, session.spaceId, prefix, KV_SYNC, { ignoreCaveats: true });\n if (!covered) return { refused: \"NOT_COVERED\" };\n if (!ucanAttUnconstrainedFor(grant.att, session.spaceId, prefix)) {\n return { refused: \"CAVEATED_AUTHORITY\" };\n }\n return {\n ucan: grant.jwt,\n device: { did: session.verificationMethod, jwk: session.jwk },\n };\n },\n plan(prefix: string): DelegationPlanResult | AuthorityRefusal {\n const session = activeSession();\n if (session === undefined) return { refused: \"SESSION_EXPIRING\" };\n if (verifiedAnchor === null) return { refused: \"NOT_COVERED\" };\n const sessionGrant = this.sessionGrant(prefix);\n if (!(\"refused\" in sessionGrant)) {\n const signed = signedSessionGrant(session);\n if (!signed || signed.expiresAt === null) return { refused: \"NOT_COVERED\" };\n return {\n path: \"session\",\n parentCid: session.delegationCid,\n expiresAt: signed.expiresAt * 1000,\n };\n }\n if (authority.sessionOnly) return sessionGrant;\n return planOrRefusal(replicationEntries(session.spaceId, prefix));\n },\n async mint(\n deviceDid: string,\n prefix: string,\n signal: AbortSignal,\n options?: { expiryMs?: number; renewalOnly?: boolean },\n ): Promise<{ ucan: string; parentCid: string; expiresAt: number }> {\n const session = activeSession();\n if (session === undefined) throw new Error(\"replication mint without the bound session\");\n if (session.siwe === undefined) throw new Error(\"compact delegate sessions cannot mint device grants\");\n if (verifiedAnchor?.source !== \"siwe\") throw new Error(\"replication mint requires verified owner consent\");\n const entries = replicationEntries(session.spaceId, prefix);\n const plan = planOrRefusal(entries, options?.expiryMs);\n if (\"refused\" in plan) {\n throw Object.assign(\n new Error(`replication authority refused the mint: ${plan.refused}`),\n { refused: plan.refused },\n );\n }\n if (options?.renewalOnly && plan.path !== \"session\") {\n throw Object.assign(new Error(\"replication renewal requires a session parent\"), { refused: \"NOT_COVERED\" as const });\n }\n signal.throwIfAborted();\n const minted = await new Promise<{ ucan: string; expiresAt: number }>((resolve, reject) => {\n const onAbort = (): void => reject(signal.reason ?? new Error(\"replication mint aborted\"));\n signal.addEventListener(\"abort\", onAbort, { once: true });\n host.mintDelegation(deviceDid, entries, options).then(\n (result) => {\n signal.removeEventListener(\"abort\", onAbort);\n resolve(result);\n },\n (error: unknown) => {\n signal.removeEventListener(\"abort\", onAbort);\n reject(error instanceof Error ? error : new Error(String(error)));\n },\n );\n });\n return { ucan: minted.ucan, parentCid: plan.parentCid, expiresAt: minted.expiresAt };\n },\n };\n return authority;\n}\n","import { MAX_GRANT_TTL_MS } from \"@tinycloud/sdk-services/kv/replication/grantPolicyConstants\";\nimport { assertFolderPrefix as assertPureFolderPrefix, kvPrefixCovers } from \"@tinycloud/sdk-services/kv/replication/prefix\";\nimport type { ReplicationOptions } from \"@tinycloud/sdk-core\";\n\n/** Constructor-time validation; the space-dependent secrets check runs at sign-in and open. */\nexport function assertValidReplicationConfig(\n replication: (ReplicationOptions & { storage?: unknown }) | undefined,\n): void {\n if (replication === undefined || !replication.enabled) return;\n if (replication.storage === undefined || replication.storage === null) {\n throw new TypeError(\"replication.enabled requires replication.storage\");\n }\n if (!Array.isArray(replication.prefixes) || replication.prefixes.length === 0) {\n throw new TypeError(\"replication.prefixes must be a non-empty array\");\n }\n const grantTtlMs = replication.grantTtlMs;\n if (grantTtlMs !== undefined && (!Number.isFinite(grantTtlMs) || grantTtlMs <= 0 || grantTtlMs > MAX_GRANT_TTL_MS)) {\n throw new TypeError(`replication.grantTtlMs must be a positive number of milliseconds no greater than ${MAX_GRANT_TTL_MS}`);\n }\n for (const prefix of replication.prefixes) {\n try {\n assertPureFolderPrefix(prefix);\n } catch (error) {\n throw new TypeError(error instanceof Error ? error.message : String(error));\n }\n }\n for (const [index, prefix] of replication.prefixes.entries()) {\n for (const other of replication.prefixes.slice(index + 1)) {\n if (kvPrefixCovers(prefix, other) || kvPrefixCovers(other, prefix)) {\n throw new TypeError(\n `replication.prefixes must not overlap: ${JSON.stringify(prefix)} and ${JSON.stringify(other)}`,\n );\n }\n }\n if ((prefix === \"/\" || prefix.split(\"/\", 1)[0] === \"vault\") && replication.allowSecrets !== true) {\n throw new TypeError(\n `replication prefix ${JSON.stringify(prefix)} overlaps the vault namespace; pass allowSecrets to opt in`,\n );\n }\n }\n}\n","import {\n KV,\n isCapabilitySubset,\n type PermissionEntry,\n type ReplicationOptions,\n} from \"@tinycloud/sdk-core\";\nimport { requiresSecretsOptIn } from \"@tinycloud/sdk-services\";\nimport { assertFolderPrefix } from \"@tinycloud/sdk-services/kv/replication/prefix\";\n\nconst KV_GET = KV.GET;\nconst KV_SYNC = KV.SYNC;\nconst KV_SERVICE = \"tinycloud.kv\";\n\nexport function hasUnrestrictedGetCoverage(\n entries: readonly PermissionEntry[],\n spaceId: string,\n prefix: string,\n): boolean {\n return isCapabilitySubset(\n [{ service: KV_SERVICE, space: spaceId, path: prefix, actions: [KV_GET] }],\n [...entries],\n ).subset;\n}\n\nexport function augmentSignInEntriesWithReplication(input: {\n entries: readonly PermissionEntry[];\n primarySpaceId: string;\n replication?: Pick<ReplicationOptions, \"prefixes\" | \"allowSecrets\">;\n}): PermissionEntry[] {\n const out: PermissionEntry[] = [];\n const replication = input.replication;\n if (replication === undefined) return out;\n const eligiblePaths: string[] = [];\n for (const prefix of replication.prefixes) {\n assertFolderPrefix(prefix);\n const path = prefix === \"/\" ? \"\" : prefix;\n if (\n requiresSecretsOptIn(input.primarySpaceId, prefix) &&\n replication.allowSecrets !== true\n ) {\n continue;\n }\n if (!hasUnrestrictedGetCoverage(input.entries, input.primarySpaceId, path)) {\n continue;\n }\n eligiblePaths.push(path);\n }\n if (\n eligiblePaths.length === replication.prefixes.length &&\n eligiblePaths.length > 0 &&\n hasUnrestrictedGetCoverage(input.entries, input.primarySpaceId, \"\")\n ) {\n return [{\n service: KV_SERVICE,\n space: input.primarySpaceId,\n path: \"\",\n actions: [KV_GET, KV_SYNC],\n }];\n }\n for (const path of eligiblePaths) {\n out.push({\n service: KV_SERVICE,\n space: input.primarySpaceId,\n path,\n actions: [KV_GET, KV_SYNC],\n });\n }\n return out;\n}\n"],"mappings":"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","names":["import_sdk_core","assertPureFolderPrefix","import_prefix","replicaParseUcanGrant","KV_GET","KV_SYNC","KV_SERVICE"]}
@@ -1,3 +1,6 @@
1
1
  import '@tinycloud/sdk-core';
2
2
  import '@tinycloud/sdk-services';
3
- export { A as AUTHORITY_EXPIRY_MARGIN_MS, D as DelegationPlanResult, R as ReplicationAuthorityHost, a as ReplicationAuthoritySession, b as assertValidReplicationConfig, c as augmentSignInEntriesWithReplication, d as createReplicationAuthority, h as hasUnrestrictedGetCoverage, r as replicationScopeFromSignedSession, u as ucanAttCovers, e as ucanAttUnconstrainedFor } from '../authority-DDGtccBK.cjs';
3
+ import '@tinycloud/sdk-services/kv/replication';
4
+ import '../TinyCloudNode-CcNh20QX.cjs';
5
+ export { A as AUTHORITY_EXPIRY_MARGIN_MS, D as DelegationPlanResult, R as ReplicationAuthorityHost, a as ReplicationAuthoritySession, b as assertRenewalParent, c as assertValidReplicationConfig, d as augmentSignInEntriesWithReplication, e as createReplicationAuthority, f as establishReplicaSessionStamp, h as hasUnrestrictedGetCoverage, m as mintNodeReplicationGrant, r as replicationScopeFromSignedSession, g as reportReplicaDenial, i as restoreReplicaSessionStamp, u as ucanAttCovers, j as ucanAttUnconstrainedFor, v as verifiedOwnerConsentAnchor } from '../authority-Cwotwza3.cjs';
6
+ import 'events';
@@ -1,3 +1,6 @@
1
1
  import '@tinycloud/sdk-core';
2
2
  import '@tinycloud/sdk-services';
3
- export { A as AUTHORITY_EXPIRY_MARGIN_MS, D as DelegationPlanResult, R as ReplicationAuthorityHost, a as ReplicationAuthoritySession, b as assertValidReplicationConfig, c as augmentSignInEntriesWithReplication, d as createReplicationAuthority, h as hasUnrestrictedGetCoverage, r as replicationScopeFromSignedSession, u as ucanAttCovers, e as ucanAttUnconstrainedFor } from '../authority-DDGtccBK.js';
3
+ import '@tinycloud/sdk-services/kv/replication';
4
+ import '../TinyCloudNode-CcNh20QX.js';
5
+ export { A as AUTHORITY_EXPIRY_MARGIN_MS, D as DelegationPlanResult, R as ReplicationAuthorityHost, a as ReplicationAuthoritySession, b as assertRenewalParent, c as assertValidReplicationConfig, d as augmentSignInEntriesWithReplication, e as createReplicationAuthority, f as establishReplicaSessionStamp, h as hasUnrestrictedGetCoverage, m as mintNodeReplicationGrant, r as replicationScopeFromSignedSession, g as reportReplicaDenial, i as restoreReplicaSessionStamp, u as ucanAttCovers, j as ucanAttUnconstrainedFor, v as verifiedOwnerConsentAnchor } from '../authority-D_u9a7Wl.js';
6
+ import 'events';