@learncard/network-plugin 2.11.5 → 2.12.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.
@@ -13184,6 +13184,19 @@ var VC2EvidenceValidator = external_exports.object({
13184
13184
  genre: external_exports.string().optional(),
13185
13185
  audience: external_exports.string().optional()
13186
13186
  }).catchall(external_exports.any());
13187
+ var TemplateRenderMethodValidator = external_exports.object({
13188
+ type: external_exports.literal("TemplateRenderMethod"),
13189
+ renderSuite: external_exports.string(),
13190
+ template: external_exports.string(),
13191
+ renderProperty: external_exports.array(external_exports.string()).optional(),
13192
+ outputPreference: external_exports.object({
13193
+ mediaType: external_exports.string()
13194
+ }).optional()
13195
+ });
13196
+ var RenderMethodValidator = external_exports.union([
13197
+ TemplateRenderMethodValidator,
13198
+ external_exports.record(external_exports.string(), external_exports.any())
13199
+ ]);
13187
13200
  var UnsignedVCValidator = external_exports.object({
13188
13201
  "@context": ContextValidator,
13189
13202
  id: external_exports.string().optional(),
@@ -13207,7 +13220,8 @@ var UnsignedVCValidator = external_exports.object({
13207
13220
  validUntil: external_exports.string().optional(),
13208
13221
  status: CredentialStatusValidator.or(CredentialStatusValidator.array()).optional(),
13209
13222
  termsOfUse: TermsOfUseValidator.or(TermsOfUseValidator.array()).optional(),
13210
- evidence: external_exports.union([VC2EvidenceValidator, external_exports.array(VC2EvidenceValidator)]).optional()
13223
+ evidence: external_exports.union([VC2EvidenceValidator, external_exports.array(VC2EvidenceValidator)]).optional(),
13224
+ renderMethod: external_exports.union([RenderMethodValidator, external_exports.array(RenderMethodValidator)]).optional()
13211
13225
  }).catchall(external_exports.any());
13212
13226
  var ProofValidator = external_exports.object({
13213
13227
  type: external_exports.string(),
@@ -13515,10 +13529,45 @@ var UnsignedClrCredentialValidator = UnsignedVCValidator.extend({
13515
13529
  var ClrCredentialValidator = UnsignedClrCredentialValidator.extend({
13516
13530
  proof: ProofValidator.or(ProofValidator.array())
13517
13531
  });
13532
+ var StatusCheckEntryValidator = external_exports.object({
13533
+ /**
13534
+ * The `credentialStatus.type` as it appeared on the credential.
13535
+ * One of `BitstringStatusListEntry`, `StatusList2021Entry`,
13536
+ * `RevocationList2020Status`, or any future custom status type.
13537
+ */
13538
+ entryType: external_exports.string(),
13539
+ /**
13540
+ * The claimed purpose of the entry. Standard values are
13541
+ * `"revocation"` and `"suspension"`; the spec allows arbitrary
13542
+ * strings.
13543
+ */
13544
+ statusPurpose: external_exports.string(),
13545
+ /**
13546
+ * Whether the bit at the credential's index in the status list
13547
+ * bitstring was set.
13548
+ */
13549
+ isSet: external_exports.boolean(),
13550
+ /** URL of the status list credential, when known. */
13551
+ statusListCredential: external_exports.string().optional(),
13552
+ /** Original (string) index within the status list. */
13553
+ statusListIndex: external_exports.string().optional()
13554
+ });
13518
13555
  var VerificationCheckValidator = external_exports.object({
13519
13556
  checks: external_exports.string().array(),
13520
13557
  warnings: external_exports.string().array(),
13521
- errors: external_exports.string().array()
13558
+ errors: external_exports.string().array(),
13559
+ /**
13560
+ * Per-entry results for the `credentialStatus` check, populated
13561
+ * by `@learncard/didkit-plugin` when the verified credential
13562
+ * carries one or more `credentialStatus` entries. Empty / absent
13563
+ * for credentials without a status entry.
13564
+ *
13565
+ * Marked `.optional()` because the underlying `ssi-ldp`
13566
+ * serializer omits the field when empty (`skip_serializing_if`),
13567
+ * so older WASM builds that pre-date the structured-status
13568
+ * change still validate against this schema.
13569
+ */
13570
+ status: StatusCheckEntryValidator.array().optional()
13522
13571
  });
13523
13572
  var VerificationStatusValidator = external_exports.enum(["Success", "Failed", "Error"]);
13524
13573
  var VerificationStatusEnum = VerificationStatusValidator.enum;
@@ -14921,9 +14970,31 @@ var AuthSessionError = (_a2 = class extends Error {
14921
14970
  this.name = "AuthSessionError";
14922
14971
  }
14923
14972
  }, __name(_a2, "AuthSessionError"), __name2(_a2, "AuthSessionError"), _a2);
14973
+ var BITSTRING_STATUS_PURPOSES = ["revocation", "suspension"];
14974
+ var BitstringStatusPurposeValidator = external_exports.enum(BITSTRING_STATUS_PURPOSES);
14975
+ var BitstringStatusListEntryValidator = external_exports.object({
14976
+ id: external_exports.string().optional(),
14977
+ type: external_exports.literal("BitstringStatusListEntry"),
14978
+ statusPurpose: BitstringStatusPurposeValidator,
14979
+ statusListIndex: external_exports.string(),
14980
+ statusListCredential: external_exports.string()
14981
+ });
14982
+ var AllocatedBitstringStatusListEntryValidator = BitstringStatusListEntryValidator.extend({
14983
+ id: external_exports.string()
14984
+ });
14985
+ var BitstringStatusListCredentialSubjectValidator = external_exports.object({
14986
+ id: external_exports.string().optional(),
14987
+ type: external_exports.literal("BitstringStatusList"),
14988
+ statusPurpose: BitstringStatusPurposeValidator,
14989
+ encodedList: external_exports.string()
14990
+ });
14991
+ var AllocateCredentialStatusInputValidator = external_exports.object({
14992
+ statusPurposes: external_exports.array(BitstringStatusPurposeValidator).optional(),
14993
+ listSize: external_exports.number().int().positive().optional()
14994
+ }).default({});
14924
14995
 
14925
14996
  // src/plugin.ts
14926
- import { isVC2Format } from "@learncard/helpers";
14997
+ import { getCredentialStatusArray, isVC2Format } from "@learncard/helpers";
14927
14998
 
14928
14999
  // ../../../node_modules/.pnpm/mustache@4.2.0/node_modules/mustache/mustache.mjs
14929
15000
  var objectToString = Object.prototype.toString;
@@ -15454,6 +15525,27 @@ var appendTemplateEvidence = /* @__PURE__ */ __name((boost, templateData, allowA
15454
15525
  var hasDid = /* @__PURE__ */ __name((profile) => {
15455
15526
  return !!profile && "did" in profile && typeof profile.did === "string" && profile.did.length > 0;
15456
15527
  }, "hasDid");
15528
+ var appendNetworkCredentialStatus = /* @__PURE__ */ __name(async (client, credential, statusPurposes = ["revocation"]) => {
15529
+ if (!isVC2Format(credential)) return credential;
15530
+ const existingStatuses = getCredentialStatusArray(credential);
15531
+ const missingPurposes = statusPurposes.filter((statusPurpose) => {
15532
+ return !existingStatuses.some(
15533
+ (status) => status.type === "BitstringStatusListEntry" && status.statusPurpose === statusPurpose
15534
+ );
15535
+ });
15536
+ if (missingPurposes.length === 0) return credential;
15537
+ const entries = await client.boost.allocateCredentialStatus.mutate({
15538
+ statusPurposes: missingPurposes
15539
+ });
15540
+ const credentialStatuses = [...existingStatuses, ...entries];
15541
+ credential.credentialStatus = credentialStatuses.length === 1 ? credentialStatuses[0] : credentialStatuses;
15542
+ return credential;
15543
+ }, "appendNetworkCredentialStatus");
15544
+ var issueCredentialWithNetworkStatus = /* @__PURE__ */ __name(async (learnCard, client, credential, statusPurposes) => {
15545
+ return learnCard.invoke.issueCredential(
15546
+ await appendNetworkCredentialStatus(client, credential, statusPurposes)
15547
+ );
15548
+ }, "issueCredentialWithNetworkStatus");
15457
15549
  async function getLearnCardNetworkPlugin(learnCard, url2, apiTokenOrOptions, options) {
15458
15550
  const apiToken = typeof apiTokenOrOptions === "string" ? apiTokenOrOptions : void 0;
15459
15551
  const guardianApprovalGetter = (typeof apiTokenOrOptions === "object" ? apiTokenOrOptions?.guardianApprovalGetter : void 0) ?? options?.guardianApprovalGetter;
@@ -15833,7 +15925,11 @@ async function getLearnCardNetworkPlugin(learnCard, url2, apiTokenOrOptions, opt
15833
15925
  const myProfile = await client.profile.getProfile.query();
15834
15926
  const issuerDid = myProfile?.did || await client.utilities.getDid.query();
15835
15927
  const issuerDisplayName = myProfile?.displayName || "Unknown Issuer";
15836
- const signedCredential = await _learnCard.invoke.issueCredential(vc);
15928
+ const signedCredential = await issueCredentialWithNetworkStatus(
15929
+ _learnCard,
15930
+ client,
15931
+ vc
15932
+ );
15837
15933
  const didAuthJwt = await _learnCard.invoke.getDidAuthVp({
15838
15934
  proofFormat: "jwt",
15839
15935
  challenge: `inbox-federation-${crypto.randomUUID()}`
@@ -16171,10 +16267,28 @@ async function getLearnCardNetworkPlugin(learnCard, url2, apiTokenOrOptions, opt
16171
16267
  if (result) await _learnCard.invoke.clearDidWebCache?.();
16172
16268
  return result;
16173
16269
  }, "removeBoostAdmin"),
16270
+ allocateCredentialStatus: /* @__PURE__ */ __name(async (_learnCard, options2 = {}) => {
16271
+ await ensureUser();
16272
+ return client.boost.allocateCredentialStatus.mutate(options2);
16273
+ }, "allocateCredentialStatus"),
16174
16274
  revokeBoostRecipient: /* @__PURE__ */ __name(async (_learnCard, boostUri, recipientProfileId) => {
16175
16275
  await ensureUser();
16176
16276
  return client.boost.revokeBoostRecipient.mutate({ boostUri, recipientProfileId });
16177
16277
  }, "revokeBoostRecipient"),
16278
+ suspendBoostRecipient: /* @__PURE__ */ __name(async (_learnCard, boostUri, recipientProfileId) => {
16279
+ await ensureUser();
16280
+ return client.boost.suspendBoostRecipient.mutate({
16281
+ boostUri,
16282
+ recipientProfileId
16283
+ });
16284
+ }, "suspendBoostRecipient"),
16285
+ unsuspendBoostRecipient: /* @__PURE__ */ __name(async (_learnCard, boostUri, recipientProfileId) => {
16286
+ await ensureUser();
16287
+ return client.boost.unsuspendBoostRecipient.mutate({
16288
+ boostUri,
16289
+ recipientProfileId
16290
+ });
16291
+ }, "unsuspendBoostRecipient"),
16178
16292
  deleteBoost: /* @__PURE__ */ __name(async (_learnCard, uri) => {
16179
16293
  await ensureUser();
16180
16294
  return client.boost.deleteBoost.mutate({ uri });
@@ -16223,7 +16337,13 @@ async function getLearnCardNetworkPlugin(learnCard, url2, apiTokenOrOptions, opt
16223
16337
  if (typeof options2 === "object" && options2.overideFn) {
16224
16338
  boost = options2.overideFn(boost);
16225
16339
  }
16226
- const vc = await _learnCard.invoke.issueCredential(boost);
16340
+ const statusPurposes = typeof options2 === "object" ? options2.statusPurposes : void 0;
16341
+ const vc = await issueCredentialWithNetworkStatus(
16342
+ _learnCard,
16343
+ client,
16344
+ boost,
16345
+ statusPurposes
16346
+ );
16227
16347
  if (typeof options2 === "object" && !options2.encrypt || !options2) {
16228
16348
  return client.boost.sendBoost.mutate({
16229
16349
  profileId,
@@ -16331,7 +16451,11 @@ async function getLearnCardNetworkPlugin(learnCard, url2, apiTokenOrOptions, opt
16331
16451
  if (boost.type?.includes("BoostCredential")) {
16332
16452
  boost.boostId = input.templateUri;
16333
16453
  }
16334
- const signedCredential = await _learnCard.invoke.issueCredential(boost);
16454
+ const signedCredential = await issueCredentialWithNetworkStatus(
16455
+ _learnCard,
16456
+ client,
16457
+ boost
16458
+ );
16335
16459
  const credentialUri = await _learnCard.invoke.sendCredential(
16336
16460
  recipient,
16337
16461
  signedCredential,
@@ -16405,7 +16529,11 @@ async function getLearnCardNetworkPlugin(learnCard, url2, apiTokenOrOptions, opt
16405
16529
  }
16406
16530
  if (boost?.type?.includes("BoostCredential"))
16407
16531
  boost.boostId = input.templateUri;
16408
- const signedCredential = await _learnCard.invoke.issueCredential(boost);
16532
+ const signedCredential = await issueCredentialWithNetworkStatus(
16533
+ _learnCard,
16534
+ client,
16535
+ boost
16536
+ );
16409
16537
  if (isDid && recipient.startsWith("did:web:")) {
16410
16538
  const credentialUri = await _learnCard.invoke.sendCredential(
16411
16539
  recipient,
@@ -16530,6 +16658,12 @@ async function getLearnCardNetworkPlugin(learnCard, url2, apiTokenOrOptions, opt
16530
16658
  categories
16531
16659
  });
16532
16660
  }, "syncCredentialsToContract"),
16661
+ deleteCredentialFromAllContracts: /* @__PURE__ */ __name(async (_learnCard, deletedUris) => {
16662
+ await ensureUser();
16663
+ return client.contracts.deleteCredentialFromAllContracts.mutate({
16664
+ deletedUris
16665
+ });
16666
+ }, "deleteCredentialFromAllContracts"),
16533
16667
  sendAiInsightsContractRequest: /* @__PURE__ */ __name(async (_learnCard, contractUri, targetProfileId, shareLink) => {
16534
16668
  await ensureUser();
16535
16669
  return client.contracts.sendAiInsightsContractRequest.mutate({
@@ -17131,14 +17265,28 @@ var getVerifyBoostPlugin = /* @__PURE__ */ __name(async (learnCard, trustedBoost
17131
17265
  const verifyBoostCredential = await learnCard.invoke.verifyCredential(
17132
17266
  boostCredential
17133
17267
  );
17268
+ const boostCredentialErrors = verifyBoostCredential.errors ?? [];
17269
+ if (verifyBoostCredential.status?.length) {
17270
+ verificationCheck.status = [
17271
+ ...verificationCheck.status ?? [],
17272
+ ...verifyBoostCredential.status
17273
+ ];
17274
+ }
17134
17275
  if (!boostCredential?.boostId && !credential?.boostId) {
17135
17276
  verificationCheck.warnings.push(
17136
17277
  "Boost Authenticity could not be verified: Boost ID metadata is missing."
17137
17278
  );
17138
17279
  }
17139
- if (verifyBoostCredential.errors?.length > 0) {
17280
+ if (boostCredentialErrors.length > 0) {
17281
+ if (boostCredentialErrors.some(
17282
+ (error46) => /revoked|suspend|status/i.test(error46)
17283
+ )) {
17284
+ verificationCheck.checks = verificationCheck.checks.filter(
17285
+ (check2) => check2 !== "status"
17286
+ );
17287
+ }
17140
17288
  verificationCheck.errors = [
17141
- ...verifyBoostCredential.errors || [],
17289
+ ...boostCredentialErrors,
17142
17290
  ...verificationCheck.errors || [],
17143
17291
  "Boost Credential could not be verified."
17144
17292
  ];