@tinycloud/operations 0.4.0-beta.11 → 0.4.0-beta.12
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.d.cts +1 -1
- package/dist/artifacts.d.ts +1 -1
- package/dist/cli-runtime.cjs +110 -19
- 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 +110 -18
- 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 +60 -12
- 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 +59 -12
- package/dist/delegation-binding.js.map +1 -1
- package/dist/index.cjs +108 -20
- 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 +108 -19
- 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 +3 -3
package/dist/index.cjs
CHANGED
|
@@ -3615,6 +3615,32 @@ ORDER BY type, name`;
|
|
|
3615
3615
|
}
|
|
3616
3616
|
});
|
|
3617
3617
|
|
|
3618
|
+
// src/contract.ts
|
|
3619
|
+
var STORED_GRANT_SKIP_REASONS, DELEGATION_CID_PATTERN;
|
|
3620
|
+
var init_contract = __esm({
|
|
3621
|
+
"src/contract.ts"() {
|
|
3622
|
+
"use strict";
|
|
3623
|
+
STORED_GRANT_SKIP_REASONS = [
|
|
3624
|
+
"malformed",
|
|
3625
|
+
"unbound",
|
|
3626
|
+
"outside_request",
|
|
3627
|
+
"host_mismatch",
|
|
3628
|
+
"expired",
|
|
3629
|
+
"cid_mismatch",
|
|
3630
|
+
"authority_invalid",
|
|
3631
|
+
"proof_missing",
|
|
3632
|
+
"proof_invalid",
|
|
3633
|
+
"owner_mismatch",
|
|
3634
|
+
"audience_mismatch",
|
|
3635
|
+
"resources_mismatch",
|
|
3636
|
+
"unsupported",
|
|
3637
|
+
"activation_rejected",
|
|
3638
|
+
"invalid"
|
|
3639
|
+
];
|
|
3640
|
+
DELEGATION_CID_PATTERN = "^bafkr4i[a-z2-7]{52}$";
|
|
3641
|
+
}
|
|
3642
|
+
});
|
|
3643
|
+
|
|
3618
3644
|
// src/delegation-binding.ts
|
|
3619
3645
|
function bindingMigrationPath(profile) {
|
|
3620
3646
|
return (0, import_node_path2.join)(profilePath(profile), "delegation-binding-migration.json");
|
|
@@ -3638,12 +3664,12 @@ function replayLimit(entry, migrated) {
|
|
|
3638
3664
|
if (binding.success) return binding.data.requested;
|
|
3639
3665
|
return !migrated && kind === "compact" && !("authorityRequest" in entry) ? "signed" : void 0;
|
|
3640
3666
|
}
|
|
3641
|
-
function
|
|
3667
|
+
function bindToRequest(record, requested, source, recordedAt = (/* @__PURE__ */ new Date()).toISOString()) {
|
|
3642
3668
|
return {
|
|
3643
3669
|
...record,
|
|
3644
3670
|
authorityRequest: DelegationRequestBindingSchema.parse({
|
|
3645
3671
|
requestId: `${REQUEST_ID_PREFIX[source]}:${record.delegation.cid}`,
|
|
3646
|
-
requested: structuredClone(
|
|
3672
|
+
requested: structuredClone(requested)
|
|
3647
3673
|
}),
|
|
3648
3674
|
authorityRequestAudit: { source, recordedAt, note: BINDING_NOTES[source] }
|
|
3649
3675
|
};
|
|
@@ -3699,23 +3725,40 @@ async function migratedRecord(node, entry, host, recordedAt) {
|
|
|
3699
3725
|
const signed = await signedCapabilities(node, delegation, host);
|
|
3700
3726
|
if (signed === void 0) return void 0;
|
|
3701
3727
|
try {
|
|
3702
|
-
return
|
|
3728
|
+
return bindToRequest({ ...entry, delegation: { ...entry.delegation, cid: delegation.cid } }, signed, "migration", recordedAt);
|
|
3703
3729
|
} catch {
|
|
3704
3730
|
return void 0;
|
|
3705
3731
|
}
|
|
3706
3732
|
}
|
|
3733
|
+
function skipped(reason) {
|
|
3734
|
+
return { status: "skipped", reason };
|
|
3735
|
+
}
|
|
3707
3736
|
async function replayStoredDelegation(node, entry, options) {
|
|
3737
|
+
const kind = storedDelegationKind(entry);
|
|
3708
3738
|
const delegation = normalizeStoredDelegation(entry);
|
|
3709
|
-
if (
|
|
3739
|
+
if (kind === "refused" || delegation === void 0) return skipped("malformed");
|
|
3740
|
+
if (delegation.expiry.getTime() <= Date.now()) return NOT_REPLAYED;
|
|
3741
|
+
if (kind === "other") return skipped("proof_missing");
|
|
3710
3742
|
const limit = replayLimit(entry, options.migrated);
|
|
3711
|
-
if (limit === void 0) return
|
|
3712
|
-
|
|
3743
|
+
if (limit === void 0) return skipped("unbound");
|
|
3744
|
+
let outsideRequest = false;
|
|
3745
|
+
const authorize = limit === "signed" ? () => true : (effective) => {
|
|
3746
|
+
outsideRequest = !delegationWithinRequest(limit, effective, options.resolveSpace);
|
|
3747
|
+
return !outsideRequest;
|
|
3748
|
+
};
|
|
3713
3749
|
try {
|
|
3714
|
-
return
|
|
3715
|
-
|
|
3716
|
-
|
|
3750
|
+
return {
|
|
3751
|
+
status: "installed",
|
|
3752
|
+
delegation: await nodeSdk3.activateValidatedRuntimeDelegation(node, delegation, { host: options.host, authorize })
|
|
3753
|
+
};
|
|
3754
|
+
} catch (error) {
|
|
3755
|
+
return skipped(outsideRequest ? "outside_request" : rejectionReason(error));
|
|
3717
3756
|
}
|
|
3718
3757
|
}
|
|
3758
|
+
function rejectionReason(error) {
|
|
3759
|
+
const reason = isRecord4(error) ? error.reason : void 0;
|
|
3760
|
+
return typeof reason === "string" && STORED_GRANT_SKIP_REASONS.includes(reason) ? reason : "invalid";
|
|
3761
|
+
}
|
|
3719
3762
|
async function bindingMigrationRecorded(profile) {
|
|
3720
3763
|
try {
|
|
3721
3764
|
return await readJson(bindingMigrationPath(profile)) !== null;
|
|
@@ -3760,7 +3803,7 @@ function recordKey(entry) {
|
|
|
3760
3803
|
function isRecord4(value) {
|
|
3761
3804
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
3762
3805
|
}
|
|
3763
|
-
var import_node_path2, nodeSdk3, REQUEST_ID_PREFIX, BINDING_NOTES, MIGRATION_LOCK_TIMEOUT_MS;
|
|
3806
|
+
var import_node_path2, nodeSdk3, REQUEST_ID_PREFIX, BINDING_NOTES, MIGRATION_LOCK_TIMEOUT_MS, NOT_REPLAYED;
|
|
3764
3807
|
var init_delegation_binding = __esm({
|
|
3765
3808
|
"src/delegation-binding.ts"() {
|
|
3766
3809
|
"use strict";
|
|
@@ -3768,17 +3811,21 @@ var init_delegation_binding = __esm({
|
|
|
3768
3811
|
nodeSdk3 = __toESM(require("@tinycloud/node-sdk"), 1);
|
|
3769
3812
|
init_artifacts();
|
|
3770
3813
|
init_authority();
|
|
3814
|
+
init_contract();
|
|
3771
3815
|
init_state();
|
|
3772
3816
|
init_secrets();
|
|
3773
3817
|
REQUEST_ID_PREFIX = {
|
|
3774
3818
|
migration: "migrated",
|
|
3775
|
-
"unbound-import": "unbound-import"
|
|
3819
|
+
"unbound-import": "unbound-import",
|
|
3820
|
+
"cli-grant": "cli-grant"
|
|
3776
3821
|
};
|
|
3777
3822
|
BINDING_NOTES = {
|
|
3778
3823
|
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."
|
|
3824
|
+
"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.",
|
|
3825
|
+
"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
3826
|
};
|
|
3781
3827
|
MIGRATION_LOCK_TIMEOUT_MS = 250;
|
|
3828
|
+
NOT_REPLAYED = { status: "not-replayed" };
|
|
3782
3829
|
}
|
|
3783
3830
|
});
|
|
3784
3831
|
|
|
@@ -4190,7 +4237,18 @@ async function createInvocationRuntime(target, requirement = "authenticated") {
|
|
|
4190
4237
|
));
|
|
4191
4238
|
}
|
|
4192
4239
|
} else {
|
|
4193
|
-
|
|
4240
|
+
try {
|
|
4241
|
+
await node.restoreSession(activeSession);
|
|
4242
|
+
} catch (error) {
|
|
4243
|
+
if (isRecord7(error) && error.code === "AUTH_EXPIRED") {
|
|
4244
|
+
return failed(summary, operationError(
|
|
4245
|
+
"AUTH_REQUIRED",
|
|
4246
|
+
"The stored session has expired or is no longer valid. Sign in again.",
|
|
4247
|
+
{ retryable: false }
|
|
4248
|
+
));
|
|
4249
|
+
}
|
|
4250
|
+
throw error;
|
|
4251
|
+
}
|
|
4194
4252
|
}
|
|
4195
4253
|
const activeSessionDid = normalizeDid(node.sessionDid);
|
|
4196
4254
|
const livePrincipalDid = normalizeDid(node.did);
|
|
@@ -4198,6 +4256,7 @@ async function createInvocationRuntime(target, requirement = "authenticated") {
|
|
|
4198
4256
|
const livePermissions = [...node.getVerifiedSessionCapabilities()];
|
|
4199
4257
|
const resolveSpace2 = operationSpaceResolver(node, authenticatedSpace ?? summary.space);
|
|
4200
4258
|
const seenCids = /* @__PURE__ */ new Set();
|
|
4259
|
+
const warnings = [];
|
|
4201
4260
|
if (!explicitPrivateKeyOverride) {
|
|
4202
4261
|
const activator = node;
|
|
4203
4262
|
const migrated = await prepareStoredDelegationReplay(profileName, activator, {
|
|
@@ -4207,20 +4266,25 @@ async function createInvocationRuntime(target, requirement = "authenticated") {
|
|
|
4207
4266
|
migrate: activeSession !== void 0
|
|
4208
4267
|
});
|
|
4209
4268
|
for (const entry of await readAdditionalDelegations(profileName)) {
|
|
4210
|
-
const
|
|
4269
|
+
const replay = await replayStoredDelegation(activator, entry, {
|
|
4211
4270
|
host: summary.host,
|
|
4212
4271
|
migrated,
|
|
4213
4272
|
resolveSpace: resolveSpace2
|
|
4214
4273
|
});
|
|
4215
|
-
if (
|
|
4216
|
-
seenCids.
|
|
4217
|
-
|
|
4274
|
+
if (replay.status === "installed") {
|
|
4275
|
+
if (!seenCids.has(replay.delegation.cid)) {
|
|
4276
|
+
seenCids.add(replay.delegation.cid);
|
|
4277
|
+
livePermissions.push(...replay.delegation.effectivePermissions);
|
|
4278
|
+
}
|
|
4279
|
+
} else if (replay.status === "skipped") {
|
|
4280
|
+
warnings.push(skippedGrantWarning(node, entry, replay.reason));
|
|
4218
4281
|
}
|
|
4219
4282
|
}
|
|
4220
4283
|
}
|
|
4221
4284
|
const runtime = {
|
|
4222
4285
|
node,
|
|
4223
|
-
granted: canonicalizeCapabilities(livePermissions)
|
|
4286
|
+
granted: canonicalizeCapabilities(livePermissions),
|
|
4287
|
+
...warnings.length === 0 ? {} : { warnings }
|
|
4224
4288
|
};
|
|
4225
4289
|
return {
|
|
4226
4290
|
ok: true,
|
|
@@ -4244,6 +4308,24 @@ async function createInvocationRuntime(target, requirement = "authenticated") {
|
|
|
4244
4308
|
));
|
|
4245
4309
|
}
|
|
4246
4310
|
}
|
|
4311
|
+
function skippedGrantWarning(node, entry, reason) {
|
|
4312
|
+
const grantCid = verifiedStoredCid(node, entry);
|
|
4313
|
+
return { code: "STORED_GRANT_SKIPPED", reason, ...grantCid === void 0 ? {} : { grantCid } };
|
|
4314
|
+
}
|
|
4315
|
+
function verifiedStoredCid(node, entry) {
|
|
4316
|
+
const delegation = isRecord7(entry) && isRecord7(entry.delegation) ? entry.delegation : void 0;
|
|
4317
|
+
const header = isRecord7(delegation?.delegationHeader) ? delegation.delegationHeader : void 0;
|
|
4318
|
+
const cid = delegation?.cid;
|
|
4319
|
+
const computeDelegationCid = isRecord7(node) ? node.computeDelegationCid : void 0;
|
|
4320
|
+
if (typeof cid !== "string" || typeof header?.Authorization !== "string" || typeof computeDelegationCid !== "function") {
|
|
4321
|
+
return void 0;
|
|
4322
|
+
}
|
|
4323
|
+
try {
|
|
4324
|
+
return computeDelegationCid.call(node, header.Authorization) === cid && DELEGATION_CID.test(cid) ? cid : void 0;
|
|
4325
|
+
} catch {
|
|
4326
|
+
return void 0;
|
|
4327
|
+
}
|
|
4328
|
+
}
|
|
4247
4329
|
function spaceForAuthenticatedPrincipal(principal2) {
|
|
4248
4330
|
if (principal2 === void 0) return void 0;
|
|
4249
4331
|
try {
|
|
@@ -4292,17 +4374,19 @@ function unresolvedSummary(target) {
|
|
|
4292
4374
|
posture: "unauthenticated"
|
|
4293
4375
|
};
|
|
4294
4376
|
}
|
|
4295
|
-
var nodeSdk4;
|
|
4377
|
+
var nodeSdk4, DELEGATION_CID;
|
|
4296
4378
|
var init_runtime = __esm({
|
|
4297
4379
|
"src/runtime.ts"() {
|
|
4298
4380
|
"use strict";
|
|
4299
4381
|
nodeSdk4 = __toESM(require("@tinycloud/node-sdk"), 1);
|
|
4382
|
+
init_contract();
|
|
4300
4383
|
init_authority();
|
|
4301
4384
|
init_errors();
|
|
4302
4385
|
init_profile();
|
|
4303
4386
|
init_secrets();
|
|
4304
4387
|
init_state();
|
|
4305
4388
|
init_delegation_binding();
|
|
4389
|
+
DELEGATION_CID = new RegExp(DELEGATION_CID_PATTERN);
|
|
4306
4390
|
}
|
|
4307
4391
|
});
|
|
4308
4392
|
|
|
@@ -4685,9 +4769,13 @@ async function invokeOperation(operationId, operationVersion, invocationTarget,
|
|
|
4685
4769
|
unknownInput
|
|
4686
4770
|
);
|
|
4687
4771
|
if (isPreparedError(prepared)) return prepared.result;
|
|
4688
|
-
return executePreparedInvocation(prepared);
|
|
4772
|
+
return withRuntimeWarnings(await executePreparedInvocation(prepared), prepared);
|
|
4689
4773
|
});
|
|
4690
4774
|
}
|
|
4775
|
+
function withRuntimeWarnings(result, prepared) {
|
|
4776
|
+
const warnings = prepared.runtimeResolution.context.runtime?.warnings;
|
|
4777
|
+
return warnings === void 0 || warnings.length === 0 ? result : { ...result, warnings: [...warnings] };
|
|
4778
|
+
}
|
|
4691
4779
|
function isPreparedError(prepared) {
|
|
4692
4780
|
return "status" in prepared;
|
|
4693
4781
|
}
|