@tinycloud/sdk-core 3.1.0-beta.8 → 3.1.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.
- package/dist/{credential-admission-CFsYiCPH.d.ts → credential-admission-BaP4pdpy.d.ts} +13 -5
- package/dist/{credential-admission-Cfum4B79.d.cts → credential-admission-ohx0XnQr.d.cts} +13 -5
- package/dist/delegations/index.cjs +32 -14
- package/dist/delegations/index.cjs.map +1 -1
- package/dist/delegations/index.d.cts +29 -29
- package/dist/delegations/index.d.ts +29 -29
- package/dist/delegations/index.js +32 -14
- package/dist/delegations/index.js.map +1 -1
- package/dist/index.cjs +111 -14
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +30 -17
- package/dist/index.d.ts +30 -17
- package/dist/index.js +113 -14
- package/dist/index.js.map +1 -1
- package/dist/policy/index.cjs +27 -0
- package/dist/policy/index.cjs.map +1 -1
- package/dist/policy/index.d.cts +2 -2
- package/dist/policy/index.d.ts +2 -2
- package/dist/policy/index.js +27 -0
- package/dist/policy/index.js.map +1 -1
- package/dist/{recipient-types.schema-B5vpbtf-.d.cts → recipient-types.schema-D-IMys0b.d.cts} +181 -178
- package/dist/{recipient-types.schema-B5vpbtf-.d.ts → recipient-types.schema-D-IMys0b.d.ts} +181 -178
- package/package.json +5 -5
package/dist/index.cjs
CHANGED
|
@@ -43,6 +43,7 @@ __export(index_exports, {
|
|
|
43
43
|
ACCOUNT_MANIFEST_PERMISSIONS: () => import_bootstrap4.ACCOUNT_MANIFEST_PERMISSIONS,
|
|
44
44
|
ACCOUNT_REGISTRY_PATH: () => ACCOUNT_REGISTRY_PATH,
|
|
45
45
|
ACCOUNT_REGISTRY_SPACE: () => ACCOUNT_REGISTRY_SPACE,
|
|
46
|
+
AGENTS_SPACE: () => import_bootstrap4.AGENTS_SPACE,
|
|
46
47
|
ATTESTED_ENFORCER_BINDING_V2_SCHEMA: () => ATTESTED_ENFORCER_BINDING_V2_SCHEMA,
|
|
47
48
|
AccountService: () => AccountService,
|
|
48
49
|
AutoApproveSpaceCreationHandler: () => AutoApproveSpaceCreationHandler,
|
|
@@ -215,6 +216,7 @@ __export(index_exports, {
|
|
|
215
216
|
SpaceErrorCodes: () => SpaceErrorCodes,
|
|
216
217
|
SpaceService: () => SpaceService,
|
|
217
218
|
TINYCLOUD_ACCOUNT_SPACE_MANIFEST: () => import_bootstrap4.TINYCLOUD_ACCOUNT_SPACE_MANIFEST,
|
|
219
|
+
TINYCLOUD_AGENTS_SPACE_MANIFEST: () => import_bootstrap4.TINYCLOUD_AGENTS_SPACE_MANIFEST,
|
|
218
220
|
TINYCLOUD_APPLICATIONS_SPACE_MANIFEST: () => import_bootstrap4.TINYCLOUD_APPLICATIONS_SPACE_MANIFEST,
|
|
219
221
|
TINYCLOUD_CANONICAL_IDENTITY_CLAIM: () => TINYCLOUD_CANONICAL_IDENTITY_CLAIM,
|
|
220
222
|
TINYCLOUD_DEFAULT_SPACE_MANIFEST: () => import_bootstrap4.TINYCLOUD_DEFAULT_SPACE_MANIFEST,
|
|
@@ -359,6 +361,7 @@ __export(index_exports, {
|
|
|
359
361
|
isCapabilitySubset: () => isCapabilitySubset,
|
|
360
362
|
isDigest: () => isDigest,
|
|
361
363
|
isEvmAddress: () => isEvmAddress,
|
|
364
|
+
isExplicitOnlyAction: () => isExplicitOnlyAction,
|
|
362
365
|
isNetworkId: () => import_sdk_services9.isNetworkId,
|
|
363
366
|
isPlausibleOpenKeyActionId: () => isPlausibleOpenKeyActionId,
|
|
364
367
|
isStorageFullError: () => import_sdk_services9.isStorageFullError,
|
|
@@ -397,6 +400,7 @@ __export(index_exports, {
|
|
|
397
400
|
parseSecretCatalogKey: () => import_sdk_services9.parseSecretCatalogKey,
|
|
398
401
|
parseShareArtifact: () => parseShareArtifact,
|
|
399
402
|
parseShareUrl: () => parseShareUrl,
|
|
403
|
+
parseSignedCompactUcanAttenuation: () => parseSignedCompactUcanAttenuation,
|
|
400
404
|
parseSpaceUri: () => parseSpaceUri,
|
|
401
405
|
pkhDid: () => pkhDid,
|
|
402
406
|
policyCidFromCanonicalBytes: () => policyCidFromCanonicalBytes,
|
|
@@ -4679,6 +4683,32 @@ function parseCompactUcanAuthorization(input, expectedCid) {
|
|
|
4679
4683
|
throw new Error("compact UCAN CID does not match exact Authorization bytes");
|
|
4680
4684
|
return { authorization: input, cid: cid2, header, payload };
|
|
4681
4685
|
}
|
|
4686
|
+
var SignedCompactAttenuationSchema = import_zod2.z.record(import_zod2.z.record(import_zod2.z.array(import_zod2.z.unknown()).min(1)));
|
|
4687
|
+
function parseSignedCompactUcanAttenuation(input, expectedCid) {
|
|
4688
|
+
if (typeof input !== "string" || /\s/.test(input))
|
|
4689
|
+
throw new Error("Authorization must be compact UCAN bytes");
|
|
4690
|
+
const segments = input.split(".");
|
|
4691
|
+
if (segments.length !== 3 || segments.some((segment) => segment.length === 0))
|
|
4692
|
+
throw new Error("Authorization must have three compact segments");
|
|
4693
|
+
const [headerSegment, payloadSegment, signatureSegment] = segments;
|
|
4694
|
+
const headerValue = JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(decodeBase64Url2(headerSegment)));
|
|
4695
|
+
const payloadValue = JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(decodeBase64Url2(payloadSegment)));
|
|
4696
|
+
if (!isRecordValue(headerValue) || !isRecordValue(headerValue.jwk) || headerValue.alg !== "EdDSA" || headerValue.typ !== "JWT" || headerValue.ucv !== "0.10.0" || headerValue.jwk.kty !== "OKP" || headerValue.jwk.crv !== "Ed25519" || !isRecordValue(payloadValue) || typeof payloadValue.iss !== "string")
|
|
4697
|
+
throw new Error("Authorization has an invalid signed UCAN header or issuer");
|
|
4698
|
+
const att = SignedCompactAttenuationSchema.parse(payloadValue.att);
|
|
4699
|
+
const principal = payloadValue.iss.split("#", 1)[0];
|
|
4700
|
+
const didMaterial = principal.startsWith("did:key:") ? base58btc.decode(principal.slice("did:key:".length)) : new Uint8Array();
|
|
4701
|
+
const publicKey = didMaterial.length === 34 && didMaterial[0] === 237 && didMaterial[1] === 1 ? didMaterial.slice(2) : new Uint8Array();
|
|
4702
|
+
const jwkKey = typeof headerValue.jwk.x === "string" ? decodeBase64Url2(headerValue.jwk.x) : new Uint8Array();
|
|
4703
|
+
if (publicKey.length !== 32 || !equalBytes(publicKey, jwkKey))
|
|
4704
|
+
throw new Error("compact UCAN JWK does not bind issuer");
|
|
4705
|
+
const signature = decodeBase64Url2(signatureSegment);
|
|
4706
|
+
if (!import_ed255193.ed25519.verify(signature, new TextEncoder().encode(`${headerSegment}.${payloadSegment}`), publicKey))
|
|
4707
|
+
throw new Error("compact UCAN signature is invalid");
|
|
4708
|
+
const cid2 = CID.createV1(85, create(30, (0, import_blake3.blake3)(new TextEncoder().encode(input)))).toString();
|
|
4709
|
+
if (expectedCid !== void 0 && cid2 !== expectedCid) throw new Error("compact UCAN CID does not match exact Authorization bytes");
|
|
4710
|
+
return { cid: cid2, payload: { att } };
|
|
4711
|
+
}
|
|
4682
4712
|
function parsePolicySessionUcan(authorization, expectedProofs) {
|
|
4683
4713
|
const parsed = parseCompactUcanAuthorization(authorization);
|
|
4684
4714
|
const fact = parsed.payload.fct[0];
|
|
@@ -7166,7 +7196,7 @@ var DelegationManager = class {
|
|
|
7166
7196
|
* }
|
|
7167
7197
|
* ```
|
|
7168
7198
|
*/
|
|
7169
|
-
async revoke(cid2) {
|
|
7199
|
+
async revoke(cid2, options2) {
|
|
7170
7200
|
if (!cid2) {
|
|
7171
7201
|
return {
|
|
7172
7202
|
ok: false,
|
|
@@ -7186,15 +7216,20 @@ var DelegationManager = class {
|
|
|
7186
7216
|
)
|
|
7187
7217
|
};
|
|
7188
7218
|
}
|
|
7189
|
-
const
|
|
7190
|
-
|
|
7191
|
-
|
|
7192
|
-
|
|
7193
|
-
|
|
7194
|
-
|
|
7195
|
-
|
|
7196
|
-
|
|
7197
|
-
|
|
7219
|
+
const entry = {
|
|
7220
|
+
resource: `urn:cid:${cid2}`,
|
|
7221
|
+
...options2?.targetSpaceId === void 0 ? {} : { spaceId: options2.targetSpaceId },
|
|
7222
|
+
service: "delegation",
|
|
7223
|
+
path: "",
|
|
7224
|
+
action: DelegationAction.REVOKE
|
|
7225
|
+
};
|
|
7226
|
+
if (options2?.authorityCid !== void 0) {
|
|
7227
|
+
Object.defineProperty(entry, "revokeAuthorityCid", {
|
|
7228
|
+
value: options2.authorityCid,
|
|
7229
|
+
enumerable: false
|
|
7230
|
+
});
|
|
7231
|
+
}
|
|
7232
|
+
const headers = this.invokeAny(this.session, [entry]);
|
|
7198
7233
|
const response = await this.fetchFn(`${this.host}/revoke`, {
|
|
7199
7234
|
method: "POST",
|
|
7200
7235
|
headers
|
|
@@ -7352,7 +7387,8 @@ var DelegationManager = class {
|
|
|
7352
7387
|
)
|
|
7353
7388
|
};
|
|
7354
7389
|
}
|
|
7355
|
-
|
|
7390
|
+
const accountSpaceId = this.accountSpaceId;
|
|
7391
|
+
if (!accountSpaceId) {
|
|
7356
7392
|
return {
|
|
7357
7393
|
ok: false,
|
|
7358
7394
|
error: createError(
|
|
@@ -7363,7 +7399,7 @@ var DelegationManager = class {
|
|
|
7363
7399
|
}
|
|
7364
7400
|
try {
|
|
7365
7401
|
const invocationHeaders = this.invokeAny(this.session, [{
|
|
7366
|
-
spaceId:
|
|
7402
|
+
spaceId: accountSpaceId,
|
|
7367
7403
|
service: "delegation",
|
|
7368
7404
|
path: "",
|
|
7369
7405
|
action: DelegationAction.LIST
|
|
@@ -8661,8 +8697,17 @@ function canonicalizeRecapCaveats(caveats) {
|
|
|
8661
8697
|
}
|
|
8662
8698
|
return `[${branches.join(",")}]`;
|
|
8663
8699
|
}
|
|
8700
|
+
var EXPLICIT_ONLY_ACTIONS = {
|
|
8701
|
+
"tinycloud.kv/sync": true,
|
|
8702
|
+
"tinycloud.kv/retain": true
|
|
8703
|
+
};
|
|
8704
|
+
function isExplicitOnlyAction(action) {
|
|
8705
|
+
return Object.prototype.hasOwnProperty.call(EXPLICIT_ONLY_ACTIONS, action);
|
|
8706
|
+
}
|
|
8664
8707
|
function actionContains(grantedAction, requestedAction) {
|
|
8665
|
-
if (grantedAction ===
|
|
8708
|
+
if (grantedAction === requestedAction) return true;
|
|
8709
|
+
if (isExplicitOnlyAction(requestedAction)) return false;
|
|
8710
|
+
if (grantedAction === "*") return true;
|
|
8666
8711
|
if (!grantedAction.endsWith("/*")) return false;
|
|
8667
8712
|
const service = grantedAction.slice(0, -2);
|
|
8668
8713
|
return requestedAction === service || requestedAction.startsWith(`${service}/`);
|
|
@@ -11345,7 +11390,9 @@ var SharingService = class {
|
|
|
11345
11390
|
if (delegation.allowSubDelegation === false) continue;
|
|
11346
11391
|
if (!this.pathMatches(delegation.path || "", path)) continue;
|
|
11347
11392
|
const delegationActions = delegation.actions || [];
|
|
11348
|
-
if (!actions.every(
|
|
11393
|
+
if (!actions.every(
|
|
11394
|
+
(action) => delegationActions.some((granted) => actionContains(granted, action))
|
|
11395
|
+
)) {
|
|
11349
11396
|
continue;
|
|
11350
11397
|
}
|
|
11351
11398
|
if ((delegation.caveats?.length ?? 0) > 0) {
|
|
@@ -14396,6 +14443,56 @@ var AccountService = class {
|
|
|
14396
14443
|
await this.upsertSpacesIndexQuietly(registered);
|
|
14397
14444
|
return (0, import_sdk_services7.ok)({ spaces: registered, recoveredFromBatchError: batchResult.error });
|
|
14398
14445
|
},
|
|
14446
|
+
/**
|
|
14447
|
+
* Register only spaces without a registry record (TC-800). Existing
|
|
14448
|
+
* records, including renamed or archived ones, are kept byte-for-byte.
|
|
14449
|
+
* Bootstrap repair uses this on populated accounts.
|
|
14450
|
+
*/
|
|
14451
|
+
registerMissing: async (spaces) => {
|
|
14452
|
+
if (spaces.length === 0) return (0, import_sdk_services7.ok)([]);
|
|
14453
|
+
await this.config.ensureAccountSpaceHosted?.();
|
|
14454
|
+
const kvResult = this.accountKV();
|
|
14455
|
+
if (!kvResult.ok) return kvResult;
|
|
14456
|
+
const kv = kvResult.data;
|
|
14457
|
+
const stored = spaces.map((space) => spaceRecordFromInput(space));
|
|
14458
|
+
const keys = stored.map((record2) => spaceKey(record2.space_id));
|
|
14459
|
+
const read2 = await kv.batchGet(keys);
|
|
14460
|
+
if (!read2.ok) return accountErr(read2.error);
|
|
14461
|
+
const byKey = new Map(read2.data.results.map((result) => [result.key, result.result]));
|
|
14462
|
+
const final = new Array(keys.length);
|
|
14463
|
+
const missing = [];
|
|
14464
|
+
for (let i = 0; i < keys.length; i++) {
|
|
14465
|
+
const key = keys[i];
|
|
14466
|
+
const result = byKey.get(key);
|
|
14467
|
+
if (!result) {
|
|
14468
|
+
return (0, import_sdk_services7.err)((0, import_sdk_services7.serviceError)(
|
|
14469
|
+
import_sdk_services7.ErrorCodes.NETWORK_ERROR,
|
|
14470
|
+
`KV batch read omitted requested key ${JSON.stringify(key)}`,
|
|
14471
|
+
SERVICE_NAME2
|
|
14472
|
+
));
|
|
14473
|
+
}
|
|
14474
|
+
if (result.ok) {
|
|
14475
|
+
final[i] = spaceFromRecord(key, result.data.data);
|
|
14476
|
+
} else if (result.error.code === import_sdk_services7.ErrorCodes.KV_NOT_FOUND) {
|
|
14477
|
+
missing.push({ index: i, key, record: stored[i] });
|
|
14478
|
+
} else {
|
|
14479
|
+
return accountErr(result.error);
|
|
14480
|
+
}
|
|
14481
|
+
}
|
|
14482
|
+
const creates = await Promise.all(missing.map(async ({ index, key, record: record2 }) => {
|
|
14483
|
+
const written = await kv.put(key, record2, { ifNoneMatch: "*" });
|
|
14484
|
+
if (written.ok) return { index, result: (0, import_sdk_services7.ok)(spaceFromRecord(key, record2)) };
|
|
14485
|
+
const raced = await kv.get(key);
|
|
14486
|
+
if (raced.ok) return { index, result: (0, import_sdk_services7.ok)(spaceFromRecord(key, raced.data.data)) };
|
|
14487
|
+
return { index, result: (0, import_sdk_services7.err)(written.error) };
|
|
14488
|
+
}));
|
|
14489
|
+
for (const { index, result } of creates) {
|
|
14490
|
+
if (!result.ok) return accountErr(result.error);
|
|
14491
|
+
final[index] = result.data;
|
|
14492
|
+
}
|
|
14493
|
+
await this.upsertSpacesIndexQuietly(final);
|
|
14494
|
+
return (0, import_sdk_services7.ok)(final);
|
|
14495
|
+
},
|
|
14399
14496
|
syncAccessible: async () => {
|
|
14400
14497
|
const synced = await this.syncAccessibleSpaces({ tolerateStorageFull: false });
|
|
14401
14498
|
return synced.ok ? (0, import_sdk_services7.ok)(synced.data.spaces) : synced;
|