@tinycloud/operations 0.4.0-beta.11 → 0.4.0-beta.13
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/artifacts.cjs +10 -1
- package/dist/artifacts.cjs.map +1 -1
- package/dist/artifacts.d.cts +1 -1
- package/dist/artifacts.d.ts +1 -1
- package/dist/artifacts.js +10 -1
- package/dist/artifacts.js.map +1 -1
- package/dist/cli-runtime.cjs +121 -20
- package/dist/cli-runtime.cjs.map +1 -1
- package/dist/cli-runtime.d.cts +1 -1
- package/dist/cli-runtime.d.ts +1 -1
- package/dist/cli-runtime.js +121 -19
- package/dist/cli-runtime.js.map +1 -1
- package/dist/{contract-eWtDSMeI.d.cts → contract-BRwWJpPs.d.cts} +23 -1
- package/dist/{contract-eWtDSMeI.d.ts → contract-BRwWJpPs.d.ts} +23 -1
- package/dist/delegation-binding.cjs +70 -13
- package/dist/delegation-binding.cjs.map +1 -1
- package/dist/delegation-binding.d.cts +43 -13
- package/dist/delegation-binding.d.ts +43 -13
- package/dist/delegation-binding.js +69 -13
- package/dist/delegation-binding.js.map +1 -1
- package/dist/index.cjs +119 -21
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +119 -20
- package/dist/index.js.map +1 -1
- package/dist/profile.d.cts +1 -1
- package/dist/profile.d.ts +1 -1
- package/generated/operations.json +2628 -4
- package/package.json +4 -4
package/dist/index.cjs
CHANGED
|
@@ -357,8 +357,13 @@ function canonicalizeRecapCaveats(caveats) {
|
|
|
357
357
|
}
|
|
358
358
|
return `[${branches.join(",")}]`;
|
|
359
359
|
}
|
|
360
|
+
function isExplicitOnlyAction(action) {
|
|
361
|
+
return Object.prototype.hasOwnProperty.call(EXPLICIT_ONLY_ACTIONS, action);
|
|
362
|
+
}
|
|
360
363
|
function actionContains(grantedAction, requestedAction) {
|
|
361
|
-
if (grantedAction ===
|
|
364
|
+
if (grantedAction === requestedAction) return true;
|
|
365
|
+
if (isExplicitOnlyAction(requestedAction)) return false;
|
|
366
|
+
if (grantedAction === "*") return true;
|
|
362
367
|
if (!grantedAction.endsWith("/*")) return false;
|
|
363
368
|
const service = grantedAction.slice(0, -2);
|
|
364
369
|
return requestedAction === service || requestedAction.startsWith(`${service}/`);
|
|
@@ -383,10 +388,15 @@ function cloneEntry(entry) {
|
|
|
383
388
|
...entry.expiry !== void 0 ? { expiry: entry.expiry } : {}
|
|
384
389
|
};
|
|
385
390
|
}
|
|
391
|
+
var EXPLICIT_ONLY_ACTIONS;
|
|
386
392
|
var init_capabilities = __esm({
|
|
387
393
|
"../sdk-core/src/capabilities.ts"() {
|
|
388
394
|
"use strict";
|
|
389
395
|
init_manifest();
|
|
396
|
+
EXPLICIT_ONLY_ACTIONS = {
|
|
397
|
+
"tinycloud.kv/sync": true,
|
|
398
|
+
"tinycloud.kv/retain": true
|
|
399
|
+
};
|
|
390
400
|
}
|
|
391
401
|
});
|
|
392
402
|
|
|
@@ -3615,6 +3625,32 @@ ORDER BY type, name`;
|
|
|
3615
3625
|
}
|
|
3616
3626
|
});
|
|
3617
3627
|
|
|
3628
|
+
// src/contract.ts
|
|
3629
|
+
var STORED_GRANT_SKIP_REASONS, DELEGATION_CID_PATTERN;
|
|
3630
|
+
var init_contract = __esm({
|
|
3631
|
+
"src/contract.ts"() {
|
|
3632
|
+
"use strict";
|
|
3633
|
+
STORED_GRANT_SKIP_REASONS = [
|
|
3634
|
+
"malformed",
|
|
3635
|
+
"unbound",
|
|
3636
|
+
"outside_request",
|
|
3637
|
+
"host_mismatch",
|
|
3638
|
+
"expired",
|
|
3639
|
+
"cid_mismatch",
|
|
3640
|
+
"authority_invalid",
|
|
3641
|
+
"proof_missing",
|
|
3642
|
+
"proof_invalid",
|
|
3643
|
+
"owner_mismatch",
|
|
3644
|
+
"audience_mismatch",
|
|
3645
|
+
"resources_mismatch",
|
|
3646
|
+
"unsupported",
|
|
3647
|
+
"activation_rejected",
|
|
3648
|
+
"invalid"
|
|
3649
|
+
];
|
|
3650
|
+
DELEGATION_CID_PATTERN = "^bafkr4i[a-z2-7]{52}$";
|
|
3651
|
+
}
|
|
3652
|
+
});
|
|
3653
|
+
|
|
3618
3654
|
// src/delegation-binding.ts
|
|
3619
3655
|
function bindingMigrationPath(profile) {
|
|
3620
3656
|
return (0, import_node_path2.join)(profilePath(profile), "delegation-binding-migration.json");
|
|
@@ -3638,12 +3674,12 @@ function replayLimit(entry, migrated) {
|
|
|
3638
3674
|
if (binding.success) return binding.data.requested;
|
|
3639
3675
|
return !migrated && kind === "compact" && !("authorityRequest" in entry) ? "signed" : void 0;
|
|
3640
3676
|
}
|
|
3641
|
-
function
|
|
3677
|
+
function bindToRequest(record, requested, source, recordedAt = (/* @__PURE__ */ new Date()).toISOString()) {
|
|
3642
3678
|
return {
|
|
3643
3679
|
...record,
|
|
3644
3680
|
authorityRequest: DelegationRequestBindingSchema.parse({
|
|
3645
3681
|
requestId: `${REQUEST_ID_PREFIX[source]}:${record.delegation.cid}`,
|
|
3646
|
-
requested: structuredClone(
|
|
3682
|
+
requested: structuredClone(requested)
|
|
3647
3683
|
}),
|
|
3648
3684
|
authorityRequestAudit: { source, recordedAt, note: BINDING_NOTES[source] }
|
|
3649
3685
|
};
|
|
@@ -3699,23 +3735,40 @@ async function migratedRecord(node, entry, host, recordedAt) {
|
|
|
3699
3735
|
const signed = await signedCapabilities(node, delegation, host);
|
|
3700
3736
|
if (signed === void 0) return void 0;
|
|
3701
3737
|
try {
|
|
3702
|
-
return
|
|
3738
|
+
return bindToRequest({ ...entry, delegation: { ...entry.delegation, cid: delegation.cid } }, signed, "migration", recordedAt);
|
|
3703
3739
|
} catch {
|
|
3704
3740
|
return void 0;
|
|
3705
3741
|
}
|
|
3706
3742
|
}
|
|
3743
|
+
function skipped(reason) {
|
|
3744
|
+
return { status: "skipped", reason };
|
|
3745
|
+
}
|
|
3707
3746
|
async function replayStoredDelegation(node, entry, options) {
|
|
3747
|
+
const kind = storedDelegationKind(entry);
|
|
3708
3748
|
const delegation = normalizeStoredDelegation(entry);
|
|
3709
|
-
if (
|
|
3749
|
+
if (kind === "refused" || delegation === void 0) return skipped("malformed");
|
|
3750
|
+
if (delegation.expiry.getTime() <= Date.now()) return NOT_REPLAYED;
|
|
3751
|
+
if (kind === "other") return skipped("proof_missing");
|
|
3710
3752
|
const limit = replayLimit(entry, options.migrated);
|
|
3711
|
-
if (limit === void 0) return
|
|
3712
|
-
|
|
3753
|
+
if (limit === void 0) return skipped("unbound");
|
|
3754
|
+
let outsideRequest = false;
|
|
3755
|
+
const authorize = limit === "signed" ? () => true : (effective) => {
|
|
3756
|
+
outsideRequest = !delegationWithinRequest(limit, effective, options.resolveSpace);
|
|
3757
|
+
return !outsideRequest;
|
|
3758
|
+
};
|
|
3713
3759
|
try {
|
|
3714
|
-
return
|
|
3715
|
-
|
|
3716
|
-
|
|
3760
|
+
return {
|
|
3761
|
+
status: "installed",
|
|
3762
|
+
delegation: await nodeSdk3.activateValidatedRuntimeDelegation(node, delegation, { host: options.host, authorize })
|
|
3763
|
+
};
|
|
3764
|
+
} catch (error) {
|
|
3765
|
+
return skipped(outsideRequest ? "outside_request" : rejectionReason(error));
|
|
3717
3766
|
}
|
|
3718
3767
|
}
|
|
3768
|
+
function rejectionReason(error) {
|
|
3769
|
+
const reason = isRecord4(error) ? error.reason : void 0;
|
|
3770
|
+
return typeof reason === "string" && STORED_GRANT_SKIP_REASONS.includes(reason) ? reason : "invalid";
|
|
3771
|
+
}
|
|
3719
3772
|
async function bindingMigrationRecorded(profile) {
|
|
3720
3773
|
try {
|
|
3721
3774
|
return await readJson(bindingMigrationPath(profile)) !== null;
|
|
@@ -3760,7 +3813,7 @@ function recordKey(entry) {
|
|
|
3760
3813
|
function isRecord4(value) {
|
|
3761
3814
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
3762
3815
|
}
|
|
3763
|
-
var import_node_path2, nodeSdk3, REQUEST_ID_PREFIX, BINDING_NOTES, MIGRATION_LOCK_TIMEOUT_MS;
|
|
3816
|
+
var import_node_path2, nodeSdk3, REQUEST_ID_PREFIX, BINDING_NOTES, MIGRATION_LOCK_TIMEOUT_MS, NOT_REPLAYED;
|
|
3764
3817
|
var init_delegation_binding = __esm({
|
|
3765
3818
|
"src/delegation-binding.ts"() {
|
|
3766
3819
|
"use strict";
|
|
@@ -3768,17 +3821,21 @@ var init_delegation_binding = __esm({
|
|
|
3768
3821
|
nodeSdk3 = __toESM(require("@tinycloud/node-sdk"), 1);
|
|
3769
3822
|
init_artifacts();
|
|
3770
3823
|
init_authority();
|
|
3824
|
+
init_contract();
|
|
3771
3825
|
init_state();
|
|
3772
3826
|
init_secrets();
|
|
3773
3827
|
REQUEST_ID_PREFIX = {
|
|
3774
3828
|
migration: "migrated",
|
|
3775
|
-
"unbound-import": "unbound-import"
|
|
3829
|
+
"unbound-import": "unbound-import",
|
|
3830
|
+
"cli-grant": "cli-grant"
|
|
3776
3831
|
};
|
|
3777
3832
|
BINDING_NOTES = {
|
|
3778
3833
|
migration: "Stored without a request binding before bindings were required. Bound at migration to exactly its own signed capabilities, so replay refuses any delegation in this record that exceeds them.",
|
|
3779
|
-
"unbound-import": "Imported by `tc auth import` without a stored request. Bound to exactly its own signed capabilities, so replay refuses any delegation in this record that exceeds them."
|
|
3834
|
+
"unbound-import": "Imported by `tc auth import` without a stored request. Bound to exactly its own signed capabilities, so replay refuses any delegation in this record that exceeds them.",
|
|
3835
|
+
"cli-grant": "Granted to this CLI by `tc auth request --grant` or a permission escalation, and checked against the request it answered. Bound to exactly its own signed capabilities, so replay refuses any delegation in this record that exceeds them."
|
|
3780
3836
|
};
|
|
3781
3837
|
MIGRATION_LOCK_TIMEOUT_MS = 250;
|
|
3838
|
+
NOT_REPLAYED = { status: "not-replayed" };
|
|
3782
3839
|
}
|
|
3783
3840
|
});
|
|
3784
3841
|
|
|
@@ -4190,7 +4247,18 @@ async function createInvocationRuntime(target, requirement = "authenticated") {
|
|
|
4190
4247
|
));
|
|
4191
4248
|
}
|
|
4192
4249
|
} else {
|
|
4193
|
-
|
|
4250
|
+
try {
|
|
4251
|
+
await node.restoreSession(activeSession);
|
|
4252
|
+
} catch (error) {
|
|
4253
|
+
if (isRecord7(error) && error.code === "AUTH_EXPIRED") {
|
|
4254
|
+
return failed(summary, operationError(
|
|
4255
|
+
"AUTH_REQUIRED",
|
|
4256
|
+
"The stored session has expired or is no longer valid. Sign in again.",
|
|
4257
|
+
{ retryable: false }
|
|
4258
|
+
));
|
|
4259
|
+
}
|
|
4260
|
+
throw error;
|
|
4261
|
+
}
|
|
4194
4262
|
}
|
|
4195
4263
|
const activeSessionDid = normalizeDid(node.sessionDid);
|
|
4196
4264
|
const livePrincipalDid = normalizeDid(node.did);
|
|
@@ -4198,6 +4266,7 @@ async function createInvocationRuntime(target, requirement = "authenticated") {
|
|
|
4198
4266
|
const livePermissions = [...node.getVerifiedSessionCapabilities()];
|
|
4199
4267
|
const resolveSpace2 = operationSpaceResolver(node, authenticatedSpace ?? summary.space);
|
|
4200
4268
|
const seenCids = /* @__PURE__ */ new Set();
|
|
4269
|
+
const warnings = [];
|
|
4201
4270
|
if (!explicitPrivateKeyOverride) {
|
|
4202
4271
|
const activator = node;
|
|
4203
4272
|
const migrated = await prepareStoredDelegationReplay(profileName, activator, {
|
|
@@ -4207,20 +4276,25 @@ async function createInvocationRuntime(target, requirement = "authenticated") {
|
|
|
4207
4276
|
migrate: activeSession !== void 0
|
|
4208
4277
|
});
|
|
4209
4278
|
for (const entry of await readAdditionalDelegations(profileName)) {
|
|
4210
|
-
const
|
|
4279
|
+
const replay = await replayStoredDelegation(activator, entry, {
|
|
4211
4280
|
host: summary.host,
|
|
4212
4281
|
migrated,
|
|
4213
4282
|
resolveSpace: resolveSpace2
|
|
4214
4283
|
});
|
|
4215
|
-
if (
|
|
4216
|
-
seenCids.
|
|
4217
|
-
|
|
4284
|
+
if (replay.status === "installed") {
|
|
4285
|
+
if (!seenCids.has(replay.delegation.cid)) {
|
|
4286
|
+
seenCids.add(replay.delegation.cid);
|
|
4287
|
+
livePermissions.push(...replay.delegation.effectivePermissions);
|
|
4288
|
+
}
|
|
4289
|
+
} else if (replay.status === "skipped") {
|
|
4290
|
+
warnings.push(skippedGrantWarning(node, entry, replay.reason));
|
|
4218
4291
|
}
|
|
4219
4292
|
}
|
|
4220
4293
|
}
|
|
4221
4294
|
const runtime = {
|
|
4222
4295
|
node,
|
|
4223
|
-
granted: canonicalizeCapabilities(livePermissions)
|
|
4296
|
+
granted: canonicalizeCapabilities(livePermissions),
|
|
4297
|
+
...warnings.length === 0 ? {} : { warnings }
|
|
4224
4298
|
};
|
|
4225
4299
|
return {
|
|
4226
4300
|
ok: true,
|
|
@@ -4244,6 +4318,24 @@ async function createInvocationRuntime(target, requirement = "authenticated") {
|
|
|
4244
4318
|
));
|
|
4245
4319
|
}
|
|
4246
4320
|
}
|
|
4321
|
+
function skippedGrantWarning(node, entry, reason) {
|
|
4322
|
+
const grantCid = verifiedStoredCid(node, entry);
|
|
4323
|
+
return { code: "STORED_GRANT_SKIPPED", reason, ...grantCid === void 0 ? {} : { grantCid } };
|
|
4324
|
+
}
|
|
4325
|
+
function verifiedStoredCid(node, entry) {
|
|
4326
|
+
const delegation = isRecord7(entry) && isRecord7(entry.delegation) ? entry.delegation : void 0;
|
|
4327
|
+
const header = isRecord7(delegation?.delegationHeader) ? delegation.delegationHeader : void 0;
|
|
4328
|
+
const cid = delegation?.cid;
|
|
4329
|
+
const computeDelegationCid = isRecord7(node) ? node.computeDelegationCid : void 0;
|
|
4330
|
+
if (typeof cid !== "string" || typeof header?.Authorization !== "string" || typeof computeDelegationCid !== "function") {
|
|
4331
|
+
return void 0;
|
|
4332
|
+
}
|
|
4333
|
+
try {
|
|
4334
|
+
return computeDelegationCid.call(node, header.Authorization) === cid && DELEGATION_CID.test(cid) ? cid : void 0;
|
|
4335
|
+
} catch {
|
|
4336
|
+
return void 0;
|
|
4337
|
+
}
|
|
4338
|
+
}
|
|
4247
4339
|
function spaceForAuthenticatedPrincipal(principal2) {
|
|
4248
4340
|
if (principal2 === void 0) return void 0;
|
|
4249
4341
|
try {
|
|
@@ -4292,17 +4384,19 @@ function unresolvedSummary(target) {
|
|
|
4292
4384
|
posture: "unauthenticated"
|
|
4293
4385
|
};
|
|
4294
4386
|
}
|
|
4295
|
-
var nodeSdk4;
|
|
4387
|
+
var nodeSdk4, DELEGATION_CID;
|
|
4296
4388
|
var init_runtime = __esm({
|
|
4297
4389
|
"src/runtime.ts"() {
|
|
4298
4390
|
"use strict";
|
|
4299
4391
|
nodeSdk4 = __toESM(require("@tinycloud/node-sdk"), 1);
|
|
4392
|
+
init_contract();
|
|
4300
4393
|
init_authority();
|
|
4301
4394
|
init_errors();
|
|
4302
4395
|
init_profile();
|
|
4303
4396
|
init_secrets();
|
|
4304
4397
|
init_state();
|
|
4305
4398
|
init_delegation_binding();
|
|
4399
|
+
DELEGATION_CID = new RegExp(DELEGATION_CID_PATTERN);
|
|
4306
4400
|
}
|
|
4307
4401
|
});
|
|
4308
4402
|
|
|
@@ -4685,9 +4779,13 @@ async function invokeOperation(operationId, operationVersion, invocationTarget,
|
|
|
4685
4779
|
unknownInput
|
|
4686
4780
|
);
|
|
4687
4781
|
if (isPreparedError(prepared)) return prepared.result;
|
|
4688
|
-
return executePreparedInvocation(prepared);
|
|
4782
|
+
return withRuntimeWarnings(await executePreparedInvocation(prepared), prepared);
|
|
4689
4783
|
});
|
|
4690
4784
|
}
|
|
4785
|
+
function withRuntimeWarnings(result, prepared) {
|
|
4786
|
+
const warnings = prepared.runtimeResolution.context.runtime?.warnings;
|
|
4787
|
+
return warnings === void 0 || warnings.length === 0 ? result : { ...result, warnings: [...warnings] };
|
|
4788
|
+
}
|
|
4691
4789
|
function isPreparedError(prepared) {
|
|
4692
4790
|
return "status" in prepared;
|
|
4693
4791
|
}
|