@tinycloud/operations 0.3.4-beta.6 → 0.4.0-beta.7
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 -2
- package/dist/artifacts.cjs.map +1 -1
- package/dist/artifacts.d.cts +115 -58
- package/dist/artifacts.d.ts +115 -58
- package/dist/artifacts.js +9 -2
- package/dist/artifacts.js.map +1 -1
- package/dist/authority-ofwbEqmj.d.cts +30 -0
- package/dist/authority-ofwbEqmj.d.ts +30 -0
- package/dist/cli-runtime.cjs +249 -71
- package/dist/cli-runtime.cjs.map +1 -1
- package/dist/cli-runtime.js +240 -67
- package/dist/cli-runtime.js.map +1 -1
- package/dist/delegation-binding.cjs +7598 -0
- package/dist/delegation-binding.cjs.map +1 -0
- package/dist/delegation-binding.d.cts +130 -0
- package/dist/delegation-binding.d.ts +130 -0
- package/dist/delegation-binding.js +7588 -0
- package/dist/delegation-binding.js.map +1 -0
- package/dist/index.cjs +246 -68
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +240 -67
- package/dist/index.js.map +1 -1
- package/dist/profile.cjs +7 -2
- package/dist/profile.cjs.map +1 -1
- package/dist/profile.js +7 -2
- package/dist/profile.js.map +1 -1
- package/dist/state.cjs +7 -2
- package/dist/state.cjs.map +1 -1
- package/dist/state.js +7 -2
- package/dist/state.js.map +1 -1
- package/generated/operations.json +8 -4
- package/package.json +8 -3
package/dist/index.js
CHANGED
|
@@ -6965,6 +6965,9 @@ function evaluateOperationAuthority(granted, required, resolveSpace2) {
|
|
|
6965
6965
|
missing: canonicalizeCapabilities(missing)
|
|
6966
6966
|
};
|
|
6967
6967
|
}
|
|
6968
|
+
function delegationWithinRequest(requested, effective, resolveSpace2) {
|
|
6969
|
+
return requested.length > 0 && evaluateOperationAuthority(requested, canonicalizeCapabilities(effective), resolveSpace2).satisfied;
|
|
6970
|
+
}
|
|
6968
6971
|
function isExactCapabilityMemberSubset(hinted, planned, resolveSpace2) {
|
|
6969
6972
|
const canonicalHinted = canonicalizeOperationCapabilities(hinted, resolveSpace2);
|
|
6970
6973
|
const canonicalPlanned = canonicalizeOperationCapabilities(planned, resolveSpace2);
|
|
@@ -7093,6 +7096,11 @@ import {
|
|
|
7093
7096
|
} from "fs/promises";
|
|
7094
7097
|
import { homedir } from "os";
|
|
7095
7098
|
import { basename, dirname, isAbsolute, join, relative, resolve } from "path";
|
|
7099
|
+
function processWideContext(key) {
|
|
7100
|
+
var _a;
|
|
7101
|
+
const registry = globalThis;
|
|
7102
|
+
return registry[_a = Symbol.for(key)] ?? (registry[_a] = new AsyncLocalStorage());
|
|
7103
|
+
}
|
|
7096
7104
|
function tinycloudHomePath() {
|
|
7097
7105
|
const home = invocationStateRoot.getStore() ?? process.env.TC_HOME ?? process.env.HOME ?? process.env.USERPROFILE ?? homedir();
|
|
7098
7106
|
return join(home, ".tinycloud");
|
|
@@ -7427,8 +7435,8 @@ var init_state = __esm({
|
|
|
7427
7435
|
TEST_LOCK_CLAIMED_BARRIER_DIR = "TC_TEST_PROFILE_LOCK_CLAIMED_BARRIER_DIR";
|
|
7428
7436
|
TEST_LOCK_FENCED_BARRIER_DIR = "TC_TEST_PROFILE_LOCK_FENCED_BARRIER_DIR";
|
|
7429
7437
|
TEST_LOCK_VERIFIED_BARRIER_DIR = "TC_TEST_PROFILE_LOCK_VERIFIED_BARRIER_DIR";
|
|
7430
|
-
invocationStateRoot =
|
|
7431
|
-
heldProfileLocks =
|
|
7438
|
+
invocationStateRoot = processWideContext("tinycloud.operations.invocationStateRoot.v1");
|
|
7439
|
+
heldProfileLocks = processWideContext("tinycloud.operations.heldProfileLocks.v1");
|
|
7432
7440
|
ProfileLockTimeoutError = class extends Error {
|
|
7433
7441
|
constructor(profile, timeoutMs) {
|
|
7434
7442
|
super(`Timed out waiting for the profile lock for "${profile}" after ${timeoutMs}ms.`);
|
|
@@ -7645,7 +7653,7 @@ function evaluateArtifactAuthority(granted, required, resolveSpace2) {
|
|
|
7645
7653
|
function defaultRequestId(now) {
|
|
7646
7654
|
return `req_${now.getTime().toString(36)}_${randomUUID2().replace(/-/g, "")}`;
|
|
7647
7655
|
}
|
|
7648
|
-
var THIRTY_DAYS_MS, PermissionEntrySchema, CommandSchema, LegacyPermissionRequestArtifactSchema, PortableDelegationSchema, PermissionRequestArtifactSchema, DelegationImportArtifactSchema;
|
|
7656
|
+
var THIRTY_DAYS_MS, PermissionEntrySchema, CommandSchema, LegacyPermissionRequestArtifactSchema, PortableDelegationSchema, PermissionRequestArtifactSchema, DelegationImportArtifactSchema, DelegationRequestBindingSchema;
|
|
7649
7657
|
var init_artifacts = __esm({
|
|
7650
7658
|
"src/artifacts.ts"() {
|
|
7651
7659
|
"use strict";
|
|
@@ -7718,16 +7726,12 @@ var init_artifacts = __esm({
|
|
|
7718
7726
|
expiry: z2.string().datetime({ offset: true }).optional(),
|
|
7719
7727
|
prompted: z2.boolean().optional()
|
|
7720
7728
|
}).strict();
|
|
7729
|
+
DelegationRequestBindingSchema = PermissionRequestArtifactSchema.pick({ requestId: true, requested: true }).strict();
|
|
7721
7730
|
}
|
|
7722
7731
|
});
|
|
7723
7732
|
|
|
7724
7733
|
// src/secrets.ts
|
|
7725
|
-
import
|
|
7726
|
-
canonicalizeAddress,
|
|
7727
|
-
makePkhSpaceId,
|
|
7728
|
-
parsePkhDid,
|
|
7729
|
-
parseSpaceUri
|
|
7730
|
-
} from "@tinycloud/node-sdk";
|
|
7734
|
+
import * as nodeSdk from "@tinycloud/node-sdk";
|
|
7731
7735
|
function normalizeSecretsGetInput(input) {
|
|
7732
7736
|
const reference = resolveSecretReference(input);
|
|
7733
7737
|
return {
|
|
@@ -7783,18 +7787,18 @@ function resolveOperationSpace(space, node, ownerSpace) {
|
|
|
7783
7787
|
if (resolved !== void 0) return canonicalizeSpaceUri(resolved);
|
|
7784
7788
|
}
|
|
7785
7789
|
const did = typeof candidate.did === "string" ? candidate.did : void 0;
|
|
7786
|
-
const pkh = did === void 0 ? null : parsePkhDid(did);
|
|
7790
|
+
const pkh = did === void 0 ? null : nodeSdk.parsePkhDid(did);
|
|
7787
7791
|
if (pkh === null) {
|
|
7788
7792
|
throw invalidSecretInput();
|
|
7789
7793
|
}
|
|
7790
|
-
return makePkhSpaceId(pkh.address, pkh.chainId, space);
|
|
7794
|
+
return nodeSdk.makePkhSpaceId(pkh.address, pkh.chainId, space);
|
|
7791
7795
|
}
|
|
7792
7796
|
function ownedSpaceForName(ownerSpace, name) {
|
|
7793
|
-
const parsed = parseSpaceUri(ownerSpace);
|
|
7797
|
+
const parsed = nodeSdk.parseSpaceUri(ownerSpace);
|
|
7794
7798
|
if (parsed === null) return void 0;
|
|
7795
7799
|
try {
|
|
7796
|
-
const pkh = parsePkhDid(parsed.owner);
|
|
7797
|
-
return pkh === null ? void 0 : makePkhSpaceId(pkh.address, pkh.chainId, name);
|
|
7800
|
+
const pkh = nodeSdk.parsePkhDid(parsed.owner);
|
|
7801
|
+
return pkh === null ? void 0 : nodeSdk.makePkhSpaceId(pkh.address, pkh.chainId, name);
|
|
7798
7802
|
} catch {
|
|
7799
7803
|
return void 0;
|
|
7800
7804
|
}
|
|
@@ -7809,7 +7813,7 @@ function canonicalizeSpaceUri(space) {
|
|
|
7809
7813
|
/^tinycloud:pkh:eip155:(\d+):(0x[0-9a-fA-F]{40}):([^:]+)$/
|
|
7810
7814
|
);
|
|
7811
7815
|
if (pkh !== null) {
|
|
7812
|
-
return `tinycloud:pkh:eip155:${pkh[1]}:${canonicalizeAddress(pkh[2]).toLowerCase()}:${pkh[3]}`;
|
|
7816
|
+
return `tinycloud:pkh:eip155:${pkh[1]}:${nodeSdk.canonicalizeAddress(pkh[2]).toLowerCase()}:${pkh[3]}`;
|
|
7813
7817
|
}
|
|
7814
7818
|
return space;
|
|
7815
7819
|
}
|
|
@@ -7862,7 +7866,7 @@ var init_secrets = __esm({
|
|
|
7862
7866
|
});
|
|
7863
7867
|
|
|
7864
7868
|
// src/operations/auth.ts
|
|
7865
|
-
import * as
|
|
7869
|
+
import * as nodeSdk2 from "@tinycloud/node-sdk";
|
|
7866
7870
|
import { z as z3 } from "zod";
|
|
7867
7871
|
async function requestExactAuthority(context, input) {
|
|
7868
7872
|
const sessionDid = context.summary.sessionDid;
|
|
@@ -8007,7 +8011,7 @@ async function importRequestBoundDelegation(context, input) {
|
|
|
8007
8011
|
};
|
|
8008
8012
|
let activated;
|
|
8009
8013
|
try {
|
|
8010
|
-
activated = await
|
|
8014
|
+
activated = await nodeSdk2.activateValidatedRuntimeDelegation(
|
|
8011
8015
|
context.runtime.node,
|
|
8012
8016
|
delegation,
|
|
8013
8017
|
{ host }
|
|
@@ -8023,11 +8027,7 @@ async function importRequestBoundDelegation(context, input) {
|
|
|
8023
8027
|
context.runtime.node,
|
|
8024
8028
|
context.summary.space
|
|
8025
8029
|
);
|
|
8026
|
-
if (request.requested
|
|
8027
|
-
request.requested,
|
|
8028
|
-
effectivePermissions,
|
|
8029
|
-
resolveSpace2
|
|
8030
|
-
).satisfied) {
|
|
8030
|
+
if (!delegationWithinRequest(request.requested, effectivePermissions, resolveSpace2)) {
|
|
8031
8031
|
return operationFailure(
|
|
8032
8032
|
"DELEGATION_REJECTED",
|
|
8033
8033
|
"The delegation exceeds the stored authority request."
|
|
@@ -8055,12 +8055,19 @@ async function importRequestBoundDelegation(context, input) {
|
|
|
8055
8055
|
)
|
|
8056
8056
|
};
|
|
8057
8057
|
}
|
|
8058
|
-
const
|
|
8058
|
+
const record = {
|
|
8059
|
+
delegation: activated.delegation,
|
|
8060
|
+
permissions: activated.effectivePermissions,
|
|
8061
|
+
authorityRequest: {
|
|
8062
|
+
requestId: request.requestId,
|
|
8063
|
+
requested: request.requested
|
|
8064
|
+
}
|
|
8065
|
+
};
|
|
8066
|
+
const position = records.findIndex((entry) => delegationCid(entry) === activated.cid);
|
|
8067
|
+
const alreadyPresent = position !== -1;
|
|
8068
|
+
const others = records.filter((entry) => delegationCid(entry) !== activated.cid);
|
|
8059
8069
|
return {
|
|
8060
|
-
records: alreadyPresent ?
|
|
8061
|
-
delegation: activated.delegation,
|
|
8062
|
-
permissions: activated.effectivePermissions
|
|
8063
|
-
}],
|
|
8070
|
+
records: alreadyPresent ? [...others.slice(0, position), record, ...others.slice(position)] : [...records, record],
|
|
8064
8071
|
result: {
|
|
8065
8072
|
status: "ok",
|
|
8066
8073
|
output: {
|
|
@@ -9788,6 +9795,173 @@ ORDER BY type, name`;
|
|
|
9788
9795
|
}
|
|
9789
9796
|
});
|
|
9790
9797
|
|
|
9798
|
+
// src/delegation-binding.ts
|
|
9799
|
+
import { join as join2 } from "path";
|
|
9800
|
+
import * as nodeSdk3 from "@tinycloud/node-sdk";
|
|
9801
|
+
function bindingMigrationPath(profile) {
|
|
9802
|
+
return join2(profilePath(profile), "delegation-binding-migration.json");
|
|
9803
|
+
}
|
|
9804
|
+
function storedDelegationKind(entry) {
|
|
9805
|
+
if (!isRecord4(entry)) return "refused";
|
|
9806
|
+
const delegation = entry.delegation;
|
|
9807
|
+
if (!isRecord4(delegation)) return "refused";
|
|
9808
|
+
const header = delegation.delegationHeader;
|
|
9809
|
+
if (!isRecord4(header) || Object.keys(header).length !== 1 || !Object.prototype.hasOwnProperty.call(header, "Authorization") || typeof header.Authorization !== "string") {
|
|
9810
|
+
return "refused";
|
|
9811
|
+
}
|
|
9812
|
+
if ("siweProof" in delegation) return "signed-login";
|
|
9813
|
+
if (header.Authorization.includes(".")) return "compact";
|
|
9814
|
+
return "authorityRequest" in entry ? "refused" : "other";
|
|
9815
|
+
}
|
|
9816
|
+
function replayLimit(entry, migrated) {
|
|
9817
|
+
const kind = storedDelegationKind(entry);
|
|
9818
|
+
if (!isRecord4(entry) || kind !== "compact" && kind !== "signed-login") return void 0;
|
|
9819
|
+
const binding = DelegationRequestBindingSchema.safeParse(entry.authorityRequest);
|
|
9820
|
+
if (binding.success) return binding.data.requested;
|
|
9821
|
+
return !migrated && kind === "compact" && !("authorityRequest" in entry) ? "signed" : void 0;
|
|
9822
|
+
}
|
|
9823
|
+
function bindToSignedCapabilities(record, signed, source, recordedAt = (/* @__PURE__ */ new Date()).toISOString()) {
|
|
9824
|
+
return {
|
|
9825
|
+
...record,
|
|
9826
|
+
authorityRequest: DelegationRequestBindingSchema.parse({
|
|
9827
|
+
requestId: `${REQUEST_ID_PREFIX[source]}:${record.delegation.cid}`,
|
|
9828
|
+
requested: structuredClone(signed)
|
|
9829
|
+
}),
|
|
9830
|
+
authorityRequestAudit: { source, recordedAt, note: BINDING_NOTES[source] }
|
|
9831
|
+
};
|
|
9832
|
+
}
|
|
9833
|
+
async function prepareStoredDelegationReplay(profile, node, options) {
|
|
9834
|
+
if (await bindingMigrationRecorded(profile)) return true;
|
|
9835
|
+
if (!options.migrate || !await holdsPersistedSession(profile, node)) return false;
|
|
9836
|
+
try {
|
|
9837
|
+
return await withProfileLock(profile, async () => {
|
|
9838
|
+
if (await bindingMigrationRecorded(profile)) return true;
|
|
9839
|
+
if (!await holdsPersistedSession(profile, node)) return false;
|
|
9840
|
+
const recordedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
9841
|
+
const bound = /* @__PURE__ */ new Map();
|
|
9842
|
+
const unbound = [];
|
|
9843
|
+
for (const entry of await readAdditionalDelegations(profile)) {
|
|
9844
|
+
if (!isRecord4(entry) || "authorityRequest" in entry || storedDelegationKind(entry) !== "compact") continue;
|
|
9845
|
+
const migrated = await migratedRecord(node, entry, options.host, recordedAt);
|
|
9846
|
+
if (migrated === void 0) unbound.push(String(storedCid(entry)));
|
|
9847
|
+
else bound.set(recordKey(entry), migrated);
|
|
9848
|
+
}
|
|
9849
|
+
if (bound.size > 0) {
|
|
9850
|
+
await updateProfileStore(profile, "additional-delegations", (records) => ({
|
|
9851
|
+
records: records.map((entry) => {
|
|
9852
|
+
const key = !isRecord4(entry) || "authorityRequest" in entry ? void 0 : recordKey(entry);
|
|
9853
|
+
return (key === void 0 ? void 0 : bound.get(key)) ?? entry;
|
|
9854
|
+
}),
|
|
9855
|
+
result: void 0
|
|
9856
|
+
}));
|
|
9857
|
+
}
|
|
9858
|
+
await writeJsonAtomic(bindingMigrationPath(profile), {
|
|
9859
|
+
formatVersion: 1,
|
|
9860
|
+
migratedAt: recordedAt,
|
|
9861
|
+
bound: [...bound.values()].map(storedCid),
|
|
9862
|
+
unbound
|
|
9863
|
+
});
|
|
9864
|
+
return true;
|
|
9865
|
+
}, { timeoutMs: MIGRATION_LOCK_TIMEOUT_MS });
|
|
9866
|
+
} catch {
|
|
9867
|
+
return false;
|
|
9868
|
+
}
|
|
9869
|
+
}
|
|
9870
|
+
async function holdsPersistedSession(profile, node) {
|
|
9871
|
+
try {
|
|
9872
|
+
const persisted = await readSession(profile);
|
|
9873
|
+
return typeof persisted?.verificationMethod === "string" && typeof node.sessionDid === "string" && persisted.verificationMethod.split("#", 1)[0] === node.sessionDid.split("#", 1)[0];
|
|
9874
|
+
} catch {
|
|
9875
|
+
return false;
|
|
9876
|
+
}
|
|
9877
|
+
}
|
|
9878
|
+
async function migratedRecord(node, entry, host, recordedAt) {
|
|
9879
|
+
const delegation = normalizeStoredDelegation(entry);
|
|
9880
|
+
if (delegation === void 0) return void 0;
|
|
9881
|
+
const signed = await signedCapabilities(node, delegation, host);
|
|
9882
|
+
if (signed === void 0) return void 0;
|
|
9883
|
+
try {
|
|
9884
|
+
return bindToSignedCapabilities({ ...entry, delegation: { ...entry.delegation, cid: delegation.cid } }, signed, "migration", recordedAt);
|
|
9885
|
+
} catch {
|
|
9886
|
+
return void 0;
|
|
9887
|
+
}
|
|
9888
|
+
}
|
|
9889
|
+
async function replayStoredDelegation(node, entry, options) {
|
|
9890
|
+
const delegation = normalizeStoredDelegation(entry);
|
|
9891
|
+
if (delegation === void 0 || delegation.expiry.getTime() <= Date.now()) return void 0;
|
|
9892
|
+
const limit = replayLimit(entry, options.migrated);
|
|
9893
|
+
if (limit === void 0) return void 0;
|
|
9894
|
+
const authorize = limit === "signed" ? () => true : (effective) => delegationWithinRequest(limit, effective, options.resolveSpace);
|
|
9895
|
+
try {
|
|
9896
|
+
return await nodeSdk3.activateValidatedRuntimeDelegation(node, delegation, { host: options.host, authorize });
|
|
9897
|
+
} catch {
|
|
9898
|
+
return void 0;
|
|
9899
|
+
}
|
|
9900
|
+
}
|
|
9901
|
+
async function bindingMigrationRecorded(profile) {
|
|
9902
|
+
try {
|
|
9903
|
+
return await readJson(bindingMigrationPath(profile)) !== null;
|
|
9904
|
+
} catch {
|
|
9905
|
+
return true;
|
|
9906
|
+
}
|
|
9907
|
+
}
|
|
9908
|
+
async function signedCapabilities(node, delegation, host) {
|
|
9909
|
+
let signed;
|
|
9910
|
+
try {
|
|
9911
|
+
await nodeSdk3.activateValidatedRuntimeDelegation(node, delegation, {
|
|
9912
|
+
// The transport host is not signed authority; check it at replay instead.
|
|
9913
|
+
host: delegation.host ?? host,
|
|
9914
|
+
authorize: (effective) => {
|
|
9915
|
+
signed = effective;
|
|
9916
|
+
return false;
|
|
9917
|
+
}
|
|
9918
|
+
});
|
|
9919
|
+
} catch {
|
|
9920
|
+
}
|
|
9921
|
+
return signed;
|
|
9922
|
+
}
|
|
9923
|
+
function normalizeStoredDelegation(entry) {
|
|
9924
|
+
if (!isRecord4(entry)) return void 0;
|
|
9925
|
+
const raw = entry.delegation;
|
|
9926
|
+
if (!isRecord4(raw) || !isRecord4(raw.delegationHeader)) return void 0;
|
|
9927
|
+
const expiry = raw.expiry instanceof Date ? raw.expiry : typeof raw.expiry === "string" ? new Date(raw.expiry) : void 0;
|
|
9928
|
+
if (expiry === void 0 || Number.isNaN(expiry.getTime()) || typeof raw.cid !== "string" || typeof raw.spaceId !== "string" || typeof raw.path !== "string" || !Array.isArray(raw.actions) || !raw.actions.every((action) => typeof action === "string") || typeof raw.delegateDID !== "string" || typeof raw.ownerAddress !== "string" || typeof raw.chainId !== "number" || typeof raw.delegationHeader.Authorization !== "string") {
|
|
9929
|
+
return void 0;
|
|
9930
|
+
}
|
|
9931
|
+
return { ...raw, expiry };
|
|
9932
|
+
}
|
|
9933
|
+
function storedCid(entry) {
|
|
9934
|
+
const cid = isRecord4(entry) && isRecord4(entry.delegation) ? entry.delegation.cid : void 0;
|
|
9935
|
+
return typeof cid === "string" ? cid : void 0;
|
|
9936
|
+
}
|
|
9937
|
+
function recordKey(entry) {
|
|
9938
|
+
const delegation = entry.delegation;
|
|
9939
|
+
if (!isRecord4(delegation) || !isRecord4(delegation.delegationHeader)) return void 0;
|
|
9940
|
+
return JSON.stringify([delegation.cid, delegation.delegationHeader.Authorization]);
|
|
9941
|
+
}
|
|
9942
|
+
function isRecord4(value) {
|
|
9943
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
9944
|
+
}
|
|
9945
|
+
var REQUEST_ID_PREFIX, BINDING_NOTES, MIGRATION_LOCK_TIMEOUT_MS;
|
|
9946
|
+
var init_delegation_binding = __esm({
|
|
9947
|
+
"src/delegation-binding.ts"() {
|
|
9948
|
+
"use strict";
|
|
9949
|
+
init_artifacts();
|
|
9950
|
+
init_authority();
|
|
9951
|
+
init_state();
|
|
9952
|
+
init_secrets();
|
|
9953
|
+
REQUEST_ID_PREFIX = {
|
|
9954
|
+
migration: "migrated",
|
|
9955
|
+
"unbound-import": "unbound-import"
|
|
9956
|
+
};
|
|
9957
|
+
BINDING_NOTES = {
|
|
9958
|
+
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.",
|
|
9959
|
+
"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."
|
|
9960
|
+
};
|
|
9961
|
+
MIGRATION_LOCK_TIMEOUT_MS = 250;
|
|
9962
|
+
}
|
|
9963
|
+
});
|
|
9964
|
+
|
|
9791
9965
|
// src/operations/status.ts
|
|
9792
9966
|
import { z as z7 } from "zod";
|
|
9793
9967
|
function createStatusDefinition(params) {
|
|
@@ -9844,7 +10018,7 @@ async function inspectPinnedProfileStatus(context, _input) {
|
|
|
9844
10018
|
async function pinnedProfileExists(profile) {
|
|
9845
10019
|
try {
|
|
9846
10020
|
const storedProfile = await readProfile(profile);
|
|
9847
|
-
return
|
|
10021
|
+
return isRecord5(storedProfile);
|
|
9848
10022
|
} catch {
|
|
9849
10023
|
return false;
|
|
9850
10024
|
}
|
|
@@ -9855,16 +10029,18 @@ async function countLiveAdditionalDelegations(profile) {
|
|
|
9855
10029
|
if (rawDelegations === null) return 0;
|
|
9856
10030
|
if (!Array.isArray(rawDelegations)) throw new TypeError("Invalid additional delegation store.");
|
|
9857
10031
|
const now = Date.now();
|
|
10032
|
+
const migrated = await bindingMigrationRecorded(profile);
|
|
9858
10033
|
let count = 0;
|
|
9859
10034
|
for (const entry of rawDelegations) {
|
|
10035
|
+
if (storedDelegationKind(entry) === "refused") continue;
|
|
9860
10036
|
const expiry = storedDelegationExpiry(entry);
|
|
9861
|
-
if (expiry.getTime() > now) count += 1;
|
|
10037
|
+
if (expiry.getTime() > now && replayLimit(entry, migrated) !== void 0) count += 1;
|
|
9862
10038
|
}
|
|
9863
10039
|
return count;
|
|
9864
10040
|
}
|
|
9865
10041
|
function summarizeSession(session) {
|
|
9866
10042
|
if (session === null) return { present: false, expired: null, expiresAt: null };
|
|
9867
|
-
if (!
|
|
10043
|
+
if (!isRecord5(session)) throw new TypeError("Invalid session store.");
|
|
9868
10044
|
const expiry = extractSessionExpiry(session);
|
|
9869
10045
|
if (expiry === null) return { present: true, expired: null, expiresAt: null };
|
|
9870
10046
|
return {
|
|
@@ -9874,7 +10050,7 @@ function summarizeSession(session) {
|
|
|
9874
10050
|
};
|
|
9875
10051
|
}
|
|
9876
10052
|
function storedDelegationExpiry(entry) {
|
|
9877
|
-
if (!
|
|
10053
|
+
if (!isRecord5(entry) || !isRecord5(entry.delegation) || !("expiry" in entry.delegation)) {
|
|
9878
10054
|
throw new TypeError("Invalid stored delegation.");
|
|
9879
10055
|
}
|
|
9880
10056
|
return parseExpiry(entry.delegation.expiry);
|
|
@@ -9903,13 +10079,14 @@ function profileNotFound(profile) {
|
|
|
9903
10079
|
)
|
|
9904
10080
|
};
|
|
9905
10081
|
}
|
|
9906
|
-
function
|
|
10082
|
+
function isRecord5(value) {
|
|
9907
10083
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
9908
10084
|
}
|
|
9909
10085
|
var StatusInputSchema, StatusOutputSchema, STATUS_POSTURES, STATUS_EXPOSURE, STATUS_SENSITIVITY, statusOperationDefinitions;
|
|
9910
10086
|
var init_status = __esm({
|
|
9911
10087
|
"src/operations/status.ts"() {
|
|
9912
10088
|
"use strict";
|
|
10089
|
+
init_delegation_binding();
|
|
9913
10090
|
init_errors();
|
|
9914
10091
|
init_state();
|
|
9915
10092
|
StatusInputSchema = z7.object({}).strict();
|
|
@@ -9932,7 +10109,9 @@ var init_status = __esm({
|
|
|
9932
10109
|
expired: z7.boolean().nullable(),
|
|
9933
10110
|
expiresAt: z7.string().datetime({ offset: true }).nullable()
|
|
9934
10111
|
}).strict(),
|
|
9935
|
-
liveAdditionalDelegationCount: z7.number().int().nonnegative()
|
|
10112
|
+
liveAdditionalDelegationCount: z7.number().int().nonnegative().describe(
|
|
10113
|
+
"Stored, unexpired delegations the replay rule accepts: compact-UCAN or signed-login records with a request binding, and unbound compact-UCAN records before the profile's one-time binding migration. Each is still validated, and checked against its binding, when a runtime installs it."
|
|
10114
|
+
)
|
|
9936
10115
|
}).strict();
|
|
9937
10116
|
STATUS_POSTURES = [
|
|
9938
10117
|
"owner-openkey",
|
|
@@ -10086,9 +10265,9 @@ function isOperatorType(value) {
|
|
|
10086
10265
|
return value === "human" || value === "agent";
|
|
10087
10266
|
}
|
|
10088
10267
|
function isStoredProfile(value) {
|
|
10089
|
-
return
|
|
10268
|
+
return isRecord6(value) && isNonEmptyString(value.name) && isNonEmptyString(value.host) && typeof value.chainId === "number" && Number.isFinite(value.chainId) && isNonEmptyString(value.spaceName) && isNonEmptyString(value.did) && isNonEmptyString(value.createdAt) && isOptionalNonEmptyString(value.sessionDid) && isOptionalNonEmptyString(value.ownerDid) && isOptionalNonEmptyString(value.spaceId) && isOptionalPosture(value.posture) && isOptionalOperatorType(value.operatorType) && isOptionalAuthMethod(value.authMethod) && isOptionalNonEmptyString(value.defaultSpace) && isOptionalNonEmptyString(value.privateKey) && isOptionalNonEmptyString(value.address) && isOptionalNonEmptyString(value.openkeyHost);
|
|
10090
10269
|
}
|
|
10091
|
-
function
|
|
10270
|
+
function isRecord6(value) {
|
|
10092
10271
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
10093
10272
|
}
|
|
10094
10273
|
function isNonEmptyString(value) {
|
|
@@ -10129,7 +10308,7 @@ var runtime_exports = {};
|
|
|
10129
10308
|
__export(runtime_exports, {
|
|
10130
10309
|
createInvocationRuntime: () => createInvocationRuntime
|
|
10131
10310
|
});
|
|
10132
|
-
import * as
|
|
10311
|
+
import * as nodeSdk4 from "@tinycloud/node-sdk";
|
|
10133
10312
|
async function createInvocationRuntime(target, requirement = "authenticated") {
|
|
10134
10313
|
const resolved = await resolveInvocationProfile(target);
|
|
10135
10314
|
if (!resolved.ok) {
|
|
@@ -10146,14 +10325,12 @@ async function createInvocationRuntime(target, requirement = "authenticated") {
|
|
|
10146
10325
|
const profileName = summary.profile;
|
|
10147
10326
|
try {
|
|
10148
10327
|
const {
|
|
10149
|
-
activateValidatedRuntimeDelegation: activateValidatedRuntimeDelegation2,
|
|
10150
10328
|
TinyCloudNode: TinyCloudNodeConstructor
|
|
10151
|
-
} =
|
|
10329
|
+
} = nodeSdk4;
|
|
10152
10330
|
const explicitPrivateKeyOverride = typeof target.privateKey === "string";
|
|
10153
|
-
const [session, key
|
|
10331
|
+
const [session, key] = explicitPrivateKeyOverride ? [null, null] : await Promise.all([
|
|
10154
10332
|
readSession(profileName),
|
|
10155
|
-
readJson(`${profilePath(profileName)}/key.json`)
|
|
10156
|
-
readAdditionalDelegations(profileName)
|
|
10333
|
+
readJson(`${profilePath(profileName)}/key.json`)
|
|
10157
10334
|
]);
|
|
10158
10335
|
const profile = resolved.profile;
|
|
10159
10336
|
const actualPosture = resolvePosture(profile);
|
|
@@ -10200,19 +10377,26 @@ async function createInvocationRuntime(target, requirement = "authenticated") {
|
|
|
10200
10377
|
const livePrincipalDid = normalizeDid(node.did);
|
|
10201
10378
|
const authenticatedSpace = explicitPrivateKeyOverride ? spaceForAuthenticatedPrincipal(livePrincipalDid) : void 0;
|
|
10202
10379
|
const livePermissions = [...node.getVerifiedSessionCapabilities()];
|
|
10380
|
+
const resolveSpace2 = operationSpaceResolver(node, authenticatedSpace ?? summary.space);
|
|
10203
10381
|
const seenCids = /* @__PURE__ */ new Set();
|
|
10204
|
-
|
|
10205
|
-
const
|
|
10206
|
-
|
|
10207
|
-
|
|
10208
|
-
|
|
10209
|
-
|
|
10382
|
+
if (!explicitPrivateKeyOverride) {
|
|
10383
|
+
const activator = node;
|
|
10384
|
+
const migrated = await prepareStoredDelegationReplay(profileName, activator, {
|
|
10385
|
+
host: summary.host,
|
|
10386
|
+
// Only the profile's own restored session; a local sign-in without
|
|
10387
|
+
// one uses a fresh session key the stored records do not address.
|
|
10388
|
+
migrate: activeSession !== void 0
|
|
10389
|
+
});
|
|
10390
|
+
for (const entry of await readAdditionalDelegations(profileName)) {
|
|
10391
|
+
const activated = await replayStoredDelegation(activator, entry, {
|
|
10392
|
+
host: summary.host,
|
|
10393
|
+
migrated,
|
|
10394
|
+
resolveSpace: resolveSpace2
|
|
10210
10395
|
});
|
|
10211
|
-
if (!seenCids.has(activated.cid)) {
|
|
10396
|
+
if (activated !== void 0 && !seenCids.has(activated.cid)) {
|
|
10212
10397
|
seenCids.add(activated.cid);
|
|
10213
10398
|
livePermissions.push(...activated.effectivePermissions);
|
|
10214
10399
|
}
|
|
10215
|
-
} catch {
|
|
10216
10400
|
}
|
|
10217
10401
|
}
|
|
10218
10402
|
const runtime = {
|
|
@@ -10244,8 +10428,8 @@ async function createInvocationRuntime(target, requirement = "authenticated") {
|
|
|
10244
10428
|
function spaceForAuthenticatedPrincipal(principal2) {
|
|
10245
10429
|
if (principal2 === void 0) return void 0;
|
|
10246
10430
|
try {
|
|
10247
|
-
const pkh =
|
|
10248
|
-
return pkh === null ? void 0 :
|
|
10431
|
+
const pkh = nodeSdk4.parsePkhDid(principal2);
|
|
10432
|
+
return pkh === null ? void 0 : nodeSdk4.makePkhSpaceId(pkh.address, pkh.chainId, "secrets");
|
|
10249
10433
|
} catch {
|
|
10250
10434
|
return void 0;
|
|
10251
10435
|
}
|
|
@@ -10253,7 +10437,7 @@ function spaceForAuthenticatedPrincipal(principal2) {
|
|
|
10253
10437
|
function normalizeSession(session, key) {
|
|
10254
10438
|
const header = session.delegationHeader;
|
|
10255
10439
|
const jwk = hasPrivateParameter(session.jwk) ? session.jwk : key;
|
|
10256
|
-
if (!
|
|
10440
|
+
if (!isRecord7(header) || typeof header.Authorization !== "string" || typeof session.delegationCid !== "string" || typeof session.spaceId !== "string" || !hasPrivateParameter(jwk) || typeof session.verificationMethod !== "string") {
|
|
10257
10441
|
return void 0;
|
|
10258
10442
|
}
|
|
10259
10443
|
return {
|
|
@@ -10269,27 +10453,14 @@ function normalizeSession(session, key) {
|
|
|
10269
10453
|
...Array.isArray(session.tinycloudHosts) && session.tinycloudHosts.every((host) => typeof host === "string") ? { tinycloudHosts: session.tinycloudHosts } : {}
|
|
10270
10454
|
};
|
|
10271
10455
|
}
|
|
10272
|
-
function normalizeStoredDelegation(entry) {
|
|
10273
|
-
const raw = entry.delegation;
|
|
10274
|
-
if (!isRecord6(raw) || !isRecord6(raw.delegationHeader)) return void 0;
|
|
10275
|
-
const expiry = parseExpiry2(raw.expiry);
|
|
10276
|
-
if (expiry === void 0 || typeof raw.cid !== "string" || typeof raw.spaceId !== "string" || typeof raw.path !== "string" || !Array.isArray(raw.actions) || !raw.actions.every((action) => typeof action === "string") || typeof raw.delegateDID !== "string" || typeof raw.ownerAddress !== "string" || typeof raw.chainId !== "number" || typeof raw.delegationHeader.Authorization !== "string") {
|
|
10277
|
-
return void 0;
|
|
10278
|
-
}
|
|
10279
|
-
return { ...raw, expiry };
|
|
10280
|
-
}
|
|
10281
|
-
function parseExpiry2(value) {
|
|
10282
|
-
const expiry = value instanceof Date ? value : typeof value === "string" ? new Date(value) : void 0;
|
|
10283
|
-
return expiry !== void 0 && !Number.isNaN(expiry.getTime()) ? expiry : void 0;
|
|
10284
|
-
}
|
|
10285
10456
|
function hasPrivateParameter(value) {
|
|
10286
|
-
return
|
|
10457
|
+
return isRecord7(value) && typeof value.d === "string" && value.d.length > 0;
|
|
10287
10458
|
}
|
|
10288
10459
|
function normalizeDid(value) {
|
|
10289
10460
|
if (typeof value !== "string" || value.length === 0) return void 0;
|
|
10290
10461
|
return value.split("#", 1)[0];
|
|
10291
10462
|
}
|
|
10292
|
-
function
|
|
10463
|
+
function isRecord7(value) {
|
|
10293
10464
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
10294
10465
|
}
|
|
10295
10466
|
function failed(context, error) {
|
|
@@ -10308,7 +10479,9 @@ var init_runtime = __esm({
|
|
|
10308
10479
|
init_authority();
|
|
10309
10480
|
init_errors();
|
|
10310
10481
|
init_profile();
|
|
10482
|
+
init_secrets();
|
|
10311
10483
|
init_state();
|
|
10484
|
+
init_delegation_binding();
|
|
10312
10485
|
}
|
|
10313
10486
|
});
|
|
10314
10487
|
|