@tinycloud/node-sdk 3.4.0 → 3.5.0-beta.1
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/{TinyCloudNode-DeV-L_14.d.cts → TinyCloudNode-N4mfZI_k.d.cts} +7 -1
- package/dist/{TinyCloudNode-DeV-L_14.d.ts → TinyCloudNode-N4mfZI_k.d.ts} +7 -1
- package/dist/{authority-BO2VqGnD.d.cts → authority-BgZpUFss.d.cts} +1 -1
- package/dist/{authority-CtsxSAoP.d.ts → authority-C670-9su.d.ts} +1 -1
- package/dist/core.cjs +256 -34
- package/dist/core.cjs.map +1 -1
- package/dist/core.d.cts +2 -2
- package/dist/core.d.ts +2 -2
- package/dist/core.js +273 -43
- package/dist/core.js.map +1 -1
- package/dist/index.cjs +272 -50
- 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 +281 -51
- package/dist/index.js.map +1 -1
- package/dist/replication/authority.d.cts +2 -2
- package/dist/replication/authority.d.ts +2 -2
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -17430,7 +17430,7 @@ __export(authority_exports, {
|
|
|
17430
17430
|
});
|
|
17431
17431
|
import { SiweMessage as SiweMessage4 } from "siwe";
|
|
17432
17432
|
import {
|
|
17433
|
-
actionContains,
|
|
17433
|
+
actionContains as actionContains2,
|
|
17434
17434
|
KV as KV4,
|
|
17435
17435
|
canonicalizeRecapCaveats as canonicalizeRecapCaveats3,
|
|
17436
17436
|
isCapabilitySubset as isCapabilitySubset3,
|
|
@@ -17546,7 +17546,7 @@ function ucanAttCovers(att, space, prefix, ability, options) {
|
|
|
17546
17546
|
const path = kvPathInResource(resource, space);
|
|
17547
17547
|
if (path === void 0) continue;
|
|
17548
17548
|
for (const [granted, caveats] of Object.entries(abilities)) {
|
|
17549
|
-
if (!
|
|
17549
|
+
if (!actionContains2(granted, ability)) continue;
|
|
17550
17550
|
if (!isCapabilitySubset3(
|
|
17551
17551
|
[{ service: KV_SERVICE2, space, path: prefix, actions: [ability] }],
|
|
17552
17552
|
[{ service: KV_SERVICE2, space, path, actions: [granted] }]
|
|
@@ -17936,6 +17936,173 @@ var PrivateKeySigner = class {
|
|
|
17936
17936
|
}
|
|
17937
17937
|
};
|
|
17938
17938
|
|
|
17939
|
+
// src/recordingServiceContext.ts
|
|
17940
|
+
import {
|
|
17941
|
+
ServiceContext
|
|
17942
|
+
} from "@tinycloud/sdk-services";
|
|
17943
|
+
import {
|
|
17944
|
+
buildRequestEvent,
|
|
17945
|
+
invocationMetaOf,
|
|
17946
|
+
requestBytesOf
|
|
17947
|
+
} from "@tinycloud/sdk-services/telemetry/requestLog";
|
|
17948
|
+
|
|
17949
|
+
// src/recordingRegistry.ts
|
|
17950
|
+
var unrecordedFetches = /* @__PURE__ */ new WeakMap();
|
|
17951
|
+
function registerRecording(context, unrecordedFetch) {
|
|
17952
|
+
unrecordedFetches.set(context, unrecordedFetch);
|
|
17953
|
+
}
|
|
17954
|
+
function unrecordedFetchOf(context) {
|
|
17955
|
+
const unrecordedFetch = unrecordedFetches.get(context);
|
|
17956
|
+
return unrecordedFetch ? unrecordedFetch() : context.fetch;
|
|
17957
|
+
}
|
|
17958
|
+
|
|
17959
|
+
// src/recordingServiceContext.ts
|
|
17960
|
+
var SYNC_ABILITY = "tinycloud.kv/sync";
|
|
17961
|
+
var INFO_PATH = "/info";
|
|
17962
|
+
function outcomeCodeOf(response) {
|
|
17963
|
+
return response === void 0 ? "ERROR" : response.ok ? "ok" : `HTTP_${response.status}`;
|
|
17964
|
+
}
|
|
17965
|
+
function replicationOp(url, meta) {
|
|
17966
|
+
if (meta !== void 0) return meta.action === SYNC_ABILITY ? `${meta.service}/sync` : void 0;
|
|
17967
|
+
return isInfoUrl(url) ? "sync/info" : void 0;
|
|
17968
|
+
}
|
|
17969
|
+
function isInfoUrl(url) {
|
|
17970
|
+
try {
|
|
17971
|
+
return new URL(url).pathname.replace(/\/+$/, "") === INFO_PATH;
|
|
17972
|
+
} catch {
|
|
17973
|
+
return false;
|
|
17974
|
+
}
|
|
17975
|
+
}
|
|
17976
|
+
function replicationEvent(sample, op) {
|
|
17977
|
+
return buildRequestEvent({
|
|
17978
|
+
service: "sync",
|
|
17979
|
+
op,
|
|
17980
|
+
url: sample.url,
|
|
17981
|
+
bytes: requestBytesOf(sample.init?.body, sample.response?.headers.get("content-length")),
|
|
17982
|
+
durationMs: performance.now() - sample.clock,
|
|
17983
|
+
attempts: sample.attempts ?? 1,
|
|
17984
|
+
ok: sample.response?.ok === true,
|
|
17985
|
+
code: outcomeCodeOf(sample.response),
|
|
17986
|
+
at: sample.at
|
|
17987
|
+
});
|
|
17988
|
+
}
|
|
17989
|
+
function createServiceContext(config) {
|
|
17990
|
+
const { requestSink, ...base2 } = config;
|
|
17991
|
+
return requestSink === void 0 ? new ServiceContext(base2) : new RecordingServiceContext(base2, requestSink);
|
|
17992
|
+
}
|
|
17993
|
+
var RecordingServiceContext = class extends ServiceContext {
|
|
17994
|
+
constructor(config, sink) {
|
|
17995
|
+
const pending = {};
|
|
17996
|
+
super({
|
|
17997
|
+
...config,
|
|
17998
|
+
invoke: rememberInvoke(config.invoke, sink, pending),
|
|
17999
|
+
invokeAny: config.invokeAny ? rememberInvokeAny(config.invokeAny, sink, pending) : void 0
|
|
18000
|
+
});
|
|
18001
|
+
this.requestSink = sink;
|
|
18002
|
+
this.pending = pending;
|
|
18003
|
+
registerRecording(this, () => this.unrecordedFetch);
|
|
18004
|
+
}
|
|
18005
|
+
/** Per-call recording; `_fetch` is read at access time, so overrides apply. */
|
|
18006
|
+
get fetch() {
|
|
18007
|
+
const raw = super.fetch;
|
|
18008
|
+
return (url, init2) => this.recordCall(raw, url, init2);
|
|
18009
|
+
}
|
|
18010
|
+
/** Transport without per-call recording. */
|
|
18011
|
+
get unrecordedFetch() {
|
|
18012
|
+
return super.fetch;
|
|
18013
|
+
}
|
|
18014
|
+
/**
|
|
18015
|
+
* One event per logical request. The first resolved attempt's init is the logged request and
|
|
18016
|
+
* `attempts` counts resolved builds. A retired context throws before the first build and records
|
|
18017
|
+
* nothing, as master does.
|
|
18018
|
+
*/
|
|
18019
|
+
async invokeWithRetry(url, build) {
|
|
18020
|
+
const at = Date.now();
|
|
18021
|
+
const clock = performance.now();
|
|
18022
|
+
let reached = false;
|
|
18023
|
+
let attempts = 0;
|
|
18024
|
+
let first;
|
|
18025
|
+
let firstMeta;
|
|
18026
|
+
let response;
|
|
18027
|
+
const attempt = async () => {
|
|
18028
|
+
reached = true;
|
|
18029
|
+
this.pending.meta = void 0;
|
|
18030
|
+
const built = build();
|
|
18031
|
+
const meta = this.pending.meta;
|
|
18032
|
+
const init2 = await built;
|
|
18033
|
+
attempts += 1;
|
|
18034
|
+
if (first === void 0) {
|
|
18035
|
+
first = init2;
|
|
18036
|
+
firstMeta = meta;
|
|
18037
|
+
}
|
|
18038
|
+
return init2;
|
|
18039
|
+
};
|
|
18040
|
+
try {
|
|
18041
|
+
response = await super.invokeWithRetry(url, attempt);
|
|
18042
|
+
return response;
|
|
18043
|
+
} finally {
|
|
18044
|
+
if (reached) {
|
|
18045
|
+
this.observeAttempt({ url, init: first, response, meta: firstMeta, at, clock, attempts });
|
|
18046
|
+
}
|
|
18047
|
+
}
|
|
18048
|
+
}
|
|
18049
|
+
async recordCall(fetchFn, url, init2) {
|
|
18050
|
+
const at = Date.now();
|
|
18051
|
+
const clock = performance.now();
|
|
18052
|
+
let response;
|
|
18053
|
+
try {
|
|
18054
|
+
response = await fetchFn(url, init2);
|
|
18055
|
+
return response;
|
|
18056
|
+
} finally {
|
|
18057
|
+
this.observeAttempt({ url, init: init2, response, at, clock });
|
|
18058
|
+
}
|
|
18059
|
+
}
|
|
18060
|
+
observeAttempt(sample) {
|
|
18061
|
+
try {
|
|
18062
|
+
const replication = replicationOp(sample.url, sample.meta ?? invocationMetaOf(sample.init?.headers));
|
|
18063
|
+
if (replication !== void 0) {
|
|
18064
|
+
this.requestSink.record(replicationEvent(sample, replication));
|
|
18065
|
+
return;
|
|
18066
|
+
}
|
|
18067
|
+
const headers = sample.init?.headers;
|
|
18068
|
+
if (sample.meta !== void 0 && typeof headers === "object" && headers !== null) {
|
|
18069
|
+
this.requestSink.remember(headers, sample.meta);
|
|
18070
|
+
}
|
|
18071
|
+
this.requestSink.observe({
|
|
18072
|
+
url: sample.url,
|
|
18073
|
+
requestHeaders: headers,
|
|
18074
|
+
requestBody: sample.init?.body,
|
|
18075
|
+
responseContentLength: sample.response?.headers.get("content-length"),
|
|
18076
|
+
ok: sample.response?.ok === true,
|
|
18077
|
+
code: outcomeCodeOf(sample.response),
|
|
18078
|
+
durationMs: performance.now() - sample.clock,
|
|
18079
|
+
attempts: sample.attempts ?? 1,
|
|
18080
|
+
at: sample.at
|
|
18081
|
+
});
|
|
18082
|
+
} catch {
|
|
18083
|
+
}
|
|
18084
|
+
}
|
|
18085
|
+
};
|
|
18086
|
+
function rememberInvoke(invoke2, sink, pending) {
|
|
18087
|
+
return (session, service, path, action, facts) => {
|
|
18088
|
+
const headers = invoke2(session, service, path, action, facts);
|
|
18089
|
+
const meta = { service, path, action, spaceId: session.spaceId };
|
|
18090
|
+
pending.meta = meta;
|
|
18091
|
+
sink.remember(headers, meta);
|
|
18092
|
+
return headers;
|
|
18093
|
+
};
|
|
18094
|
+
}
|
|
18095
|
+
function rememberInvokeAny(invokeAny2, sink, pending) {
|
|
18096
|
+
return (session, entries, facts) => {
|
|
18097
|
+
const headers = invokeAny2(session, entries, facts);
|
|
18098
|
+
const first = entries[0];
|
|
18099
|
+
const meta = first === void 0 ? void 0 : { service: first.service, path: first.path, action: first.action, spaceId: first.spaceId ?? session.spaceId };
|
|
18100
|
+
pending.meta = meta;
|
|
18101
|
+
if (meta !== void 0) sink.remember(headers, meta);
|
|
18102
|
+
return headers;
|
|
18103
|
+
};
|
|
18104
|
+
}
|
|
18105
|
+
|
|
17939
18106
|
// src/delegation.ts
|
|
17940
18107
|
import {
|
|
17941
18108
|
canonicalizeRecapCaveats,
|
|
@@ -18511,7 +18678,6 @@ import {
|
|
|
18511
18678
|
DecryptTransportResponseError,
|
|
18512
18679
|
SecretsService,
|
|
18513
18680
|
createVaultCrypto,
|
|
18514
|
-
ServiceContext as ServiceContext2,
|
|
18515
18681
|
SilentNotificationHandler,
|
|
18516
18682
|
DelegationManager,
|
|
18517
18683
|
SpaceService,
|
|
@@ -18542,7 +18708,7 @@ import {
|
|
|
18542
18708
|
KV as KV3,
|
|
18543
18709
|
SQL as SQL2,
|
|
18544
18710
|
DUCKDB as DUCKDB2,
|
|
18545
|
-
ENCRYPTION as
|
|
18711
|
+
ENCRYPTION as ENCRYPTION3,
|
|
18546
18712
|
EXPIRY as EXPIRY3,
|
|
18547
18713
|
canonicalHashHex,
|
|
18548
18714
|
canonicalizeEncryptionJson,
|
|
@@ -18554,7 +18720,7 @@ import {
|
|
|
18554
18720
|
createInMemoryRegistrySequenceStore as createInMemoryRegistrySequenceStore2,
|
|
18555
18721
|
publishLocationRecord,
|
|
18556
18722
|
principalDidEquals as principalDidEquals3,
|
|
18557
|
-
parseNetworkId as
|
|
18723
|
+
parseNetworkId as parseNetworkId3,
|
|
18558
18724
|
resolveSecretPath as resolveSecretPath2,
|
|
18559
18725
|
registerPolicyV3,
|
|
18560
18726
|
CREDENTIAL_INVITATION_REQUEST_DOMAIN,
|
|
@@ -18575,6 +18741,7 @@ import {
|
|
|
18575
18741
|
parsePermissionHint,
|
|
18576
18742
|
tinyCloudDebugLogger
|
|
18577
18743
|
} from "@tinycloud/sdk-services";
|
|
18744
|
+
import { RequestLog, observeReplicaReads, readOnlyRequestLog } from "@tinycloud/sdk-services/telemetry/requestLog";
|
|
18578
18745
|
|
|
18579
18746
|
// src/authorization/NodeUserAuthorization.ts
|
|
18580
18747
|
init_authority_sign_in();
|
|
@@ -20425,8 +20592,7 @@ import {
|
|
|
20425
20592
|
KVService,
|
|
20426
20593
|
HooksService,
|
|
20427
20594
|
SQLService,
|
|
20428
|
-
DuckDbService
|
|
20429
|
-
ServiceContext
|
|
20595
|
+
DuckDbService
|
|
20430
20596
|
} from "@tinycloud/sdk-core";
|
|
20431
20597
|
var DelegatedAccess = class {
|
|
20432
20598
|
/**
|
|
@@ -20439,12 +20605,13 @@ var DelegatedAccess = class {
|
|
|
20439
20605
|
this.session = session;
|
|
20440
20606
|
this._delegation = delegation;
|
|
20441
20607
|
this.host = host;
|
|
20442
|
-
const context =
|
|
20608
|
+
const context = createServiceContext({
|
|
20443
20609
|
invoke: invoke2,
|
|
20444
20610
|
invokeAny: invokeAny2,
|
|
20445
20611
|
fetch: lifetime?.fetch ?? globalThis.fetch.bind(globalThis),
|
|
20446
20612
|
hosts: [host],
|
|
20447
|
-
telemetry
|
|
20613
|
+
telemetry,
|
|
20614
|
+
requestSink: lifetime?.requestSink
|
|
20448
20615
|
});
|
|
20449
20616
|
this._serviceContext = lifetime ? lifetime.track(context) : context;
|
|
20450
20617
|
const prefix = this._delegation.path.replace(/\/$/, "");
|
|
@@ -20608,7 +20775,11 @@ function createWasmKeyProvider(sessionManager) {
|
|
|
20608
20775
|
|
|
20609
20776
|
// src/delegateToHelpers.ts
|
|
20610
20777
|
import {
|
|
20778
|
+
actionContains,
|
|
20779
|
+
ENCRYPTION as ENCRYPTION2,
|
|
20611
20780
|
parseExpiry,
|
|
20781
|
+
isNetworkId,
|
|
20782
|
+
parseNetworkId as parseNetworkId2,
|
|
20612
20783
|
SiweMessage as SiweMessage2,
|
|
20613
20784
|
EXPIRY as EXPIRY2
|
|
20614
20785
|
} from "@tinycloud/sdk-core";
|
|
@@ -20643,6 +20814,16 @@ function legacyParamsToPermissionEntries(actions, path, spaceIdOverride) {
|
|
|
20643
20814
|
return entries;
|
|
20644
20815
|
}
|
|
20645
20816
|
var DEFAULT_DELEGATION_EXPIRY_MS = EXPIRY2.SESSION_MS;
|
|
20817
|
+
var SHARE_NETWORK_NAME_RE = /^share-[a-z0-9][a-z0-9-]{15,35}$/;
|
|
20818
|
+
function grantsCappedDecrypt(path, actions) {
|
|
20819
|
+
if (!actions.some((action) => actionContains(action, ENCRYPTION2.DECRYPT))) {
|
|
20820
|
+
return false;
|
|
20821
|
+
}
|
|
20822
|
+
return !(isNetworkId(path) && SHARE_NETWORK_NAME_RE.test(parseNetworkId2(path).name));
|
|
20823
|
+
}
|
|
20824
|
+
function includesDecrypt(entries) {
|
|
20825
|
+
return entries.some((entry) => grantsCappedDecrypt(entry.path, entry.actions));
|
|
20826
|
+
}
|
|
20646
20827
|
function resolveExpiryMs(expiry) {
|
|
20647
20828
|
if (expiry === void 0) {
|
|
20648
20829
|
return DEFAULT_DELEGATION_EXPIRY_MS;
|
|
@@ -20816,6 +20997,15 @@ var NodeSecretsService = class {
|
|
|
20816
20997
|
if (this.hasPermission(permissionEntries)) {
|
|
20817
20998
|
return ok();
|
|
20818
20999
|
}
|
|
21000
|
+
let escalation;
|
|
21001
|
+
try {
|
|
21002
|
+
escalation = this.config.uncoveredEntries?.(permissionEntries) ?? permissionEntries;
|
|
21003
|
+
} catch (error) {
|
|
21004
|
+
return this.escalationError(action, target, error);
|
|
21005
|
+
}
|
|
21006
|
+
if (this.config.uncoveredEntries !== void 0 && escalation.length === 0) {
|
|
21007
|
+
return ok();
|
|
21008
|
+
}
|
|
20819
21009
|
if (!this.config.canEscalate()) {
|
|
20820
21010
|
return secretsError(
|
|
20821
21011
|
ErrorCodes.PERMISSION_DENIED,
|
|
@@ -20823,16 +21013,20 @@ var NodeSecretsService = class {
|
|
|
20823
21013
|
);
|
|
20824
21014
|
}
|
|
20825
21015
|
try {
|
|
20826
|
-
|
|
21016
|
+
const grant = action === "get" && this.config.grantGetPermissions !== void 0 ? this.config.grantGetPermissions : this.config.grantPermissions;
|
|
21017
|
+
await grant(escalation);
|
|
20827
21018
|
return this.restoreUnlockAfterEscalation();
|
|
20828
21019
|
} catch (error) {
|
|
20829
|
-
return
|
|
20830
|
-
ErrorCodes.PERMISSION_DENIED,
|
|
20831
|
-
error instanceof Error ? error.message : `Autosign escalation for ${displayActionUrn(action)} on ${target} failed.`,
|
|
20832
|
-
error instanceof Error ? error : void 0
|
|
20833
|
-
);
|
|
21020
|
+
return this.escalationError(action, target, error);
|
|
20834
21021
|
}
|
|
20835
21022
|
}
|
|
21023
|
+
escalationError(action, target, error) {
|
|
21024
|
+
return secretsError(
|
|
21025
|
+
ErrorCodes.PERMISSION_DENIED,
|
|
21026
|
+
error instanceof Error ? error.message : `Autosign escalation for ${displayActionUrn(action)} on ${target} failed.`,
|
|
21027
|
+
error instanceof Error ? error : void 0
|
|
21028
|
+
);
|
|
21029
|
+
}
|
|
20836
21030
|
async restoreUnlockAfterEscalation() {
|
|
20837
21031
|
if (!this.shouldRestoreUnlock) {
|
|
20838
21032
|
return ok();
|
|
@@ -20867,8 +21061,8 @@ var NodeSecretsService = class {
|
|
|
20867
21061
|
// src/TinyCloudNode.ts
|
|
20868
21062
|
var DEFAULT_HOST = "https://node.tinycloud.xyz";
|
|
20869
21063
|
var DEFAULT_ENCRYPTION_NETWORK_NAME = "default";
|
|
20870
|
-
var NETWORK_CREATE_ACTION2 =
|
|
20871
|
-
var DECRYPT_ACTION2 =
|
|
21064
|
+
var NETWORK_CREATE_ACTION2 = ENCRYPTION3.NETWORK_CREATE;
|
|
21065
|
+
var DECRYPT_ACTION2 = ENCRYPTION3.DECRYPT;
|
|
20872
21066
|
var BOOTSTRAP_COMPLETION_MARKER_KEY = "system/bootstrap/complete";
|
|
20873
21067
|
var BOOTSTRAP_COMPLETION_MARKER_VERSION = 1;
|
|
20874
21068
|
var ACCEPTED_MARKER_VERSIONS = [BOOTSTRAP_COMPLETION_MARKER_VERSION];
|
|
@@ -21044,11 +21238,12 @@ function createDefaultSessionKey(wasm) {
|
|
|
21044
21238
|
return { manager, keyId, jwk: JSON.parse(jwkStr) };
|
|
21045
21239
|
}
|
|
21046
21240
|
var ServiceGraphLifetime = class {
|
|
21047
|
-
constructor(invokeFn, invokeAnyFn, fetchFn, observeContext) {
|
|
21241
|
+
constructor(invokeFn, invokeAnyFn, fetchFn, observeContext, requestSink) {
|
|
21048
21242
|
this.invokeFn = invokeFn;
|
|
21049
21243
|
this.invokeAnyFn = invokeAnyFn;
|
|
21050
21244
|
this.fetchFn = fetchFn;
|
|
21051
21245
|
this.observeContext = observeContext;
|
|
21246
|
+
this.requestSink = requestSink;
|
|
21052
21247
|
this.abortController = new AbortController();
|
|
21053
21248
|
this.contexts = /* @__PURE__ */ new Set();
|
|
21054
21249
|
this.retired = false;
|
|
@@ -21214,7 +21409,7 @@ function ownerDelegationPermissions(params) {
|
|
|
21214
21409
|
}
|
|
21215
21410
|
if (permission.service === ENCRYPTION_PERMISSION_SERVICE2) {
|
|
21216
21411
|
try {
|
|
21217
|
-
|
|
21412
|
+
parseNetworkId3(permission.path);
|
|
21218
21413
|
} catch {
|
|
21219
21414
|
throw new Error("Owner delegation encryption permission requires a canonical network URN");
|
|
21220
21415
|
}
|
|
@@ -21237,6 +21432,8 @@ function ownerPermissionsToAbilities(permissions) {
|
|
|
21237
21432
|
return { abilities, rawAbilities };
|
|
21238
21433
|
}
|
|
21239
21434
|
var TERMINAL_DELEGATION_REQUIRES_SESSION_KEY = "disableSubDelegation requires a session-key delegation to a did:key (not did:pkh); use the session-key DID or drop the flag";
|
|
21435
|
+
var DECRYPT_GRANT_MAX_EXPIRY_MS = 60 * 60 * 1e3;
|
|
21436
|
+
var SECRET_GET_GRANT_EXPIRY_MS = 59 * 60 * 1e3;
|
|
21240
21437
|
function base64UrlEncode(bytes) {
|
|
21241
21438
|
const alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
|
|
21242
21439
|
let output = "";
|
|
@@ -21619,6 +21816,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
21619
21816
|
this.sessionManager = sessionKey.manager;
|
|
21620
21817
|
this.sessionKeyId = sessionKey.keyId;
|
|
21621
21818
|
this.sessionKeyJwk = sessionKey.jwk;
|
|
21819
|
+
this._requestLog = config.requestLog === true ? new RequestLog() : void 0;
|
|
21622
21820
|
this._serviceGraph = this.createServiceGraphLifetime();
|
|
21623
21821
|
this._capabilityRegistry = new CapabilityKeyRegistry();
|
|
21624
21822
|
this._keyProvider = new WasmKeyProvider({
|
|
@@ -21790,7 +21988,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
21790
21988
|
createKVService: (config) => {
|
|
21791
21989
|
const prefix = config.pathPrefix?.replace(/\/$/, "");
|
|
21792
21990
|
const kvService = new KVService2({ prefix });
|
|
21793
|
-
const kvContext = receiveOnlyGraph.track(
|
|
21991
|
+
const kvContext = receiveOnlyGraph.track(createServiceContext({
|
|
21992
|
+
requestSink: receiveOnlyGraph.requestSink,
|
|
21794
21993
|
invoke: config.invoke,
|
|
21795
21994
|
fetch: config.fetch ?? globalThis.fetch.bind(globalThis),
|
|
21796
21995
|
hosts: config.hosts,
|
|
@@ -21853,6 +22052,10 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
21853
22052
|
shouldUseBootstrapSignInRequest(config) {
|
|
21854
22053
|
return config.autoBootstrapAccount !== false && config.manifest === void 0 && config.capabilityRequest === void 0 && (config.prefix ?? "default") === "default" && isOpenKeyAutoSignStrategy(config.signStrategy);
|
|
21855
22054
|
}
|
|
22055
|
+
/** Sanitized developer request events; undefined unless the node was built with `requestLog: true`. */
|
|
22056
|
+
get requests() {
|
|
22057
|
+
return this._requestLog === void 0 ? void 0 : readOnlyRequestLog(this._requestLog);
|
|
22058
|
+
}
|
|
21856
22059
|
createServiceGraphLifetime() {
|
|
21857
22060
|
return new ServiceGraphLifetime(
|
|
21858
22061
|
this.invokeWithRuntimePermissions,
|
|
@@ -21863,7 +22066,9 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
21863
22066
|
(url, init2) => globalThis.fetch(url, init2),
|
|
21864
22067
|
(context) => {
|
|
21865
22068
|
this.storageFull.observe(context);
|
|
21866
|
-
|
|
22069
|
+
if (this._requestLog) observeReplicaReads(context, this._requestLog);
|
|
22070
|
+
},
|
|
22071
|
+
this._requestLog
|
|
21867
22072
|
);
|
|
21868
22073
|
}
|
|
21869
22074
|
syncResolvedHostFromAuth() {
|
|
@@ -22186,6 +22391,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
22186
22391
|
this.hostedOwnedSpaceIds.clear();
|
|
22187
22392
|
this.cancelOwnedSpaceHosts();
|
|
22188
22393
|
this.storageFull.clear();
|
|
22394
|
+
this._requestLog?.clear();
|
|
22189
22395
|
this._bootstrapSkipped = false;
|
|
22190
22396
|
this._bootstrapStatus = { skipped: false };
|
|
22191
22397
|
this.replicationDelegateSession = void 0;
|
|
@@ -22277,7 +22483,10 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
22277
22483
|
const denial = await this.denyReplicaGate({ reason: "account_switch", principal: priorPrincipal, next: nextPrincipal });
|
|
22278
22484
|
this.replicaRestoreGate = denial?.status === "unguarded" ? "gate_unavailable" : "stamp_stale";
|
|
22279
22485
|
}
|
|
22280
|
-
if (address !== this._address || chainId !== this._chainId)
|
|
22486
|
+
if (address !== this._address || chainId !== this._chainId) {
|
|
22487
|
+
this.storageFull.clear();
|
|
22488
|
+
this._requestLog?.clear();
|
|
22489
|
+
}
|
|
22281
22490
|
this._address = address;
|
|
22282
22491
|
this._chainId = chainId;
|
|
22283
22492
|
this._kv = void 0;
|
|
@@ -22856,10 +23065,11 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
22856
23065
|
const contexts = [context];
|
|
22857
23066
|
const accountSpaceId = this.ownedSpaceId(ACCOUNT_REGISTRY_SPACE2);
|
|
22858
23067
|
const createScopedContext = (spaceId) => {
|
|
22859
|
-
const scoped = this._serviceGraph.track(
|
|
23068
|
+
const scoped = this._serviceGraph.track(createServiceContext({
|
|
23069
|
+
requestSink: this._serviceGraph.requestSink,
|
|
22860
23070
|
invoke: context.invoke,
|
|
22861
23071
|
invokeAny: context.invokeAny,
|
|
22862
|
-
fetch: context
|
|
23072
|
+
fetch: unrecordedFetchOf(context),
|
|
22863
23073
|
hosts: context.hosts,
|
|
22864
23074
|
telemetry: this.config.telemetry,
|
|
22865
23075
|
retryPolicy: this.config.retryPolicy
|
|
@@ -22923,10 +23133,11 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
22923
23133
|
const promise = this.enqueueAccountRegistryOperation(session, async () => {
|
|
22924
23134
|
const sharedContext = this._serviceContext;
|
|
22925
23135
|
if (!sharedContext) return;
|
|
22926
|
-
const context = this._serviceGraph.track(
|
|
23136
|
+
const context = this._serviceGraph.track(createServiceContext({
|
|
23137
|
+
requestSink: this._serviceGraph.requestSink,
|
|
22927
23138
|
invoke: sharedContext.invoke,
|
|
22928
23139
|
invokeAny: sharedContext.invokeAny,
|
|
22929
|
-
fetch: sharedContext
|
|
23140
|
+
fetch: unrecordedFetchOf(sharedContext),
|
|
22930
23141
|
hosts: sharedContext.hosts,
|
|
22931
23142
|
telemetry: this.config.telemetry,
|
|
22932
23143
|
retryPolicy: this.config.retryPolicy
|
|
@@ -23131,7 +23342,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
23131
23342
|
return;
|
|
23132
23343
|
}
|
|
23133
23344
|
for (const networkId of this.requestedEncryptionNetworkIds()) {
|
|
23134
|
-
const parsed =
|
|
23345
|
+
const parsed = parseNetworkId3(networkId);
|
|
23135
23346
|
if (!didPrincipalMatches2(parsed.ownerDid, this.did)) {
|
|
23136
23347
|
continue;
|
|
23137
23348
|
}
|
|
@@ -23660,6 +23871,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
23660
23871
|
if (resolvedHost) this.config.host = resolvedHost;
|
|
23661
23872
|
if (spaceOwnerKey(serviceSession.spaceId) !== this.currentStorageOwner()) {
|
|
23662
23873
|
this.storageFull.clear();
|
|
23874
|
+
this._requestLog?.clear();
|
|
23663
23875
|
}
|
|
23664
23876
|
this._address = stagedAddress;
|
|
23665
23877
|
this._chainId = stagedChainId;
|
|
@@ -23779,7 +23991,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
23779
23991
|
const coreContext = graph.track(core.serviceContext);
|
|
23780
23992
|
coreContext.setSession(input.serviceSession);
|
|
23781
23993
|
}
|
|
23782
|
-
const serviceContext = graph.track(
|
|
23994
|
+
const serviceContext = graph.track(createServiceContext({
|
|
23995
|
+
requestSink: graph.requestSink,
|
|
23783
23996
|
invoke: graph.invoke,
|
|
23784
23997
|
invokeAny: graph.invokeAny,
|
|
23785
23998
|
fetch: graph.fetch,
|
|
@@ -23867,7 +24080,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
23867
24080
|
},
|
|
23868
24081
|
createKVService: (config) => {
|
|
23869
24082
|
const service = new KVService2({ prefix: config.pathPrefix?.replace(/\/$/, "") });
|
|
23870
|
-
const context = graph.track(
|
|
24083
|
+
const context = graph.track(createServiceContext({
|
|
24084
|
+
requestSink: graph.requestSink,
|
|
23871
24085
|
invoke: config.invoke,
|
|
23872
24086
|
fetch: config.fetch ?? globalThis.fetch.bind(globalThis),
|
|
23873
24087
|
hosts: config.hosts,
|
|
@@ -23907,7 +24121,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
23907
24121
|
createKVService: (spaceId) => {
|
|
23908
24122
|
graph.assertActive();
|
|
23909
24123
|
const scopedKv = new KVService2({});
|
|
23910
|
-
const context = graph.track(
|
|
24124
|
+
const context = graph.track(createServiceContext({
|
|
24125
|
+
requestSink: graph.requestSink,
|
|
23911
24126
|
invoke: graph.invoke,
|
|
23912
24127
|
invokeAny: graph.invokeAny,
|
|
23913
24128
|
fetch: graph.fetch,
|
|
@@ -23923,7 +24138,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
23923
24138
|
createVaultService: (spaceId) => {
|
|
23924
24139
|
graph.assertActive();
|
|
23925
24140
|
const scopedKv = new KVService2({});
|
|
23926
|
-
const context = graph.track(
|
|
24141
|
+
const context = graph.track(createServiceContext({
|
|
24142
|
+
requestSink: graph.requestSink,
|
|
23927
24143
|
invoke: graph.invoke,
|
|
23928
24144
|
invokeAny: graph.invokeAny,
|
|
23929
24145
|
fetch: graph.fetch,
|
|
@@ -24322,7 +24538,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
24322
24538
|
this._serviceGraph.fetch
|
|
24323
24539
|
);
|
|
24324
24540
|
this._serviceGraph.track(this.tc.serviceContext);
|
|
24325
|
-
this._serviceContext = this._serviceGraph.track(
|
|
24541
|
+
this._serviceContext = this._serviceGraph.track(createServiceContext({
|
|
24542
|
+
requestSink: this._serviceGraph.requestSink,
|
|
24326
24543
|
invoke: this._serviceGraph.invoke,
|
|
24327
24544
|
invokeAny: this._serviceGraph.invokeAny,
|
|
24328
24545
|
fetch: this._serviceGraph.fetch,
|
|
@@ -24370,10 +24587,11 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
24370
24587
|
createSpaceScopedKVService(spaceId) {
|
|
24371
24588
|
const kvService = new KVService2({});
|
|
24372
24589
|
if (this._serviceContext) {
|
|
24373
|
-
const spaceScopedContext = this._serviceGraph.track(
|
|
24590
|
+
const spaceScopedContext = this._serviceGraph.track(createServiceContext({
|
|
24591
|
+
requestSink: this._serviceGraph.requestSink,
|
|
24374
24592
|
invoke: this._serviceContext.invoke,
|
|
24375
24593
|
invokeAny: this._serviceContext.invokeAny,
|
|
24376
|
-
fetch: this._serviceContext
|
|
24594
|
+
fetch: unrecordedFetchOf(this._serviceContext),
|
|
24377
24595
|
hosts: this._serviceContext.hosts,
|
|
24378
24596
|
telemetry: this.config.telemetry,
|
|
24379
24597
|
retryPolicy: this.config.retryPolicy
|
|
@@ -24839,7 +25057,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
24839
25057
|
createKVService: (config) => {
|
|
24840
25058
|
graph.assertActive();
|
|
24841
25059
|
const service = new KVService2({ prefix: config.pathPrefix?.replace(/\/$/, "") });
|
|
24842
|
-
const context = graph.track(
|
|
25060
|
+
const context = graph.track(createServiceContext({
|
|
25061
|
+
requestSink: graph.requestSink,
|
|
24843
25062
|
invoke: config.invoke,
|
|
24844
25063
|
fetch: config.fetch ?? graph.fetch,
|
|
24845
25064
|
hosts: config.hosts,
|
|
@@ -24942,7 +25161,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
24942
25161
|
if (!session) throw new Error("Owner session is required");
|
|
24943
25162
|
const ownerDid = pkhDid2(session.address, session.chainId);
|
|
24944
25163
|
for (const permission of permissions) {
|
|
24945
|
-
if (permission.service === ENCRYPTION_PERMISSION_SERVICE2 && !principalDidEquals3(
|
|
25164
|
+
if (permission.service === ENCRYPTION_PERMISSION_SERVICE2 && !principalDidEquals3(parseNetworkId3(permission.path).ownerDid, ownerDid)) {
|
|
24946
25165
|
throw new Error("Owner delegation cannot grant a foreign encryption network");
|
|
24947
25166
|
}
|
|
24948
25167
|
}
|
|
@@ -25160,10 +25379,11 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
25160
25379
|
throw new Error("Not signed in. Call signIn() first.");
|
|
25161
25380
|
}
|
|
25162
25381
|
const sql = new SQLService2({});
|
|
25163
|
-
const spaceScopedContext = this._serviceGraph.track(
|
|
25382
|
+
const spaceScopedContext = this._serviceGraph.track(createServiceContext({
|
|
25383
|
+
requestSink: this._serviceGraph.requestSink,
|
|
25164
25384
|
invoke: this._serviceContext.invoke,
|
|
25165
25385
|
invokeAny: this._serviceContext.invokeAny,
|
|
25166
|
-
fetch: this._serviceContext
|
|
25386
|
+
fetch: unrecordedFetchOf(this._serviceContext),
|
|
25167
25387
|
hosts: this._serviceContext.hosts,
|
|
25168
25388
|
telemetry: this.config.telemetry,
|
|
25169
25389
|
retryPolicy: this.config.retryPolicy
|
|
@@ -25191,10 +25411,11 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
25191
25411
|
throw new Error("Not signed in. Call signIn() first.");
|
|
25192
25412
|
}
|
|
25193
25413
|
const kv = new KVService2({});
|
|
25194
|
-
const spaceScopedContext = this._serviceGraph.track(
|
|
25414
|
+
const spaceScopedContext = this._serviceGraph.track(createServiceContext({
|
|
25415
|
+
requestSink: this._serviceGraph.requestSink,
|
|
25195
25416
|
invoke: this._serviceContext.invoke,
|
|
25196
25417
|
invokeAny: this._serviceContext.invokeAny,
|
|
25197
|
-
fetch: this._serviceContext
|
|
25418
|
+
fetch: unrecordedFetchOf(this._serviceContext),
|
|
25198
25419
|
hosts: this._serviceContext.hosts
|
|
25199
25420
|
}));
|
|
25200
25421
|
spaceScopedContext.setSession({ ...this._serviceContext.session, spaceId });
|
|
@@ -25302,7 +25523,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
25302
25523
|
return existing;
|
|
25303
25524
|
}
|
|
25304
25525
|
}
|
|
25305
|
-
const parsed =
|
|
25526
|
+
const parsed = parseNetworkId3(networkId);
|
|
25306
25527
|
if (!didPrincipalMatches2(parsed.ownerDid, this.did)) {
|
|
25307
25528
|
throw new Error(
|
|
25308
25529
|
`Cannot create encryption network ${networkId}: owner ${parsed.ownerDid} does not match signed-in DID ${this.did}`
|
|
@@ -25335,6 +25556,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
25335
25556
|
getManifest: () => this.manifest,
|
|
25336
25557
|
hasPermissions: (permissions) => this.hasRuntimePermissions(permissions),
|
|
25337
25558
|
grantPermissions: (additional) => this.grantRuntimePermissions(additional),
|
|
25559
|
+
grantGetPermissions: (additional) => this.grantRuntimePermissions(additional, { expiry: SECRET_GET_GRANT_EXPIRY_MS }),
|
|
25560
|
+
uncoveredEntries: (permissions) => permissions.filter((entry) => !this.hasRuntimePermissions([entry])),
|
|
25338
25561
|
canEscalate: () => this.signer !== void 0 && this.tc !== void 0,
|
|
25339
25562
|
getEncryptionNetworkId: () => this.getEncryptionNetworkIdForSpace(resolvedSpace),
|
|
25340
25563
|
resolveSpace: (space) => space.startsWith("tinycloud:") ? space : this.ownedSpaceId(space),
|
|
@@ -25682,6 +25905,13 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
25682
25905
|
}
|
|
25683
25906
|
}
|
|
25684
25907
|
const expanded = this.expandPermissionEntries(permissions);
|
|
25908
|
+
const requestsDecrypt = includesDecrypt(expanded);
|
|
25909
|
+
const requestedExpiryMs = requestsDecrypt && options?.expiry === void 0 ? DECRYPT_GRANT_MAX_EXPIRY_MS : resolveExpiryMs(options?.expiry);
|
|
25910
|
+
if (requestsDecrypt && requestedExpiryMs > DECRYPT_GRANT_MAX_EXPIRY_MS) {
|
|
25911
|
+
throw Object.assign(new Error("decrypt grants last at most one hour"), {
|
|
25912
|
+
code: "DECRYPT_EXPIRY_TOO_LONG"
|
|
25913
|
+
});
|
|
25914
|
+
}
|
|
25685
25915
|
if (this.sessionCoversPermissionEntries(session, expanded)) {
|
|
25686
25916
|
return [];
|
|
25687
25917
|
}
|
|
@@ -25712,7 +25942,6 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
25712
25942
|
bySpace.set(session.spaceId, []);
|
|
25713
25943
|
}
|
|
25714
25944
|
const now = /* @__PURE__ */ new Date();
|
|
25715
|
-
const requestedExpiryMs = resolveExpiryMs(options?.expiry);
|
|
25716
25945
|
let expiresAt = new Date(now.getTime() + requestedExpiryMs);
|
|
25717
25946
|
if (sessionExpiry !== void 0 && sessionExpiry < expiresAt) {
|
|
25718
25947
|
expiresAt = sessionExpiry;
|
|
@@ -25980,7 +26209,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
25980
26209
|
}
|
|
25981
26210
|
if (this._serviceContext) {
|
|
25982
26211
|
const publicKV = new KVService2({ prefix: "" });
|
|
25983
|
-
const publicContext = this._serviceGraph.track(
|
|
26212
|
+
const publicContext = this._serviceGraph.track(createServiceContext({
|
|
26213
|
+
requestSink: this._serviceGraph.requestSink,
|
|
25984
26214
|
invoke: this._serviceGraph.invoke,
|
|
25985
26215
|
fetch: this._serviceGraph.fetch,
|
|
25986
26216
|
hosts: this._serviceContext.hosts,
|
|
@@ -27762,9 +27992,9 @@ import {
|
|
|
27762
27992
|
import {
|
|
27763
27993
|
EncryptionService as EncryptionService2,
|
|
27764
27994
|
DecryptTransportResponseError as DecryptTransportResponseError2,
|
|
27765
|
-
parseNetworkId as
|
|
27995
|
+
parseNetworkId as parseNetworkId4,
|
|
27766
27996
|
buildNetworkId,
|
|
27767
|
-
isNetworkId,
|
|
27997
|
+
isNetworkId as isNetworkId2,
|
|
27768
27998
|
networkDiscoveryKey,
|
|
27769
27999
|
NetworkIdError,
|
|
27770
28000
|
ENCRYPTION_NETWORK_URN_PREFIX,
|
|
@@ -27829,7 +28059,7 @@ import {
|
|
|
27829
28059
|
UnsupportedFeatureError as UnsupportedFeatureError2,
|
|
27830
28060
|
checkNodeInfo as checkNodeInfo3
|
|
27831
28061
|
} from "@tinycloud/sdk-core";
|
|
27832
|
-
import { ServiceContext as
|
|
28062
|
+
import { ServiceContext as ServiceContext5 } from "@tinycloud/sdk-core";
|
|
27833
28063
|
|
|
27834
28064
|
// src/replication/sqlite.ts
|
|
27835
28065
|
init_authority();
|
|
@@ -27838,7 +28068,7 @@ import { createHash as createHash2, randomBytes as randomBytes2 } from "crypto";
|
|
|
27838
28068
|
import { lstatSync, readFileSync as readFileSync2, statSync } from "fs";
|
|
27839
28069
|
import { chmod, lstat, mkdir, open as openFile, readFile, readdir, realpath, rename, rm, rmdir, stat } from "fs/promises";
|
|
27840
28070
|
import { basename, dirname as dirname2, join as join2, parse as parse2, resolve, sep } from "path";
|
|
27841
|
-
import { KVService as KVService3, ServiceContext as
|
|
28071
|
+
import { KVService as KVService3, ServiceContext as ServiceContext4, principalDid as principalDid2 } from "@tinycloud/sdk-core";
|
|
27842
28072
|
import {
|
|
27843
28073
|
canonicalReplicationIdentity,
|
|
27844
28074
|
replicationIdentityKey,
|
|
@@ -28999,7 +29229,7 @@ transports_fn = async function() {
|
|
|
28999
29229
|
const device = __privateGet(this, _device);
|
|
29000
29230
|
const fetch2 = spec.fetch ?? globalThis.fetch.bind(globalThis);
|
|
29001
29231
|
return (grant) => {
|
|
29002
|
-
const context = new
|
|
29232
|
+
const context = new ServiceContext4({
|
|
29003
29233
|
invoke: wasm.invoke,
|
|
29004
29234
|
invokeAny: wasm.invokeAny,
|
|
29005
29235
|
fetch: fetch2,
|
|
@@ -30406,7 +30636,7 @@ export {
|
|
|
30406
30636
|
STORAGE_MANAGE_URL,
|
|
30407
30637
|
STORAGE_WRITE_TOO_LARGE_MESSAGE2 as STORAGE_WRITE_TOO_LARGE_MESSAGE,
|
|
30408
30638
|
SecretsService2 as SecretsService,
|
|
30409
|
-
|
|
30639
|
+
ServiceContext5 as ServiceContext,
|
|
30410
30640
|
SessionExpiredError2 as SessionExpiredError,
|
|
30411
30641
|
SharingService2 as SharingService,
|
|
30412
30642
|
SilentNotificationHandler2 as SilentNotificationHandler,
|
|
@@ -30483,7 +30713,7 @@ export {
|
|
|
30483
30713
|
installTinyCloudDebugGlobals,
|
|
30484
30714
|
isCapabilitySubset4 as isCapabilitySubset,
|
|
30485
30715
|
isEvmAddress,
|
|
30486
|
-
isNetworkId,
|
|
30716
|
+
isNetworkId2 as isNetworkId,
|
|
30487
30717
|
isStorageFullError2 as isStorageFullError,
|
|
30488
30718
|
loadManifest,
|
|
30489
30719
|
logoutPrincipalDigest,
|
|
@@ -30493,7 +30723,7 @@ export {
|
|
|
30493
30723
|
openWrappedKey,
|
|
30494
30724
|
parseCanonicalNetworkId,
|
|
30495
30725
|
parseExpiry2 as parseExpiry,
|
|
30496
|
-
|
|
30726
|
+
parseNetworkId4 as parseNetworkId,
|
|
30497
30727
|
parsePkhDid,
|
|
30498
30728
|
parseSecretCatalogKey,
|
|
30499
30729
|
parseSpaceUri3 as parseSpaceUri,
|