@sphereon/ssi-sdk.vc-status-list 0.34.1-next.7 → 0.34.1-next.86
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +695 -122
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +163 -37
- package/dist/index.d.ts +163 -37
- package/dist/index.js +698 -125
- package/dist/index.js.map +1 -1
- package/package.json +10 -7
- package/src/functions.ts +126 -47
- package/src/impl/BitstringStatusListImplementation.ts +496 -0
- package/src/impl/IStatusList.ts +102 -8
- package/src/impl/OAuthStatusList.ts +133 -38
- package/src/impl/StatusList2021.ts +114 -34
- package/src/impl/StatusListFactory.ts +2 -0
- package/src/impl/encoding/cbor.ts +14 -12
- package/src/index.ts +1 -0
- package/src/types/BitstringStatusList.ts +4 -0
- package/src/types/index.ts +56 -35
- package/src/utils.ts +82 -20
package/dist/index.cjs
CHANGED
|
@@ -35,12 +35,15 @@ __export(index_exports, {
|
|
|
35
35
|
StatusOAuth: () => StatusOAuth,
|
|
36
36
|
checkStatusForCredential: () => checkStatusForCredential,
|
|
37
37
|
checkStatusIndexFromStatusListCredential: () => checkStatusIndexFromStatusListCredential,
|
|
38
|
+
createCredentialStatusFromStatusList: () => createCredentialStatusFromStatusList,
|
|
38
39
|
createNewStatusList: () => createNewStatusList,
|
|
40
|
+
determineStatusListType: () => determineStatusListType,
|
|
41
|
+
extractCredentialDetails: () => extractCredentialDetails,
|
|
39
42
|
fetchStatusListCredential: () => fetchStatusListCredential,
|
|
40
43
|
simpleCheckStatusFromStatusListUrl: () => simpleCheckStatusFromStatusListUrl,
|
|
41
44
|
statusList2021ToVerifiableCredential: () => statusList2021ToVerifiableCredential,
|
|
42
|
-
statusListCredentialToDetails: () => statusListCredentialToDetails,
|
|
43
45
|
statusPluginStatusFunction: () => statusPluginStatusFunction,
|
|
46
|
+
toStatusListDetails: () => toStatusListDetails,
|
|
44
47
|
updateStatusIndexFromStatusListCredential: () => updateStatusIndexFromStatusListCredential,
|
|
45
48
|
updateStatusListIndexFromEncodedList: () => updateStatusListIndexFromEncodedList,
|
|
46
49
|
vcLibCheckStatusFunction: () => vcLibCheckStatusFunction
|
|
@@ -48,20 +51,20 @@ __export(index_exports, {
|
|
|
48
51
|
module.exports = __toCommonJS(index_exports);
|
|
49
52
|
|
|
50
53
|
// src/types/index.ts
|
|
51
|
-
var StatusOAuth = /* @__PURE__ */ function(StatusOAuth2) {
|
|
54
|
+
var StatusOAuth = /* @__PURE__ */ (function(StatusOAuth2) {
|
|
52
55
|
StatusOAuth2[StatusOAuth2["Valid"] = 0] = "Valid";
|
|
53
56
|
StatusOAuth2[StatusOAuth2["Invalid"] = 1] = "Invalid";
|
|
54
57
|
StatusOAuth2[StatusOAuth2["Suspended"] = 2] = "Suspended";
|
|
55
58
|
return StatusOAuth2;
|
|
56
|
-
}({});
|
|
57
|
-
var Status2021 = /* @__PURE__ */ function(Status20212) {
|
|
59
|
+
})({});
|
|
60
|
+
var Status2021 = /* @__PURE__ */ (function(Status20212) {
|
|
58
61
|
Status20212[Status20212["Valid"] = 0] = "Valid";
|
|
59
62
|
Status20212[Status20212["Invalid"] = 1] = "Invalid";
|
|
60
63
|
return Status20212;
|
|
61
|
-
}({});
|
|
64
|
+
})({});
|
|
62
65
|
|
|
63
66
|
// src/functions.ts
|
|
64
|
-
var
|
|
67
|
+
var import_ssi_types7 = require("@sphereon/ssi-types");
|
|
65
68
|
var import_vc_status_list2 = require("@sphereon/vc-status-list");
|
|
66
69
|
|
|
67
70
|
// src/utils.ts
|
|
@@ -71,7 +74,8 @@ function getAssertedStatusListType(type) {
|
|
|
71
74
|
const assertedType = type ?? import_ssi_types.StatusListType.StatusList2021;
|
|
72
75
|
if (![
|
|
73
76
|
import_ssi_types.StatusListType.StatusList2021,
|
|
74
|
-
import_ssi_types.StatusListType.OAuthStatusList
|
|
77
|
+
import_ssi_types.StatusListType.OAuthStatusList,
|
|
78
|
+
import_ssi_types.StatusListType.BitstringStatusList
|
|
75
79
|
].includes(assertedType)) {
|
|
76
80
|
throw Error(`StatusList type ${assertedType} is not supported (yet)`);
|
|
77
81
|
}
|
|
@@ -108,8 +112,7 @@ var ValidProofTypeMap = /* @__PURE__ */ new Map([
|
|
|
108
112
|
import_ssi_types.StatusListType.StatusList2021,
|
|
109
113
|
[
|
|
110
114
|
"jwt",
|
|
111
|
-
"lds"
|
|
112
|
-
"EthereumEip712Signature2021"
|
|
115
|
+
"lds"
|
|
113
116
|
]
|
|
114
117
|
],
|
|
115
118
|
[
|
|
@@ -118,6 +121,13 @@ var ValidProofTypeMap = /* @__PURE__ */ new Map([
|
|
|
118
121
|
"jwt",
|
|
119
122
|
"cbor"
|
|
120
123
|
]
|
|
124
|
+
],
|
|
125
|
+
[
|
|
126
|
+
import_ssi_types.StatusListType.BitstringStatusList,
|
|
127
|
+
[
|
|
128
|
+
"lds",
|
|
129
|
+
"vc+jwt"
|
|
130
|
+
]
|
|
121
131
|
]
|
|
122
132
|
]);
|
|
123
133
|
function assertValidProofType(type, proofFormat) {
|
|
@@ -131,29 +141,50 @@ function determineStatusListType(credential) {
|
|
|
131
141
|
const proofFormat = determineProofFormat(credential);
|
|
132
142
|
switch (proofFormat) {
|
|
133
143
|
case "jwt":
|
|
134
|
-
|
|
135
|
-
const keys = Object.keys(payload);
|
|
136
|
-
if (keys.includes("status_list")) {
|
|
137
|
-
return import_ssi_types.StatusListType.OAuthStatusList;
|
|
138
|
-
} else if (keys.includes("vc")) {
|
|
139
|
-
return import_ssi_types.StatusListType.StatusList2021;
|
|
140
|
-
}
|
|
141
|
-
break;
|
|
144
|
+
return determineJwtStatusListType(credential);
|
|
142
145
|
case "lds":
|
|
143
|
-
|
|
144
|
-
const type = uniform.type.find((t) => {
|
|
145
|
-
return Object.values(import_ssi_types.StatusListType).some((statusType) => t.includes(statusType));
|
|
146
|
-
});
|
|
147
|
-
if (!type) {
|
|
148
|
-
throw new Error("Invalid status list credential type");
|
|
149
|
-
}
|
|
150
|
-
return type.replace("Credential", "");
|
|
146
|
+
return determineLdsStatusListType(credential);
|
|
151
147
|
case "cbor":
|
|
152
148
|
return import_ssi_types.StatusListType.OAuthStatusList;
|
|
149
|
+
default:
|
|
150
|
+
throw new Error("Cannot determine status list type from credential payload");
|
|
153
151
|
}
|
|
154
|
-
throw new Error("Cannot determine status list type from credential payload");
|
|
155
152
|
}
|
|
156
153
|
__name(determineStatusListType, "determineStatusListType");
|
|
154
|
+
function determineJwtStatusListType(credential) {
|
|
155
|
+
const payload = (0, import_jwt_decode.jwtDecode)(credential);
|
|
156
|
+
if ("status_list" in payload) {
|
|
157
|
+
return import_ssi_types.StatusListType.OAuthStatusList;
|
|
158
|
+
}
|
|
159
|
+
if ("credentialSubject" in payload) {
|
|
160
|
+
return getStatusListTypeFromSubject(payload.credentialSubject);
|
|
161
|
+
}
|
|
162
|
+
if ("vc" in payload && "credentialSubject" in payload.vc) {
|
|
163
|
+
return getStatusListTypeFromSubject(payload.vc.credentialSubject);
|
|
164
|
+
}
|
|
165
|
+
throw new Error("Invalid status list credential: credentialSubject not found");
|
|
166
|
+
}
|
|
167
|
+
__name(determineJwtStatusListType, "determineJwtStatusListType");
|
|
168
|
+
function determineLdsStatusListType(credential) {
|
|
169
|
+
const uniform = import_ssi_types.CredentialMapper.toUniformCredential(credential);
|
|
170
|
+
const statusListType = uniform.type.find((type) => Object.values(import_ssi_types.StatusListType).some((statusType) => type.includes(statusType)));
|
|
171
|
+
if (!statusListType) {
|
|
172
|
+
throw new Error("Invalid status list credential type");
|
|
173
|
+
}
|
|
174
|
+
return statusListType.replace("Credential", "");
|
|
175
|
+
}
|
|
176
|
+
__name(determineLdsStatusListType, "determineLdsStatusListType");
|
|
177
|
+
function getStatusListTypeFromSubject(credentialSubject) {
|
|
178
|
+
switch (credentialSubject.type) {
|
|
179
|
+
case "StatusList2021":
|
|
180
|
+
return import_ssi_types.StatusListType.StatusList2021;
|
|
181
|
+
case "BitstringStatusList":
|
|
182
|
+
return import_ssi_types.StatusListType.BitstringStatusList;
|
|
183
|
+
default:
|
|
184
|
+
throw new Error(`Unknown credential subject type: ${credentialSubject.type}`);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
__name(getStatusListTypeFromSubject, "getStatusListTypeFromSubject");
|
|
157
188
|
function determineProofFormat(credential) {
|
|
158
189
|
const type = import_ssi_types.CredentialMapper.detectDocumentType(credential);
|
|
159
190
|
switch (type) {
|
|
@@ -168,6 +199,26 @@ function determineProofFormat(credential) {
|
|
|
168
199
|
}
|
|
169
200
|
}
|
|
170
201
|
__name(determineProofFormat, "determineProofFormat");
|
|
202
|
+
function ensureDate(value) {
|
|
203
|
+
if (value === void 0 || value === null) {
|
|
204
|
+
return void 0;
|
|
205
|
+
}
|
|
206
|
+
if (value instanceof Date) {
|
|
207
|
+
return value;
|
|
208
|
+
}
|
|
209
|
+
if (typeof value === "string") {
|
|
210
|
+
if (value.trim() === "") {
|
|
211
|
+
return void 0;
|
|
212
|
+
}
|
|
213
|
+
const date = new Date(value);
|
|
214
|
+
if (isNaN(date.getTime())) {
|
|
215
|
+
return void 0;
|
|
216
|
+
}
|
|
217
|
+
return date;
|
|
218
|
+
}
|
|
219
|
+
return void 0;
|
|
220
|
+
}
|
|
221
|
+
__name(ensureDate, "ensureDate");
|
|
171
222
|
|
|
172
223
|
// src/impl/StatusList2021.ts
|
|
173
224
|
var import_ssi_types2 = require("@sphereon/ssi-types");
|
|
@@ -231,13 +282,14 @@ var StatusList2021Implementation = class {
|
|
|
231
282
|
encodedList,
|
|
232
283
|
proofFormat
|
|
233
284
|
}, context);
|
|
285
|
+
if (!("statusPurpose" in credentialSubject)) {
|
|
286
|
+
return Promise.reject(Error("statusPurpose is required in credentialSubject for StatusList2021"));
|
|
287
|
+
}
|
|
234
288
|
return {
|
|
235
289
|
statusListCredential: updatedCredential,
|
|
236
290
|
encodedList,
|
|
237
291
|
statusList2021: {
|
|
238
|
-
|
|
239
|
-
statusPurpose: credentialSubject.statusPurpose
|
|
240
|
-
} : {},
|
|
292
|
+
statusPurpose: credentialSubject.statusPurpose,
|
|
241
293
|
indexingDirection: "rightToLeft"
|
|
242
294
|
},
|
|
243
295
|
length: statusList.length - 1,
|
|
@@ -260,7 +312,7 @@ var StatusList2021Implementation = class {
|
|
|
260
312
|
encodedList: args.encodedList
|
|
261
313
|
});
|
|
262
314
|
const index = typeof args.statusListIndex === "number" ? args.statusListIndex : parseInt(args.statusListIndex);
|
|
263
|
-
statusList.setStatus(index, args.value);
|
|
315
|
+
statusList.setStatus(index, args.value !== 0);
|
|
264
316
|
const newEncodedList = await statusList.encode();
|
|
265
317
|
const credential = await this.createVerifiableCredential({
|
|
266
318
|
id,
|
|
@@ -294,36 +346,88 @@ var StatusList2021Implementation = class {
|
|
|
294
346
|
const status = statusList.getStatus(typeof args.statusListIndex === "number" ? args.statusListIndex : parseInt(args.statusListIndex));
|
|
295
347
|
return status ? Status2021.Invalid : Status2021.Valid;
|
|
296
348
|
}
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
349
|
+
/**
|
|
350
|
+
* Performs the initial parsing of a StatusListCredential.
|
|
351
|
+
* This method handles expensive operations like JWT/CWT decoding once.
|
|
352
|
+
* It extracts all details available from the credential payload itself.
|
|
353
|
+
*/
|
|
354
|
+
async extractCredentialDetails(credential) {
|
|
355
|
+
const uniform = import_ssi_types2.CredentialMapper.toUniformCredential(credential);
|
|
300
356
|
const { issuer, credentialSubject } = uniform;
|
|
301
|
-
const
|
|
302
|
-
const encodedList = getAssertedProperty("encodedList", credentialSubject);
|
|
303
|
-
const proofFormat = import_ssi_types2.CredentialMapper.detectDocumentType(statusListPayload) === import_ssi_types2.DocumentFormat.JWT ? "jwt" : "lds";
|
|
304
|
-
const statusPurpose = getAssertedProperty("statusPurpose", credentialSubject);
|
|
305
|
-
const list = await import_vc_status_list.StatusList.decode({
|
|
306
|
-
encodedList
|
|
307
|
-
});
|
|
357
|
+
const subject = Array.isArray(credentialSubject) ? credentialSubject[0] : credentialSubject;
|
|
308
358
|
return {
|
|
309
|
-
id,
|
|
310
|
-
encodedList,
|
|
359
|
+
id: getAssertedValue("id", uniform.id),
|
|
311
360
|
issuer,
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
361
|
+
encodedList: getAssertedProperty("encodedList", subject)
|
|
362
|
+
};
|
|
363
|
+
}
|
|
364
|
+
async toStatusListDetails(args) {
|
|
365
|
+
if ("statusListCredential" in args) {
|
|
366
|
+
const { statusListCredential, correlationId, driverType } = args;
|
|
367
|
+
const uniform = import_ssi_types2.CredentialMapper.toUniformCredential(statusListCredential);
|
|
368
|
+
const { issuer, credentialSubject } = uniform;
|
|
369
|
+
const subject = Array.isArray(credentialSubject) ? credentialSubject[0] : credentialSubject;
|
|
370
|
+
const id = getAssertedValue("id", uniform.id);
|
|
371
|
+
const encodedList = getAssertedProperty("encodedList", subject);
|
|
372
|
+
const statusPurpose = getAssertedProperty("statusPurpose", subject);
|
|
373
|
+
const proofFormat = import_ssi_types2.CredentialMapper.detectDocumentType(statusListCredential) === import_ssi_types2.DocumentFormat.JWT ? "jwt" : "lds";
|
|
374
|
+
const list = await import_vc_status_list.StatusList.decode({
|
|
375
|
+
encodedList
|
|
376
|
+
});
|
|
377
|
+
return {
|
|
378
|
+
id,
|
|
379
|
+
encodedList,
|
|
380
|
+
issuer,
|
|
381
|
+
type: import_ssi_types2.StatusListType.StatusList2021,
|
|
382
|
+
proofFormat,
|
|
383
|
+
length: list.length,
|
|
384
|
+
statusListCredential,
|
|
385
|
+
statuslistContentType: this.buildContentType(proofFormat),
|
|
386
|
+
correlationId,
|
|
387
|
+
driverType,
|
|
318
388
|
indexingDirection: "rightToLeft",
|
|
319
|
-
statusPurpose
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
}
|
|
389
|
+
statusPurpose,
|
|
390
|
+
statusList2021: {
|
|
391
|
+
indexingDirection: "rightToLeft",
|
|
392
|
+
statusPurpose
|
|
393
|
+
}
|
|
394
|
+
};
|
|
395
|
+
} else {
|
|
396
|
+
const { extractedDetails, statusListEntity } = args;
|
|
397
|
+
const statusList2021Entity = statusListEntity;
|
|
398
|
+
const proofFormat = import_ssi_types2.CredentialMapper.detectDocumentType(statusListEntity.statusListCredential) === import_ssi_types2.DocumentFormat.JWT ? "jwt" : "lds";
|
|
399
|
+
const list = await import_vc_status_list.StatusList.decode({
|
|
400
|
+
encodedList: extractedDetails.encodedList
|
|
401
|
+
});
|
|
402
|
+
return {
|
|
403
|
+
id: extractedDetails.id,
|
|
404
|
+
encodedList: extractedDetails.encodedList,
|
|
405
|
+
issuer: extractedDetails.issuer,
|
|
406
|
+
type: import_ssi_types2.StatusListType.StatusList2021,
|
|
407
|
+
proofFormat,
|
|
408
|
+
length: list.length,
|
|
409
|
+
statusListCredential: statusListEntity.statusListCredential,
|
|
410
|
+
statuslistContentType: this.buildContentType(proofFormat),
|
|
411
|
+
correlationId: statusListEntity.correlationId,
|
|
412
|
+
driverType: statusListEntity.driverType,
|
|
413
|
+
indexingDirection: statusList2021Entity.indexingDirection,
|
|
414
|
+
statusPurpose: statusList2021Entity.statusPurpose,
|
|
415
|
+
statusList2021: {
|
|
416
|
+
indexingDirection: statusList2021Entity.indexingDirection,
|
|
417
|
+
statusPurpose: statusList2021Entity.statusPurpose
|
|
418
|
+
}
|
|
419
|
+
};
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
async createCredentialStatus(args) {
|
|
423
|
+
const { statusList, statusListIndex } = args;
|
|
424
|
+
const statusList2021 = statusList;
|
|
425
|
+
return {
|
|
426
|
+
id: `${statusList.id}#${statusListIndex}`,
|
|
427
|
+
type: "StatusList2021Entry",
|
|
428
|
+
statusPurpose: statusList2021.statusPurpose ?? "revocation",
|
|
429
|
+
statusListIndex: "" + statusListIndex,
|
|
430
|
+
statusListCredential: statusList.id
|
|
327
431
|
};
|
|
328
432
|
}
|
|
329
433
|
async createVerifiableCredential(args, context) {
|
|
@@ -462,9 +566,9 @@ var import_pako = require("pako");
|
|
|
462
566
|
var import_kmp_mdoc_core = __toESM(require("@sphereon/kmp-mdoc-core"), 1);
|
|
463
567
|
var import_base64url2 = __toESM(require("base64url"), 1);
|
|
464
568
|
var { com, kotlin } = import_kmp_mdoc_core.default;
|
|
465
|
-
var CborByteString = com.sphereon.cbor.CborByteString;
|
|
466
|
-
var CborUInt = com.sphereon.cbor.CborUInt;
|
|
467
|
-
var CborString = com.sphereon.cbor.CborString;
|
|
569
|
+
var CborByteString = import_kmp_mdoc_core.default.com.sphereon.cbor.CborByteString;
|
|
570
|
+
var CborUInt = import_kmp_mdoc_core.default.com.sphereon.cbor.CborUInt;
|
|
571
|
+
var CborString = import_kmp_mdoc_core.default.com.sphereon.cbor.CborString;
|
|
468
572
|
var decompressRawStatusList = import_jwt_status_list2.StatusList.decodeStatusList.bind(import_jwt_status_list2.StatusList);
|
|
469
573
|
var CWT_CLAIMS = {
|
|
470
574
|
SUBJECT: 2,
|
|
@@ -618,7 +722,8 @@ var OAuthStatusListImplementation = class {
|
|
|
618
722
|
}
|
|
619
723
|
const proofFormat = args?.proofFormat ?? DEFAULT_PROOF_FORMAT2;
|
|
620
724
|
const { issuer, id, oauthStatusList, keyRef } = args;
|
|
621
|
-
const { bitsPerStatus
|
|
725
|
+
const { bitsPerStatus } = oauthStatusList;
|
|
726
|
+
const expiresAt = ensureDate(oauthStatusList.expiresAt);
|
|
622
727
|
const length = args.length ?? DEFAULT_LIST_LENGTH2;
|
|
623
728
|
const issuerString = typeof issuer === "string" ? issuer : issuer.id;
|
|
624
729
|
const correlationId = getAssertedValue("correlationId", args.correlationId);
|
|
@@ -641,7 +746,8 @@ var OAuthStatusListImplementation = class {
|
|
|
641
746
|
};
|
|
642
747
|
}
|
|
643
748
|
async updateStatusListIndex(args, context) {
|
|
644
|
-
const { statusListCredential, value,
|
|
749
|
+
const { statusListCredential, value, keyRef } = args;
|
|
750
|
+
const expiresAt = ensureDate(args.expiresAt);
|
|
645
751
|
if (typeof statusListCredential !== "string") {
|
|
646
752
|
return Promise.reject("statusListCredential in neither JWT nor CWT");
|
|
647
753
|
}
|
|
@@ -652,6 +758,9 @@ var OAuthStatusListImplementation = class {
|
|
|
652
758
|
if (index < 0 || index >= statusList.statusList.length) {
|
|
653
759
|
throw new Error("Status list index out of bounds");
|
|
654
760
|
}
|
|
761
|
+
if (typeof value !== "number") {
|
|
762
|
+
throw new Error("Status list values should be of type number");
|
|
763
|
+
}
|
|
655
764
|
statusList.setStatus(index, value);
|
|
656
765
|
const { statusListCredential: signedCredential, encodedList } = await this.createSignedStatusList(proofFormat, context, statusList, issuer, id, expiresAt, keyRef);
|
|
657
766
|
return {
|
|
@@ -674,12 +783,13 @@ var OAuthStatusListImplementation = class {
|
|
|
674
783
|
throw new Error("OAuthStatusList options are required for type OAuthStatusList");
|
|
675
784
|
}
|
|
676
785
|
const { proofFormat, oauthStatusList, keyRef } = args;
|
|
677
|
-
const { bitsPerStatus
|
|
786
|
+
const { bitsPerStatus } = oauthStatusList;
|
|
787
|
+
const expiresAt = ensureDate(oauthStatusList.expiresAt);
|
|
678
788
|
const { issuer, id } = getAssertedValues(args);
|
|
679
789
|
const issuerString = typeof issuer === "string" ? issuer : issuer.id;
|
|
680
790
|
const listToUpdate = import_jwt_status_list3.StatusList.decompressStatusList(args.encodedList, bitsPerStatus ?? DEFAULT_BITS_PER_STATUS);
|
|
681
791
|
const index = typeof args.statusListIndex === "number" ? args.statusListIndex : parseInt(args.statusListIndex);
|
|
682
|
-
listToUpdate.setStatus(index, args.value
|
|
792
|
+
listToUpdate.setStatus(index, args.value);
|
|
683
793
|
const { statusListCredential, encodedList } = await this.createSignedStatusList(proofFormat ?? DEFAULT_PROOF_FORMAT2, context, listToUpdate, issuerString, id, expiresAt, keyRef);
|
|
684
794
|
return {
|
|
685
795
|
encodedList,
|
|
@@ -696,9 +806,6 @@ var OAuthStatusListImplementation = class {
|
|
|
696
806
|
statuslistContentType: this.buildContentType(proofFormat)
|
|
697
807
|
};
|
|
698
808
|
}
|
|
699
|
-
buildContentType(proofFormat) {
|
|
700
|
-
return `application/statuslist+${proofFormat === "cbor" ? "cwt" : "jwt"}`;
|
|
701
|
-
}
|
|
702
809
|
async checkStatusIndex(args) {
|
|
703
810
|
const { statusListCredential, statusListIndex } = args;
|
|
704
811
|
if (typeof statusListCredential !== "string") {
|
|
@@ -708,38 +815,105 @@ var OAuthStatusListImplementation = class {
|
|
|
708
815
|
const { statusList } = proofFormat === "jwt" ? decodeStatusListJWT(statusListCredential) : decodeStatusListCWT(statusListCredential);
|
|
709
816
|
const index = typeof statusListIndex === "number" ? statusListIndex : parseInt(statusListIndex);
|
|
710
817
|
if (index < 0 || index >= statusList.statusList.length) {
|
|
711
|
-
throw new Error(
|
|
818
|
+
throw new Error(`Status list index out of bounds, has ${statusList.statusList.length} items, requested ${index}`);
|
|
712
819
|
}
|
|
713
820
|
return statusList.getStatus(index);
|
|
714
821
|
}
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
822
|
+
/**
|
|
823
|
+
* Performs the initial parsing of a StatusListCredential.
|
|
824
|
+
* This method handles expensive operations like JWT/CWT decoding once.
|
|
825
|
+
* It extracts all details available from the credential payload itself.
|
|
826
|
+
*/
|
|
827
|
+
async extractCredentialDetails(credential) {
|
|
828
|
+
if (typeof credential !== "string") {
|
|
829
|
+
return Promise.reject("statusListCredential must be a JWT or CWT string");
|
|
830
|
+
}
|
|
831
|
+
const proofFormat = determineProofFormat(credential);
|
|
832
|
+
const decoded = proofFormat === "jwt" ? decodeStatusListJWT(credential) : decodeStatusListCWT(credential);
|
|
720
833
|
return {
|
|
721
|
-
id,
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
expiresAt: new Date(exp * 1e3)
|
|
733
|
-
}
|
|
734
|
-
},
|
|
735
|
-
...args.correlationId && {
|
|
736
|
-
correlationId: args.correlationId
|
|
737
|
-
},
|
|
738
|
-
...args.driverType && {
|
|
739
|
-
driverType: args.driverType
|
|
834
|
+
id: decoded.id,
|
|
835
|
+
issuer: decoded.issuer,
|
|
836
|
+
encodedList: decoded.statusList.compressStatusList(),
|
|
837
|
+
decodedPayload: decoded
|
|
838
|
+
};
|
|
839
|
+
}
|
|
840
|
+
async toStatusListDetails(args) {
|
|
841
|
+
if ("statusListCredential" in args) {
|
|
842
|
+
const { statusListCredential, bitsPerStatus, correlationId, driverType } = args;
|
|
843
|
+
if (!bitsPerStatus || bitsPerStatus < 1) {
|
|
844
|
+
return Promise.reject(Error("bitsPerStatus must be set for OAuth status lists and must be 1 or higher"));
|
|
740
845
|
}
|
|
846
|
+
const proofFormat = determineProofFormat(statusListCredential);
|
|
847
|
+
const decoded = proofFormat === "jwt" ? decodeStatusListJWT(statusListCredential) : decodeStatusListCWT(statusListCredential);
|
|
848
|
+
const { statusList, issuer, id, exp } = decoded;
|
|
849
|
+
const expiresAt = exp ? new Date(exp * 1e3) : void 0;
|
|
850
|
+
return {
|
|
851
|
+
id,
|
|
852
|
+
encodedList: statusList.compressStatusList(),
|
|
853
|
+
issuer,
|
|
854
|
+
type: import_ssi_types4.StatusListType.OAuthStatusList,
|
|
855
|
+
proofFormat,
|
|
856
|
+
length: statusList.statusList.length,
|
|
857
|
+
statusListCredential,
|
|
858
|
+
statuslistContentType: this.buildContentType(proofFormat),
|
|
859
|
+
correlationId,
|
|
860
|
+
driverType,
|
|
861
|
+
bitsPerStatus,
|
|
862
|
+
...expiresAt && {
|
|
863
|
+
expiresAt
|
|
864
|
+
},
|
|
865
|
+
oauthStatusList: {
|
|
866
|
+
bitsPerStatus,
|
|
867
|
+
...expiresAt && {
|
|
868
|
+
expiresAt
|
|
869
|
+
}
|
|
870
|
+
}
|
|
871
|
+
};
|
|
872
|
+
} else {
|
|
873
|
+
const { extractedDetails, statusListEntity } = args;
|
|
874
|
+
const oauthEntity = statusListEntity;
|
|
875
|
+
const decoded = extractedDetails.decodedPayload;
|
|
876
|
+
const proofFormat = determineProofFormat(statusListEntity.statusListCredential);
|
|
877
|
+
const expiresAt = decoded.exp ? new Date(decoded.exp * 1e3) : void 0;
|
|
878
|
+
return {
|
|
879
|
+
id: extractedDetails.id,
|
|
880
|
+
encodedList: extractedDetails.encodedList,
|
|
881
|
+
issuer: extractedDetails.issuer,
|
|
882
|
+
type: import_ssi_types4.StatusListType.OAuthStatusList,
|
|
883
|
+
proofFormat,
|
|
884
|
+
length: decoded.statusList.statusList.length,
|
|
885
|
+
statusListCredential: statusListEntity.statusListCredential,
|
|
886
|
+
statuslistContentType: this.buildContentType(proofFormat),
|
|
887
|
+
correlationId: statusListEntity.correlationId,
|
|
888
|
+
driverType: statusListEntity.driverType,
|
|
889
|
+
bitsPerStatus: oauthEntity.bitsPerStatus,
|
|
890
|
+
...expiresAt && {
|
|
891
|
+
expiresAt
|
|
892
|
+
},
|
|
893
|
+
oauthStatusList: {
|
|
894
|
+
bitsPerStatus: oauthEntity.bitsPerStatus,
|
|
895
|
+
...expiresAt && {
|
|
896
|
+
expiresAt
|
|
897
|
+
}
|
|
898
|
+
}
|
|
899
|
+
};
|
|
900
|
+
}
|
|
901
|
+
}
|
|
902
|
+
async createCredentialStatus(args) {
|
|
903
|
+
const { statusList, statusListIndex } = args;
|
|
904
|
+
const oauthStatusList = statusList;
|
|
905
|
+
return {
|
|
906
|
+
id: `${statusList.id}#${statusListIndex}`,
|
|
907
|
+
type: "OAuthStatusListEntry",
|
|
908
|
+
bitsPerStatus: oauthStatusList.bitsPerStatus,
|
|
909
|
+
statusListIndex: "" + statusListIndex,
|
|
910
|
+
statusListCredential: statusList.id,
|
|
911
|
+
expiresAt: oauthStatusList.expiresAt
|
|
741
912
|
};
|
|
742
913
|
}
|
|
914
|
+
buildContentType(proofFormat) {
|
|
915
|
+
return `application/statuslist+${proofFormat === "cbor" ? "cwt" : "jwt"}`;
|
|
916
|
+
}
|
|
743
917
|
async createSignedStatusList(proofFormat, context, statusList, issuerString, id, expiresAt, keyRef) {
|
|
744
918
|
switch (proofFormat) {
|
|
745
919
|
case "jwt": {
|
|
@@ -755,7 +929,405 @@ var OAuthStatusListImplementation = class {
|
|
|
755
929
|
};
|
|
756
930
|
|
|
757
931
|
// src/impl/StatusListFactory.ts
|
|
932
|
+
var import_ssi_types6 = require("@sphereon/ssi-types");
|
|
933
|
+
|
|
934
|
+
// src/impl/BitstringStatusListImplementation.ts
|
|
758
935
|
var import_ssi_types5 = require("@sphereon/ssi-types");
|
|
936
|
+
var import_vc_bitstring_status_lists = require("@4sure-tech/vc-bitstring-status-lists");
|
|
937
|
+
var DEFAULT_LIST_LENGTH3 = 131072;
|
|
938
|
+
var DEFAULT_PROOF_FORMAT3 = "vc+jwt";
|
|
939
|
+
var DEFAULT_STATUS_PURPOSE = "revocation";
|
|
940
|
+
var BitstringStatusListImplementation = class {
|
|
941
|
+
static {
|
|
942
|
+
__name(this, "BitstringStatusListImplementation");
|
|
943
|
+
}
|
|
944
|
+
/**
|
|
945
|
+
* Creates a new bitstring status list with the specified configuration
|
|
946
|
+
*
|
|
947
|
+
* @param args - Configuration for the new status list including issuer, purpose, and size
|
|
948
|
+
* @param context - Veramo agent context for credential operations
|
|
949
|
+
* @returns Promise resolving to the created status list details
|
|
950
|
+
*/
|
|
951
|
+
async createNewStatusList(args, context) {
|
|
952
|
+
if (!args.bitstringStatusList) {
|
|
953
|
+
throw new Error("BitstringStatusList options are required for type BitstringStatusList");
|
|
954
|
+
}
|
|
955
|
+
const length = args?.length ?? DEFAULT_LIST_LENGTH3;
|
|
956
|
+
const proofFormat = args?.proofFormat ?? DEFAULT_PROOF_FORMAT3;
|
|
957
|
+
assertValidProofType(import_ssi_types5.StatusListType.BitstringStatusList, proofFormat);
|
|
958
|
+
const { issuer, id } = args;
|
|
959
|
+
const correlationId = getAssertedValue("correlationId", args.correlationId);
|
|
960
|
+
const { statusPurpose, bitsPerStatus, validFrom, validUntil, ttl } = args.bitstringStatusList;
|
|
961
|
+
const unsignedCredential = await (0, import_vc_bitstring_status_lists.createStatusListCredential)({
|
|
962
|
+
id,
|
|
963
|
+
issuer,
|
|
964
|
+
statusPurpose: statusPurpose ?? DEFAULT_STATUS_PURPOSE,
|
|
965
|
+
validFrom: ensureDate(validFrom),
|
|
966
|
+
validUntil: ensureDate(validUntil),
|
|
967
|
+
ttl
|
|
968
|
+
});
|
|
969
|
+
const statusListCredential = await this.createVerifiableCredential({
|
|
970
|
+
unsignedCredential,
|
|
971
|
+
id,
|
|
972
|
+
issuer,
|
|
973
|
+
proofFormat,
|
|
974
|
+
keyRef: args.keyRef
|
|
975
|
+
}, context);
|
|
976
|
+
return {
|
|
977
|
+
encodedList: unsignedCredential.credentialSubject.encodedList,
|
|
978
|
+
statusListCredential,
|
|
979
|
+
bitstringStatusList: {
|
|
980
|
+
statusPurpose: statusPurpose ?? DEFAULT_STATUS_PURPOSE,
|
|
981
|
+
...unsignedCredential.validFrom && {
|
|
982
|
+
validFrom: new Date(unsignedCredential.validFrom)
|
|
983
|
+
},
|
|
984
|
+
...unsignedCredential.validUntil && {
|
|
985
|
+
validUntil: new Date(unsignedCredential.validUntil)
|
|
986
|
+
},
|
|
987
|
+
ttl,
|
|
988
|
+
bitsPerStatus
|
|
989
|
+
},
|
|
990
|
+
length,
|
|
991
|
+
type: import_ssi_types5.StatusListType.BitstringStatusList,
|
|
992
|
+
proofFormat,
|
|
993
|
+
id,
|
|
994
|
+
correlationId,
|
|
995
|
+
issuer,
|
|
996
|
+
statuslistContentType: this.buildContentType(proofFormat)
|
|
997
|
+
};
|
|
998
|
+
}
|
|
999
|
+
/**
|
|
1000
|
+
* Updates the status of a specific credential in an existing status list
|
|
1001
|
+
*
|
|
1002
|
+
* @param args - Update parameters including the status list credential, index, and new value
|
|
1003
|
+
* @param context - Veramo agent context for credential operations
|
|
1004
|
+
* @returns Promise resolving to the updated status list details
|
|
1005
|
+
*/
|
|
1006
|
+
async updateStatusListIndex(args, context) {
|
|
1007
|
+
if (!args.bitsPerStatus || args.bitsPerStatus < 1) {
|
|
1008
|
+
return Promise.reject(Error("bitsPerStatus must be set for bitstring status lists and must be 1 or higher. (updateStatusListIndex)"));
|
|
1009
|
+
}
|
|
1010
|
+
const credential = args.statusListCredential;
|
|
1011
|
+
const uniform = import_ssi_types5.CredentialMapper.toUniformCredential(credential);
|
|
1012
|
+
const { issuer, credentialSubject } = uniform;
|
|
1013
|
+
const id = getAssertedValue("id", uniform.id);
|
|
1014
|
+
const origEncodedList = getAssertedProperty("encodedList", credentialSubject);
|
|
1015
|
+
const index = typeof args.statusListIndex === "number" ? args.statusListIndex : parseInt(args.statusListIndex);
|
|
1016
|
+
const statusList = await import_vc_bitstring_status_lists.BitstreamStatusList.decode({
|
|
1017
|
+
encodedList: origEncodedList,
|
|
1018
|
+
statusSize: args.bitsPerStatus
|
|
1019
|
+
});
|
|
1020
|
+
const bitstringStatusId = args.value;
|
|
1021
|
+
statusList.setStatus(index, bitstringStatusId);
|
|
1022
|
+
const proofFormat = import_ssi_types5.CredentialMapper.detectDocumentType(credential) === import_ssi_types5.DocumentFormat.JWT ? "vc+jwt" : "lds";
|
|
1023
|
+
const credSubject = Array.isArray(credentialSubject) ? credentialSubject[0] : credentialSubject;
|
|
1024
|
+
const statusPurpose = getAssertedProperty("statusPurpose", credSubject);
|
|
1025
|
+
const validFrom = uniform.validFrom ? new Date(uniform.validFrom) : void 0;
|
|
1026
|
+
const validUntil = uniform.validUntil ? new Date(uniform.validUntil) : void 0;
|
|
1027
|
+
const ttl = credSubject.ttl;
|
|
1028
|
+
const unsignedCredential = await (0, import_vc_bitstring_status_lists.createStatusListCredential)({
|
|
1029
|
+
id,
|
|
1030
|
+
issuer,
|
|
1031
|
+
statusList,
|
|
1032
|
+
statusPurpose: statusPurpose ?? DEFAULT_STATUS_PURPOSE,
|
|
1033
|
+
validFrom: ensureDate(validFrom),
|
|
1034
|
+
validUntil: ensureDate(validUntil),
|
|
1035
|
+
ttl
|
|
1036
|
+
});
|
|
1037
|
+
const updatedCredential = await this.createVerifiableCredential({
|
|
1038
|
+
unsignedCredential,
|
|
1039
|
+
id,
|
|
1040
|
+
issuer,
|
|
1041
|
+
proofFormat,
|
|
1042
|
+
keyRef: args.keyRef
|
|
1043
|
+
}, context);
|
|
1044
|
+
return {
|
|
1045
|
+
statusListCredential: updatedCredential,
|
|
1046
|
+
encodedList: unsignedCredential.credentialSubject.encodedList,
|
|
1047
|
+
bitstringStatusList: {
|
|
1048
|
+
statusPurpose,
|
|
1049
|
+
...unsignedCredential.validFrom && {
|
|
1050
|
+
validFrom: new Date(unsignedCredential.validFrom)
|
|
1051
|
+
},
|
|
1052
|
+
...unsignedCredential.validUntil && {
|
|
1053
|
+
validUntil: new Date(unsignedCredential.validUntil)
|
|
1054
|
+
},
|
|
1055
|
+
bitsPerStatus: args.bitsPerStatus,
|
|
1056
|
+
ttl
|
|
1057
|
+
},
|
|
1058
|
+
length: statusList.getLength(),
|
|
1059
|
+
type: import_ssi_types5.StatusListType.BitstringStatusList,
|
|
1060
|
+
proofFormat,
|
|
1061
|
+
id,
|
|
1062
|
+
issuer,
|
|
1063
|
+
statuslistContentType: this.buildContentType(proofFormat)
|
|
1064
|
+
};
|
|
1065
|
+
}
|
|
1066
|
+
/**
|
|
1067
|
+
* Updates a status list by decoding an encoded list, modifying it, and re-encoding
|
|
1068
|
+
*
|
|
1069
|
+
* @param args - Update parameters including encoded list, index, and new value
|
|
1070
|
+
* @param context - Veramo agent context for credential operations
|
|
1071
|
+
* @returns Promise resolving to the updated status list details
|
|
1072
|
+
*/
|
|
1073
|
+
async updateStatusListFromEncodedList(args, context) {
|
|
1074
|
+
if (!args.bitstringStatusList) {
|
|
1075
|
+
throw new Error("bitstringStatusList options required for type BitstringStatusList");
|
|
1076
|
+
}
|
|
1077
|
+
if (args.bitstringStatusList.bitsPerStatus < 1) {
|
|
1078
|
+
return Promise.reject(Error("bitsPerStatus must be set for bitstring status lists and must be 1 or higher. (updateStatusListFromEncodedList)"));
|
|
1079
|
+
}
|
|
1080
|
+
const { statusPurpose, bitsPerStatus, ttl, validFrom, validUntil } = args.bitstringStatusList;
|
|
1081
|
+
const proofFormat = args?.proofFormat ?? DEFAULT_PROOF_FORMAT3;
|
|
1082
|
+
assertValidProofType(import_ssi_types5.StatusListType.BitstringStatusList, proofFormat);
|
|
1083
|
+
const { issuer, id } = getAssertedValues(args);
|
|
1084
|
+
const statusList = await import_vc_bitstring_status_lists.BitstreamStatusList.decode({
|
|
1085
|
+
encodedList: args.encodedList,
|
|
1086
|
+
statusSize: bitsPerStatus
|
|
1087
|
+
});
|
|
1088
|
+
const index = typeof args.statusListIndex === "number" ? args.statusListIndex : parseInt(args.statusListIndex);
|
|
1089
|
+
statusList.setStatus(index, args.value);
|
|
1090
|
+
const unsignedCredential = await (0, import_vc_bitstring_status_lists.createStatusListCredential)({
|
|
1091
|
+
id,
|
|
1092
|
+
issuer,
|
|
1093
|
+
statusList,
|
|
1094
|
+
statusPurpose: statusPurpose ?? DEFAULT_STATUS_PURPOSE,
|
|
1095
|
+
validFrom: ensureDate(validFrom),
|
|
1096
|
+
validUntil: ensureDate(validUntil),
|
|
1097
|
+
ttl
|
|
1098
|
+
});
|
|
1099
|
+
const credential = await this.createVerifiableCredential({
|
|
1100
|
+
unsignedCredential,
|
|
1101
|
+
id,
|
|
1102
|
+
issuer,
|
|
1103
|
+
proofFormat,
|
|
1104
|
+
keyRef: args.keyRef
|
|
1105
|
+
}, context);
|
|
1106
|
+
return {
|
|
1107
|
+
type: import_ssi_types5.StatusListType.BitstringStatusList,
|
|
1108
|
+
statusListCredential: credential,
|
|
1109
|
+
encodedList: unsignedCredential.credentialSubject.encodedList,
|
|
1110
|
+
bitstringStatusList: {
|
|
1111
|
+
statusPurpose,
|
|
1112
|
+
bitsPerStatus,
|
|
1113
|
+
...unsignedCredential.validFrom && {
|
|
1114
|
+
validFrom: new Date(unsignedCredential.validFrom)
|
|
1115
|
+
},
|
|
1116
|
+
...unsignedCredential.validUntil && {
|
|
1117
|
+
validUntil: new Date(unsignedCredential.validUntil)
|
|
1118
|
+
},
|
|
1119
|
+
ttl
|
|
1120
|
+
},
|
|
1121
|
+
length: statusList.getLength(),
|
|
1122
|
+
proofFormat: args.proofFormat ?? "lds",
|
|
1123
|
+
id,
|
|
1124
|
+
issuer,
|
|
1125
|
+
statuslistContentType: this.buildContentType(proofFormat)
|
|
1126
|
+
};
|
|
1127
|
+
}
|
|
1128
|
+
/**
|
|
1129
|
+
* Checks the status of a specific credential by its index in the status list
|
|
1130
|
+
*
|
|
1131
|
+
* @param args - Check parameters including the status list credential and index
|
|
1132
|
+
* @returns Promise resolving to the status value at the specified index
|
|
1133
|
+
*/
|
|
1134
|
+
async checkStatusIndex(args) {
|
|
1135
|
+
if (!args.bitsPerStatus || args.bitsPerStatus < 1) {
|
|
1136
|
+
return Promise.reject(Error("bitsPerStatus must be set for bitstring status lists and must be 1 or higher. (checkStatusIndex)"));
|
|
1137
|
+
}
|
|
1138
|
+
const uniform = import_ssi_types5.CredentialMapper.toUniformCredential(args.statusListCredential);
|
|
1139
|
+
const { credentialSubject } = uniform;
|
|
1140
|
+
const encodedList = getAssertedProperty("encodedList", credentialSubject);
|
|
1141
|
+
const statusList = await import_vc_bitstring_status_lists.BitstreamStatusList.decode({
|
|
1142
|
+
encodedList,
|
|
1143
|
+
statusSize: args.bitsPerStatus
|
|
1144
|
+
});
|
|
1145
|
+
const numIndex = typeof args.statusListIndex === "number" ? args.statusListIndex : parseInt(args.statusListIndex);
|
|
1146
|
+
if (statusList.getLength() <= numIndex) {
|
|
1147
|
+
throw new Error(`Status list index out of bounds, has ${statusList.getLength()} entries, requested ${numIndex}`);
|
|
1148
|
+
}
|
|
1149
|
+
return statusList.getStatus(numIndex);
|
|
1150
|
+
}
|
|
1151
|
+
/**
|
|
1152
|
+
* Performs the initial parsing of a StatusListCredential.
|
|
1153
|
+
* This method handles expensive operations like JWT/CWT decoding once.
|
|
1154
|
+
* It extracts all details available from the credential payload itself.
|
|
1155
|
+
*/
|
|
1156
|
+
async extractCredentialDetails(credential) {
|
|
1157
|
+
const uniform = import_ssi_types5.CredentialMapper.toUniformCredential(credential);
|
|
1158
|
+
const { issuer, credentialSubject } = uniform;
|
|
1159
|
+
const subject = Array.isArray(credentialSubject) ? credentialSubject[0] : credentialSubject;
|
|
1160
|
+
return {
|
|
1161
|
+
id: getAssertedValue("id", uniform.id),
|
|
1162
|
+
issuer,
|
|
1163
|
+
encodedList: getAssertedProperty("encodedList", subject)
|
|
1164
|
+
};
|
|
1165
|
+
}
|
|
1166
|
+
async toStatusListDetails(args) {
|
|
1167
|
+
if ("statusListCredential" in args) {
|
|
1168
|
+
const { statusListCredential, bitsPerStatus, correlationId, driverType } = args;
|
|
1169
|
+
if (!bitsPerStatus || bitsPerStatus < 1) {
|
|
1170
|
+
return Promise.reject(Error("bitsPerStatus must be set for bitstring status lists and must be 1 or higher"));
|
|
1171
|
+
}
|
|
1172
|
+
const uniform = import_ssi_types5.CredentialMapper.toUniformCredential(statusListCredential);
|
|
1173
|
+
const { issuer, credentialSubject } = uniform;
|
|
1174
|
+
const subject = Array.isArray(credentialSubject) ? credentialSubject[0] : credentialSubject;
|
|
1175
|
+
const id = getAssertedValue("id", uniform.id);
|
|
1176
|
+
const encodedList = getAssertedProperty("encodedList", subject);
|
|
1177
|
+
const statusPurpose = getAssertedProperty("statusPurpose", subject);
|
|
1178
|
+
const validFrom = uniform.validFrom ? new Date(uniform.validFrom) : void 0;
|
|
1179
|
+
const validUntil = uniform.validUntil ? new Date(uniform.validUntil) : void 0;
|
|
1180
|
+
const ttl = subject.ttl;
|
|
1181
|
+
const proofFormat = import_ssi_types5.CredentialMapper.detectDocumentType(statusListCredential) === import_ssi_types5.DocumentFormat.JWT ? "vc+jwt" : "lds";
|
|
1182
|
+
const statuslistLength = import_vc_bitstring_status_lists.BitstreamStatusList.getStatusListLength(encodedList, bitsPerStatus);
|
|
1183
|
+
return {
|
|
1184
|
+
id,
|
|
1185
|
+
encodedList,
|
|
1186
|
+
issuer,
|
|
1187
|
+
type: import_ssi_types5.StatusListType.BitstringStatusList,
|
|
1188
|
+
proofFormat,
|
|
1189
|
+
length: statuslistLength,
|
|
1190
|
+
statusListCredential,
|
|
1191
|
+
statuslistContentType: this.buildContentType(proofFormat),
|
|
1192
|
+
correlationId,
|
|
1193
|
+
driverType,
|
|
1194
|
+
statusPurpose,
|
|
1195
|
+
bitsPerStatus,
|
|
1196
|
+
...validFrom && {
|
|
1197
|
+
validFrom
|
|
1198
|
+
},
|
|
1199
|
+
...validUntil && {
|
|
1200
|
+
validUntil
|
|
1201
|
+
},
|
|
1202
|
+
...ttl && {
|
|
1203
|
+
ttl
|
|
1204
|
+
},
|
|
1205
|
+
bitstringStatusList: {
|
|
1206
|
+
statusPurpose,
|
|
1207
|
+
bitsPerStatus,
|
|
1208
|
+
...validFrom && {
|
|
1209
|
+
validFrom
|
|
1210
|
+
},
|
|
1211
|
+
...validUntil && {
|
|
1212
|
+
validUntil
|
|
1213
|
+
},
|
|
1214
|
+
...ttl && {
|
|
1215
|
+
ttl
|
|
1216
|
+
}
|
|
1217
|
+
}
|
|
1218
|
+
};
|
|
1219
|
+
} else {
|
|
1220
|
+
const { extractedDetails, statusListEntity } = args;
|
|
1221
|
+
const bitstringEntity = statusListEntity;
|
|
1222
|
+
if (!bitstringEntity.bitsPerStatus) {
|
|
1223
|
+
return Promise.reject(Error("bitsPerStatus must be present for a bitstring status list"));
|
|
1224
|
+
}
|
|
1225
|
+
const proofFormat = import_ssi_types5.CredentialMapper.detectDocumentType(statusListEntity.statusListCredential) === import_ssi_types5.DocumentFormat.JWT ? "vc+jwt" : "lds";
|
|
1226
|
+
const statuslistLength = import_vc_bitstring_status_lists.BitstreamStatusList.getStatusListLength(extractedDetails.encodedList, bitstringEntity.bitsPerStatus);
|
|
1227
|
+
return {
|
|
1228
|
+
id: extractedDetails.id,
|
|
1229
|
+
encodedList: extractedDetails.encodedList,
|
|
1230
|
+
issuer: extractedDetails.issuer,
|
|
1231
|
+
type: import_ssi_types5.StatusListType.BitstringStatusList,
|
|
1232
|
+
proofFormat,
|
|
1233
|
+
length: statuslistLength,
|
|
1234
|
+
statusListCredential: statusListEntity.statusListCredential,
|
|
1235
|
+
statuslistContentType: this.buildContentType(proofFormat),
|
|
1236
|
+
correlationId: statusListEntity.correlationId,
|
|
1237
|
+
driverType: statusListEntity.driverType,
|
|
1238
|
+
statusPurpose: bitstringEntity.statusPurpose,
|
|
1239
|
+
bitsPerStatus: bitstringEntity.bitsPerStatus,
|
|
1240
|
+
...bitstringEntity.validFrom && {
|
|
1241
|
+
validFrom: bitstringEntity.validFrom
|
|
1242
|
+
},
|
|
1243
|
+
...bitstringEntity.validUntil && {
|
|
1244
|
+
validUntil: bitstringEntity.validUntil
|
|
1245
|
+
},
|
|
1246
|
+
...bitstringEntity.ttl && {
|
|
1247
|
+
ttl: bitstringEntity.ttl
|
|
1248
|
+
},
|
|
1249
|
+
bitstringStatusList: {
|
|
1250
|
+
statusPurpose: bitstringEntity.statusPurpose,
|
|
1251
|
+
bitsPerStatus: bitstringEntity.bitsPerStatus,
|
|
1252
|
+
...bitstringEntity.validFrom && {
|
|
1253
|
+
validFrom: bitstringEntity.validFrom
|
|
1254
|
+
},
|
|
1255
|
+
...bitstringEntity.validUntil && {
|
|
1256
|
+
validUntil: bitstringEntity.validUntil
|
|
1257
|
+
},
|
|
1258
|
+
...bitstringEntity.ttl && {
|
|
1259
|
+
ttl: bitstringEntity.ttl
|
|
1260
|
+
}
|
|
1261
|
+
}
|
|
1262
|
+
};
|
|
1263
|
+
}
|
|
1264
|
+
}
|
|
1265
|
+
/**
|
|
1266
|
+
* Creates a credential status entry for a specific credential in a status list
|
|
1267
|
+
*
|
|
1268
|
+
* @param args - Parameters including the status list, entry details, and index
|
|
1269
|
+
* @returns Promise resolving to the credential status entry
|
|
1270
|
+
*/
|
|
1271
|
+
async createCredentialStatus(args) {
|
|
1272
|
+
const { statusList, statusListEntry, statusListIndex } = args;
|
|
1273
|
+
const bitstringStatusList = statusList;
|
|
1274
|
+
const bitstringStatusListEntry = statusListEntry;
|
|
1275
|
+
return {
|
|
1276
|
+
id: `${statusList.id}#${statusListIndex}`,
|
|
1277
|
+
type: "BitstringStatusListEntry",
|
|
1278
|
+
statusPurpose: bitstringStatusListEntry.statusPurpose,
|
|
1279
|
+
statusListIndex: "" + statusListIndex,
|
|
1280
|
+
statusListCredential: statusList.id,
|
|
1281
|
+
bitsPerStatus: bitstringStatusList.bitsPerStatus,
|
|
1282
|
+
statusMessage: bitstringStatusListEntry.statusMessage,
|
|
1283
|
+
statusReference: bitstringStatusListEntry.statusReference
|
|
1284
|
+
};
|
|
1285
|
+
}
|
|
1286
|
+
/**
|
|
1287
|
+
* Creates a signed verifiable credential from an unsigned status list credential
|
|
1288
|
+
*
|
|
1289
|
+
* @param args - Parameters including the unsigned credential and signing details
|
|
1290
|
+
* @param context - Veramo agent context for credential operations
|
|
1291
|
+
* @returns Promise resolving to the signed credential
|
|
1292
|
+
*/
|
|
1293
|
+
async createVerifiableCredential(args, context) {
|
|
1294
|
+
const { unsignedCredential, issuer, proofFormat, keyRef } = args;
|
|
1295
|
+
const identifier = await context.agent.identifierManagedGet({
|
|
1296
|
+
identifier: typeof issuer === "string" ? issuer : issuer.id,
|
|
1297
|
+
vmRelationship: "assertionMethod",
|
|
1298
|
+
offlineWhenNoDIDRegistered: true
|
|
1299
|
+
});
|
|
1300
|
+
const verifiableCredential = await context.agent.createVerifiableCredential({
|
|
1301
|
+
credential: unsignedCredential,
|
|
1302
|
+
keyRef: keyRef ?? identifier.kmsKeyRef,
|
|
1303
|
+
proofFormat,
|
|
1304
|
+
fetchRemoteContexts: true
|
|
1305
|
+
});
|
|
1306
|
+
return import_ssi_types5.CredentialMapper.toWrappedVerifiableCredential(verifiableCredential).original;
|
|
1307
|
+
}
|
|
1308
|
+
/**
|
|
1309
|
+
* Builds the appropriate content type string for a given proof format
|
|
1310
|
+
*
|
|
1311
|
+
* @param proofFormat - The proof format to build content type for
|
|
1312
|
+
* @returns The corresponding content type string
|
|
1313
|
+
*/
|
|
1314
|
+
buildContentType(proofFormat) {
|
|
1315
|
+
switch (proofFormat) {
|
|
1316
|
+
case "jwt":
|
|
1317
|
+
return "application/statuslist+jwt";
|
|
1318
|
+
case "cbor":
|
|
1319
|
+
return "application/statuslist+cwt";
|
|
1320
|
+
case "vc+jwt":
|
|
1321
|
+
return "application/statuslist+vc+jwt";
|
|
1322
|
+
case "lds":
|
|
1323
|
+
return "application/statuslist+ld+json";
|
|
1324
|
+
default:
|
|
1325
|
+
throw Error(`Unsupported content type '${proofFormat}' for status lists`);
|
|
1326
|
+
}
|
|
1327
|
+
}
|
|
1328
|
+
};
|
|
1329
|
+
|
|
1330
|
+
// src/impl/StatusListFactory.ts
|
|
759
1331
|
var StatusListFactory = class _StatusListFactory {
|
|
760
1332
|
static {
|
|
761
1333
|
__name(this, "StatusListFactory");
|
|
@@ -764,8 +1336,9 @@ var StatusListFactory = class _StatusListFactory {
|
|
|
764
1336
|
implementations;
|
|
765
1337
|
constructor() {
|
|
766
1338
|
this.implementations = /* @__PURE__ */ new Map();
|
|
767
|
-
this.implementations.set(
|
|
768
|
-
this.implementations.set(
|
|
1339
|
+
this.implementations.set(import_ssi_types6.StatusListType.StatusList2021, new StatusList2021Implementation());
|
|
1340
|
+
this.implementations.set(import_ssi_types6.StatusListType.OAuthStatusList, new OAuthStatusListImplementation());
|
|
1341
|
+
this.implementations.set(import_ssi_types6.StatusListType.BitstringStatusList, new BitstringStatusListImplementation());
|
|
769
1342
|
}
|
|
770
1343
|
static getInstance() {
|
|
771
1344
|
if (!_StatusListFactory.instance) {
|
|
@@ -838,7 +1411,7 @@ __name(vcLibCheckStatusFunction, "vcLibCheckStatusFunction");
|
|
|
838
1411
|
async function checkStatusForCredential(args) {
|
|
839
1412
|
const verifyStatusListCredential = args.verifyStatusListCredential ?? true;
|
|
840
1413
|
const verifyMatchingIssuers = args.verifyMatchingIssuers ?? true;
|
|
841
|
-
const uniform =
|
|
1414
|
+
const uniform = import_ssi_types7.CredentialMapper.toUniformCredential(args.credential);
|
|
842
1415
|
if (!("credentialStatus" in uniform) || !uniform.credentialStatus) {
|
|
843
1416
|
if (args.mandatoryCredentialStatus) {
|
|
844
1417
|
const error = "No credential status object found in the Verifiable Credential and it is mandatory";
|
|
@@ -853,7 +1426,7 @@ async function checkStatusForCredential(args) {
|
|
|
853
1426
|
};
|
|
854
1427
|
}
|
|
855
1428
|
if ("credentialStatus" in uniform && uniform.credentialStatus) {
|
|
856
|
-
if (uniform.credentialStatus.type === "StatusList2021Entry") {
|
|
1429
|
+
if (uniform.credentialStatus.type === "StatusList2021Entry" || uniform.credentialStatus.type === "BitstringStatusListEntry") {
|
|
857
1430
|
return (0, import_vc_status_list2.checkStatus)({
|
|
858
1431
|
...args,
|
|
859
1432
|
verifyStatusListCredential,
|
|
@@ -901,35 +1474,35 @@ async function updateStatusIndexFromStatusListCredential(args, context) {
|
|
|
901
1474
|
return implementation.updateStatusListIndex(args, context);
|
|
902
1475
|
}
|
|
903
1476
|
__name(updateStatusIndexFromStatusListCredential, "updateStatusIndexFromStatusListCredential");
|
|
904
|
-
async function
|
|
905
|
-
const
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
const type = uniform.type.find((t) => t.includes("StatusList2021") || t.includes("OAuth2StatusList"));
|
|
920
|
-
if (!type) {
|
|
921
|
-
throw new Error("Invalid status list credential type");
|
|
922
|
-
}
|
|
923
|
-
statusListType = type.replace("Credential", "");
|
|
1477
|
+
async function extractCredentialDetails(statusListCredential) {
|
|
1478
|
+
const statusListType = determineStatusListType(statusListCredential);
|
|
1479
|
+
const implementation = getStatusListImplementation(statusListType);
|
|
1480
|
+
return implementation.extractCredentialDetails(statusListCredential);
|
|
1481
|
+
}
|
|
1482
|
+
__name(extractCredentialDetails, "extractCredentialDetails");
|
|
1483
|
+
async function toStatusListDetails(args) {
|
|
1484
|
+
if ("statusListCredential" in args) {
|
|
1485
|
+
const statusListType = args.statusListType;
|
|
1486
|
+
const implementation = getStatusListImplementation(statusListType);
|
|
1487
|
+
return implementation.toStatusListDetails(args);
|
|
1488
|
+
} else {
|
|
1489
|
+
const statusListType = args.statusListEntity.type;
|
|
1490
|
+
const implementation = getStatusListImplementation(statusListType);
|
|
1491
|
+
return implementation.toStatusListDetails(args);
|
|
924
1492
|
}
|
|
1493
|
+
}
|
|
1494
|
+
__name(toStatusListDetails, "toStatusListDetails");
|
|
1495
|
+
async function createCredentialStatusFromStatusList(args) {
|
|
1496
|
+
const { statusList, statusListEntry, statusListIndex } = args;
|
|
1497
|
+
const statusListType = determineStatusListType(statusList.statusListCredential);
|
|
925
1498
|
const implementation = getStatusListImplementation(statusListType);
|
|
926
|
-
return
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
1499
|
+
return implementation.createCredentialStatus({
|
|
1500
|
+
statusList,
|
|
1501
|
+
statusListEntry,
|
|
1502
|
+
statusListIndex
|
|
930
1503
|
});
|
|
931
1504
|
}
|
|
932
|
-
__name(
|
|
1505
|
+
__name(createCredentialStatusFromStatusList, "createCredentialStatusFromStatusList");
|
|
933
1506
|
async function updateStatusListIndexFromEncodedList(args, context) {
|
|
934
1507
|
const { type } = getAssertedValue("type", args);
|
|
935
1508
|
const implementation = getStatusListImplementation(type);
|
|
@@ -944,7 +1517,7 @@ async function statusList2021ToVerifiableCredential(args, context) {
|
|
|
944
1517
|
offlineWhenNoDIDRegistered: true
|
|
945
1518
|
});
|
|
946
1519
|
const proofFormat = args?.proofFormat ?? "lds";
|
|
947
|
-
assertValidProofType(
|
|
1520
|
+
assertValidProofType(import_ssi_types7.StatusListType.StatusList2021, proofFormat);
|
|
948
1521
|
const veramoProofFormat = proofFormat;
|
|
949
1522
|
const encodedList = getAssertedValue("encodedList", args.encodedList);
|
|
950
1523
|
const statusPurpose = getAssertedValue("statusPurpose", args.statusPurpose);
|
|
@@ -973,7 +1546,7 @@ async function statusList2021ToVerifiableCredential(args, context) {
|
|
|
973
1546
|
proofFormat: veramoProofFormat,
|
|
974
1547
|
fetchRemoteContexts: true
|
|
975
1548
|
});
|
|
976
|
-
return
|
|
1549
|
+
return import_ssi_types7.CredentialMapper.toWrappedVerifiableCredential(verifiableCredential).original;
|
|
977
1550
|
}
|
|
978
1551
|
__name(statusList2021ToVerifiableCredential, "statusList2021ToVerifiableCredential");
|
|
979
1552
|
//# sourceMappingURL=index.cjs.map
|