@learncard/network-plugin 3.0.0 → 3.0.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/lcn-plugin.cjs.development.cjs +510 -4
- package/dist/lcn-plugin.cjs.development.cjs.map +3 -3
- package/dist/lcn-plugin.cjs.production.min.cjs +22 -22
- package/dist/lcn-plugin.cjs.production.min.cjs.map +3 -3
- package/dist/lcn-plugin.esm.js +510 -4
- package/dist/lcn-plugin.esm.js.map +3 -3
- package/dist/plugin.d.ts.map +1 -1
- package/dist/types.d.ts +37 -2
- package/dist/types.d.ts.map +1 -1
- package/package.json +8 -8
- package/src/plugin.ts +70 -3
- package/src/types.ts +60 -1
package/dist/lcn-plugin.esm.js
CHANGED
|
@@ -17387,6 +17387,12 @@ var AuthSessionError = (_a3 = class extends Error {
|
|
|
17387
17387
|
this.name = "AuthSessionError";
|
|
17388
17388
|
}
|
|
17389
17389
|
}, __name(_a3, "AuthSessionError"), __name2(_a3, "AuthSessionError"), _a3);
|
|
17390
|
+
var EscrowPinStatusValidator = external_exports.object({
|
|
17391
|
+
state: external_exports.enum(["none", "enabled", "locked", "stale"]),
|
|
17392
|
+
enabled: external_exports.boolean(),
|
|
17393
|
+
attemptsRemaining: external_exports.number().int().nonnegative(),
|
|
17394
|
+
salt: external_exports.string().optional()
|
|
17395
|
+
});
|
|
17390
17396
|
var BITSTRING_STATUS_PURPOSES = ["revocation", "suspension"];
|
|
17391
17397
|
var BitstringStatusPurposeValidator = external_exports.enum(BITSTRING_STATUS_PURPOSES);
|
|
17392
17398
|
var BitstringStatusListEntryValidator = external_exports.object({
|
|
@@ -17495,6 +17501,456 @@ var inAppMessagesFlagValidator = external_exports.object({
|
|
|
17495
17501
|
version: external_exports.number().default(1),
|
|
17496
17502
|
messages: external_exports.array(inAppMessageValidator).default([])
|
|
17497
17503
|
}).passthrough();
|
|
17504
|
+
var SHARE_LINK_ID_BYTES = 16;
|
|
17505
|
+
var SHARE_CONTENT_KEY_BYTES = 32;
|
|
17506
|
+
var SHARE_IV_BYTES = 12;
|
|
17507
|
+
var SHARE_TAG_BYTES = 16;
|
|
17508
|
+
var MAX_SHARE_CIPHERTEXT_BYTES = 512 * 1024;
|
|
17509
|
+
var MAX_SHARE_RECOVERY_JWE_BYTES = 64 * 1024;
|
|
17510
|
+
var MAX_SELECTED_CREDENTIALS = 50;
|
|
17511
|
+
var MAX_ENDORSEMENTS = 200;
|
|
17512
|
+
var MAX_VP_MEMBERS = MAX_SELECTED_CREDENTIALS + MAX_ENDORSEMENTS;
|
|
17513
|
+
var MAX_SHARE_SOURCE_URI_CHARS = 2048;
|
|
17514
|
+
var MAX_SHARE_LINK_REQUEST_BYTES = 1024 * 1024;
|
|
17515
|
+
var SHARE_LINK_PROTOCOL = "lc-share/v1";
|
|
17516
|
+
var SHARE_RECOVERY_PROTOCOL = "lc-share-recovery/v1";
|
|
17517
|
+
var BASE64URL_ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
|
|
17518
|
+
var BASE64URL_LOOKUP = (() => {
|
|
17519
|
+
const table = new Int16Array(128).fill(-1);
|
|
17520
|
+
for (let index = 0; index < BASE64URL_ALPHABET.length; index += 1) {
|
|
17521
|
+
table[BASE64URL_ALPHABET.charCodeAt(index)] = index;
|
|
17522
|
+
}
|
|
17523
|
+
return table;
|
|
17524
|
+
})();
|
|
17525
|
+
var encodeBase64Url = /* @__PURE__ */ __name2((bytes) => {
|
|
17526
|
+
let output = "";
|
|
17527
|
+
for (let index = 0; index < bytes.length; index += 3) {
|
|
17528
|
+
const first = bytes[index];
|
|
17529
|
+
const second = bytes[index + 1];
|
|
17530
|
+
const third = bytes[index + 2];
|
|
17531
|
+
output += BASE64URL_ALPHABET[first >> 2];
|
|
17532
|
+
output += BASE64URL_ALPHABET[(first & 3) << 4 | (second ?? 0) >> 4];
|
|
17533
|
+
if (second === void 0) break;
|
|
17534
|
+
output += BASE64URL_ALPHABET[(second & 15) << 2 | (third ?? 0) >> 6];
|
|
17535
|
+
if (third === void 0) break;
|
|
17536
|
+
output += BASE64URL_ALPHABET[third & 63];
|
|
17537
|
+
}
|
|
17538
|
+
return output;
|
|
17539
|
+
}, "encodeBase64Url");
|
|
17540
|
+
var decodeBase64Url = /* @__PURE__ */ __name2((value) => {
|
|
17541
|
+
if (typeof value !== "string") return null;
|
|
17542
|
+
const output = new Uint8Array(Math.floor(value.length * 6 / 8));
|
|
17543
|
+
let bits = 0;
|
|
17544
|
+
let bitCount = 0;
|
|
17545
|
+
let outputIndex = 0;
|
|
17546
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
17547
|
+
const code = value.charCodeAt(index);
|
|
17548
|
+
const digit = code < 128 ? BASE64URL_LOOKUP[code] : -1;
|
|
17549
|
+
if (digit < 0) return null;
|
|
17550
|
+
bits = bits << 6 | digit;
|
|
17551
|
+
bitCount += 6;
|
|
17552
|
+
if (bitCount >= 8) {
|
|
17553
|
+
bitCount -= 8;
|
|
17554
|
+
output[outputIndex] = bits >> bitCount & 255;
|
|
17555
|
+
outputIndex += 1;
|
|
17556
|
+
}
|
|
17557
|
+
}
|
|
17558
|
+
return output;
|
|
17559
|
+
}, "decodeBase64Url");
|
|
17560
|
+
var isCanonicalBase64Url = /* @__PURE__ */ __name2((value, expectedBytes) => {
|
|
17561
|
+
if (typeof value !== "string") return false;
|
|
17562
|
+
if (expectedBytes !== void 0 && value.length !== Math.ceil(expectedBytes * 4 / 3))
|
|
17563
|
+
return false;
|
|
17564
|
+
const decoded = decodeBase64Url(value);
|
|
17565
|
+
if (decoded === null) return false;
|
|
17566
|
+
if (expectedBytes !== void 0 && decoded.length !== expectedBytes) return false;
|
|
17567
|
+
return encodeBase64Url(decoded) === value;
|
|
17568
|
+
}, "isCanonicalBase64Url");
|
|
17569
|
+
var utf8ByteLength = /* @__PURE__ */ __name2((value) => new TextEncoder().encode(value).length, "utf8ByteLength");
|
|
17570
|
+
var canonicalBase64Url = /* @__PURE__ */ __name2((bytes) => external_exports.string().refine((value) => isCanonicalBase64Url(value, bytes), {
|
|
17571
|
+
message: `must be canonical base64url for exactly ${bytes} bytes`
|
|
17572
|
+
}), "canonicalBase64Url");
|
|
17573
|
+
var ShareLinkIdValidator = canonicalBase64Url(SHARE_LINK_ID_BYTES);
|
|
17574
|
+
var ShareContentKeyValidator = canonicalBase64Url(SHARE_CONTENT_KEY_BYTES);
|
|
17575
|
+
var ShareIvValidator = canonicalBase64Url(SHARE_IV_BYTES);
|
|
17576
|
+
var ShareCiphertextValidator = external_exports.string().refine(
|
|
17577
|
+
(value) => {
|
|
17578
|
+
if (value.length > Math.ceil(MAX_SHARE_CIPHERTEXT_BYTES * 4 / 3)) return false;
|
|
17579
|
+
const decoded = decodeBase64Url(value);
|
|
17580
|
+
if (decoded === null) return false;
|
|
17581
|
+
if (encodeBase64Url(decoded) !== value) return false;
|
|
17582
|
+
return decoded.length >= SHARE_TAG_BYTES && decoded.length <= MAX_SHARE_CIPHERTEXT_BYTES;
|
|
17583
|
+
},
|
|
17584
|
+
{
|
|
17585
|
+
message: `must be canonical base64url decoding to ${SHARE_TAG_BYTES}..${MAX_SHARE_CIPHERTEXT_BYTES} bytes`
|
|
17586
|
+
}
|
|
17587
|
+
);
|
|
17588
|
+
var ShareEnvelopeValidator = external_exports.object({
|
|
17589
|
+
v: external_exports.literal(1),
|
|
17590
|
+
alg: external_exports.literal("A256GCM"),
|
|
17591
|
+
iv: ShareIvValidator,
|
|
17592
|
+
ct: ShareCiphertextValidator
|
|
17593
|
+
}).strict();
|
|
17594
|
+
var safeVersion = external_exports.number().int().min(1).max(2 ** 31 - 1);
|
|
17595
|
+
var safeCredentialIndex = external_exports.number().int().min(0).max(MAX_VP_MEMBERS - 1);
|
|
17596
|
+
var ShareSelectionEntryValidator = external_exports.object({ credentialIndex: safeCredentialIndex }).strict();
|
|
17597
|
+
var ShareEndorsementEntryValidator = external_exports.object({ credentialIndex: safeCredentialIndex, targetCredentialIndex: safeCredentialIndex }).strict();
|
|
17598
|
+
var ShareSharerValidator = external_exports.object({
|
|
17599
|
+
profileId: external_exports.string().min(1).max(128),
|
|
17600
|
+
displayName: external_exports.string().min(1).max(120),
|
|
17601
|
+
avatar: external_exports.string().max(2048).optional()
|
|
17602
|
+
}).strict();
|
|
17603
|
+
var presentationShape = VPValidator.extend({
|
|
17604
|
+
verifiableCredential: VCValidator.array().min(1).max(MAX_VP_MEMBERS)
|
|
17605
|
+
});
|
|
17606
|
+
var hasBoundedPresentation = /* @__PURE__ */ __name2((value) => {
|
|
17607
|
+
let credentialCount = 0;
|
|
17608
|
+
const ancestors = /* @__PURE__ */ new Set();
|
|
17609
|
+
const visit = /* @__PURE__ */ __name2((node, depth) => {
|
|
17610
|
+
if (node === null || typeof node !== "object") return true;
|
|
17611
|
+
if (depth > 32 || ancestors.has(node)) return false;
|
|
17612
|
+
ancestors.add(node);
|
|
17613
|
+
try {
|
|
17614
|
+
for (const [key, child] of Object.entries(node)) {
|
|
17615
|
+
if (key === "verifiableCredential") {
|
|
17616
|
+
credentialCount += Array.isArray(child) ? child.length : 1;
|
|
17617
|
+
if (credentialCount > MAX_VP_MEMBERS) return false;
|
|
17618
|
+
}
|
|
17619
|
+
if (!visit(child, depth + 1)) return false;
|
|
17620
|
+
}
|
|
17621
|
+
return true;
|
|
17622
|
+
} finally {
|
|
17623
|
+
ancestors.delete(node);
|
|
17624
|
+
}
|
|
17625
|
+
}, "visit");
|
|
17626
|
+
return visit(value, 0);
|
|
17627
|
+
}, "hasBoundedPresentation");
|
|
17628
|
+
var ShareManifestPresentationValidator = external_exports.custom(
|
|
17629
|
+
(value) => hasBoundedPresentation(value) && presentationShape.safeParse(value).success,
|
|
17630
|
+
{ message: "invalid share presentation" }
|
|
17631
|
+
);
|
|
17632
|
+
var SharePayloadValidatorShape = external_exports.object({
|
|
17633
|
+
protocol: external_exports.literal(SHARE_LINK_PROTOCOL),
|
|
17634
|
+
shareId: ShareLinkIdValidator,
|
|
17635
|
+
contentVersion: safeVersion,
|
|
17636
|
+
createdAt: external_exports.iso.datetime(),
|
|
17637
|
+
sharer: ShareSharerValidator,
|
|
17638
|
+
presentation: ShareManifestPresentationValidator,
|
|
17639
|
+
selection: ShareSelectionEntryValidator.array().min(1).max(MAX_SELECTED_CREDENTIALS),
|
|
17640
|
+
endorsements: ShareEndorsementEntryValidator.array().max(MAX_ENDORSEMENTS).default([])
|
|
17641
|
+
}).strict();
|
|
17642
|
+
var classificationFailure = /* @__PURE__ */ __name2((code, message, path = []) => ({ ok: false, code, message, path }), "classificationFailure");
|
|
17643
|
+
var readSignedClaimId = /* @__PURE__ */ __name2((member) => {
|
|
17644
|
+
if (member === null || typeof member !== "object") return void 0;
|
|
17645
|
+
const record2 = member;
|
|
17646
|
+
const claim = record2.credentialSubject ?? record2.endorsement;
|
|
17647
|
+
if (claim === null || typeof claim !== "object") return void 0;
|
|
17648
|
+
const claimRecord = claim;
|
|
17649
|
+
const nested = claimRecord.endorsement;
|
|
17650
|
+
const nestedId = nested !== null && typeof nested === "object" ? nested.id : void 0;
|
|
17651
|
+
return claimRecord.id ?? nestedId;
|
|
17652
|
+
}, "readSignedClaimId");
|
|
17653
|
+
var classifyShareManifest = /* @__PURE__ */ __name2((payload) => {
|
|
17654
|
+
const members = payload.presentation?.verifiableCredential;
|
|
17655
|
+
if (!Array.isArray(members) || members.length === 0) {
|
|
17656
|
+
return classificationFailure("NO_PRESENTATION_MEMBERS", "presentation has no credentials");
|
|
17657
|
+
}
|
|
17658
|
+
if (members.length > MAX_VP_MEMBERS) {
|
|
17659
|
+
return classificationFailure(
|
|
17660
|
+
"TOO_MANY_VP_MEMBERS",
|
|
17661
|
+
`presentation has ${members.length} members, over the ${MAX_VP_MEMBERS} bound`
|
|
17662
|
+
);
|
|
17663
|
+
}
|
|
17664
|
+
const selection = payload.selection;
|
|
17665
|
+
const endorsements = payload.endorsements ?? [];
|
|
17666
|
+
if (!Array.isArray(selection) || selection.length < 1 || selection.length > MAX_SELECTED_CREDENTIALS) {
|
|
17667
|
+
return classificationFailure("BAD_SELECTION", "selection must contain 1..50 entries");
|
|
17668
|
+
}
|
|
17669
|
+
if (!Array.isArray(endorsements) || endorsements.length > MAX_ENDORSEMENTS) {
|
|
17670
|
+
return classificationFailure(
|
|
17671
|
+
"BAD_ENDORSEMENTS",
|
|
17672
|
+
"endorsements must contain at most 200 entries"
|
|
17673
|
+
);
|
|
17674
|
+
}
|
|
17675
|
+
const selectedIndices = [];
|
|
17676
|
+
const selected = /* @__PURE__ */ new Set();
|
|
17677
|
+
for (let index = 0; index < selection.length; index += 1) {
|
|
17678
|
+
const entry = selection[index];
|
|
17679
|
+
const credentialIndex = entry?.credentialIndex;
|
|
17680
|
+
if (!Number.isSafeInteger(credentialIndex) || credentialIndex < 0 || credentialIndex >= members.length) {
|
|
17681
|
+
return classificationFailure(
|
|
17682
|
+
"SELECTION_INDEX_OUT_OF_BOUNDS",
|
|
17683
|
+
`selection[${index}].credentialIndex is out of bounds`,
|
|
17684
|
+
["selection", index, "credentialIndex"]
|
|
17685
|
+
);
|
|
17686
|
+
}
|
|
17687
|
+
if (selected.has(credentialIndex)) {
|
|
17688
|
+
return classificationFailure(
|
|
17689
|
+
"SELECTION_INDEX_DUPLICATE",
|
|
17690
|
+
`selection[${index}].credentialIndex is duplicated`,
|
|
17691
|
+
["selection", index, "credentialIndex"]
|
|
17692
|
+
);
|
|
17693
|
+
}
|
|
17694
|
+
selected.add(credentialIndex);
|
|
17695
|
+
selectedIndices.push(credentialIndex);
|
|
17696
|
+
}
|
|
17697
|
+
const classified = new Set(selected);
|
|
17698
|
+
const endorsementIndices = [];
|
|
17699
|
+
for (let index = 0; index < endorsements.length; index += 1) {
|
|
17700
|
+
const entry = endorsements[index];
|
|
17701
|
+
const credentialIndex = entry?.credentialIndex;
|
|
17702
|
+
const targetIndex = entry?.targetCredentialIndex;
|
|
17703
|
+
if (!Number.isSafeInteger(credentialIndex) || credentialIndex < 0 || credentialIndex >= members.length) {
|
|
17704
|
+
return classificationFailure(
|
|
17705
|
+
"ENDORSEMENT_INDEX_OUT_OF_BOUNDS",
|
|
17706
|
+
`endorsements[${index}].credentialIndex is out of bounds`,
|
|
17707
|
+
["endorsements", index, "credentialIndex"]
|
|
17708
|
+
);
|
|
17709
|
+
}
|
|
17710
|
+
if (classified.has(credentialIndex)) {
|
|
17711
|
+
return classificationFailure(
|
|
17712
|
+
"VP_MEMBER_CLASSIFIED_TWICE",
|
|
17713
|
+
`endorsements[${index}].credentialIndex was already classified`,
|
|
17714
|
+
["endorsements", index, "credentialIndex"]
|
|
17715
|
+
);
|
|
17716
|
+
}
|
|
17717
|
+
if (!selected.has(targetIndex)) {
|
|
17718
|
+
return classificationFailure(
|
|
17719
|
+
"ENDORSEMENT_TARGET_NOT_SELECTED",
|
|
17720
|
+
`endorsements[${index}].targetCredentialIndex must reference a selected credential`,
|
|
17721
|
+
["endorsements", index, "targetCredentialIndex"]
|
|
17722
|
+
);
|
|
17723
|
+
}
|
|
17724
|
+
const referenced = readSignedClaimId(members[credentialIndex]);
|
|
17725
|
+
const target = members[targetIndex];
|
|
17726
|
+
const targetId = target !== null && typeof target === "object" ? target.id : void 0;
|
|
17727
|
+
if (typeof referenced !== "string" || typeof targetId !== "string" || referenced !== targetId) {
|
|
17728
|
+
return classificationFailure(
|
|
17729
|
+
"ENDORSEMENT_TARGET_UNBOUND",
|
|
17730
|
+
`endorsements[${index}] claim does not reference the target credential id`,
|
|
17731
|
+
["endorsements", index]
|
|
17732
|
+
);
|
|
17733
|
+
}
|
|
17734
|
+
classified.add(credentialIndex);
|
|
17735
|
+
endorsementIndices.push(credentialIndex);
|
|
17736
|
+
}
|
|
17737
|
+
if (classified.size !== members.length) {
|
|
17738
|
+
return classificationFailure(
|
|
17739
|
+
"UNCLASSIFIED_VP_MEMBER",
|
|
17740
|
+
"every presentation member must be classified exactly once",
|
|
17741
|
+
["presentation", "verifiableCredential"]
|
|
17742
|
+
);
|
|
17743
|
+
}
|
|
17744
|
+
return {
|
|
17745
|
+
ok: true,
|
|
17746
|
+
classification: { selectedIndices, endorsementIndices, memberCount: members.length }
|
|
17747
|
+
};
|
|
17748
|
+
}, "classifyShareManifest");
|
|
17749
|
+
var SharePayloadValidator = SharePayloadValidatorShape.superRefine((payload, ctx) => {
|
|
17750
|
+
const result = classifyShareManifest(payload);
|
|
17751
|
+
if (!result.ok) {
|
|
17752
|
+
ctx.addIssue({
|
|
17753
|
+
code: "custom",
|
|
17754
|
+
message: result.message,
|
|
17755
|
+
path: result.path,
|
|
17756
|
+
params: { shareLinkCode: result.code }
|
|
17757
|
+
});
|
|
17758
|
+
}
|
|
17759
|
+
});
|
|
17760
|
+
var ShareRecoverySelectionValidator = external_exports.object({
|
|
17761
|
+
ref: external_exports.string().min(1).max(MAX_SHARE_SOURCE_URI_CHARS),
|
|
17762
|
+
order: external_exports.number().int().min(0).max(MAX_SELECTED_CREDENTIALS - 1)
|
|
17763
|
+
}).strict();
|
|
17764
|
+
var ShareRecoveryEndorsementValidator = external_exports.object({ targetRef: external_exports.string().min(1).max(MAX_SHARE_SOURCE_URI_CHARS) }).strict();
|
|
17765
|
+
var ShareRecoveryPlaintextValidator = external_exports.object({
|
|
17766
|
+
protocol: external_exports.literal(SHARE_RECOVERY_PROTOCOL),
|
|
17767
|
+
shareId: ShareLinkIdValidator,
|
|
17768
|
+
ownerProfileId: external_exports.string().min(1).max(128),
|
|
17769
|
+
createdAt: external_exports.iso.datetime(),
|
|
17770
|
+
latest: external_exports.object({ contentVersion: safeVersion, key: ShareContentKeyValidator }).strict(),
|
|
17771
|
+
selection: ShareRecoverySelectionValidator.array().min(1).max(MAX_SELECTED_CREDENTIALS),
|
|
17772
|
+
endorsements: ShareRecoveryEndorsementValidator.array().max(MAX_ENDORSEMENTS).default([])
|
|
17773
|
+
}).strict().superRefine((recovery, ctx) => {
|
|
17774
|
+
const orders = /* @__PURE__ */ new Set();
|
|
17775
|
+
recovery.selection.forEach((entry, index) => {
|
|
17776
|
+
if (entry.order >= recovery.selection.length) {
|
|
17777
|
+
ctx.addIssue({
|
|
17778
|
+
code: "custom",
|
|
17779
|
+
message: "order must be within the selection bounds",
|
|
17780
|
+
path: ["selection", index, "order"]
|
|
17781
|
+
});
|
|
17782
|
+
}
|
|
17783
|
+
if (orders.has(entry.order)) {
|
|
17784
|
+
ctx.addIssue({
|
|
17785
|
+
code: "custom",
|
|
17786
|
+
message: "order must be unique within the selection",
|
|
17787
|
+
path: ["selection", index, "order"]
|
|
17788
|
+
});
|
|
17789
|
+
}
|
|
17790
|
+
orders.add(entry.order);
|
|
17791
|
+
});
|
|
17792
|
+
});
|
|
17793
|
+
var ShareOwnerRecoveryValidator = JWEValidator.refine(
|
|
17794
|
+
(value) => utf8ByteLength(JSON.stringify(value)) <= MAX_SHARE_RECOVERY_JWE_BYTES,
|
|
17795
|
+
{ message: `serialized recovery JWE must be at most ${MAX_SHARE_RECOVERY_JWE_BYTES} bytes` }
|
|
17796
|
+
);
|
|
17797
|
+
var ShareLinkStatusValidator = external_exports.enum(["pending", "active", "stopped"]);
|
|
17798
|
+
var ShareContentStateValidator = external_exports.enum(["staging", "finalized", "content_missing"]);
|
|
17799
|
+
var ShareLinkValidator = external_exports.object({
|
|
17800
|
+
id: ShareLinkIdValidator,
|
|
17801
|
+
title: external_exports.string().min(1).max(120),
|
|
17802
|
+
note: external_exports.string().max(500).optional(),
|
|
17803
|
+
selectedCount: external_exports.number().int().min(1).max(MAX_SELECTED_CREDENTIALS),
|
|
17804
|
+
version: safeVersion,
|
|
17805
|
+
contentVersion: safeVersion,
|
|
17806
|
+
status: ShareLinkStatusValidator,
|
|
17807
|
+
contentState: ShareContentStateValidator,
|
|
17808
|
+
createdAt: external_exports.iso.datetime(),
|
|
17809
|
+
updatedAt: external_exports.iso.datetime(),
|
|
17810
|
+
expiresAt: external_exports.iso.datetime().nullable(),
|
|
17811
|
+
stoppedAt: external_exports.iso.datetime().nullable(),
|
|
17812
|
+
lastViewedAt: external_exports.iso.datetime().nullable(),
|
|
17813
|
+
viewCount: external_exports.number().int().min(0).optional(),
|
|
17814
|
+
passcodeProtected: external_exports.boolean(),
|
|
17815
|
+
notifyOnView: external_exports.boolean(),
|
|
17816
|
+
minorPolicy: external_exports.object({
|
|
17817
|
+
isMinor: external_exports.boolean().nullable(),
|
|
17818
|
+
policyResolved: external_exports.boolean(),
|
|
17819
|
+
defaultExpiryDays: external_exports.union([external_exports.literal(30), external_exports.literal(365)]),
|
|
17820
|
+
viewCountingEnabled: external_exports.boolean()
|
|
17821
|
+
}),
|
|
17822
|
+
/**
|
|
17823
|
+
* Guarded application/API URL for the content. Optional because owner APIs in
|
|
17824
|
+
* D1 have no public resolve/content endpoint yet; it must never be a
|
|
17825
|
+
* LearnCloud object URL or carry a fabricated decryption key.
|
|
17826
|
+
*/
|
|
17827
|
+
contentUrl: external_exports.string().optional()
|
|
17828
|
+
});
|
|
17829
|
+
var clientRequestId = external_exports.string().uuid();
|
|
17830
|
+
var CreateShareLinkInputValidator = external_exports.object({
|
|
17831
|
+
id: ShareLinkIdValidator,
|
|
17832
|
+
clientRequestId,
|
|
17833
|
+
title: external_exports.string().min(1).max(120),
|
|
17834
|
+
note: external_exports.string().max(500).optional(),
|
|
17835
|
+
expiresAt: external_exports.iso.datetime().nullable().optional(),
|
|
17836
|
+
passcode: external_exports.string().min(8).max(64).optional(),
|
|
17837
|
+
notifyOnView: external_exports.boolean().default(false),
|
|
17838
|
+
selectedCount: external_exports.number().int().min(1).max(MAX_SELECTED_CREDENTIALS),
|
|
17839
|
+
contentVersion: external_exports.literal(1),
|
|
17840
|
+
envelope: ShareEnvelopeValidator,
|
|
17841
|
+
ownerEncryptedRecovery: ShareOwnerRecoveryValidator
|
|
17842
|
+
}).strict();
|
|
17843
|
+
var UpdateShareLinkInputValidator = external_exports.object({
|
|
17844
|
+
id: ShareLinkIdValidator,
|
|
17845
|
+
expectedVersion: safeVersion,
|
|
17846
|
+
clientRequestId,
|
|
17847
|
+
title: external_exports.string().min(1).max(120).optional(),
|
|
17848
|
+
note: external_exports.string().max(500).nullable().optional(),
|
|
17849
|
+
expiresAt: external_exports.iso.datetime().nullable().optional(),
|
|
17850
|
+
/** Omitted preserves the current passcode, null removes it, and a string replaces it. */
|
|
17851
|
+
passcode: external_exports.string().min(8).max(64).nullable().optional(),
|
|
17852
|
+
notifyOnView: external_exports.boolean().optional(),
|
|
17853
|
+
contentVersion: safeVersion.optional(),
|
|
17854
|
+
selectedCount: external_exports.number().int().min(1).max(MAX_SELECTED_CREDENTIALS).optional(),
|
|
17855
|
+
envelope: ShareEnvelopeValidator.optional(),
|
|
17856
|
+
ownerEncryptedRecovery: ShareOwnerRecoveryValidator.optional()
|
|
17857
|
+
}).strict().superRefine((value, ctx) => {
|
|
17858
|
+
const provided = [
|
|
17859
|
+
value.contentVersion,
|
|
17860
|
+
value.selectedCount,
|
|
17861
|
+
value.envelope,
|
|
17862
|
+
value.ownerEncryptedRecovery
|
|
17863
|
+
].filter((field) => field !== void 0).length;
|
|
17864
|
+
if (provided !== 0 && provided !== 4) {
|
|
17865
|
+
ctx.addIssue({
|
|
17866
|
+
code: "custom",
|
|
17867
|
+
message: "content replacement requires contentVersion, selectedCount, envelope and ownerEncryptedRecovery together"
|
|
17868
|
+
});
|
|
17869
|
+
}
|
|
17870
|
+
});
|
|
17871
|
+
var ShareLinkIdInputValidator = external_exports.object({ id: ShareLinkIdValidator }).strict();
|
|
17872
|
+
var ShareLinkOperationKeyInputValidator = external_exports.object({ id: ShareLinkIdValidator, operationId: external_exports.string().uuid() }).strict();
|
|
17873
|
+
var ShareLinkOwnerCommitOutputValidator = external_exports.discriminatedUnion("status", [
|
|
17874
|
+
external_exports.object({ status: external_exports.literal("completed"), share: ShareLinkValidator }).strict(),
|
|
17875
|
+
external_exports.object({
|
|
17876
|
+
status: external_exports.literal("pending"),
|
|
17877
|
+
id: ShareLinkIdValidator,
|
|
17878
|
+
operationId: external_exports.string().uuid()
|
|
17879
|
+
}).strict()
|
|
17880
|
+
]);
|
|
17881
|
+
var ShareLinkOwnerStatusOutputValidator = external_exports.discriminatedUnion("status", [
|
|
17882
|
+
external_exports.object({ status: external_exports.literal("found"), share: ShareLinkValidator }).strict(),
|
|
17883
|
+
external_exports.object({
|
|
17884
|
+
status: external_exports.literal("pending"),
|
|
17885
|
+
id: ShareLinkIdValidator,
|
|
17886
|
+
operationId: external_exports.string().uuid()
|
|
17887
|
+
}).strict(),
|
|
17888
|
+
external_exports.object({ status: external_exports.literal("not_found"), id: ShareLinkIdValidator }).strict()
|
|
17889
|
+
]);
|
|
17890
|
+
var ShareLinkOwnerRecoveryOutputValidator = external_exports.object({ recovery: ShareOwnerRecoveryValidator }).strict();
|
|
17891
|
+
var ShareLinkOwnerContentOutputValidator = external_exports.object({
|
|
17892
|
+
id: ShareLinkIdValidator,
|
|
17893
|
+
contentVersion: safeVersion,
|
|
17894
|
+
envelope: ShareEnvelopeValidator
|
|
17895
|
+
}).strict();
|
|
17896
|
+
var ResolveShareLinkInputValidator = external_exports.object({
|
|
17897
|
+
id: ShareLinkIdValidator,
|
|
17898
|
+
/** Sent only in a POST body; it must never be placed in a share URL. */
|
|
17899
|
+
passcode: external_exports.string().min(4).max(64).optional()
|
|
17900
|
+
}).strict();
|
|
17901
|
+
var ShareLinkPublicStateValidator = external_exports.discriminatedUnion("state", [
|
|
17902
|
+
external_exports.object({
|
|
17903
|
+
state: external_exports.literal("passcode_required"),
|
|
17904
|
+
id: ShareLinkIdValidator
|
|
17905
|
+
}).strict(),
|
|
17906
|
+
external_exports.object({ state: external_exports.literal("try_later"), id: ShareLinkIdValidator }).strict(),
|
|
17907
|
+
external_exports.object({
|
|
17908
|
+
state: external_exports.literal("active"),
|
|
17909
|
+
id: ShareLinkIdValidator,
|
|
17910
|
+
title: external_exports.string().max(120),
|
|
17911
|
+
note: external_exports.string().max(500).optional(),
|
|
17912
|
+
selectedCount: external_exports.number().int().min(1).max(MAX_SELECTED_CREDENTIALS),
|
|
17913
|
+
contentVersion: safeVersion,
|
|
17914
|
+
contentUrl: external_exports.string(),
|
|
17915
|
+
sharer: external_exports.object({
|
|
17916
|
+
displayName: external_exports.string().max(120),
|
|
17917
|
+
avatar: external_exports.string().max(2048).optional()
|
|
17918
|
+
}),
|
|
17919
|
+
createdAt: external_exports.iso.datetime(),
|
|
17920
|
+
updatedAt: external_exports.iso.datetime(),
|
|
17921
|
+
expiresAt: external_exports.iso.datetime().nullable()
|
|
17922
|
+
}).strict(),
|
|
17923
|
+
external_exports.object({
|
|
17924
|
+
state: external_exports.literal("expired"),
|
|
17925
|
+
id: ShareLinkIdValidator,
|
|
17926
|
+
expiresAt: external_exports.iso.datetime()
|
|
17927
|
+
}).strict(),
|
|
17928
|
+
external_exports.object({
|
|
17929
|
+
state: external_exports.literal("stopped"),
|
|
17930
|
+
id: ShareLinkIdValidator,
|
|
17931
|
+
stoppedAt: external_exports.iso.datetime()
|
|
17932
|
+
}).strict(),
|
|
17933
|
+
external_exports.object({ state: external_exports.literal("not_found"), id: ShareLinkIdValidator }).strict()
|
|
17934
|
+
]);
|
|
17935
|
+
var ListShareLinksInputValidator = external_exports.object({
|
|
17936
|
+
limit: external_exports.number().int().min(1).max(50).default(25),
|
|
17937
|
+
cursor: external_exports.string().max(512).optional()
|
|
17938
|
+
}).strict();
|
|
17939
|
+
var PaginatedShareLinksValidator = PaginationResponseValidator.extend({
|
|
17940
|
+
records: ShareLinkValidator.array()
|
|
17941
|
+
});
|
|
17942
|
+
var AcknowledgeViewInputValidator = external_exports.object({
|
|
17943
|
+
receipt: external_exports.string().min(22).max(128).regex(/^[A-Za-z0-9_-]+$/)
|
|
17944
|
+
}).strict();
|
|
17945
|
+
var AcknowledgeViewOutputValidator = external_exports.object({ ok: external_exports.literal(true) }).strict();
|
|
17946
|
+
var SHARE_VIEW_RECEIPT_TTL_SECONDS = 10 * 60;
|
|
17947
|
+
var ShareLinkPublicContentViewValidator = external_exports.object({
|
|
17948
|
+
id: ShareLinkIdValidator,
|
|
17949
|
+
contentVersion: safeVersion,
|
|
17950
|
+
envelope: ShareEnvelopeValidator,
|
|
17951
|
+
contentUrl: external_exports.string(),
|
|
17952
|
+
receipt: external_exports.string().min(22).max(128).regex(/^[A-Za-z0-9_-]+$/)
|
|
17953
|
+
}).strict();
|
|
17498
17954
|
|
|
17499
17955
|
// src/plugin.ts
|
|
17500
17956
|
import {
|
|
@@ -18564,6 +19020,49 @@ async function getLearnCardNetworkPlugin(learnCard, url2, apiTokenOrOptions, opt
|
|
|
18564
19020
|
await ensureUser();
|
|
18565
19021
|
return client.profile.invalidateInvite.mutate({ challenge });
|
|
18566
19022
|
}, "invalidateInvite"),
|
|
19023
|
+
createShareLink: /* @__PURE__ */ __name(async (_learnCard, input) => {
|
|
19024
|
+
await ensureUser();
|
|
19025
|
+
return client.shareLinks.create.mutate(input);
|
|
19026
|
+
}, "createShareLink"),
|
|
19027
|
+
updateShareLink: /* @__PURE__ */ __name(async (_learnCard, input) => {
|
|
19028
|
+
await ensureUser();
|
|
19029
|
+
return client.shareLinks.update.mutate(input);
|
|
19030
|
+
}, "updateShareLink"),
|
|
19031
|
+
revokeShareLink: /* @__PURE__ */ __name(async (_learnCard, input) => {
|
|
19032
|
+
await ensureUser();
|
|
19033
|
+
return client.shareLinks.revoke.mutate(input);
|
|
19034
|
+
}, "revokeShareLink"),
|
|
19035
|
+
getShareLink: /* @__PURE__ */ __name(async (_learnCard, id) => {
|
|
19036
|
+
await ensureUser();
|
|
19037
|
+
return client.shareLinks.get.query({ id });
|
|
19038
|
+
}, "getShareLink"),
|
|
19039
|
+
getShareLinkOperationStatus: /* @__PURE__ */ __name(async (_learnCard, input) => {
|
|
19040
|
+
await ensureUser();
|
|
19041
|
+
return client.shareLinks.getOperationStatus.query(input);
|
|
19042
|
+
}, "getShareLinkOperationStatus"),
|
|
19043
|
+
retryShareLinkOperation: /* @__PURE__ */ __name(async (_learnCard, input) => {
|
|
19044
|
+
await ensureUser();
|
|
19045
|
+
return client.shareLinks.retry.mutate(input);
|
|
19046
|
+
}, "retryShareLinkOperation"),
|
|
19047
|
+
getShareLinkRecovery: /* @__PURE__ */ __name(async (_learnCard, id) => {
|
|
19048
|
+
await ensureUser();
|
|
19049
|
+
return client.shareLinks.getRecovery.query({ id });
|
|
19050
|
+
}, "getShareLinkRecovery"),
|
|
19051
|
+
getShareLinkOwnerContent: /* @__PURE__ */ __name(async (_learnCard, id) => {
|
|
19052
|
+
await ensureUser();
|
|
19053
|
+
return client.shareLinks.getContent.query({ id });
|
|
19054
|
+
}, "getShareLinkOwnerContent"),
|
|
19055
|
+
listShareLinks: /* @__PURE__ */ __name(async (_learnCard, input) => {
|
|
19056
|
+
await ensureUser();
|
|
19057
|
+
return client.shareLinks.list.query(input);
|
|
19058
|
+
}, "listShareLinks"),
|
|
19059
|
+
// Anonymous public methods: deliberately NO `ensureUser()`. A viewer
|
|
19060
|
+
// has no account and must not need one.
|
|
19061
|
+
// POST keeps an optional passcode in the request body and out of URLs,
|
|
19062
|
+
// access logs, browser history and referrers.
|
|
19063
|
+
resolveShareLink: /* @__PURE__ */ __name(async (_learnCard, id, passcode) => client.publicShareLinks.resolve.mutate({ id, passcode }), "resolveShareLink"),
|
|
19064
|
+
getShareLinkContent: /* @__PURE__ */ __name(async (_learnCard, id, passcode) => client.publicShareLinks.content.mutate({ id, passcode }), "getShareLinkContent"),
|
|
19065
|
+
acknowledgeShareLinkView: /* @__PURE__ */ __name(async (_learnCard, receipt) => client.publicShareLinks.acknowledgeView.mutate({ receipt }), "acknowledgeShareLinkView"),
|
|
18567
19066
|
blockProfile: /* @__PURE__ */ __name(async (_learnCard, profileId) => {
|
|
18568
19067
|
await ensureUser();
|
|
18569
19068
|
return client.profile.blockProfile.mutate({ profileId });
|
|
@@ -18678,12 +19177,15 @@ async function getLearnCardNetworkPlugin(learnCard, url2, apiTokenOrOptions, opt
|
|
|
18678
19177
|
await ensureUser();
|
|
18679
19178
|
return client.credential.deleteCredential.mutate({ uri });
|
|
18680
19179
|
}, "deleteCredential"),
|
|
18681
|
-
sendPresentation: /* @__PURE__ */ __name(async (_learnCard, profileId, vp, encrypt
|
|
19180
|
+
sendPresentation: /* @__PURE__ */ __name(async (_learnCard, profileId, vp, metadataOrEncrypt, encrypt) => {
|
|
18682
19181
|
await ensureUser();
|
|
18683
|
-
|
|
19182
|
+
const metadata = typeof metadataOrEncrypt === "object" ? metadataOrEncrypt : void 0;
|
|
19183
|
+
const shouldEncrypt = typeof metadataOrEncrypt === "boolean" ? metadataOrEncrypt : encrypt ?? true;
|
|
19184
|
+
if (!shouldEncrypt) {
|
|
18684
19185
|
return client.presentation.sendPresentation.mutate({
|
|
18685
19186
|
profileId,
|
|
18686
|
-
presentation: vp
|
|
19187
|
+
presentation: vp,
|
|
19188
|
+
metadata
|
|
18687
19189
|
});
|
|
18688
19190
|
}
|
|
18689
19191
|
const target = await _learnCard.invoke.getProfile(profileId);
|
|
@@ -18693,7 +19195,11 @@ async function getLearnCardNetworkPlugin(learnCard, url2, apiTokenOrOptions, opt
|
|
|
18693
19195
|
_learnCard.id.did(),
|
|
18694
19196
|
target.did
|
|
18695
19197
|
]);
|
|
18696
|
-
return client.presentation.sendPresentation.mutate({
|
|
19198
|
+
return client.presentation.sendPresentation.mutate({
|
|
19199
|
+
profileId,
|
|
19200
|
+
presentation,
|
|
19201
|
+
metadata
|
|
19202
|
+
});
|
|
18697
19203
|
}, "sendPresentation"),
|
|
18698
19204
|
acceptPresentation: /* @__PURE__ */ __name(async (_learnCard, uri) => {
|
|
18699
19205
|
await ensureUser();
|