@tinycloud/share-sdk 1.0.0-beta.7 → 1.0.0-beta.8
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/index.cjs +39 -11
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +6 -2
- package/dist/index.d.ts +6 -2
- package/dist/index.js +37 -11
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -45,6 +45,7 @@ __export(index_exports, {
|
|
|
45
45
|
authorizationMethodForTarget: () => authorizationMethodForTarget,
|
|
46
46
|
authorizeShare: () => authorizeShare,
|
|
47
47
|
canonicalOwnerSharePolicy: () => canonicalOwnerSharePolicy,
|
|
48
|
+
canonicalShareFilename: () => canonicalShareFilename,
|
|
48
49
|
canonicalize: () => canonicalize,
|
|
49
50
|
checkBearerDelegation: () => checkBearerDelegation,
|
|
50
51
|
claimShare: () => claimShare,
|
|
@@ -56,6 +57,7 @@ __export(index_exports, {
|
|
|
56
57
|
createShareV2HolderBindingArtifact: () => createShareV2HolderBindingArtifact,
|
|
57
58
|
deliverCredentialInvitation: () => deliverCredentialInvitation,
|
|
58
59
|
fromBase64Url: () => fromBase64Url,
|
|
60
|
+
hasUnsafeFilenameCodePoint: () => hasUnsafeFilenameCodePoint,
|
|
59
61
|
historyRecordForPublishedShare: () => historyRecordForPublishedShare,
|
|
60
62
|
inspectShare: () => inspectShare,
|
|
61
63
|
listShares: () => listShares,
|
|
@@ -85,6 +87,19 @@ __export(index_exports, {
|
|
|
85
87
|
});
|
|
86
88
|
module.exports = __toCommonJS(index_exports);
|
|
87
89
|
|
|
90
|
+
// src/filename-policy.ts
|
|
91
|
+
var UNSAFE_FILENAME_CODE_POINT = /[\p{Cc}\p{Cf}\p{Cs}\u2028\u2029]/u;
|
|
92
|
+
function hasUnsafeFilenameCodePoint(value) {
|
|
93
|
+
return UNSAFE_FILENAME_CODE_POINT.test(value);
|
|
94
|
+
}
|
|
95
|
+
function canonicalShareFilename(value) {
|
|
96
|
+
const canonical = value.normalize("NFC");
|
|
97
|
+
if (canonical.length === 0 || canonical === "." || canonical === ".." || canonical.includes("/") || canonical.includes("\\") || hasUnsafeFilenameCodePoint(canonical)) {
|
|
98
|
+
throw new TypeError("share filename is unsafe");
|
|
99
|
+
}
|
|
100
|
+
return canonical;
|
|
101
|
+
}
|
|
102
|
+
|
|
88
103
|
// ../share-envelope/dist/index.js
|
|
89
104
|
var import_sha2 = require("@noble/hashes/sha2");
|
|
90
105
|
var import_ed25519 = require("@noble/curves/ed25519");
|
|
@@ -6566,8 +6581,17 @@ function normalizeShareTarget(target) {
|
|
|
6566
6581
|
function targetAuthorizationMethod(target) {
|
|
6567
6582
|
return authorizationMethodForTarget(target);
|
|
6568
6583
|
}
|
|
6584
|
+
function publishFilename(value) {
|
|
6585
|
+
try {
|
|
6586
|
+
return canonicalShareFilename(value);
|
|
6587
|
+
} catch {
|
|
6588
|
+
throw new SharePublishError("invalid-argument", hasUnsafeFilenameCodePoint(value) ? "filename contains control or invisible characters" : "filename must be one safe path segment");
|
|
6589
|
+
}
|
|
6590
|
+
}
|
|
6569
6591
|
async function publishTargetShare(input) {
|
|
6570
6592
|
const target = normalizeShareTarget(input.target);
|
|
6593
|
+
const filename = publishFilename(input.filename);
|
|
6594
|
+
const files = input.files?.map((file) => ({ ...file, filename: publishFilename(file.filename) }));
|
|
6571
6595
|
if (input.targetAdapter === void 0) {
|
|
6572
6596
|
if (target.kind === "bearer") throw new SharePublishError("authority-required", "native bearer publication requires an authenticated TinyCloud node");
|
|
6573
6597
|
return {
|
|
@@ -6593,9 +6617,6 @@ async function publishTargetShare(input) {
|
|
|
6593
6617
|
return bytes3;
|
|
6594
6618
|
})();
|
|
6595
6619
|
if (source.byteLength === 0) throw new SharePublishError("invalid-argument", "share content is empty");
|
|
6596
|
-
if (!input.filename || input.filename === "." || input.filename === ".." || /[/\\\u0000-\u001f\u007f]/.test(input.filename)) {
|
|
6597
|
-
throw new SharePublishError("invalid-argument", "filename must be one safe path segment");
|
|
6598
|
-
}
|
|
6599
6620
|
if (target.kind === "bearer" && input.allowBinary !== true) {
|
|
6600
6621
|
try {
|
|
6601
6622
|
new TextDecoder("utf-8", { fatal: true }).decode(source);
|
|
@@ -6603,10 +6624,10 @@ async function publishTargetShare(input) {
|
|
|
6603
6624
|
throw new SharePublishError("invalid-argument", "Markdown input must be valid UTF-8");
|
|
6604
6625
|
}
|
|
6605
6626
|
}
|
|
6606
|
-
const
|
|
6627
|
+
const publishFiles = files === void 0 || files.length === 0 ? [{ bytes: source }] : files;
|
|
6607
6628
|
const limit = input.maxBytes ?? SHARE_CONTENT_LIMIT;
|
|
6608
6629
|
let totalBytes = 0;
|
|
6609
|
-
for (const file of
|
|
6630
|
+
for (const file of publishFiles) {
|
|
6610
6631
|
totalBytes += file.bytes.byteLength;
|
|
6611
6632
|
if (!Number.isSafeInteger(totalBytes) || totalBytes > limit) {
|
|
6612
6633
|
throw new SharePublishError("max-bytes-exceeded", "share publication exceeds the combined byte limit");
|
|
@@ -6617,8 +6638,8 @@ async function publishTargetShare(input) {
|
|
|
6617
6638
|
if (!Number.isFinite(expiresAt.getTime()) || expiresAt.getTime() <= nowMs) throw new SharePublishError("invalid-argument", "expiresAt must be a valid future time");
|
|
6618
6639
|
return input.targetAdapter.publish({
|
|
6619
6640
|
source,
|
|
6620
|
-
filename
|
|
6621
|
-
...
|
|
6641
|
+
filename,
|
|
6642
|
+
...files === void 0 ? {} : { files },
|
|
6622
6643
|
...input.mediaType === void 0 ? {} : { mediaType: input.mediaType },
|
|
6623
6644
|
...input.resourceKind === void 0 ? {} : { resourceKind: input.resourceKind },
|
|
6624
6645
|
...input.actions === void 0 ? {} : { actions: input.actions },
|
|
@@ -6768,7 +6789,11 @@ function addressedCredentialRequirement(target) {
|
|
|
6768
6789
|
return mailboxCredentialCommitment(normalized);
|
|
6769
6790
|
}
|
|
6770
6791
|
function prepareAddressedShare(request) {
|
|
6771
|
-
|
|
6792
|
+
try {
|
|
6793
|
+
canonicalShareFilename(request.filename);
|
|
6794
|
+
} catch {
|
|
6795
|
+
throw new TypeError("addressed filename is invalid");
|
|
6796
|
+
}
|
|
6772
6797
|
if (request.actions.length === 0 || request.policyActions.length === 0) throw new TypeError("addressed share actions are empty");
|
|
6773
6798
|
const target = normalizeShareTarget(request.target);
|
|
6774
6799
|
if (target.kind === "bearer") throw new TypeError("addressed target is required");
|
|
@@ -6786,9 +6811,10 @@ function assertMailboxCommitment(commitment, target) {
|
|
|
6786
6811
|
if (canonicalize(commitment.profile) !== canonicalize(expected.profile) || canonicalize(commitment.credentialType) !== canonicalize(expected.credentialType) || commitment.descriptorDigest !== expected.descriptorDigest || commitment.issuerDid !== expected.issuerDid || commitment.issuerKid !== expected.issuerKid) throw new TypeError(`${label} shares require the ${label} credential profile`);
|
|
6787
6812
|
if (commitment.requirementDigest !== expected.requirementDigest) throw new TypeError(`credential requirement is not bound to the email ${target.kind === "email" ? "address" : "domain"}`);
|
|
6788
6813
|
}
|
|
6789
|
-
async function publishAddressedShare(
|
|
6790
|
-
assertSafeInput(
|
|
6791
|
-
const { target } = prepareAddressedShare(
|
|
6814
|
+
async function publishAddressedShare(input) {
|
|
6815
|
+
assertSafeInput(input);
|
|
6816
|
+
const { target } = prepareAddressedShare(input);
|
|
6817
|
+
const options = { ...input, filename: canonicalShareFilename(input.filename) };
|
|
6792
6818
|
if (target.kind !== "recipientDid") assertMailboxCommitment(options.credentialRequirement, target);
|
|
6793
6819
|
const expiry = rfc3339Seconds(options.expiresAt);
|
|
6794
6820
|
const matcher = targetMatcher(target);
|
|
@@ -8655,6 +8681,7 @@ async function openNativeShare(sharing, link) {
|
|
|
8655
8681
|
authorizationMethodForTarget,
|
|
8656
8682
|
authorizeShare,
|
|
8657
8683
|
canonicalOwnerSharePolicy,
|
|
8684
|
+
canonicalShareFilename,
|
|
8658
8685
|
canonicalize,
|
|
8659
8686
|
checkBearerDelegation,
|
|
8660
8687
|
claimShare,
|
|
@@ -8666,6 +8693,7 @@ async function openNativeShare(sharing, link) {
|
|
|
8666
8693
|
createShareV2HolderBindingArtifact,
|
|
8667
8694
|
deliverCredentialInvitation,
|
|
8668
8695
|
fromBase64Url,
|
|
8696
|
+
hasUnsafeFilenameCodePoint,
|
|
8669
8697
|
historyRecordForPublishedShare,
|
|
8670
8698
|
inspectShare,
|
|
8671
8699
|
listShares,
|