@tinycloud/sdk-core 3.10.0 → 3.11.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/delegations/index.cjs +1 -3
- package/dist/delegations/index.cjs.map +1 -1
- package/dist/delegations/index.js +1 -3
- package/dist/delegations/index.js.map +1 -1
- package/dist/index.cjs +77 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +79 -2
- package/dist/index.d.ts +79 -2
- package/dist/index.js +77 -4
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -140,6 +140,8 @@ __export(index_exports, {
|
|
|
140
140
|
MAX_SECRET_SCOPE_LENGTH: () => import_sdk_services10.MAX_SECRET_SCOPE_LENGTH,
|
|
141
141
|
MAX_SHARE_ARTIFACT_BYTES: () => MAX_SHARE_ARTIFACT_BYTES,
|
|
142
142
|
MAX_SHARE_CONTENT_BYTES: () => MAX_SHARE_CONTENT_BYTES,
|
|
143
|
+
MAX_SIWE_EXPIRY_MS: () => MAX_SIWE_EXPIRY_MS,
|
|
144
|
+
MAX_UCAN_EXPIRY_MS: () => MAX_UCAN_EXPIRY_MS,
|
|
143
145
|
ManifestValidationError: () => ManifestValidationError,
|
|
144
146
|
MemorySenderShareKeyStorage: () => MemorySenderShareKeyStorage,
|
|
145
147
|
MemorySenderShareRecordStorage: () => MemorySenderShareRecordStorage,
|
|
@@ -259,6 +261,7 @@ __export(index_exports, {
|
|
|
259
261
|
admitPolicyCredentialV4: () => admitPolicyCredentialV4,
|
|
260
262
|
appSecretScope: () => import_sdk_services10.appSecretScope,
|
|
261
263
|
applyPrefix: () => applyPrefix,
|
|
264
|
+
assertExpiryWithinTechnicalLimit: () => assertExpiryWithinTechnicalLimit,
|
|
262
265
|
assertSpaceCreationAllowed: () => assertSpaceCreationAllowed,
|
|
263
266
|
authorizationVerdictOf: () => import_sdk_services10.authorizationVerdictOf,
|
|
264
267
|
bootstrapEncryptionNetworkId: () => import_bootstrap4.bootstrapEncryptionNetworkId,
|
|
@@ -288,6 +291,7 @@ __export(index_exports, {
|
|
|
288
291
|
canonicalizeSecretScope: () => import_sdk_services10.canonicalizeSecretScope,
|
|
289
292
|
canonicalizeSignedObjectUnsigned: () => canonicalizeSignedObjectUnsigned,
|
|
290
293
|
canonicalizeUnifiedPolicyCapability: () => canonicalizeUnifiedPolicyCapability,
|
|
294
|
+
checkChangedExpiration: () => checkChangedExpiration,
|
|
291
295
|
checkDecryptInvocationInput: () => import_sdk_services10.checkDecryptInvocationInput,
|
|
292
296
|
checkNodeInfo: () => checkNodeInfo,
|
|
293
297
|
classifyRegistryLookup: () => classifyRegistryLookup,
|
|
@@ -475,6 +479,7 @@ __export(index_exports, {
|
|
|
475
479
|
signedObjectIdFor: () => signedObjectIdFor,
|
|
476
480
|
storageUsageState: () => import_sdk_services10.storageUsageState,
|
|
477
481
|
submitHostDelegation: () => submitHostDelegation,
|
|
482
|
+
technicalExpiryRefusal: () => technicalExpiryRefusal,
|
|
478
483
|
tinyCloudDebugLogger: () => import_sdk_services10.tinyCloudDebugLogger,
|
|
479
484
|
toSignedObjectError: () => toSignedObjectError,
|
|
480
485
|
unauthorizedRecapCapabilities: () => unauthorizedRecapCapabilities,
|
|
@@ -11126,15 +11131,27 @@ var SIGNED_READ_URL_MS = 5 * 60 * 1e3;
|
|
|
11126
11131
|
var SESSION_MS = 30 * 24 * 60 * 60 * 1e3;
|
|
11127
11132
|
var SHARE_MS = 7 * 24 * 60 * 60 * 1e3;
|
|
11128
11133
|
var APP_MS = 30 * 24 * 60 * 60 * 1e3;
|
|
11129
|
-
var MAX_MS = 10 * 365 * 24 * 60 * 60 * 1e3;
|
|
11130
11134
|
var EXPIRY = {
|
|
11131
11135
|
EPHEMERAL_MS,
|
|
11132
11136
|
SIGNED_READ_URL_MS,
|
|
11133
11137
|
SESSION_MS,
|
|
11134
11138
|
SHARE_MS,
|
|
11135
|
-
APP_MS
|
|
11136
|
-
MAX_MS
|
|
11139
|
+
APP_MS
|
|
11137
11140
|
};
|
|
11141
|
+
var MAX_SIWE_EXPIRY_MS = 253402300799e3;
|
|
11142
|
+
var MAX_UCAN_EXPIRY_MS = 9007199254e3;
|
|
11143
|
+
function technicalExpiryRefusal(expiresAt, kind) {
|
|
11144
|
+
const ms2 = Number(expiresAt);
|
|
11145
|
+
const siwe = kind === "siwe";
|
|
11146
|
+
const last = siwe ? "9999-12-31" : "2255-06-05";
|
|
11147
|
+
if (!Number.isFinite(ms2) || ms2 < 0) return `expiry is not a valid date or is too far away to hold; choose one before ${last}`;
|
|
11148
|
+
if (ms2 <= (siwe ? MAX_SIWE_EXPIRY_MS : MAX_UCAN_EXPIRY_MS)) return null;
|
|
11149
|
+
return `expiry is later than ${last}, ${siwe ? "the latest date a TinyCloud signed message can carry" : "the latest date an agent or share delegation can carry (UCAN limit); a delegation signed by the wallet (delegateTo with forceWalletSign: true) can go to 9999-12-31"}; choose an earlier expiry`;
|
|
11150
|
+
}
|
|
11151
|
+
function assertExpiryWithinTechnicalLimit(expiresAt, kind) {
|
|
11152
|
+
const refusal = technicalExpiryRefusal(expiresAt, kind);
|
|
11153
|
+
if (refusal) throw new Error(refusal);
|
|
11154
|
+
}
|
|
11138
11155
|
var DEFAULT_SIGNED_READ_URL_EXPIRY_MS = EXPIRY.SIGNED_READ_URL_MS;
|
|
11139
11156
|
|
|
11140
11157
|
// src/delegations/SharingService.ts
|
|
@@ -16679,7 +16696,7 @@ function diffImmutableSiweFields(original, signed, options2) {
|
|
|
16679
16696
|
"requestId",
|
|
16680
16697
|
"nonRecapResources"
|
|
16681
16698
|
];
|
|
16682
|
-
const keys = options2?.originalHasRecap ? baseKeys : [...baseKeys, "statement"];
|
|
16699
|
+
const keys = (options2?.originalHasRecap ? baseKeys : [...baseKeys, "statement"]).filter((key) => !(options2?.allowExpirationChange === true && key === "expirationTime"));
|
|
16683
16700
|
const diffs = [];
|
|
16684
16701
|
for (const key of keys) {
|
|
16685
16702
|
const a = original[key] ?? "";
|
|
@@ -16690,6 +16707,62 @@ function diffImmutableSiweFields(original, signed, options2) {
|
|
|
16690
16707
|
}
|
|
16691
16708
|
return diffs;
|
|
16692
16709
|
}
|
|
16710
|
+
var CHANGED_EXPIRY_MIN_REMAINING_MS = 6e4;
|
|
16711
|
+
var ISO_INSTANT = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(?:\.\d+)?(?:Z|[+-]\d{2}:\d{2})$/;
|
|
16712
|
+
function parseInstantMs(value) {
|
|
16713
|
+
const match = value === void 0 ? null : ISO_INSTANT.exec(value);
|
|
16714
|
+
if (!match || value === void 0) return void 0;
|
|
16715
|
+
const [year, month, day] = [Number(match[1]), Number(match[2]), Number(match[3])];
|
|
16716
|
+
if (new Date(Date.UTC(year, month - 1, day)).getUTCDate() !== day) return void 0;
|
|
16717
|
+
const ms2 = Date.parse(value);
|
|
16718
|
+
return Number.isFinite(ms2) ? ms2 : void 0;
|
|
16719
|
+
}
|
|
16720
|
+
var EXPIRATION_LINE = /^Expiration Time:/;
|
|
16721
|
+
function hasCanonicalExpirationLine(siwe) {
|
|
16722
|
+
if (siwe.includes("\r")) return false;
|
|
16723
|
+
const lines = siwe.split("\n");
|
|
16724
|
+
const index = lines.findIndex((line) => EXPIRATION_LINE.test(line));
|
|
16725
|
+
if (index < 0 || !/^Expiration Time: \S+$/.test(lines[index])) return false;
|
|
16726
|
+
const resources = lines.indexOf("Resources:", 4);
|
|
16727
|
+
return resources < 0 || index < resources;
|
|
16728
|
+
}
|
|
16729
|
+
function checkChangedExpiration(input) {
|
|
16730
|
+
const nowMs = input.now instanceof Date ? input.now.getTime() : input.now;
|
|
16731
|
+
if (!Number.isFinite(nowMs)) return "expiry check needs a finite current time";
|
|
16732
|
+
const maxMs = input.maxExpiresAt === void 0 ? void 0 : input.maxExpiresAt instanceof Date ? input.maxExpiresAt.getTime() : input.maxExpiresAt;
|
|
16733
|
+
if (maxMs !== void 0 && !Number.isFinite(new Date(maxMs).getTime())) return "expiry check needs a finite maximum";
|
|
16734
|
+
const originalHasRecap = input.originalHasRecap ?? /(?:^|\n)-\s+urn:recap:/i.test(input.preparedSiwe);
|
|
16735
|
+
const countLines = (siwe) => siwe.split(/\r?\n/).filter((line) => EXPIRATION_LINE.test(line)).length;
|
|
16736
|
+
if (countLines(input.preparedSiwe) !== 1 || countLines(input.signedSiwe) !== 1) {
|
|
16737
|
+
return "expiry check needs exactly one Expiration Time line in both messages";
|
|
16738
|
+
}
|
|
16739
|
+
if (!hasCanonicalExpirationLine(input.signedSiwe)) {
|
|
16740
|
+
return "the Expiration Time line is not in canonical SIWE form";
|
|
16741
|
+
}
|
|
16742
|
+
const prepared = extractImmutableSiweFields(input.preparedSiwe);
|
|
16743
|
+
const signed = extractImmutableSiweFields(input.signedSiwe);
|
|
16744
|
+
const drift = diffImmutableSiweFields(prepared, signed, { originalHasRecap, allowExpirationChange: true });
|
|
16745
|
+
if (drift.length > 0) return `altered immutable SIWE fields: ${drift.join(", ")}`;
|
|
16746
|
+
if (signed.expirationTime === prepared.expirationTime) return null;
|
|
16747
|
+
const expiresAt = parseInstantMs(signed.expirationTime);
|
|
16748
|
+
if (expiresAt === void 0) {
|
|
16749
|
+
const later = Date.parse(signed.expirationTime ?? "");
|
|
16750
|
+
return later > MAX_SIWE_EXPIRY_MS ? technicalExpiryRefusal(later, "siwe") : "expiry is not a valid timestamp";
|
|
16751
|
+
}
|
|
16752
|
+
if (expiresAt <= nowMs + CHANGED_EXPIRY_MIN_REMAINING_MS) {
|
|
16753
|
+
return "expiry must be more than 60 seconds from now; choose a longer expiry";
|
|
16754
|
+
}
|
|
16755
|
+
for (const [label, value] of [["Issued At", prepared.issuedAt], ["Not Before", prepared.notBefore]]) {
|
|
16756
|
+
if (value === void 0 || value === "") continue;
|
|
16757
|
+
const bound = parseInstantMs(value);
|
|
16758
|
+
if (bound === void 0) return `${label} is not a valid timestamp`;
|
|
16759
|
+
if (expiresAt <= bound) return `expiry must be after ${label}; choose a later expiry`;
|
|
16760
|
+
}
|
|
16761
|
+
if (maxMs !== void 0 && expiresAt > maxMs) {
|
|
16762
|
+
return `expiry is later than the maximum for this request (the latest allowed is ${new Date(maxMs).toISOString()}); choose an earlier expiry`;
|
|
16763
|
+
}
|
|
16764
|
+
return technicalExpiryRefusal(expiresAt, "siwe");
|
|
16765
|
+
}
|
|
16693
16766
|
function extractRecapAttenuations(siwe) {
|
|
16694
16767
|
const merged = {};
|
|
16695
16768
|
const lines = siwe.split(/\r?\n/);
|