@learncard/network-plugin 2.14.1 → 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/README.md +12 -0
- package/dist/inbox-batch.d.ts +5 -0
- package/dist/inbox-batch.d.ts.map +1 -0
- package/dist/inbox-batch.test.d.ts +2 -0
- package/dist/inbox-batch.test.d.ts.map +1 -0
- package/dist/lcn-plugin.cjs.development.cjs +1091 -203
- package/dist/lcn-plugin.cjs.development.cjs.map +4 -4
- package/dist/lcn-plugin.cjs.production.min.cjs +36 -36
- package/dist/lcn-plugin.cjs.production.min.cjs.map +4 -4
- package/dist/lcn-plugin.esm.js +1093 -203
- package/dist/lcn-plugin.esm.js.map +4 -4
- package/dist/plugin.d.ts +11 -0
- package/dist/plugin.d.ts.map +1 -1
- package/dist/test/act-as.test.d.ts +2 -0
- package/dist/test/act-as.test.d.ts.map +1 -0
- package/dist/test/refresh-send.test-d.d.ts +2 -0
- package/dist/test/refresh-send.test-d.d.ts.map +1 -0
- package/dist/test/refresh-send.test.d.ts +2 -0
- package/dist/test/refresh-send.test.d.ts.map +1 -0
- package/dist/types.d.ts +129 -20
- package/dist/types.d.ts.map +1 -1
- package/package.json +8 -8
- package/src/inbox-batch.test.ts +105 -0
- package/src/inbox-batch.ts +66 -0
- package/src/plugin.ts +402 -55
- package/src/test/act-as.test.ts +323 -0
- package/src/test/index.test.ts +161 -10
- package/src/test/refresh-send.test-d.ts +152 -0
- package/src/test/refresh-send.test.ts +646 -0
- package/src/types.ts +178 -23
package/dist/lcn-plugin.esm.js
CHANGED
|
@@ -5,6 +5,53 @@ var __export = (target, all) => {
|
|
|
5
5
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
6
6
|
};
|
|
7
7
|
|
|
8
|
+
// src/inbox-batch.ts
|
|
9
|
+
var waitForInboxCredentialBatch = /* @__PURE__ */ __name(async (read, options = {}) => {
|
|
10
|
+
const { timeoutMs = 6e5, intervalMs = 2e3, signal, onProgress } = options;
|
|
11
|
+
if (!Number.isFinite(timeoutMs) || timeoutMs <= 0 || timeoutMs > 2147483647 || !Number.isFinite(intervalMs) || intervalMs <= 0 || intervalMs > 2147483647) {
|
|
12
|
+
throw new RangeError("timeoutMs and intervalMs must be positive finite timer durations.");
|
|
13
|
+
}
|
|
14
|
+
const controller = new AbortController();
|
|
15
|
+
const abort = /* @__PURE__ */ __name(() => controller.abort(signal?.reason), "abort");
|
|
16
|
+
signal?.addEventListener("abort", abort, { once: true });
|
|
17
|
+
if (signal?.aborted) abort();
|
|
18
|
+
const timeout = setTimeout(() => {
|
|
19
|
+
const error51 = new Error(
|
|
20
|
+
"Timed out waiting for inbox batch. Keep the batch ID to check again."
|
|
21
|
+
);
|
|
22
|
+
error51.name = "TimeoutError";
|
|
23
|
+
controller.abort(error51);
|
|
24
|
+
}, timeoutMs);
|
|
25
|
+
const cancellable = /* @__PURE__ */ __name((operation) => new Promise((resolve, reject) => {
|
|
26
|
+
const interrupted = /* @__PURE__ */ __name(() => reject(controller.signal.reason), "interrupted");
|
|
27
|
+
if (controller.signal.aborted) return interrupted();
|
|
28
|
+
controller.signal.addEventListener("abort", interrupted, { once: true });
|
|
29
|
+
Promise.resolve().then(() => {
|
|
30
|
+
if (controller.signal.aborted) throw controller.signal.reason;
|
|
31
|
+
return operation();
|
|
32
|
+
}).then(resolve, reject).finally(() => controller.signal.removeEventListener("abort", interrupted));
|
|
33
|
+
}), "cancellable");
|
|
34
|
+
let delay = intervalMs;
|
|
35
|
+
let sleepTimer;
|
|
36
|
+
try {
|
|
37
|
+
while (true) {
|
|
38
|
+
const batch = await cancellable(() => read(controller.signal));
|
|
39
|
+
onProgress?.(batch);
|
|
40
|
+
if (batch.done) return batch;
|
|
41
|
+
await cancellable(
|
|
42
|
+
() => new Promise((resolve) => {
|
|
43
|
+
sleepTimer = setTimeout(resolve, delay);
|
|
44
|
+
})
|
|
45
|
+
);
|
|
46
|
+
delay = Math.min(delay * 1.5, Math.max(intervalMs, 1e4));
|
|
47
|
+
}
|
|
48
|
+
} finally {
|
|
49
|
+
clearTimeout(timeout);
|
|
50
|
+
clearTimeout(sleepTimer);
|
|
51
|
+
signal?.removeEventListener("abort", abort);
|
|
52
|
+
}
|
|
53
|
+
}, "waitForInboxCredentialBatch");
|
|
54
|
+
|
|
8
55
|
// src/plugin.ts
|
|
9
56
|
import { getClient, getApiTokenClient } from "@learncard/network-brain-client";
|
|
10
57
|
|
|
@@ -15562,6 +15609,204 @@ var StringQuery = external_exports.union([
|
|
|
15562
15609
|
$or: BaseStringQuery.array()
|
|
15563
15610
|
})
|
|
15564
15611
|
]);
|
|
15612
|
+
var LearnCardRefreshAuthorizationValidator = external_exports.object({ type: external_exports.literal("LearnCardDIDAuth") }).catchall(external_exports.any());
|
|
15613
|
+
var ManagedCredentialRefreshServiceValidator = external_exports.object({
|
|
15614
|
+
id: external_exports.string().min(1),
|
|
15615
|
+
type: external_exports.literal("LearnCardCredentialRefresh2026"),
|
|
15616
|
+
authorization: LearnCardRefreshAuthorizationValidator.optional()
|
|
15617
|
+
}).catchall(external_exports.any());
|
|
15618
|
+
var StandardCredentialRefreshServiceValidator = external_exports.object({
|
|
15619
|
+
id: external_exports.string().min(1),
|
|
15620
|
+
type: external_exports.literal("1EdTechCredentialRefresh")
|
|
15621
|
+
}).catchall(external_exports.any());
|
|
15622
|
+
var SupportedCredentialRefreshServiceValidator = external_exports.union([
|
|
15623
|
+
ManagedCredentialRefreshServiceValidator,
|
|
15624
|
+
StandardCredentialRefreshServiceValidator
|
|
15625
|
+
]);
|
|
15626
|
+
var AllocateCredentialRefreshInputValidator = external_exports.object({
|
|
15627
|
+
holder: external_exports.object({
|
|
15628
|
+
profileId: external_exports.string().optional(),
|
|
15629
|
+
did: external_exports.string().min(1)
|
|
15630
|
+
}),
|
|
15631
|
+
credentialId: external_exports.string().min(1)
|
|
15632
|
+
});
|
|
15633
|
+
var AllocateCredentialRefreshResultValidator = external_exports.object({
|
|
15634
|
+
refreshId: external_exports.string().min(1),
|
|
15635
|
+
refreshService: ManagedCredentialRefreshServiceValidator.extend({
|
|
15636
|
+
authorization: LearnCardRefreshAuthorizationValidator
|
|
15637
|
+
})
|
|
15638
|
+
});
|
|
15639
|
+
var ManagedCredentialRefreshReceiptValidator = external_exports.object({
|
|
15640
|
+
refreshId: external_exports.string().min(1),
|
|
15641
|
+
refreshService: ManagedCredentialRefreshServiceValidator,
|
|
15642
|
+
credentialId: external_exports.string().min(1),
|
|
15643
|
+
issuerDid: external_exports.string().min(1),
|
|
15644
|
+
holderDid: external_exports.string().min(1),
|
|
15645
|
+
credentialStatus: CredentialStatusValidator.or(
|
|
15646
|
+
CredentialStatusValidator.array()
|
|
15647
|
+
).optional()
|
|
15648
|
+
}).strip();
|
|
15649
|
+
var InboxCredentialRefreshReceiptValidator = ManagedCredentialRefreshReceiptValidator.omit(
|
|
15650
|
+
{ holderDid: true }
|
|
15651
|
+
).extend({ holderDid: external_exports.string().min(1).optional() });
|
|
15652
|
+
var CredentialRefreshSigningModeValidator = external_exports.enum(["issuer-signed", "signing-authority"]);
|
|
15653
|
+
var PublishCredentialRefreshBaseFields = {
|
|
15654
|
+
refreshId: external_exports.string().min(1),
|
|
15655
|
+
notifyHolder: external_exports.boolean().optional(),
|
|
15656
|
+
updateSummary: external_exports.string().optional(),
|
|
15657
|
+
idempotencyKey: external_exports.string().optional()
|
|
15658
|
+
};
|
|
15659
|
+
var PublishIssuerSignedRefreshValidator = external_exports.object({
|
|
15660
|
+
...PublishCredentialRefreshBaseFields,
|
|
15661
|
+
mode: external_exports.literal("issuer-signed"),
|
|
15662
|
+
signedCredential: VCValidator
|
|
15663
|
+
});
|
|
15664
|
+
var PublishSigningAuthorityRefreshValidator = external_exports.object({
|
|
15665
|
+
...PublishCredentialRefreshBaseFields,
|
|
15666
|
+
mode: external_exports.literal("signing-authority"),
|
|
15667
|
+
credential: UnsignedVCValidator,
|
|
15668
|
+
signingAuthority: external_exports.object({
|
|
15669
|
+
type: external_exports.string().min(1)
|
|
15670
|
+
}).catchall(external_exports.any())
|
|
15671
|
+
});
|
|
15672
|
+
var PublishCredentialRefreshInputValidator = external_exports.object({
|
|
15673
|
+
...PublishCredentialRefreshBaseFields,
|
|
15674
|
+
mode: CredentialRefreshSigningModeValidator,
|
|
15675
|
+
signedCredential: VCValidator.optional(),
|
|
15676
|
+
credential: UnsignedVCValidator.optional(),
|
|
15677
|
+
signingAuthority: external_exports.object({
|
|
15678
|
+
type: external_exports.string().min(1)
|
|
15679
|
+
}).catchall(external_exports.any()).optional()
|
|
15680
|
+
}).superRefine((input, ctx) => {
|
|
15681
|
+
if (input.mode === "issuer-signed" && !input.signedCredential) {
|
|
15682
|
+
ctx.addIssue({
|
|
15683
|
+
code: "custom",
|
|
15684
|
+
path: ["signedCredential"],
|
|
15685
|
+
message: "signedCredential is required for issuer-signed publication"
|
|
15686
|
+
});
|
|
15687
|
+
}
|
|
15688
|
+
if (input.mode === "issuer-signed" && (input.credential !== void 0 || input.signingAuthority !== void 0)) {
|
|
15689
|
+
ctx.addIssue({
|
|
15690
|
+
code: "custom",
|
|
15691
|
+
path: ["mode"],
|
|
15692
|
+
message: "issuer-signed publication cannot include signing-authority fields"
|
|
15693
|
+
});
|
|
15694
|
+
}
|
|
15695
|
+
if (input.mode === "signing-authority") {
|
|
15696
|
+
if (input.signedCredential !== void 0) {
|
|
15697
|
+
ctx.addIssue({
|
|
15698
|
+
code: "custom",
|
|
15699
|
+
path: ["signedCredential"],
|
|
15700
|
+
message: "signing-authority publication cannot include signedCredential"
|
|
15701
|
+
});
|
|
15702
|
+
}
|
|
15703
|
+
if (!input.credential) {
|
|
15704
|
+
ctx.addIssue({
|
|
15705
|
+
code: "custom",
|
|
15706
|
+
path: ["credential"],
|
|
15707
|
+
message: "credential is required for signing-authority publication"
|
|
15708
|
+
});
|
|
15709
|
+
}
|
|
15710
|
+
if (!input.signingAuthority) {
|
|
15711
|
+
ctx.addIssue({
|
|
15712
|
+
code: "custom",
|
|
15713
|
+
path: ["signingAuthority"],
|
|
15714
|
+
message: "signingAuthority is required for signing-authority publication"
|
|
15715
|
+
});
|
|
15716
|
+
}
|
|
15717
|
+
}
|
|
15718
|
+
});
|
|
15719
|
+
var PublishCredentialRefreshNotificationValidator = external_exports.enum([
|
|
15720
|
+
"queued",
|
|
15721
|
+
"suppressed",
|
|
15722
|
+
"not-applicable",
|
|
15723
|
+
/** Publication succeeded, but the post-commit notification enqueue must be retried. */
|
|
15724
|
+
"delivery-failed"
|
|
15725
|
+
]);
|
|
15726
|
+
var PublishCredentialRefreshResultValidator = external_exports.object({
|
|
15727
|
+
refreshId: external_exports.string().min(1),
|
|
15728
|
+
version: external_exports.number().int().positive(),
|
|
15729
|
+
publishedAt: external_exports.string().min(1),
|
|
15730
|
+
notification: PublishCredentialRefreshNotificationValidator
|
|
15731
|
+
});
|
|
15732
|
+
var CredentialRefreshVersionMetadataValidator = external_exports.object({
|
|
15733
|
+
version: external_exports.number().int().positive(),
|
|
15734
|
+
publishedAt: external_exports.string().min(1),
|
|
15735
|
+
effectiveAt: external_exports.string().optional(),
|
|
15736
|
+
etag: external_exports.string().optional(),
|
|
15737
|
+
signingMode: CredentialRefreshSigningModeValidator.optional(),
|
|
15738
|
+
updateSummary: external_exports.string().optional()
|
|
15739
|
+
});
|
|
15740
|
+
var GetCredentialRefreshHistoryInputValidator = external_exports.object({
|
|
15741
|
+
refreshId: external_exports.string().min(1),
|
|
15742
|
+
cursor: external_exports.string().optional(),
|
|
15743
|
+
limit: external_exports.number().int().positive().optional()
|
|
15744
|
+
});
|
|
15745
|
+
var GetCredentialRefreshHistoryResultValidator = external_exports.object({
|
|
15746
|
+
records: CredentialRefreshVersionMetadataValidator.array(),
|
|
15747
|
+
hasMore: external_exports.boolean(),
|
|
15748
|
+
cursor: external_exports.string().optional()
|
|
15749
|
+
});
|
|
15750
|
+
var CredentialRefreshChallengeValidator = external_exports.object({
|
|
15751
|
+
challenge: external_exports.string().min(1),
|
|
15752
|
+
expiresAt: external_exports.string().min(1),
|
|
15753
|
+
domain: external_exports.string().optional(),
|
|
15754
|
+
scheme: external_exports.literal("LearnCardDIDAuth").optional()
|
|
15755
|
+
});
|
|
15756
|
+
var PublicCredentialRefreshEnvelopeValidator = external_exports.object({
|
|
15757
|
+
format: external_exports.literal("vc"),
|
|
15758
|
+
credential: VCValidator,
|
|
15759
|
+
etag: external_exports.string().optional()
|
|
15760
|
+
});
|
|
15761
|
+
var JweCredentialRefreshEnvelopeValidator = external_exports.object({
|
|
15762
|
+
format: external_exports.literal("jwe"),
|
|
15763
|
+
jwe: JWEValidator,
|
|
15764
|
+
etag: external_exports.string().optional(),
|
|
15765
|
+
/** Present on LearnCard-managed endpoints; optional for interoperable JWE services. */
|
|
15766
|
+
version: external_exports.number().int().positive().optional()
|
|
15767
|
+
});
|
|
15768
|
+
var CredentialRefreshResponseEnvelopeValidator = external_exports.discriminatedUnion("format", [
|
|
15769
|
+
PublicCredentialRefreshEnvelopeValidator,
|
|
15770
|
+
JweCredentialRefreshEnvelopeValidator
|
|
15771
|
+
]);
|
|
15772
|
+
var CredentialRefreshFailureCodeValidator = external_exports.enum([
|
|
15773
|
+
"UNAVAILABLE",
|
|
15774
|
+
"TIMEOUT",
|
|
15775
|
+
"UNSUPPORTED_SERVICE",
|
|
15776
|
+
"UNAUTHORIZED",
|
|
15777
|
+
"MALFORMED_RESPONSE",
|
|
15778
|
+
"INVALID_PROOF",
|
|
15779
|
+
"ISSUER_MISMATCH",
|
|
15780
|
+
"ID_MISMATCH",
|
|
15781
|
+
"ROLLBACK",
|
|
15782
|
+
"REVOKED",
|
|
15783
|
+
"UNSAFE_ENDPOINT"
|
|
15784
|
+
]);
|
|
15785
|
+
var CredentialRefreshUpdatedResultValidator = external_exports.object({
|
|
15786
|
+
status: external_exports.literal("updated"),
|
|
15787
|
+
credential: VCValidator,
|
|
15788
|
+
etag: external_exports.string().optional(),
|
|
15789
|
+
managedVersion: external_exports.number().int().positive().optional()
|
|
15790
|
+
});
|
|
15791
|
+
var CredentialRefreshUnchangedResultValidator = external_exports.object({
|
|
15792
|
+
status: external_exports.literal("unchanged"),
|
|
15793
|
+
checkedAt: external_exports.string().min(1),
|
|
15794
|
+
etag: external_exports.string().optional()
|
|
15795
|
+
});
|
|
15796
|
+
var CredentialRefreshUnsupportedResultValidator = external_exports.object({
|
|
15797
|
+
status: external_exports.literal("unsupported")
|
|
15798
|
+
});
|
|
15799
|
+
var CredentialRefreshFailedResultValidator = external_exports.object({
|
|
15800
|
+
status: external_exports.literal("failed"),
|
|
15801
|
+
code: CredentialRefreshFailureCodeValidator,
|
|
15802
|
+
retryable: external_exports.boolean()
|
|
15803
|
+
});
|
|
15804
|
+
var CredentialRefreshResultValidator = external_exports.discriminatedUnion("status", [
|
|
15805
|
+
CredentialRefreshUpdatedResultValidator,
|
|
15806
|
+
CredentialRefreshUnchangedResultValidator,
|
|
15807
|
+
CredentialRefreshUnsupportedResultValidator,
|
|
15808
|
+
CredentialRefreshFailedResultValidator
|
|
15809
|
+
]);
|
|
15565
15810
|
var LCNProfileDisplayValidator = external_exports.object({
|
|
15566
15811
|
backgroundColor: external_exports.string().optional(),
|
|
15567
15812
|
backgroundImage: external_exports.string().optional(),
|
|
@@ -15897,7 +16142,13 @@ var SendBoostInputValidator = external_exports.object({
|
|
|
15897
16142
|
"Options for email/phone recipients (Universal Inbox)"
|
|
15898
16143
|
),
|
|
15899
16144
|
templateData: external_exports.record(external_exports.string(), external_exports.unknown()).optional(),
|
|
15900
|
-
integrationId: external_exports.string().optional().describe("Integration ID for activity tracking")
|
|
16145
|
+
integrationId: external_exports.string().optional().describe("Integration ID for activity tracking"),
|
|
16146
|
+
refresh: external_exports.boolean().optional().describe(
|
|
16147
|
+
"Request managed credential refresh for this send. Profile/DID recipients use immediate issuance; email/phone recipients use deferred Universal Inbox signing and bind the holder at claim."
|
|
16148
|
+
),
|
|
16149
|
+
idempotencyKey: external_exports.string().min(1).max(200).optional().describe(
|
|
16150
|
+
"Caller-chosen key that makes a managed refresh send (refresh: true) safe to retry as a whole: retries with the same key reuse the same boost, refresh allocation and result. Reusing a key for a different request is rejected. With signedCredential, requires prior tRPC prepareRefreshableSend; direct REST callers omit the key and retry the exact signed credential and templateUri."
|
|
16151
|
+
)
|
|
15901
16152
|
}).refine((data) => data.templateUri || data.template || data.signedCredential, {
|
|
15902
16153
|
message: "Either templateUri, template, or signedCredential must be provided.",
|
|
15903
16154
|
path: ["templateUri"]
|
|
@@ -15912,8 +16163,12 @@ var SendBoostInputValidator = external_exports.object({
|
|
|
15912
16163
|
message: "guardianEmail must differ from recipient (self-approval not allowed)",
|
|
15913
16164
|
path: ["options", "guardianEmail"]
|
|
15914
16165
|
}
|
|
15915
|
-
)
|
|
16166
|
+
).refine((data) => !data.idempotencyKey || data.refresh === true, {
|
|
16167
|
+
message: "idempotencyKey is only supported with refresh: true.",
|
|
16168
|
+
path: ["idempotencyKey"]
|
|
16169
|
+
});
|
|
15916
16170
|
var SendInboxResponseValidator = external_exports.object({
|
|
16171
|
+
refresh: InboxCredentialRefreshReceiptValidator.optional(),
|
|
15917
16172
|
issuanceId: external_exports.string(),
|
|
15918
16173
|
status: external_exports.enum(["PENDING", "ISSUED", "EXPIRED", "DELIVERED", "CLAIMED"]),
|
|
15919
16174
|
claimUrl: external_exports.string().url().optional().describe("Present when suppressDelivery=true"),
|
|
@@ -15928,8 +16183,34 @@ var SendBoostResponseValidator = external_exports.object({
|
|
|
15928
16183
|
activityId: external_exports.string().describe("Links to the activity lifecycle for this issuance"),
|
|
15929
16184
|
inbox: SendInboxResponseValidator.optional().describe(
|
|
15930
16185
|
"Present when sent via email/phone (Universal Inbox)"
|
|
16186
|
+
),
|
|
16187
|
+
refresh: ManagedCredentialRefreshReceiptValidator.optional().describe(
|
|
16188
|
+
"Present when managed refresh was requested: issuance metadata the issuer keeps to publish future updates"
|
|
15931
16189
|
)
|
|
15932
16190
|
});
|
|
16191
|
+
var PrepareRefreshableSendInputValidator = external_exports.object({
|
|
16192
|
+
recipient: external_exports.string(),
|
|
16193
|
+
templateUri: external_exports.string().optional(),
|
|
16194
|
+
template: SendBoostTemplateValidator.optional(),
|
|
16195
|
+
contractUri: external_exports.string().optional(),
|
|
16196
|
+
templateData: external_exports.record(external_exports.string(), external_exports.unknown()).optional(),
|
|
16197
|
+
integrationId: external_exports.string().optional(),
|
|
16198
|
+
/** Credential ID to allocate for; generated server-side when omitted. */
|
|
16199
|
+
credentialId: external_exports.string().min(1).optional(),
|
|
16200
|
+
idempotencyKey: external_exports.string().min(1).max(200).optional()
|
|
16201
|
+
}).refine((data) => Boolean(data.templateUri) !== Boolean(data.template), {
|
|
16202
|
+
message: "Provide exactly one of templateUri or template."
|
|
16203
|
+
});
|
|
16204
|
+
var PrepareRefreshableSendResultValidator = external_exports.object({
|
|
16205
|
+
boostUri: external_exports.string(),
|
|
16206
|
+
credentialId: external_exports.string(),
|
|
16207
|
+
refreshId: external_exports.string(),
|
|
16208
|
+
refreshService: ManagedCredentialRefreshServiceValidator,
|
|
16209
|
+
/** The DID to use as credentialSubject.id (recipient DID, or the profile's did:web). */
|
|
16210
|
+
holderDid: external_exports.string(),
|
|
16211
|
+
/** Present when this idempotencyKey already completed: return it without signing. */
|
|
16212
|
+
completed: SendBoostResponseValidator.optional()
|
|
16213
|
+
});
|
|
15933
16214
|
var SendInputValidator = external_exports.discriminatedUnion("type", [SendBoostInputValidator]);
|
|
15934
16215
|
var SendResponseValidator = external_exports.discriminatedUnion("type", [SendBoostResponseValidator]);
|
|
15935
16216
|
var ConsentFlowTermsStatusValidator = external_exports.enum(["live", "stale", "withdrawn"]);
|
|
@@ -16248,6 +16529,7 @@ var LCNNotificationValidator = external_exports.object({
|
|
|
16248
16529
|
webhookUrl: external_exports.string().optional()
|
|
16249
16530
|
});
|
|
16250
16531
|
var AUTH_GRANT_AUDIENCE_DOMAIN_PREFIX = "auth-grant:";
|
|
16532
|
+
var ACT_AS_HEADER = "X-LearnCard-Act-As";
|
|
16251
16533
|
var AuthGrantValidator = external_exports.object({
|
|
16252
16534
|
id: external_exports.string(),
|
|
16253
16535
|
name: external_exports.string(),
|
|
@@ -16260,6 +16542,7 @@ var AuthGrantValidator = external_exports.object({
|
|
|
16260
16542
|
}, "error")
|
|
16261
16543
|
}),
|
|
16262
16544
|
scope: external_exports.string(),
|
|
16545
|
+
actAs: external_exports.string().optional(),
|
|
16263
16546
|
createdAt: external_exports.iso.datetime({ error: "createdAt must be a valid ISO 8601 datetime string" }),
|
|
16264
16547
|
expiresAt: external_exports.iso.datetime({ error: "expiresAt must be a valid ISO 8601 datetime string" }).nullish().optional()
|
|
16265
16548
|
});
|
|
@@ -16331,6 +16614,8 @@ var CreateContactMethodSessionResponseValidator = external_exports.object({
|
|
|
16331
16614
|
sessionJwt: external_exports.string()
|
|
16332
16615
|
});
|
|
16333
16616
|
var InboxCredentialValidator = external_exports.object({
|
|
16617
|
+
refresh: InboxCredentialRefreshReceiptValidator.optional(),
|
|
16618
|
+
refreshId: external_exports.string().optional(),
|
|
16334
16619
|
id: external_exports.string(),
|
|
16335
16620
|
credential: external_exports.string().optional(),
|
|
16336
16621
|
isSigned: external_exports.boolean(),
|
|
@@ -16385,12 +16670,19 @@ var IssueInboxCredentialValidator = external_exports.object({
|
|
|
16385
16670
|
templateUri: external_exports.string().optional().describe(
|
|
16386
16671
|
"URI of a boost template to use for issuance. The boost credential will be resolved and used. Mutually exclusive with credential field."
|
|
16387
16672
|
),
|
|
16673
|
+
refresh: external_exports.boolean().optional().describe(
|
|
16674
|
+
"Allocate managed refresh before signing. Requires unsigned content and a registered signing authority; binds the holder on claim."
|
|
16675
|
+
),
|
|
16676
|
+
idempotencyKey: external_exports.string().min(1).max(200).optional(),
|
|
16388
16677
|
// === OPTIONAL FEATURES ===
|
|
16389
16678
|
// Add major, distinct features at the top level.
|
|
16390
16679
|
//consentRequest: ConsentRequestValidator.optional(),
|
|
16391
16680
|
// === PROCESS CONFIGURATION (Optional) ===
|
|
16392
16681
|
// HOW should this issuance be handled?
|
|
16393
16682
|
configuration: external_exports.object({
|
|
16683
|
+
guardianEmail: external_exports.string().email().optional().describe(
|
|
16684
|
+
"Require approval from this guardian before the recipient can claim. Must differ from the recipient email."
|
|
16685
|
+
),
|
|
16394
16686
|
signingAuthority: IssueInboxSigningAuthorityValidator.optional().describe(
|
|
16395
16687
|
"The signing authority to use for the credential. If not provided, the users default signing authority will be used if the credential is not signed."
|
|
16396
16688
|
),
|
|
@@ -16444,17 +16736,130 @@ var IssueInboxCredentialValidator = external_exports.object({
|
|
|
16444
16736
|
}).optional().describe(
|
|
16445
16737
|
"Configuration for the credential issuance. If not provided, the default configuration will be used."
|
|
16446
16738
|
)
|
|
16739
|
+
}).refine((data) => !data.idempotencyKey || data.refresh === true, {
|
|
16740
|
+
message: "idempotencyKey requires refresh: true."
|
|
16447
16741
|
}).refine((data) => data.credential || data.templateUri, {
|
|
16448
16742
|
message: "Either credential or templateUri must be provided.",
|
|
16449
16743
|
path: ["credential"]
|
|
16450
|
-
})
|
|
16744
|
+
}).refine(
|
|
16745
|
+
(data) => !data.configuration?.guardianEmail || data.recipient.type !== "email" || data.configuration.guardianEmail.toLowerCase() !== data.recipient.value.toLowerCase(),
|
|
16746
|
+
{
|
|
16747
|
+
message: "guardianEmail must differ from recipient (self-approval not allowed)",
|
|
16748
|
+
path: ["configuration", "guardianEmail"]
|
|
16749
|
+
}
|
|
16750
|
+
);
|
|
16451
16751
|
var IssueInboxCredentialResponseValidator = external_exports.object({
|
|
16752
|
+
refresh: InboxCredentialRefreshReceiptValidator.optional(),
|
|
16452
16753
|
issuanceId: external_exports.string(),
|
|
16453
16754
|
status: LCNInboxStatusEnumValidator,
|
|
16454
16755
|
recipient: ContactMethodQueryValidator,
|
|
16455
16756
|
claimUrl: external_exports.string().url().optional(),
|
|
16456
16757
|
recipientDid: external_exports.string().optional()
|
|
16457
16758
|
});
|
|
16759
|
+
var InboxBatchConfigurationValidator = IssueInboxCredentialValidator.shape.configuration.unwrap().extend({
|
|
16760
|
+
refresh: IssueInboxCredentialValidator.shape.refresh.describe(
|
|
16761
|
+
"Enable managed refresh by default. An item configuration.refresh overrides this value, including false."
|
|
16762
|
+
),
|
|
16763
|
+
delivery: IssueInboxCredentialValidator.shape.configuration.unwrap().shape.delivery.unwrap().extend({ suppress: external_exports.boolean().optional() }).optional()
|
|
16764
|
+
});
|
|
16765
|
+
var InboxBatchItemConfigurationValidator = InboxBatchConfigurationValidator.extend({
|
|
16766
|
+
guardianEmail: InboxBatchConfigurationValidator.shape.guardianEmail.nullable().describe(
|
|
16767
|
+
"Require guardian approval, or set null to clear a batch-level guardianEmail for this item."
|
|
16768
|
+
)
|
|
16769
|
+
});
|
|
16770
|
+
var IssueInboxCredentialBatchItemValidator = external_exports.object({
|
|
16771
|
+
...IssueInboxCredentialValidator.shape,
|
|
16772
|
+
configuration: InboxBatchItemConfigurationValidator.optional(),
|
|
16773
|
+
idempotencyKey: external_exports.string().max(256).optional()
|
|
16774
|
+
}).refine((data) => data.credential || data.templateUri, {
|
|
16775
|
+
message: "Either credential or templateUri must be provided.",
|
|
16776
|
+
path: ["credential"]
|
|
16777
|
+
}).describe(
|
|
16778
|
+
"One issuance: provide credential or templateUri. Invalid input is rejected at submission with its item index."
|
|
16779
|
+
);
|
|
16780
|
+
var IssueInboxCredentialBatchValidator = external_exports.object({
|
|
16781
|
+
requestId: external_exports.string().min(1).max(256).optional(),
|
|
16782
|
+
items: external_exports.array(IssueInboxCredentialBatchItemValidator).min(1).max(100),
|
|
16783
|
+
configuration: InboxBatchConfigurationValidator.optional()
|
|
16784
|
+
}).superRefine((batch, ctx) => {
|
|
16785
|
+
batch.items.forEach((item, index) => {
|
|
16786
|
+
const itemGuardian = item.configuration?.guardianEmail;
|
|
16787
|
+
const guardian = itemGuardian === null ? void 0 : itemGuardian ?? batch.configuration?.guardianEmail;
|
|
16788
|
+
if (guardian && item.recipient.type === "email" && guardian.toLowerCase() === item.recipient.value.toLowerCase()) {
|
|
16789
|
+
ctx.addIssue({
|
|
16790
|
+
code: "custom",
|
|
16791
|
+
path: ["items", index, "configuration", "guardianEmail"],
|
|
16792
|
+
message: "guardianEmail must differ from recipient (self-approval not allowed)"
|
|
16793
|
+
});
|
|
16794
|
+
}
|
|
16795
|
+
});
|
|
16796
|
+
});
|
|
16797
|
+
var InboxBatchErrorReasonValidator = external_exports.enum([
|
|
16798
|
+
"DUPLICATE_KEY",
|
|
16799
|
+
"IDEMPOTENCY_MISMATCH",
|
|
16800
|
+
"IN_PROGRESS",
|
|
16801
|
+
"UNCONFIRMED"
|
|
16802
|
+
]);
|
|
16803
|
+
var IssueInboxCredentialBatchItemResultValidator = external_exports.discriminatedUnion("success", [
|
|
16804
|
+
IssueInboxCredentialResponseValidator.extend({
|
|
16805
|
+
success: external_exports.literal(true),
|
|
16806
|
+
index: external_exports.number().int().nonnegative(),
|
|
16807
|
+
deduplicated: external_exports.boolean().optional(),
|
|
16808
|
+
guardianStatus: GuardianStatusValidator.optional(),
|
|
16809
|
+
idempotencyKey: external_exports.string().optional()
|
|
16810
|
+
}),
|
|
16811
|
+
external_exports.object({
|
|
16812
|
+
success: external_exports.literal(false),
|
|
16813
|
+
index: external_exports.number().int().nonnegative(),
|
|
16814
|
+
idempotencyKey: external_exports.string().optional(),
|
|
16815
|
+
recipient: ContactMethodQueryValidator.optional(),
|
|
16816
|
+
error: external_exports.object({
|
|
16817
|
+
code: external_exports.string(),
|
|
16818
|
+
message: external_exports.string(),
|
|
16819
|
+
reason: InboxBatchErrorReasonValidator.optional()
|
|
16820
|
+
}),
|
|
16821
|
+
issuanceId: external_exports.string().optional().describe(
|
|
16822
|
+
"Present when issuance completed but replay storage could not be confirmed. Reconcile this issuance; do not issue again with a new key."
|
|
16823
|
+
),
|
|
16824
|
+
claimUrl: external_exports.string().url().optional().describe(
|
|
16825
|
+
"Claim URL of the completed issuance, if available, when replay storage could not be confirmed."
|
|
16826
|
+
)
|
|
16827
|
+
})
|
|
16828
|
+
]);
|
|
16829
|
+
var IssueInboxCredentialBatchResponseValidator = external_exports.object({
|
|
16830
|
+
results: external_exports.array(IssueInboxCredentialBatchItemResultValidator),
|
|
16831
|
+
summary: external_exports.object({
|
|
16832
|
+
total: external_exports.number(),
|
|
16833
|
+
succeeded: external_exports.number(),
|
|
16834
|
+
failed: external_exports.number(),
|
|
16835
|
+
deduplicated: external_exports.number()
|
|
16836
|
+
})
|
|
16837
|
+
});
|
|
16838
|
+
var InboxBatchReceiptValidator = external_exports.object({
|
|
16839
|
+
batchId: external_exports.string(),
|
|
16840
|
+
status: external_exports.enum(["QUEUED", "PROCESSING", "COMPLETED", "NEEDS_RECONCILIATION"]),
|
|
16841
|
+
createdAt: external_exports.string()
|
|
16842
|
+
});
|
|
16843
|
+
var InboxBatchStatusValidator = external_exports.object({
|
|
16844
|
+
batchId: external_exports.string(),
|
|
16845
|
+
createdAt: external_exports.string(),
|
|
16846
|
+
done: external_exports.boolean().describe(
|
|
16847
|
+
"True when no queued or processing items remain, including unconfirmed outcomes."
|
|
16848
|
+
),
|
|
16849
|
+
status: external_exports.enum(["QUEUED", "PROCESSING", "COMPLETED", "NEEDS_RECONCILIATION"]),
|
|
16850
|
+
items: external_exports.array(
|
|
16851
|
+
external_exports.object({
|
|
16852
|
+
index: external_exports.number().int().nonnegative(),
|
|
16853
|
+
state: external_exports.enum(["QUEUED", "PROCESSING", "COMPLETED", "NEEDS_RECONCILIATION"]),
|
|
16854
|
+
result: IssueInboxCredentialBatchItemResultValidator.optional()
|
|
16855
|
+
})
|
|
16856
|
+
),
|
|
16857
|
+
summary: IssueInboxCredentialBatchResponseValidator.shape.summary.extend({
|
|
16858
|
+
completed: external_exports.number(),
|
|
16859
|
+
pending: external_exports.number(),
|
|
16860
|
+
unconfirmed: external_exports.number()
|
|
16861
|
+
})
|
|
16862
|
+
});
|
|
16458
16863
|
var CredentialNameRefValidator = external_exports.object({ name: external_exports.string() }).passthrough();
|
|
16459
16864
|
var ClaimInboxCredentialValidator = external_exports.object({
|
|
16460
16865
|
credential: VCValidator.or(VPValidator).or(UnsignedVCValidator).or(CredentialNameRefValidator).describe("The credential to issue, or a { name } reference to resolve a boost template."),
|
|
@@ -16940,6 +17345,7 @@ var CredentialActivityValidator = external_exports.object({
|
|
|
16940
17345
|
eventType: CredentialActivityEventTypeValidator,
|
|
16941
17346
|
timestamp: external_exports.string(),
|
|
16942
17347
|
actorProfileId: external_exports.string().optional(),
|
|
17348
|
+
onBehalfOf: external_exports.string().optional(),
|
|
16943
17349
|
recipientType: CredentialActivityRecipientTypeValidator,
|
|
16944
17350
|
recipientIdentifier: external_exports.string(),
|
|
16945
17351
|
boostUri: external_exports.string().optional(),
|
|
@@ -16981,6 +17387,12 @@ var AuthSessionError = (_a3 = class extends Error {
|
|
|
16981
17387
|
this.name = "AuthSessionError";
|
|
16982
17388
|
}
|
|
16983
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
|
+
});
|
|
16984
17396
|
var BITSTRING_STATUS_PURPOSES = ["revocation", "suspension"];
|
|
16985
17397
|
var BitstringStatusPurposeValidator = external_exports.enum(BITSTRING_STATUS_PURPOSES);
|
|
16986
17398
|
var BitstringStatusListEntryValidator = external_exports.object({
|
|
@@ -17089,195 +17501,462 @@ var inAppMessagesFlagValidator = external_exports.object({
|
|
|
17089
17501
|
version: external_exports.number().default(1),
|
|
17090
17502
|
messages: external_exports.array(inAppMessageValidator).default([])
|
|
17091
17503
|
}).passthrough();
|
|
17092
|
-
var
|
|
17093
|
-
var
|
|
17094
|
-
|
|
17095
|
-
|
|
17096
|
-
|
|
17097
|
-
|
|
17098
|
-
var
|
|
17099
|
-
|
|
17100
|
-
|
|
17101
|
-
|
|
17102
|
-
var
|
|
17103
|
-
|
|
17104
|
-
|
|
17105
|
-
|
|
17106
|
-
var
|
|
17107
|
-
|
|
17108
|
-
|
|
17109
|
-
|
|
17110
|
-
}
|
|
17111
|
-
|
|
17112
|
-
});
|
|
17113
|
-
var
|
|
17114
|
-
|
|
17115
|
-
|
|
17116
|
-
|
|
17117
|
-
|
|
17118
|
-
|
|
17119
|
-
|
|
17120
|
-
|
|
17121
|
-
|
|
17122
|
-
|
|
17123
|
-
|
|
17124
|
-
|
|
17125
|
-
}
|
|
17126
|
-
|
|
17127
|
-
|
|
17128
|
-
|
|
17129
|
-
|
|
17130
|
-
|
|
17131
|
-
|
|
17132
|
-
|
|
17133
|
-
|
|
17134
|
-
|
|
17135
|
-
|
|
17136
|
-
|
|
17137
|
-
|
|
17138
|
-
|
|
17139
|
-
|
|
17140
|
-
|
|
17141
|
-
|
|
17142
|
-
|
|
17143
|
-
|
|
17144
|
-
|
|
17145
|
-
|
|
17146
|
-
|
|
17147
|
-
}
|
|
17148
|
-
|
|
17149
|
-
|
|
17150
|
-
|
|
17151
|
-
|
|
17152
|
-
|
|
17153
|
-
|
|
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`
|
|
17154
17586
|
}
|
|
17155
|
-
|
|
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) {
|
|
17156
17752
|
ctx.addIssue({
|
|
17157
17753
|
code: "custom",
|
|
17158
|
-
|
|
17159
|
-
|
|
17754
|
+
message: result.message,
|
|
17755
|
+
path: result.path,
|
|
17756
|
+
params: { shareLinkCode: result.code }
|
|
17160
17757
|
});
|
|
17161
17758
|
}
|
|
17162
|
-
|
|
17163
|
-
|
|
17164
|
-
|
|
17165
|
-
|
|
17166
|
-
|
|
17167
|
-
|
|
17168
|
-
|
|
17169
|
-
|
|
17170
|
-
|
|
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) {
|
|
17171
17777
|
ctx.addIssue({
|
|
17172
17778
|
code: "custom",
|
|
17173
|
-
|
|
17174
|
-
|
|
17779
|
+
message: "order must be within the selection bounds",
|
|
17780
|
+
path: ["selection", index, "order"]
|
|
17175
17781
|
});
|
|
17176
17782
|
}
|
|
17177
|
-
if (
|
|
17783
|
+
if (orders.has(entry.order)) {
|
|
17178
17784
|
ctx.addIssue({
|
|
17179
17785
|
code: "custom",
|
|
17180
|
-
|
|
17181
|
-
|
|
17786
|
+
message: "order must be unique within the selection",
|
|
17787
|
+
path: ["selection", index, "order"]
|
|
17182
17788
|
});
|
|
17183
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
|
+
});
|
|
17184
17869
|
}
|
|
17185
17870
|
});
|
|
17186
|
-
var
|
|
17187
|
-
|
|
17188
|
-
|
|
17189
|
-
"
|
|
17190
|
-
|
|
17191
|
-
|
|
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()
|
|
17192
17880
|
]);
|
|
17193
|
-
var
|
|
17194
|
-
|
|
17195
|
-
|
|
17196
|
-
|
|
17197
|
-
|
|
17198
|
-
|
|
17199
|
-
|
|
17200
|
-
|
|
17201
|
-
publishedAt: external_exports.string().min(1),
|
|
17202
|
-
effectiveAt: external_exports.string().optional(),
|
|
17203
|
-
etag: external_exports.string().optional(),
|
|
17204
|
-
signingMode: CredentialRefreshSigningModeValidator.optional(),
|
|
17205
|
-
updateSummary: external_exports.string().optional()
|
|
17206
|
-
});
|
|
17207
|
-
var GetCredentialRefreshHistoryInputValidator = external_exports.object({
|
|
17208
|
-
refreshId: external_exports.string().min(1),
|
|
17209
|
-
cursor: external_exports.string().optional(),
|
|
17210
|
-
limit: external_exports.number().int().positive().optional()
|
|
17211
|
-
});
|
|
17212
|
-
var GetCredentialRefreshHistoryResultValidator = external_exports.object({
|
|
17213
|
-
records: CredentialRefreshVersionMetadataValidator.array(),
|
|
17214
|
-
hasMore: external_exports.boolean(),
|
|
17215
|
-
cursor: external_exports.string().optional()
|
|
17216
|
-
});
|
|
17217
|
-
var CredentialRefreshChallengeValidator = external_exports.object({
|
|
17218
|
-
challenge: external_exports.string().min(1),
|
|
17219
|
-
expiresAt: external_exports.string().min(1),
|
|
17220
|
-
domain: external_exports.string().optional(),
|
|
17221
|
-
scheme: external_exports.literal("LearnCardDIDAuth").optional()
|
|
17222
|
-
});
|
|
17223
|
-
var PublicCredentialRefreshEnvelopeValidator = external_exports.object({
|
|
17224
|
-
format: external_exports.literal("vc"),
|
|
17225
|
-
credential: VCValidator,
|
|
17226
|
-
etag: external_exports.string().optional()
|
|
17227
|
-
});
|
|
17228
|
-
var JweCredentialRefreshEnvelopeValidator = external_exports.object({
|
|
17229
|
-
format: external_exports.literal("jwe"),
|
|
17230
|
-
jwe: JWEValidator,
|
|
17231
|
-
etag: external_exports.string().optional(),
|
|
17232
|
-
/** Present on LearnCard-managed endpoints; optional for interoperable JWE services. */
|
|
17233
|
-
version: external_exports.number().int().positive().optional()
|
|
17234
|
-
});
|
|
17235
|
-
var CredentialRefreshResponseEnvelopeValidator = external_exports.discriminatedUnion("format", [
|
|
17236
|
-
PublicCredentialRefreshEnvelopeValidator,
|
|
17237
|
-
JweCredentialRefreshEnvelopeValidator
|
|
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()
|
|
17238
17889
|
]);
|
|
17239
|
-
var
|
|
17240
|
-
|
|
17241
|
-
|
|
17242
|
-
|
|
17243
|
-
|
|
17244
|
-
|
|
17245
|
-
|
|
17246
|
-
|
|
17247
|
-
|
|
17248
|
-
|
|
17249
|
-
|
|
17250
|
-
|
|
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()
|
|
17251
17934
|
]);
|
|
17252
|
-
var
|
|
17253
|
-
|
|
17254
|
-
|
|
17255
|
-
|
|
17256
|
-
|
|
17257
|
-
|
|
17258
|
-
var CredentialRefreshUnchangedResultValidator = external_exports.object({
|
|
17259
|
-
status: external_exports.literal("unchanged"),
|
|
17260
|
-
checkedAt: external_exports.string().min(1),
|
|
17261
|
-
etag: external_exports.string().optional()
|
|
17262
|
-
});
|
|
17263
|
-
var CredentialRefreshUnsupportedResultValidator = external_exports.object({
|
|
17264
|
-
status: external_exports.literal("unsupported")
|
|
17265
|
-
});
|
|
17266
|
-
var CredentialRefreshFailedResultValidator = external_exports.object({
|
|
17267
|
-
status: external_exports.literal("failed"),
|
|
17268
|
-
code: CredentialRefreshFailureCodeValidator,
|
|
17269
|
-
retryable: external_exports.boolean()
|
|
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()
|
|
17270
17941
|
});
|
|
17271
|
-
var
|
|
17272
|
-
|
|
17273
|
-
|
|
17274
|
-
|
|
17275
|
-
|
|
17276
|
-
|
|
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();
|
|
17277
17954
|
|
|
17278
17955
|
// src/plugin.ts
|
|
17279
17956
|
import {
|
|
17957
|
+
getCredentialIssuerId,
|
|
17280
17958
|
getCredentialStatusArray,
|
|
17959
|
+
injectManagedRefreshService as injectSharedManagedRefreshService,
|
|
17281
17960
|
isVC2Format,
|
|
17282
17961
|
resolveStorageReadResult
|
|
17283
17962
|
} from "@learncard/helpers";
|
|
@@ -17895,27 +18574,40 @@ var issueCredentialWithNetworkStatus = /* @__PURE__ */ __name(async (learnCard,
|
|
|
17895
18574
|
await appendNetworkCredentialStatus(client, credential, statusPurposes)
|
|
17896
18575
|
);
|
|
17897
18576
|
}, "issueCredentialWithNetworkStatus");
|
|
17898
|
-
var
|
|
17899
|
-
|
|
17900
|
-
|
|
17901
|
-
|
|
17902
|
-
|
|
17903
|
-
|
|
17904
|
-
|
|
17905
|
-
}
|
|
17906
|
-
};
|
|
17907
|
-
var
|
|
17908
|
-
const
|
|
17909
|
-
const
|
|
17910
|
-
const
|
|
17911
|
-
|
|
17912
|
-
);
|
|
18577
|
+
var injectManagedRefreshService = /* @__PURE__ */ __name((credential, refreshService) => injectSharedManagedRefreshService(credential, refreshService), "injectManagedRefreshService");
|
|
18578
|
+
var getCredentialSubjectIds = /* @__PURE__ */ __name((vc) => {
|
|
18579
|
+
const subject = vc.credentialSubject;
|
|
18580
|
+
const subjects = Array.isArray(subject) ? subject : subject ? [subject] : [];
|
|
18581
|
+
return subjects.flatMap((entry) => {
|
|
18582
|
+
const id = entry?.id;
|
|
18583
|
+
return typeof id === "string" && id.length > 0 ? [id] : [];
|
|
18584
|
+
});
|
|
18585
|
+
}, "getCredentialSubjectIds");
|
|
18586
|
+
var buildManagedRefreshReceipt = /* @__PURE__ */ __name((vc, allocation, credentialId, fallbackHolderDid, fallbackIssuerDid) => {
|
|
18587
|
+
const issuerDid = getCredentialIssuerId(vc) ?? fallbackIssuerDid;
|
|
18588
|
+
const holderDid = getCredentialSubjectIds(vc)[0] ?? fallbackHolderDid;
|
|
18589
|
+
const rawStatus = vc.credentialStatus;
|
|
18590
|
+
const hasStatus = rawStatus !== void 0 && rawStatus !== null && !(Array.isArray(rawStatus) && rawStatus.length === 0);
|
|
17913
18591
|
return {
|
|
17914
|
-
|
|
17915
|
-
|
|
17916
|
-
|
|
17917
|
-
|
|
17918
|
-
|
|
18592
|
+
refreshId: allocation.refreshId,
|
|
18593
|
+
refreshService: allocation.refreshService,
|
|
18594
|
+
credentialId: typeof vc.id === "string" && vc.id.length > 0 ? vc.id : credentialId,
|
|
18595
|
+
issuerDid,
|
|
18596
|
+
holderDid,
|
|
18597
|
+
...hasStatus ? {
|
|
18598
|
+
credentialStatus: rawStatus
|
|
18599
|
+
} : {}
|
|
18600
|
+
};
|
|
18601
|
+
}, "buildManagedRefreshReceipt");
|
|
18602
|
+
var ACT_AS_TARGET_NOT_FOUND_MESSAGE = "Act-as target profile not found";
|
|
18603
|
+
var isActAsDenial = /* @__PURE__ */ __name((error51) => {
|
|
18604
|
+
const code = error51?.data?.code;
|
|
18605
|
+
if (code === "FORBIDDEN" || code === "BAD_REQUEST") return true;
|
|
18606
|
+
if (code === "NOT_FOUND") {
|
|
18607
|
+
return error51?.message === ACT_AS_TARGET_NOT_FOUND_MESSAGE;
|
|
18608
|
+
}
|
|
18609
|
+
return false;
|
|
18610
|
+
}, "isActAsDenial");
|
|
17919
18611
|
async function getLearnCardNetworkPlugin(learnCard, url2, apiTokenOrOptions, options) {
|
|
17920
18612
|
const apiToken = typeof apiTokenOrOptions === "string" ? apiTokenOrOptions : void 0;
|
|
17921
18613
|
const resolvedOptions = (typeof apiTokenOrOptions === "object" ? apiTokenOrOptions : options) ?? {};
|
|
@@ -17923,8 +18615,10 @@ async function getLearnCardNetworkPlugin(learnCard, url2, apiTokenOrOptions, opt
|
|
|
17923
18615
|
guardianApprovalGetter,
|
|
17924
18616
|
extraHeaders,
|
|
17925
18617
|
trustedFederationHosts,
|
|
17926
|
-
allowLocalhostFederation
|
|
18618
|
+
allowLocalhostFederation,
|
|
18619
|
+
actAs
|
|
17927
18620
|
} = resolvedOptions;
|
|
18621
|
+
const mergedExtraHeaders = actAs ? { ...extraHeaders, [ACT_AS_HEADER]: actAs } : extraHeaders;
|
|
17928
18622
|
const serviceUrl = new URL(url2);
|
|
17929
18623
|
const serviceIsLocalhost = isLocalhostHost(serviceUrl.hostname);
|
|
17930
18624
|
const federationConfig = {
|
|
@@ -17942,7 +18636,7 @@ async function getLearnCardNetworkPlugin(learnCard, url2, apiTokenOrOptions, opt
|
|
|
17942
18636
|
learnCard?.debug?.("LCN: no local DID available at init; will fetch from profile");
|
|
17943
18637
|
}
|
|
17944
18638
|
learnCard?.debug?.("Adding LearnCardNetwork Plugin");
|
|
17945
|
-
const client = apiToken ? await getApiTokenClient(url2, apiToken, guardianApprovalGetter,
|
|
18639
|
+
const client = apiToken ? await getApiTokenClient(url2, apiToken, guardianApprovalGetter, mergedExtraHeaders) : await getClient(
|
|
17946
18640
|
url2,
|
|
17947
18641
|
async (challenge) => {
|
|
17948
18642
|
const jwt2 = await learnCard.invoke.getDidAuthVp({
|
|
@@ -17953,7 +18647,7 @@ async function getLearnCardNetworkPlugin(learnCard, url2, apiTokenOrOptions, opt
|
|
|
17953
18647
|
return jwt2;
|
|
17954
18648
|
},
|
|
17955
18649
|
guardianApprovalGetter,
|
|
17956
|
-
|
|
18650
|
+
mergedExtraHeaders
|
|
17957
18651
|
);
|
|
17958
18652
|
let userData;
|
|
17959
18653
|
learnCard?.debug?.("LCN: initial getProfile query starting", { apiToken: !!apiToken });
|
|
@@ -18156,6 +18850,23 @@ async function getLearnCardNetworkPlugin(learnCard, url2, apiTokenOrOptions, opt
|
|
|
18156
18850
|
getManagedProfiles: /* @__PURE__ */ __name(async (_learnCard, options2 = {}) => {
|
|
18157
18851
|
return client.profileManager.getManagedProfiles.query(options2);
|
|
18158
18852
|
}, "getManagedProfiles"),
|
|
18853
|
+
actAs: /* @__PURE__ */ __name(async (_learnCard, profileId) => {
|
|
18854
|
+
const actingOptions = {
|
|
18855
|
+
...resolvedOptions,
|
|
18856
|
+
actAs: profileId
|
|
18857
|
+
};
|
|
18858
|
+
const actingPlugin = apiToken ? await getLearnCardNetworkPlugin(_learnCard, url2, apiToken, actingOptions) : await getLearnCardNetworkPlugin(_learnCard, url2, actingOptions);
|
|
18859
|
+
try {
|
|
18860
|
+
await actingPlugin.methods.getLCNClient(_learnCard).profile.getProfile.query();
|
|
18861
|
+
} catch (error51) {
|
|
18862
|
+
if (isActAsDenial(error51)) {
|
|
18863
|
+
const message = error51 instanceof Error ? error51.message : "Act-as request was denied.";
|
|
18864
|
+
throw new Error(message, { cause: error51 });
|
|
18865
|
+
}
|
|
18866
|
+
_learnCard.debug?.("LCN actAs: getProfile failed (non-fatal)", error51);
|
|
18867
|
+
}
|
|
18868
|
+
return _learnCard.addPlugin(actingPlugin);
|
|
18869
|
+
}, "actAs"),
|
|
18159
18870
|
claimPendingGuardianLinks: /* @__PURE__ */ __name(async () => {
|
|
18160
18871
|
await ensureUser();
|
|
18161
18872
|
return client.inbox.claimPendingGuardianLinks.mutate({});
|
|
@@ -18309,6 +19020,49 @@ async function getLearnCardNetworkPlugin(learnCard, url2, apiTokenOrOptions, opt
|
|
|
18309
19020
|
await ensureUser();
|
|
18310
19021
|
return client.profile.invalidateInvite.mutate({ challenge });
|
|
18311
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"),
|
|
18312
19066
|
blockProfile: /* @__PURE__ */ __name(async (_learnCard, profileId) => {
|
|
18313
19067
|
await ensureUser();
|
|
18314
19068
|
return client.profile.blockProfile.mutate({ profileId });
|
|
@@ -18423,12 +19177,15 @@ async function getLearnCardNetworkPlugin(learnCard, url2, apiTokenOrOptions, opt
|
|
|
18423
19177
|
await ensureUser();
|
|
18424
19178
|
return client.credential.deleteCredential.mutate({ uri });
|
|
18425
19179
|
}, "deleteCredential"),
|
|
18426
|
-
sendPresentation: /* @__PURE__ */ __name(async (_learnCard, profileId, vp, encrypt
|
|
19180
|
+
sendPresentation: /* @__PURE__ */ __name(async (_learnCard, profileId, vp, metadataOrEncrypt, encrypt) => {
|
|
18427
19181
|
await ensureUser();
|
|
18428
|
-
|
|
19182
|
+
const metadata = typeof metadataOrEncrypt === "object" ? metadataOrEncrypt : void 0;
|
|
19183
|
+
const shouldEncrypt = typeof metadataOrEncrypt === "boolean" ? metadataOrEncrypt : encrypt ?? true;
|
|
19184
|
+
if (!shouldEncrypt) {
|
|
18429
19185
|
return client.presentation.sendPresentation.mutate({
|
|
18430
19186
|
profileId,
|
|
18431
|
-
presentation: vp
|
|
19187
|
+
presentation: vp,
|
|
19188
|
+
metadata
|
|
18432
19189
|
});
|
|
18433
19190
|
}
|
|
18434
19191
|
const target = await _learnCard.invoke.getProfile(profileId);
|
|
@@ -18438,7 +19195,11 @@ async function getLearnCardNetworkPlugin(learnCard, url2, apiTokenOrOptions, opt
|
|
|
18438
19195
|
_learnCard.id.did(),
|
|
18439
19196
|
target.did
|
|
18440
19197
|
]);
|
|
18441
|
-
return client.presentation.sendPresentation.mutate({
|
|
19198
|
+
return client.presentation.sendPresentation.mutate({
|
|
19199
|
+
profileId,
|
|
19200
|
+
presentation,
|
|
19201
|
+
metadata
|
|
19202
|
+
});
|
|
18442
19203
|
}, "sendPresentation"),
|
|
18443
19204
|
acceptPresentation: /* @__PURE__ */ __name(async (_learnCard, uri) => {
|
|
18444
19205
|
await ensureUser();
|
|
@@ -18765,15 +19526,14 @@ async function getLearnCardNetworkPlugin(learnCard, url2, apiTokenOrOptions, opt
|
|
|
18765
19526
|
boost = options2.overideFn(boost);
|
|
18766
19527
|
}
|
|
18767
19528
|
const enableRefresh = typeof options2 === "object" && options2.enableRefresh === true;
|
|
18768
|
-
let
|
|
19529
|
+
let refreshAllocation;
|
|
18769
19530
|
if (enableRefresh) {
|
|
18770
19531
|
if (!boost.id) boost.id = `urn:uuid:${crypto.randomUUID()}`;
|
|
18771
|
-
|
|
19532
|
+
refreshAllocation = await client.credentialRefresh.allocateCredentialRefresh.mutate({
|
|
18772
19533
|
holder: { profileId, did: targetProfile.did },
|
|
18773
19534
|
credentialId: boost.id
|
|
18774
19535
|
});
|
|
18775
|
-
|
|
18776
|
-
boost = injectManagedRefreshService(boost, allocation.refreshService);
|
|
19536
|
+
boost = injectManagedRefreshService(boost, refreshAllocation.refreshService);
|
|
18777
19537
|
}
|
|
18778
19538
|
const statusPurposes = typeof options2 === "object" ? options2.statusPurposes : void 0;
|
|
18779
19539
|
const vc = await issueCredentialWithNetworkStatus(
|
|
@@ -18782,13 +19542,23 @@ async function getLearnCardNetworkPlugin(learnCard, url2, apiTokenOrOptions, opt
|
|
|
18782
19542
|
boost,
|
|
18783
19543
|
statusPurposes
|
|
18784
19544
|
);
|
|
18785
|
-
if (
|
|
18786
|
-
|
|
18787
|
-
refreshId:
|
|
19545
|
+
if (refreshAllocation) {
|
|
19546
|
+
const credentialUri = await client.credentialRefresh.sendRefreshableCredential.mutate({
|
|
19547
|
+
refreshId: refreshAllocation.refreshId,
|
|
18788
19548
|
credential: vc,
|
|
18789
19549
|
boostUri,
|
|
18790
19550
|
...typeof options2 === "object" && options2.skipNotification ? { skipNotification: true } : {}
|
|
18791
19551
|
});
|
|
19552
|
+
return {
|
|
19553
|
+
credentialUri,
|
|
19554
|
+
refresh: buildManagedRefreshReceipt(
|
|
19555
|
+
vc,
|
|
19556
|
+
refreshAllocation,
|
|
19557
|
+
boost.id ?? "",
|
|
19558
|
+
targetProfile.did,
|
|
19559
|
+
_learnCard.id.did()
|
|
19560
|
+
)
|
|
19561
|
+
};
|
|
18792
19562
|
}
|
|
18793
19563
|
if (typeof options2 === "object" && !options2.encrypt || !options2) {
|
|
18794
19564
|
return client.boost.sendBoost.mutate({
|
|
@@ -18854,6 +19624,94 @@ async function getLearnCardNetworkPlugin(learnCard, url2, apiTokenOrOptions, opt
|
|
|
18854
19624
|
}, "claimBoostWithLink"),
|
|
18855
19625
|
send: /* @__PURE__ */ __name(async (_learnCard, input) => {
|
|
18856
19626
|
await ensureUser();
|
|
19627
|
+
if (input.type === "boost" && input.refresh === true) {
|
|
19628
|
+
const isEmail = /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(input.recipient);
|
|
19629
|
+
const isPhone = /^\+?[\d\s-]{10,}$/.test(input.recipient.replace(/[\s-]/g, ""));
|
|
19630
|
+
if (isEmail || isPhone) return client.boost.send.mutate(input);
|
|
19631
|
+
const canIssueLocally = "issueCredential" in _learnCard.invoke;
|
|
19632
|
+
if (canIssueLocally && !input.signedCredential && (input.templateUri || input.template)) {
|
|
19633
|
+
let boost;
|
|
19634
|
+
if (input.templateUri) {
|
|
19635
|
+
const result = await getBoostTemplateForIssuance(
|
|
19636
|
+
_learnCard,
|
|
19637
|
+
input.templateUri
|
|
19638
|
+
);
|
|
19639
|
+
const data = await UnsignedVCValidator.spa(result);
|
|
19640
|
+
if (!data.success)
|
|
19641
|
+
throw new Error("Did not get a valid boost from URI");
|
|
19642
|
+
boost = data.data;
|
|
19643
|
+
} else {
|
|
19644
|
+
boost = JSON.parse(
|
|
19645
|
+
JSON.stringify(input.template.credential)
|
|
19646
|
+
);
|
|
19647
|
+
}
|
|
19648
|
+
const prepared = await client.boost.prepareRefreshableSend.mutate({
|
|
19649
|
+
recipient: input.recipient,
|
|
19650
|
+
...input.templateUri ? { templateUri: input.templateUri } : { template: input.template },
|
|
19651
|
+
...input.contractUri ? { contractUri: input.contractUri } : {},
|
|
19652
|
+
...input.templateData ? { templateData: input.templateData } : {},
|
|
19653
|
+
...input.integrationId ? { integrationId: input.integrationId } : {},
|
|
19654
|
+
...boost.id ? { credentialId: boost.id } : {},
|
|
19655
|
+
...input.idempotencyKey ? { idempotencyKey: input.idempotencyKey } : {}
|
|
19656
|
+
});
|
|
19657
|
+
if (prepared.completed) return prepared.completed;
|
|
19658
|
+
const boostString = JSON.stringify(boost);
|
|
19659
|
+
const allowAutoAppendEvidence = !hasDynamicEvidenceTemplate(boostString);
|
|
19660
|
+
if (input.templateData && Object.keys(input.templateData).length > 0) {
|
|
19661
|
+
try {
|
|
19662
|
+
const rendered = renderTemplateJson(
|
|
19663
|
+
boostString,
|
|
19664
|
+
input.templateData
|
|
19665
|
+
);
|
|
19666
|
+
boost = JSON.parse(rendered);
|
|
19667
|
+
boost = appendTemplateEvidence(
|
|
19668
|
+
boost,
|
|
19669
|
+
input.templateData,
|
|
19670
|
+
allowAutoAppendEvidence
|
|
19671
|
+
);
|
|
19672
|
+
} catch (error51) {
|
|
19673
|
+
throw new Error(
|
|
19674
|
+
`Failed to apply template data: ${error51 instanceof Error ? error51.message : "Unknown error"}`,
|
|
19675
|
+
{ cause: error51 }
|
|
19676
|
+
);
|
|
19677
|
+
}
|
|
19678
|
+
}
|
|
19679
|
+
if (isVC2Format(boost)) {
|
|
19680
|
+
boost.validFrom = (/* @__PURE__ */ new Date()).toISOString();
|
|
19681
|
+
} else {
|
|
19682
|
+
boost.issuanceDate = (/* @__PURE__ */ new Date()).toISOString();
|
|
19683
|
+
}
|
|
19684
|
+
boost.issuer = _learnCard.id.did();
|
|
19685
|
+
if (Array.isArray(boost.credentialSubject)) {
|
|
19686
|
+
boost.credentialSubject = boost.credentialSubject.map((subject) => ({
|
|
19687
|
+
...subject,
|
|
19688
|
+
id: prepared.holderDid
|
|
19689
|
+
}));
|
|
19690
|
+
} else {
|
|
19691
|
+
boost.credentialSubject = {
|
|
19692
|
+
...boost.credentialSubject,
|
|
19693
|
+
id: prepared.holderDid
|
|
19694
|
+
};
|
|
19695
|
+
}
|
|
19696
|
+
boost.id = prepared.credentialId;
|
|
19697
|
+
if (boost.type?.includes("BoostCredential"))
|
|
19698
|
+
boost.boostId = prepared.boostUri;
|
|
19699
|
+
boost = injectManagedRefreshService(boost, prepared.refreshService);
|
|
19700
|
+
const signedCredential = await issueCredentialWithNetworkStatus(
|
|
19701
|
+
_learnCard,
|
|
19702
|
+
client,
|
|
19703
|
+
boost
|
|
19704
|
+
);
|
|
19705
|
+
return client.boost.send.mutate({
|
|
19706
|
+
...input,
|
|
19707
|
+
template: void 0,
|
|
19708
|
+
templateUri: prepared.boostUri,
|
|
19709
|
+
signedCredential,
|
|
19710
|
+
refresh: true
|
|
19711
|
+
});
|
|
19712
|
+
}
|
|
19713
|
+
return client.boost.send.mutate(input);
|
|
19714
|
+
}
|
|
18857
19715
|
if (input.type === "boost") {
|
|
18858
19716
|
const recipient = input.recipient;
|
|
18859
19717
|
const isDid = recipient.startsWith("did:");
|
|
@@ -19260,6 +20118,37 @@ async function getLearnCardNetworkPlugin(learnCard, url2, apiTokenOrOptions, opt
|
|
|
19260
20118
|
await ensureUser();
|
|
19261
20119
|
return client.inbox.issue.mutate(issueInboxCredential);
|
|
19262
20120
|
}, "sendCredentialViaInbox"),
|
|
20121
|
+
sendCredentialsViaInbox: /* @__PURE__ */ __name(async (_learnCard, batch) => {
|
|
20122
|
+
await ensureUser();
|
|
20123
|
+
return client.inbox.issueBatch.mutate(batch);
|
|
20124
|
+
}, "sendCredentialsViaInbox"),
|
|
20125
|
+
sendCredentialBatchViaInbox: /* @__PURE__ */ __name(async (_learnCard, batch) => {
|
|
20126
|
+
await ensureUser();
|
|
20127
|
+
return client.inbox.issueBatch.mutate(batch);
|
|
20128
|
+
}, "sendCredentialBatchViaInbox"),
|
|
20129
|
+
waitForInboxCredentialBatch: /* @__PURE__ */ __name(async (_learnCard, batchId, options2) => {
|
|
20130
|
+
await ensureUser();
|
|
20131
|
+
return waitForInboxCredentialBatch(
|
|
20132
|
+
(signal) => client.inbox.getBatch.query({ batchId }, { signal }),
|
|
20133
|
+
options2
|
|
20134
|
+
);
|
|
20135
|
+
}, "waitForInboxCredentialBatch"),
|
|
20136
|
+
sendCredentialsViaInboxAndWait: /* @__PURE__ */ __name(async (_learnCard, batch, options2) => {
|
|
20137
|
+
await ensureUser();
|
|
20138
|
+
if (options2?.signal?.aborted) throw options2.signal.reason;
|
|
20139
|
+
const receipt = await client.inbox.issueBatch.mutate(batch, {
|
|
20140
|
+
signal: options2?.signal
|
|
20141
|
+
});
|
|
20142
|
+
await options2?.onSubmitted?.(receipt);
|
|
20143
|
+
return waitForInboxCredentialBatch(
|
|
20144
|
+
(signal) => client.inbox.getBatch.query({ batchId: receipt.batchId }, { signal }),
|
|
20145
|
+
options2
|
|
20146
|
+
);
|
|
20147
|
+
}, "sendCredentialsViaInboxAndWait"),
|
|
20148
|
+
getInboxCredentialBatch: /* @__PURE__ */ __name(async (_learnCard, batchId) => {
|
|
20149
|
+
await ensureUser();
|
|
20150
|
+
return client.inbox.getBatch.query({ batchId });
|
|
20151
|
+
}, "getInboxCredentialBatch"),
|
|
19263
20152
|
getMySentInboxCredentials: /* @__PURE__ */ __name(async (_learnCard, options2) => {
|
|
19264
20153
|
await ensureUser();
|
|
19265
20154
|
return client.inbox.getMyIssuedCredentials.query(options2);
|
|
@@ -19803,6 +20692,7 @@ var getVerifyBoostPlugin = /* @__PURE__ */ __name(async (learnCard, trustedBoost
|
|
|
19803
20692
|
};
|
|
19804
20693
|
}, "getVerifyBoostPlugin");
|
|
19805
20694
|
export {
|
|
20695
|
+
ACT_AS_HEADER,
|
|
19806
20696
|
getLearnCardNetworkPlugin,
|
|
19807
20697
|
getVerifyBoostPlugin
|
|
19808
20698
|
};
|