@sphereon/ssi-sdk.vc-status-list 0.34.1-next.3 → 0.34.1-next.323
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 +703 -125
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +164 -37
- package/dist/index.d.ts +164 -37
- package/dist/index.js +707 -129
- package/dist/index.js.map +1 -1
- package/package.json +14 -10
- 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 +120 -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 +57 -34
- 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");
|
|
@@ -200,7 +251,8 @@ var StatusList2021Implementation = class {
|
|
|
200
251
|
statusListCredential,
|
|
201
252
|
statusList2021: {
|
|
202
253
|
statusPurpose,
|
|
203
|
-
indexingDirection: "rightToLeft"
|
|
254
|
+
indexingDirection: "rightToLeft",
|
|
255
|
+
credentialIdMode: import_ssi_types2.StatusListCredentialIdMode.ISSUANCE
|
|
204
256
|
},
|
|
205
257
|
length,
|
|
206
258
|
type: import_ssi_types2.StatusListType.StatusList2021,
|
|
@@ -231,14 +283,16 @@ var StatusList2021Implementation = class {
|
|
|
231
283
|
encodedList,
|
|
232
284
|
proofFormat
|
|
233
285
|
}, context);
|
|
286
|
+
if (!("statusPurpose" in credentialSubject)) {
|
|
287
|
+
return Promise.reject(Error("statusPurpose is required in credentialSubject for StatusList2021"));
|
|
288
|
+
}
|
|
234
289
|
return {
|
|
235
290
|
statusListCredential: updatedCredential,
|
|
236
291
|
encodedList,
|
|
237
292
|
statusList2021: {
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
indexingDirection: "rightToLeft"
|
|
293
|
+
statusPurpose: credentialSubject.statusPurpose,
|
|
294
|
+
indexingDirection: "rightToLeft",
|
|
295
|
+
credentialIdMode: import_ssi_types2.StatusListCredentialIdMode.ISSUANCE
|
|
242
296
|
},
|
|
243
297
|
length: statusList.length - 1,
|
|
244
298
|
type: import_ssi_types2.StatusListType.StatusList2021,
|
|
@@ -260,7 +314,7 @@ var StatusList2021Implementation = class {
|
|
|
260
314
|
encodedList: args.encodedList
|
|
261
315
|
});
|
|
262
316
|
const index = typeof args.statusListIndex === "number" ? args.statusListIndex : parseInt(args.statusListIndex);
|
|
263
|
-
statusList.setStatus(index, args.value);
|
|
317
|
+
statusList.setStatus(index, args.value !== 0);
|
|
264
318
|
const newEncodedList = await statusList.encode();
|
|
265
319
|
const credential = await this.createVerifiableCredential({
|
|
266
320
|
id,
|
|
@@ -275,7 +329,8 @@ var StatusList2021Implementation = class {
|
|
|
275
329
|
encodedList: newEncodedList,
|
|
276
330
|
statusList2021: {
|
|
277
331
|
statusPurpose: args.statusList2021.statusPurpose,
|
|
278
|
-
indexingDirection: "rightToLeft"
|
|
332
|
+
indexingDirection: "rightToLeft",
|
|
333
|
+
credentialIdMode: import_ssi_types2.StatusListCredentialIdMode.ISSUANCE
|
|
279
334
|
},
|
|
280
335
|
length: statusList.length,
|
|
281
336
|
proofFormat: args.proofFormat ?? "lds",
|
|
@@ -294,36 +349,90 @@ var StatusList2021Implementation = class {
|
|
|
294
349
|
const status = statusList.getStatus(typeof args.statusListIndex === "number" ? args.statusListIndex : parseInt(args.statusListIndex));
|
|
295
350
|
return status ? Status2021.Invalid : Status2021.Valid;
|
|
296
351
|
}
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
352
|
+
/**
|
|
353
|
+
* Performs the initial parsing of a StatusListCredential.
|
|
354
|
+
* This method handles expensive operations like JWT/CWT decoding once.
|
|
355
|
+
* It extracts all details available from the credential payload itself.
|
|
356
|
+
*/
|
|
357
|
+
async extractCredentialDetails(credential) {
|
|
358
|
+
const uniform = import_ssi_types2.CredentialMapper.toUniformCredential(credential);
|
|
300
359
|
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
|
-
});
|
|
360
|
+
const subject = Array.isArray(credentialSubject) ? credentialSubject[0] : credentialSubject;
|
|
308
361
|
return {
|
|
309
|
-
id,
|
|
310
|
-
encodedList,
|
|
362
|
+
id: getAssertedValue("id", uniform.id),
|
|
311
363
|
issuer,
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
364
|
+
encodedList: getAssertedProperty("encodedList", subject)
|
|
365
|
+
};
|
|
366
|
+
}
|
|
367
|
+
async toStatusListDetails(args) {
|
|
368
|
+
if ("statusListCredential" in args) {
|
|
369
|
+
const { statusListCredential, correlationId, driverType } = args;
|
|
370
|
+
const uniform = import_ssi_types2.CredentialMapper.toUniformCredential(statusListCredential);
|
|
371
|
+
const { issuer, credentialSubject } = uniform;
|
|
372
|
+
const subject = Array.isArray(credentialSubject) ? credentialSubject[0] : credentialSubject;
|
|
373
|
+
const id = getAssertedValue("id", uniform.id);
|
|
374
|
+
const encodedList = getAssertedProperty("encodedList", subject);
|
|
375
|
+
const statusPurpose = getAssertedProperty("statusPurpose", subject);
|
|
376
|
+
const proofFormat = import_ssi_types2.CredentialMapper.detectDocumentType(statusListCredential) === import_ssi_types2.DocumentFormat.JWT ? "jwt" : "lds";
|
|
377
|
+
const list = await import_vc_status_list.StatusList.decode({
|
|
378
|
+
encodedList
|
|
379
|
+
});
|
|
380
|
+
return {
|
|
381
|
+
id,
|
|
382
|
+
encodedList,
|
|
383
|
+
issuer,
|
|
384
|
+
type: import_ssi_types2.StatusListType.StatusList2021,
|
|
385
|
+
proofFormat,
|
|
386
|
+
length: list.length,
|
|
387
|
+
statusListCredential,
|
|
388
|
+
statuslistContentType: this.buildContentType(proofFormat),
|
|
389
|
+
correlationId,
|
|
390
|
+
driverType,
|
|
318
391
|
indexingDirection: "rightToLeft",
|
|
319
|
-
statusPurpose
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
392
|
+
statusPurpose,
|
|
393
|
+
statusList2021: {
|
|
394
|
+
indexingDirection: "rightToLeft",
|
|
395
|
+
statusPurpose,
|
|
396
|
+
credentialIdMode: import_ssi_types2.StatusListCredentialIdMode.ISSUANCE
|
|
397
|
+
}
|
|
398
|
+
};
|
|
399
|
+
} else {
|
|
400
|
+
const { extractedDetails, statusListEntity } = args;
|
|
401
|
+
const statusList2021Entity = statusListEntity;
|
|
402
|
+
const proofFormat = import_ssi_types2.CredentialMapper.detectDocumentType(statusListEntity.statusListCredential) === import_ssi_types2.DocumentFormat.JWT ? "jwt" : "lds";
|
|
403
|
+
const list = await import_vc_status_list.StatusList.decode({
|
|
404
|
+
encodedList: extractedDetails.encodedList
|
|
405
|
+
});
|
|
406
|
+
return {
|
|
407
|
+
id: extractedDetails.id,
|
|
408
|
+
encodedList: extractedDetails.encodedList,
|
|
409
|
+
issuer: extractedDetails.issuer,
|
|
410
|
+
type: import_ssi_types2.StatusListType.StatusList2021,
|
|
411
|
+
proofFormat,
|
|
412
|
+
length: list.length,
|
|
413
|
+
statusListCredential: statusListEntity.statusListCredential,
|
|
414
|
+
statuslistContentType: this.buildContentType(proofFormat),
|
|
415
|
+
correlationId: statusListEntity.correlationId,
|
|
416
|
+
driverType: statusListEntity.driverType,
|
|
417
|
+
indexingDirection: statusList2021Entity.indexingDirection,
|
|
418
|
+
statusPurpose: statusList2021Entity.statusPurpose,
|
|
419
|
+
statusList2021: {
|
|
420
|
+
indexingDirection: statusList2021Entity.indexingDirection,
|
|
421
|
+
statusPurpose: statusList2021Entity.statusPurpose,
|
|
422
|
+
credentialIdMode: import_ssi_types2.StatusListCredentialIdMode.ISSUANCE
|
|
423
|
+
}
|
|
424
|
+
};
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
async createCredentialStatus(args) {
|
|
428
|
+
const { statusList, statusListIndex } = args;
|
|
429
|
+
const statusList2021 = statusList;
|
|
430
|
+
return {
|
|
431
|
+
id: `${statusList.id}#${statusListIndex}`,
|
|
432
|
+
type: "StatusList2021Entry",
|
|
433
|
+
statusPurpose: statusList2021.statusPurpose ?? "revocation",
|
|
434
|
+
statusListIndex: "" + statusListIndex,
|
|
435
|
+
statusListCredential: statusList.id
|
|
327
436
|
};
|
|
328
437
|
}
|
|
329
438
|
async createVerifiableCredential(args, context) {
|
|
@@ -462,9 +571,9 @@ var import_pako = require("pako");
|
|
|
462
571
|
var import_kmp_mdoc_core = __toESM(require("@sphereon/kmp-mdoc-core"), 1);
|
|
463
572
|
var import_base64url2 = __toESM(require("base64url"), 1);
|
|
464
573
|
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;
|
|
574
|
+
var CborByteString = import_kmp_mdoc_core.default.com.sphereon.cbor.CborByteString;
|
|
575
|
+
var CborUInt = import_kmp_mdoc_core.default.com.sphereon.cbor.CborUInt;
|
|
576
|
+
var CborString = import_kmp_mdoc_core.default.com.sphereon.cbor.CborString;
|
|
468
577
|
var decompressRawStatusList = import_jwt_status_list2.StatusList.decodeStatusList.bind(import_jwt_status_list2.StatusList);
|
|
469
578
|
var CWT_CLAIMS = {
|
|
470
579
|
SUBJECT: 2,
|
|
@@ -618,7 +727,8 @@ var OAuthStatusListImplementation = class {
|
|
|
618
727
|
}
|
|
619
728
|
const proofFormat = args?.proofFormat ?? DEFAULT_PROOF_FORMAT2;
|
|
620
729
|
const { issuer, id, oauthStatusList, keyRef } = args;
|
|
621
|
-
const { bitsPerStatus
|
|
730
|
+
const { bitsPerStatus } = oauthStatusList;
|
|
731
|
+
const expiresAt = ensureDate(oauthStatusList.expiresAt);
|
|
622
732
|
const length = args.length ?? DEFAULT_LIST_LENGTH2;
|
|
623
733
|
const issuerString = typeof issuer === "string" ? issuer : issuer.id;
|
|
624
734
|
const correlationId = getAssertedValue("correlationId", args.correlationId);
|
|
@@ -641,7 +751,8 @@ var OAuthStatusListImplementation = class {
|
|
|
641
751
|
};
|
|
642
752
|
}
|
|
643
753
|
async updateStatusListIndex(args, context) {
|
|
644
|
-
const { statusListCredential, value,
|
|
754
|
+
const { statusListCredential, value, keyRef } = args;
|
|
755
|
+
const expiresAt = ensureDate(args.expiresAt);
|
|
645
756
|
if (typeof statusListCredential !== "string") {
|
|
646
757
|
return Promise.reject("statusListCredential in neither JWT nor CWT");
|
|
647
758
|
}
|
|
@@ -652,6 +763,9 @@ var OAuthStatusListImplementation = class {
|
|
|
652
763
|
if (index < 0 || index >= statusList.statusList.length) {
|
|
653
764
|
throw new Error("Status list index out of bounds");
|
|
654
765
|
}
|
|
766
|
+
if (typeof value !== "number") {
|
|
767
|
+
throw new Error("Status list values should be of type number");
|
|
768
|
+
}
|
|
655
769
|
statusList.setStatus(index, value);
|
|
656
770
|
const { statusListCredential: signedCredential, encodedList } = await this.createSignedStatusList(proofFormat, context, statusList, issuer, id, expiresAt, keyRef);
|
|
657
771
|
return {
|
|
@@ -674,12 +788,13 @@ var OAuthStatusListImplementation = class {
|
|
|
674
788
|
throw new Error("OAuthStatusList options are required for type OAuthStatusList");
|
|
675
789
|
}
|
|
676
790
|
const { proofFormat, oauthStatusList, keyRef } = args;
|
|
677
|
-
const { bitsPerStatus
|
|
791
|
+
const { bitsPerStatus } = oauthStatusList;
|
|
792
|
+
const expiresAt = ensureDate(oauthStatusList.expiresAt);
|
|
678
793
|
const { issuer, id } = getAssertedValues(args);
|
|
679
794
|
const issuerString = typeof issuer === "string" ? issuer : issuer.id;
|
|
680
795
|
const listToUpdate = import_jwt_status_list3.StatusList.decompressStatusList(args.encodedList, bitsPerStatus ?? DEFAULT_BITS_PER_STATUS);
|
|
681
796
|
const index = typeof args.statusListIndex === "number" ? args.statusListIndex : parseInt(args.statusListIndex);
|
|
682
|
-
listToUpdate.setStatus(index, args.value
|
|
797
|
+
listToUpdate.setStatus(index, args.value);
|
|
683
798
|
const { statusListCredential, encodedList } = await this.createSignedStatusList(proofFormat ?? DEFAULT_PROOF_FORMAT2, context, listToUpdate, issuerString, id, expiresAt, keyRef);
|
|
684
799
|
return {
|
|
685
800
|
encodedList,
|
|
@@ -696,9 +811,6 @@ var OAuthStatusListImplementation = class {
|
|
|
696
811
|
statuslistContentType: this.buildContentType(proofFormat)
|
|
697
812
|
};
|
|
698
813
|
}
|
|
699
|
-
buildContentType(proofFormat) {
|
|
700
|
-
return `application/statuslist+${proofFormat === "cbor" ? "cwt" : "jwt"}`;
|
|
701
|
-
}
|
|
702
814
|
async checkStatusIndex(args) {
|
|
703
815
|
const { statusListCredential, statusListIndex } = args;
|
|
704
816
|
if (typeof statusListCredential !== "string") {
|
|
@@ -708,38 +820,105 @@ var OAuthStatusListImplementation = class {
|
|
|
708
820
|
const { statusList } = proofFormat === "jwt" ? decodeStatusListJWT(statusListCredential) : decodeStatusListCWT(statusListCredential);
|
|
709
821
|
const index = typeof statusListIndex === "number" ? statusListIndex : parseInt(statusListIndex);
|
|
710
822
|
if (index < 0 || index >= statusList.statusList.length) {
|
|
711
|
-
throw new Error(
|
|
823
|
+
throw new Error(`Status list index out of bounds, has ${statusList.statusList.length} items, requested ${index}`);
|
|
712
824
|
}
|
|
713
825
|
return statusList.getStatus(index);
|
|
714
826
|
}
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
827
|
+
/**
|
|
828
|
+
* Performs the initial parsing of a StatusListCredential.
|
|
829
|
+
* This method handles expensive operations like JWT/CWT decoding once.
|
|
830
|
+
* It extracts all details available from the credential payload itself.
|
|
831
|
+
*/
|
|
832
|
+
async extractCredentialDetails(credential) {
|
|
833
|
+
if (typeof credential !== "string") {
|
|
834
|
+
return Promise.reject("statusListCredential must be a JWT or CWT string");
|
|
835
|
+
}
|
|
836
|
+
const proofFormat = determineProofFormat(credential);
|
|
837
|
+
const decoded = proofFormat === "jwt" ? decodeStatusListJWT(credential) : decodeStatusListCWT(credential);
|
|
720
838
|
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
|
|
839
|
+
id: decoded.id,
|
|
840
|
+
issuer: decoded.issuer,
|
|
841
|
+
encodedList: decoded.statusList.compressStatusList(),
|
|
842
|
+
decodedPayload: decoded
|
|
843
|
+
};
|
|
844
|
+
}
|
|
845
|
+
async toStatusListDetails(args) {
|
|
846
|
+
if ("statusListCredential" in args) {
|
|
847
|
+
const { statusListCredential, bitsPerStatus, correlationId, driverType } = args;
|
|
848
|
+
if (!bitsPerStatus || bitsPerStatus < 1) {
|
|
849
|
+
return Promise.reject(Error("bitsPerStatus must be set for OAuth status lists and must be 1 or higher"));
|
|
740
850
|
}
|
|
851
|
+
const proofFormat = determineProofFormat(statusListCredential);
|
|
852
|
+
const decoded = proofFormat === "jwt" ? decodeStatusListJWT(statusListCredential) : decodeStatusListCWT(statusListCredential);
|
|
853
|
+
const { statusList, issuer, id, exp } = decoded;
|
|
854
|
+
const expiresAt = exp ? new Date(exp * 1e3) : void 0;
|
|
855
|
+
return {
|
|
856
|
+
id,
|
|
857
|
+
encodedList: statusList.compressStatusList(),
|
|
858
|
+
issuer,
|
|
859
|
+
type: import_ssi_types4.StatusListType.OAuthStatusList,
|
|
860
|
+
proofFormat,
|
|
861
|
+
length: statusList.statusList.length,
|
|
862
|
+
statusListCredential,
|
|
863
|
+
statuslistContentType: this.buildContentType(proofFormat),
|
|
864
|
+
correlationId,
|
|
865
|
+
driverType,
|
|
866
|
+
bitsPerStatus,
|
|
867
|
+
...expiresAt && {
|
|
868
|
+
expiresAt
|
|
869
|
+
},
|
|
870
|
+
oauthStatusList: {
|
|
871
|
+
bitsPerStatus,
|
|
872
|
+
...expiresAt && {
|
|
873
|
+
expiresAt
|
|
874
|
+
}
|
|
875
|
+
}
|
|
876
|
+
};
|
|
877
|
+
} else {
|
|
878
|
+
const { extractedDetails, statusListEntity } = args;
|
|
879
|
+
const oauthEntity = statusListEntity;
|
|
880
|
+
const decoded = extractedDetails.decodedPayload;
|
|
881
|
+
const proofFormat = determineProofFormat(statusListEntity.statusListCredential);
|
|
882
|
+
const expiresAt = decoded.exp ? new Date(decoded.exp * 1e3) : void 0;
|
|
883
|
+
return {
|
|
884
|
+
id: extractedDetails.id,
|
|
885
|
+
encodedList: extractedDetails.encodedList,
|
|
886
|
+
issuer: extractedDetails.issuer,
|
|
887
|
+
type: import_ssi_types4.StatusListType.OAuthStatusList,
|
|
888
|
+
proofFormat,
|
|
889
|
+
length: decoded.statusList.statusList.length,
|
|
890
|
+
statusListCredential: statusListEntity.statusListCredential,
|
|
891
|
+
statuslistContentType: this.buildContentType(proofFormat),
|
|
892
|
+
correlationId: statusListEntity.correlationId,
|
|
893
|
+
driverType: statusListEntity.driverType,
|
|
894
|
+
bitsPerStatus: oauthEntity.bitsPerStatus,
|
|
895
|
+
...expiresAt && {
|
|
896
|
+
expiresAt
|
|
897
|
+
},
|
|
898
|
+
oauthStatusList: {
|
|
899
|
+
bitsPerStatus: oauthEntity.bitsPerStatus,
|
|
900
|
+
...expiresAt && {
|
|
901
|
+
expiresAt
|
|
902
|
+
}
|
|
903
|
+
}
|
|
904
|
+
};
|
|
905
|
+
}
|
|
906
|
+
}
|
|
907
|
+
async createCredentialStatus(args) {
|
|
908
|
+
const { statusList, statusListIndex } = args;
|
|
909
|
+
const oauthStatusList = statusList;
|
|
910
|
+
return {
|
|
911
|
+
id: `${statusList.id}#${statusListIndex}`,
|
|
912
|
+
type: "OAuthStatusListEntry",
|
|
913
|
+
bitsPerStatus: oauthStatusList.bitsPerStatus,
|
|
914
|
+
statusListIndex: "" + statusListIndex,
|
|
915
|
+
statusListCredential: statusList.id,
|
|
916
|
+
expiresAt: oauthStatusList.expiresAt
|
|
741
917
|
};
|
|
742
918
|
}
|
|
919
|
+
buildContentType(proofFormat) {
|
|
920
|
+
return `application/statuslist+${proofFormat === "cbor" ? "cwt" : "jwt"}`;
|
|
921
|
+
}
|
|
743
922
|
async createSignedStatusList(proofFormat, context, statusList, issuerString, id, expiresAt, keyRef) {
|
|
744
923
|
switch (proofFormat) {
|
|
745
924
|
case "jwt": {
|
|
@@ -755,7 +934,405 @@ var OAuthStatusListImplementation = class {
|
|
|
755
934
|
};
|
|
756
935
|
|
|
757
936
|
// src/impl/StatusListFactory.ts
|
|
937
|
+
var import_ssi_types6 = require("@sphereon/ssi-types");
|
|
938
|
+
|
|
939
|
+
// src/impl/BitstringStatusListImplementation.ts
|
|
758
940
|
var import_ssi_types5 = require("@sphereon/ssi-types");
|
|
941
|
+
var import_vc_bitstring_status_lists = require("@4sure-tech/vc-bitstring-status-lists");
|
|
942
|
+
var DEFAULT_LIST_LENGTH3 = 131072;
|
|
943
|
+
var DEFAULT_PROOF_FORMAT3 = "vc+jwt";
|
|
944
|
+
var DEFAULT_STATUS_PURPOSE = "revocation";
|
|
945
|
+
var BitstringStatusListImplementation = class {
|
|
946
|
+
static {
|
|
947
|
+
__name(this, "BitstringStatusListImplementation");
|
|
948
|
+
}
|
|
949
|
+
/**
|
|
950
|
+
* Creates a new bitstring status list with the specified configuration
|
|
951
|
+
*
|
|
952
|
+
* @param args - Configuration for the new status list including issuer, purpose, and size
|
|
953
|
+
* @param context - Veramo agent context for credential operations
|
|
954
|
+
* @returns Promise resolving to the created status list details
|
|
955
|
+
*/
|
|
956
|
+
async createNewStatusList(args, context) {
|
|
957
|
+
if (!args.bitstringStatusList) {
|
|
958
|
+
throw new Error("BitstringStatusList options are required for type BitstringStatusList");
|
|
959
|
+
}
|
|
960
|
+
const length = args?.length ?? DEFAULT_LIST_LENGTH3;
|
|
961
|
+
const proofFormat = args?.proofFormat ?? DEFAULT_PROOF_FORMAT3;
|
|
962
|
+
assertValidProofType(import_ssi_types5.StatusListType.BitstringStatusList, proofFormat);
|
|
963
|
+
const { issuer, id } = args;
|
|
964
|
+
const correlationId = getAssertedValue("correlationId", args.correlationId);
|
|
965
|
+
const { statusPurpose, bitsPerStatus, validFrom, validUntil, ttl } = args.bitstringStatusList;
|
|
966
|
+
const unsignedCredential = await (0, import_vc_bitstring_status_lists.createStatusListCredential)({
|
|
967
|
+
id,
|
|
968
|
+
issuer,
|
|
969
|
+
statusPurpose: statusPurpose ?? DEFAULT_STATUS_PURPOSE,
|
|
970
|
+
validFrom: ensureDate(validFrom),
|
|
971
|
+
validUntil: ensureDate(validUntil),
|
|
972
|
+
ttl
|
|
973
|
+
});
|
|
974
|
+
const statusListCredential = await this.createVerifiableCredential({
|
|
975
|
+
unsignedCredential,
|
|
976
|
+
id,
|
|
977
|
+
issuer,
|
|
978
|
+
proofFormat,
|
|
979
|
+
keyRef: args.keyRef
|
|
980
|
+
}, context);
|
|
981
|
+
return {
|
|
982
|
+
encodedList: unsignedCredential.credentialSubject.encodedList,
|
|
983
|
+
statusListCredential,
|
|
984
|
+
bitstringStatusList: {
|
|
985
|
+
statusPurpose: statusPurpose ?? DEFAULT_STATUS_PURPOSE,
|
|
986
|
+
...unsignedCredential.validFrom && {
|
|
987
|
+
validFrom: new Date(unsignedCredential.validFrom)
|
|
988
|
+
},
|
|
989
|
+
...unsignedCredential.validUntil && {
|
|
990
|
+
validUntil: new Date(unsignedCredential.validUntil)
|
|
991
|
+
},
|
|
992
|
+
ttl,
|
|
993
|
+
bitsPerStatus
|
|
994
|
+
},
|
|
995
|
+
length,
|
|
996
|
+
type: import_ssi_types5.StatusListType.BitstringStatusList,
|
|
997
|
+
proofFormat,
|
|
998
|
+
id,
|
|
999
|
+
correlationId,
|
|
1000
|
+
issuer,
|
|
1001
|
+
statuslistContentType: this.buildContentType(proofFormat)
|
|
1002
|
+
};
|
|
1003
|
+
}
|
|
1004
|
+
/**
|
|
1005
|
+
* Updates the status of a specific credential in an existing status list
|
|
1006
|
+
*
|
|
1007
|
+
* @param args - Update parameters including the status list credential, index, and new value
|
|
1008
|
+
* @param context - Veramo agent context for credential operations
|
|
1009
|
+
* @returns Promise resolving to the updated status list details
|
|
1010
|
+
*/
|
|
1011
|
+
async updateStatusListIndex(args, context) {
|
|
1012
|
+
if (!args.bitsPerStatus || args.bitsPerStatus < 1) {
|
|
1013
|
+
return Promise.reject(Error("bitsPerStatus must be set for bitstring status lists and must be 1 or higher. (updateStatusListIndex)"));
|
|
1014
|
+
}
|
|
1015
|
+
const credential = args.statusListCredential;
|
|
1016
|
+
const uniform = import_ssi_types5.CredentialMapper.toUniformCredential(credential);
|
|
1017
|
+
const { issuer, credentialSubject } = uniform;
|
|
1018
|
+
const id = getAssertedValue("id", uniform.id);
|
|
1019
|
+
const origEncodedList = getAssertedProperty("encodedList", credentialSubject);
|
|
1020
|
+
const index = typeof args.statusListIndex === "number" ? args.statusListIndex : parseInt(args.statusListIndex);
|
|
1021
|
+
const statusList = await import_vc_bitstring_status_lists.BitstreamStatusList.decode({
|
|
1022
|
+
encodedList: origEncodedList,
|
|
1023
|
+
statusSize: args.bitsPerStatus
|
|
1024
|
+
});
|
|
1025
|
+
const bitstringStatusId = args.value;
|
|
1026
|
+
statusList.setStatus(index, bitstringStatusId);
|
|
1027
|
+
const proofFormat = import_ssi_types5.CredentialMapper.detectDocumentType(credential) === import_ssi_types5.DocumentFormat.JWT ? "vc+jwt" : "lds";
|
|
1028
|
+
const credSubject = Array.isArray(credentialSubject) ? credentialSubject[0] : credentialSubject;
|
|
1029
|
+
const statusPurpose = getAssertedProperty("statusPurpose", credSubject);
|
|
1030
|
+
const validFrom = uniform.validFrom ? new Date(uniform.validFrom) : void 0;
|
|
1031
|
+
const validUntil = uniform.validUntil ? new Date(uniform.validUntil) : void 0;
|
|
1032
|
+
const ttl = credSubject.ttl;
|
|
1033
|
+
const unsignedCredential = await (0, import_vc_bitstring_status_lists.createStatusListCredential)({
|
|
1034
|
+
id,
|
|
1035
|
+
issuer,
|
|
1036
|
+
statusList,
|
|
1037
|
+
statusPurpose: statusPurpose ?? DEFAULT_STATUS_PURPOSE,
|
|
1038
|
+
validFrom: ensureDate(validFrom),
|
|
1039
|
+
validUntil: ensureDate(validUntil),
|
|
1040
|
+
ttl
|
|
1041
|
+
});
|
|
1042
|
+
const updatedCredential = await this.createVerifiableCredential({
|
|
1043
|
+
unsignedCredential,
|
|
1044
|
+
id,
|
|
1045
|
+
issuer,
|
|
1046
|
+
proofFormat,
|
|
1047
|
+
keyRef: args.keyRef
|
|
1048
|
+
}, context);
|
|
1049
|
+
return {
|
|
1050
|
+
statusListCredential: updatedCredential,
|
|
1051
|
+
encodedList: unsignedCredential.credentialSubject.encodedList,
|
|
1052
|
+
bitstringStatusList: {
|
|
1053
|
+
statusPurpose,
|
|
1054
|
+
...unsignedCredential.validFrom && {
|
|
1055
|
+
validFrom: new Date(unsignedCredential.validFrom)
|
|
1056
|
+
},
|
|
1057
|
+
...unsignedCredential.validUntil && {
|
|
1058
|
+
validUntil: new Date(unsignedCredential.validUntil)
|
|
1059
|
+
},
|
|
1060
|
+
bitsPerStatus: args.bitsPerStatus,
|
|
1061
|
+
ttl
|
|
1062
|
+
},
|
|
1063
|
+
length: statusList.getLength(),
|
|
1064
|
+
type: import_ssi_types5.StatusListType.BitstringStatusList,
|
|
1065
|
+
proofFormat,
|
|
1066
|
+
id,
|
|
1067
|
+
issuer,
|
|
1068
|
+
statuslistContentType: this.buildContentType(proofFormat)
|
|
1069
|
+
};
|
|
1070
|
+
}
|
|
1071
|
+
/**
|
|
1072
|
+
* Updates a status list by decoding an encoded list, modifying it, and re-encoding
|
|
1073
|
+
*
|
|
1074
|
+
* @param args - Update parameters including encoded list, index, and new value
|
|
1075
|
+
* @param context - Veramo agent context for credential operations
|
|
1076
|
+
* @returns Promise resolving to the updated status list details
|
|
1077
|
+
*/
|
|
1078
|
+
async updateStatusListFromEncodedList(args, context) {
|
|
1079
|
+
if (!args.bitstringStatusList) {
|
|
1080
|
+
throw new Error("bitstringStatusList options required for type BitstringStatusList");
|
|
1081
|
+
}
|
|
1082
|
+
if (args.bitstringStatusList.bitsPerStatus < 1) {
|
|
1083
|
+
return Promise.reject(Error("bitsPerStatus must be set for bitstring status lists and must be 1 or higher. (updateStatusListFromEncodedList)"));
|
|
1084
|
+
}
|
|
1085
|
+
const { statusPurpose, bitsPerStatus, ttl, validFrom, validUntil } = args.bitstringStatusList;
|
|
1086
|
+
const proofFormat = args?.proofFormat ?? DEFAULT_PROOF_FORMAT3;
|
|
1087
|
+
assertValidProofType(import_ssi_types5.StatusListType.BitstringStatusList, proofFormat);
|
|
1088
|
+
const { issuer, id } = getAssertedValues(args);
|
|
1089
|
+
const statusList = await import_vc_bitstring_status_lists.BitstreamStatusList.decode({
|
|
1090
|
+
encodedList: args.encodedList,
|
|
1091
|
+
statusSize: bitsPerStatus
|
|
1092
|
+
});
|
|
1093
|
+
const index = typeof args.statusListIndex === "number" ? args.statusListIndex : parseInt(args.statusListIndex);
|
|
1094
|
+
statusList.setStatus(index, args.value);
|
|
1095
|
+
const unsignedCredential = await (0, import_vc_bitstring_status_lists.createStatusListCredential)({
|
|
1096
|
+
id,
|
|
1097
|
+
issuer,
|
|
1098
|
+
statusList,
|
|
1099
|
+
statusPurpose: statusPurpose ?? DEFAULT_STATUS_PURPOSE,
|
|
1100
|
+
validFrom: ensureDate(validFrom),
|
|
1101
|
+
validUntil: ensureDate(validUntil),
|
|
1102
|
+
ttl
|
|
1103
|
+
});
|
|
1104
|
+
const credential = await this.createVerifiableCredential({
|
|
1105
|
+
unsignedCredential,
|
|
1106
|
+
id,
|
|
1107
|
+
issuer,
|
|
1108
|
+
proofFormat,
|
|
1109
|
+
keyRef: args.keyRef
|
|
1110
|
+
}, context);
|
|
1111
|
+
return {
|
|
1112
|
+
type: import_ssi_types5.StatusListType.BitstringStatusList,
|
|
1113
|
+
statusListCredential: credential,
|
|
1114
|
+
encodedList: unsignedCredential.credentialSubject.encodedList,
|
|
1115
|
+
bitstringStatusList: {
|
|
1116
|
+
statusPurpose,
|
|
1117
|
+
bitsPerStatus,
|
|
1118
|
+
...unsignedCredential.validFrom && {
|
|
1119
|
+
validFrom: new Date(unsignedCredential.validFrom)
|
|
1120
|
+
},
|
|
1121
|
+
...unsignedCredential.validUntil && {
|
|
1122
|
+
validUntil: new Date(unsignedCredential.validUntil)
|
|
1123
|
+
},
|
|
1124
|
+
ttl
|
|
1125
|
+
},
|
|
1126
|
+
length: statusList.getLength(),
|
|
1127
|
+
proofFormat: args.proofFormat ?? "lds",
|
|
1128
|
+
id,
|
|
1129
|
+
issuer,
|
|
1130
|
+
statuslistContentType: this.buildContentType(proofFormat)
|
|
1131
|
+
};
|
|
1132
|
+
}
|
|
1133
|
+
/**
|
|
1134
|
+
* Checks the status of a specific credential by its index in the status list
|
|
1135
|
+
*
|
|
1136
|
+
* @param args - Check parameters including the status list credential and index
|
|
1137
|
+
* @returns Promise resolving to the status value at the specified index
|
|
1138
|
+
*/
|
|
1139
|
+
async checkStatusIndex(args) {
|
|
1140
|
+
if (!args.bitsPerStatus || args.bitsPerStatus < 1) {
|
|
1141
|
+
return Promise.reject(Error("bitsPerStatus must be set for bitstring status lists and must be 1 or higher. (checkStatusIndex)"));
|
|
1142
|
+
}
|
|
1143
|
+
const uniform = import_ssi_types5.CredentialMapper.toUniformCredential(args.statusListCredential);
|
|
1144
|
+
const { credentialSubject } = uniform;
|
|
1145
|
+
const encodedList = getAssertedProperty("encodedList", credentialSubject);
|
|
1146
|
+
const statusList = await import_vc_bitstring_status_lists.BitstreamStatusList.decode({
|
|
1147
|
+
encodedList,
|
|
1148
|
+
statusSize: args.bitsPerStatus
|
|
1149
|
+
});
|
|
1150
|
+
const numIndex = typeof args.statusListIndex === "number" ? args.statusListIndex : parseInt(args.statusListIndex);
|
|
1151
|
+
if (statusList.getLength() <= numIndex) {
|
|
1152
|
+
throw new Error(`Status list index out of bounds, has ${statusList.getLength()} entries, requested ${numIndex}`);
|
|
1153
|
+
}
|
|
1154
|
+
return statusList.getStatus(numIndex);
|
|
1155
|
+
}
|
|
1156
|
+
/**
|
|
1157
|
+
* Performs the initial parsing of a StatusListCredential.
|
|
1158
|
+
* This method handles expensive operations like JWT/CWT decoding once.
|
|
1159
|
+
* It extracts all details available from the credential payload itself.
|
|
1160
|
+
*/
|
|
1161
|
+
async extractCredentialDetails(credential) {
|
|
1162
|
+
const uniform = import_ssi_types5.CredentialMapper.toUniformCredential(credential);
|
|
1163
|
+
const { issuer, credentialSubject } = uniform;
|
|
1164
|
+
const subject = Array.isArray(credentialSubject) ? credentialSubject[0] : credentialSubject;
|
|
1165
|
+
return {
|
|
1166
|
+
id: getAssertedValue("id", uniform.id),
|
|
1167
|
+
issuer,
|
|
1168
|
+
encodedList: getAssertedProperty("encodedList", subject)
|
|
1169
|
+
};
|
|
1170
|
+
}
|
|
1171
|
+
async toStatusListDetails(args) {
|
|
1172
|
+
if ("statusListCredential" in args) {
|
|
1173
|
+
const { statusListCredential, bitsPerStatus, correlationId, driverType } = args;
|
|
1174
|
+
if (!bitsPerStatus || bitsPerStatus < 1) {
|
|
1175
|
+
return Promise.reject(Error("bitsPerStatus must be set for bitstring status lists and must be 1 or higher"));
|
|
1176
|
+
}
|
|
1177
|
+
const uniform = import_ssi_types5.CredentialMapper.toUniformCredential(statusListCredential);
|
|
1178
|
+
const { issuer, credentialSubject } = uniform;
|
|
1179
|
+
const subject = Array.isArray(credentialSubject) ? credentialSubject[0] : credentialSubject;
|
|
1180
|
+
const id = getAssertedValue("id", uniform.id);
|
|
1181
|
+
const encodedList = getAssertedProperty("encodedList", subject);
|
|
1182
|
+
const statusPurpose = getAssertedProperty("statusPurpose", subject);
|
|
1183
|
+
const validFrom = uniform.validFrom ? new Date(uniform.validFrom) : void 0;
|
|
1184
|
+
const validUntil = uniform.validUntil ? new Date(uniform.validUntil) : void 0;
|
|
1185
|
+
const ttl = subject.ttl;
|
|
1186
|
+
const proofFormat = import_ssi_types5.CredentialMapper.detectDocumentType(statusListCredential) === import_ssi_types5.DocumentFormat.JWT ? "vc+jwt" : "lds";
|
|
1187
|
+
const statuslistLength = import_vc_bitstring_status_lists.BitstreamStatusList.getStatusListLength(encodedList, bitsPerStatus);
|
|
1188
|
+
return {
|
|
1189
|
+
id,
|
|
1190
|
+
encodedList,
|
|
1191
|
+
issuer,
|
|
1192
|
+
type: import_ssi_types5.StatusListType.BitstringStatusList,
|
|
1193
|
+
proofFormat,
|
|
1194
|
+
length: statuslistLength,
|
|
1195
|
+
statusListCredential,
|
|
1196
|
+
statuslistContentType: this.buildContentType(proofFormat),
|
|
1197
|
+
correlationId,
|
|
1198
|
+
driverType,
|
|
1199
|
+
statusPurpose,
|
|
1200
|
+
bitsPerStatus,
|
|
1201
|
+
...validFrom && {
|
|
1202
|
+
validFrom
|
|
1203
|
+
},
|
|
1204
|
+
...validUntil && {
|
|
1205
|
+
validUntil
|
|
1206
|
+
},
|
|
1207
|
+
...ttl && {
|
|
1208
|
+
ttl
|
|
1209
|
+
},
|
|
1210
|
+
bitstringStatusList: {
|
|
1211
|
+
statusPurpose,
|
|
1212
|
+
bitsPerStatus,
|
|
1213
|
+
...validFrom && {
|
|
1214
|
+
validFrom
|
|
1215
|
+
},
|
|
1216
|
+
...validUntil && {
|
|
1217
|
+
validUntil
|
|
1218
|
+
},
|
|
1219
|
+
...ttl && {
|
|
1220
|
+
ttl
|
|
1221
|
+
}
|
|
1222
|
+
}
|
|
1223
|
+
};
|
|
1224
|
+
} else {
|
|
1225
|
+
const { extractedDetails, statusListEntity } = args;
|
|
1226
|
+
const bitstringEntity = statusListEntity;
|
|
1227
|
+
if (!bitstringEntity.bitsPerStatus) {
|
|
1228
|
+
return Promise.reject(Error("bitsPerStatus must be present for a bitstring status list"));
|
|
1229
|
+
}
|
|
1230
|
+
const proofFormat = import_ssi_types5.CredentialMapper.detectDocumentType(statusListEntity.statusListCredential) === import_ssi_types5.DocumentFormat.JWT ? "vc+jwt" : "lds";
|
|
1231
|
+
const statuslistLength = import_vc_bitstring_status_lists.BitstreamStatusList.getStatusListLength(extractedDetails.encodedList, bitstringEntity.bitsPerStatus);
|
|
1232
|
+
return {
|
|
1233
|
+
id: extractedDetails.id,
|
|
1234
|
+
encodedList: extractedDetails.encodedList,
|
|
1235
|
+
issuer: extractedDetails.issuer,
|
|
1236
|
+
type: import_ssi_types5.StatusListType.BitstringStatusList,
|
|
1237
|
+
proofFormat,
|
|
1238
|
+
length: statuslistLength,
|
|
1239
|
+
statusListCredential: statusListEntity.statusListCredential,
|
|
1240
|
+
statuslistContentType: this.buildContentType(proofFormat),
|
|
1241
|
+
correlationId: statusListEntity.correlationId,
|
|
1242
|
+
driverType: statusListEntity.driverType,
|
|
1243
|
+
statusPurpose: bitstringEntity.statusPurpose,
|
|
1244
|
+
bitsPerStatus: bitstringEntity.bitsPerStatus,
|
|
1245
|
+
...bitstringEntity.validFrom && {
|
|
1246
|
+
validFrom: bitstringEntity.validFrom
|
|
1247
|
+
},
|
|
1248
|
+
...bitstringEntity.validUntil && {
|
|
1249
|
+
validUntil: bitstringEntity.validUntil
|
|
1250
|
+
},
|
|
1251
|
+
...bitstringEntity.ttl && {
|
|
1252
|
+
ttl: bitstringEntity.ttl
|
|
1253
|
+
},
|
|
1254
|
+
bitstringStatusList: {
|
|
1255
|
+
statusPurpose: bitstringEntity.statusPurpose,
|
|
1256
|
+
bitsPerStatus: bitstringEntity.bitsPerStatus,
|
|
1257
|
+
...bitstringEntity.validFrom && {
|
|
1258
|
+
validFrom: bitstringEntity.validFrom
|
|
1259
|
+
},
|
|
1260
|
+
...bitstringEntity.validUntil && {
|
|
1261
|
+
validUntil: bitstringEntity.validUntil
|
|
1262
|
+
},
|
|
1263
|
+
...bitstringEntity.ttl && {
|
|
1264
|
+
ttl: bitstringEntity.ttl
|
|
1265
|
+
}
|
|
1266
|
+
}
|
|
1267
|
+
};
|
|
1268
|
+
}
|
|
1269
|
+
}
|
|
1270
|
+
/**
|
|
1271
|
+
* Creates a credential status entry for a specific credential in a status list
|
|
1272
|
+
*
|
|
1273
|
+
* @param args - Parameters including the status list, entry details, and index
|
|
1274
|
+
* @returns Promise resolving to the credential status entry
|
|
1275
|
+
*/
|
|
1276
|
+
async createCredentialStatus(args) {
|
|
1277
|
+
const { statusList, statusListEntry, statusListIndex } = args;
|
|
1278
|
+
const bitstringStatusList = statusList;
|
|
1279
|
+
const bitstringStatusListEntry = statusListEntry;
|
|
1280
|
+
return {
|
|
1281
|
+
id: `${statusList.id}#${statusListIndex}`,
|
|
1282
|
+
type: "BitstringStatusListEntry",
|
|
1283
|
+
statusPurpose: bitstringStatusListEntry.statusPurpose,
|
|
1284
|
+
statusListIndex: "" + statusListIndex,
|
|
1285
|
+
statusListCredential: statusList.id,
|
|
1286
|
+
bitsPerStatus: bitstringStatusList.bitsPerStatus,
|
|
1287
|
+
statusMessage: bitstringStatusListEntry.statusMessage,
|
|
1288
|
+
statusReference: bitstringStatusListEntry.statusReference
|
|
1289
|
+
};
|
|
1290
|
+
}
|
|
1291
|
+
/**
|
|
1292
|
+
* Creates a signed verifiable credential from an unsigned status list credential
|
|
1293
|
+
*
|
|
1294
|
+
* @param args - Parameters including the unsigned credential and signing details
|
|
1295
|
+
* @param context - Veramo agent context for credential operations
|
|
1296
|
+
* @returns Promise resolving to the signed credential
|
|
1297
|
+
*/
|
|
1298
|
+
async createVerifiableCredential(args, context) {
|
|
1299
|
+
const { unsignedCredential, issuer, proofFormat, keyRef } = args;
|
|
1300
|
+
const identifier = await context.agent.identifierManagedGet({
|
|
1301
|
+
identifier: typeof issuer === "string" ? issuer : issuer.id,
|
|
1302
|
+
vmRelationship: "assertionMethod",
|
|
1303
|
+
offlineWhenNoDIDRegistered: true
|
|
1304
|
+
});
|
|
1305
|
+
const verifiableCredential = await context.agent.createVerifiableCredential({
|
|
1306
|
+
credential: unsignedCredential,
|
|
1307
|
+
keyRef: keyRef ?? identifier.kmsKeyRef,
|
|
1308
|
+
proofFormat,
|
|
1309
|
+
fetchRemoteContexts: true
|
|
1310
|
+
});
|
|
1311
|
+
return import_ssi_types5.CredentialMapper.toWrappedVerifiableCredential(verifiableCredential).original;
|
|
1312
|
+
}
|
|
1313
|
+
/**
|
|
1314
|
+
* Builds the appropriate content type string for a given proof format
|
|
1315
|
+
*
|
|
1316
|
+
* @param proofFormat - The proof format to build content type for
|
|
1317
|
+
* @returns The corresponding content type string
|
|
1318
|
+
*/
|
|
1319
|
+
buildContentType(proofFormat) {
|
|
1320
|
+
switch (proofFormat) {
|
|
1321
|
+
case "jwt":
|
|
1322
|
+
return "application/statuslist+jwt";
|
|
1323
|
+
case "cbor":
|
|
1324
|
+
return "application/statuslist+cwt";
|
|
1325
|
+
case "vc+jwt":
|
|
1326
|
+
return "application/statuslist+vc+jwt";
|
|
1327
|
+
case "lds":
|
|
1328
|
+
return "application/statuslist+ld+json";
|
|
1329
|
+
default:
|
|
1330
|
+
throw Error(`Unsupported content type '${proofFormat}' for status lists`);
|
|
1331
|
+
}
|
|
1332
|
+
}
|
|
1333
|
+
};
|
|
1334
|
+
|
|
1335
|
+
// src/impl/StatusListFactory.ts
|
|
759
1336
|
var StatusListFactory = class _StatusListFactory {
|
|
760
1337
|
static {
|
|
761
1338
|
__name(this, "StatusListFactory");
|
|
@@ -764,8 +1341,9 @@ var StatusListFactory = class _StatusListFactory {
|
|
|
764
1341
|
implementations;
|
|
765
1342
|
constructor() {
|
|
766
1343
|
this.implementations = /* @__PURE__ */ new Map();
|
|
767
|
-
this.implementations.set(
|
|
768
|
-
this.implementations.set(
|
|
1344
|
+
this.implementations.set(import_ssi_types6.StatusListType.StatusList2021, new StatusList2021Implementation());
|
|
1345
|
+
this.implementations.set(import_ssi_types6.StatusListType.OAuthStatusList, new OAuthStatusListImplementation());
|
|
1346
|
+
this.implementations.set(import_ssi_types6.StatusListType.BitstringStatusList, new BitstringStatusListImplementation());
|
|
769
1347
|
}
|
|
770
1348
|
static getInstance() {
|
|
771
1349
|
if (!_StatusListFactory.instance) {
|
|
@@ -838,7 +1416,7 @@ __name(vcLibCheckStatusFunction, "vcLibCheckStatusFunction");
|
|
|
838
1416
|
async function checkStatusForCredential(args) {
|
|
839
1417
|
const verifyStatusListCredential = args.verifyStatusListCredential ?? true;
|
|
840
1418
|
const verifyMatchingIssuers = args.verifyMatchingIssuers ?? true;
|
|
841
|
-
const uniform =
|
|
1419
|
+
const uniform = import_ssi_types7.CredentialMapper.toUniformCredential(args.credential);
|
|
842
1420
|
if (!("credentialStatus" in uniform) || !uniform.credentialStatus) {
|
|
843
1421
|
if (args.mandatoryCredentialStatus) {
|
|
844
1422
|
const error = "No credential status object found in the Verifiable Credential and it is mandatory";
|
|
@@ -853,7 +1431,7 @@ async function checkStatusForCredential(args) {
|
|
|
853
1431
|
};
|
|
854
1432
|
}
|
|
855
1433
|
if ("credentialStatus" in uniform && uniform.credentialStatus) {
|
|
856
|
-
if (uniform.credentialStatus.type === "StatusList2021Entry") {
|
|
1434
|
+
if (uniform.credentialStatus.type === "StatusList2021Entry" || uniform.credentialStatus.type === "BitstringStatusListEntry") {
|
|
857
1435
|
return (0, import_vc_status_list2.checkStatus)({
|
|
858
1436
|
...args,
|
|
859
1437
|
verifyStatusListCredential,
|
|
@@ -901,35 +1479,35 @@ async function updateStatusIndexFromStatusListCredential(args, context) {
|
|
|
901
1479
|
return implementation.updateStatusListIndex(args, context);
|
|
902
1480
|
}
|
|
903
1481
|
__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", "");
|
|
1482
|
+
async function extractCredentialDetails(statusListCredential) {
|
|
1483
|
+
const statusListType = determineStatusListType(statusListCredential);
|
|
1484
|
+
const implementation = getStatusListImplementation(statusListType);
|
|
1485
|
+
return implementation.extractCredentialDetails(statusListCredential);
|
|
1486
|
+
}
|
|
1487
|
+
__name(extractCredentialDetails, "extractCredentialDetails");
|
|
1488
|
+
async function toStatusListDetails(args) {
|
|
1489
|
+
if ("statusListCredential" in args) {
|
|
1490
|
+
const statusListType = args.statusListType;
|
|
1491
|
+
const implementation = getStatusListImplementation(statusListType);
|
|
1492
|
+
return implementation.toStatusListDetails(args);
|
|
1493
|
+
} else {
|
|
1494
|
+
const statusListType = args.statusListEntity.type;
|
|
1495
|
+
const implementation = getStatusListImplementation(statusListType);
|
|
1496
|
+
return implementation.toStatusListDetails(args);
|
|
924
1497
|
}
|
|
1498
|
+
}
|
|
1499
|
+
__name(toStatusListDetails, "toStatusListDetails");
|
|
1500
|
+
async function createCredentialStatusFromStatusList(args) {
|
|
1501
|
+
const { statusList, statusListEntry, statusListIndex } = args;
|
|
1502
|
+
const statusListType = determineStatusListType(statusList.statusListCredential);
|
|
925
1503
|
const implementation = getStatusListImplementation(statusListType);
|
|
926
|
-
return
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
1504
|
+
return implementation.createCredentialStatus({
|
|
1505
|
+
statusList,
|
|
1506
|
+
statusListEntry,
|
|
1507
|
+
statusListIndex
|
|
930
1508
|
});
|
|
931
1509
|
}
|
|
932
|
-
__name(
|
|
1510
|
+
__name(createCredentialStatusFromStatusList, "createCredentialStatusFromStatusList");
|
|
933
1511
|
async function updateStatusListIndexFromEncodedList(args, context) {
|
|
934
1512
|
const { type } = getAssertedValue("type", args);
|
|
935
1513
|
const implementation = getStatusListImplementation(type);
|
|
@@ -944,7 +1522,7 @@ async function statusList2021ToVerifiableCredential(args, context) {
|
|
|
944
1522
|
offlineWhenNoDIDRegistered: true
|
|
945
1523
|
});
|
|
946
1524
|
const proofFormat = args?.proofFormat ?? "lds";
|
|
947
|
-
assertValidProofType(
|
|
1525
|
+
assertValidProofType(import_ssi_types7.StatusListType.StatusList2021, proofFormat);
|
|
948
1526
|
const veramoProofFormat = proofFormat;
|
|
949
1527
|
const encodedList = getAssertedValue("encodedList", args.encodedList);
|
|
950
1528
|
const statusPurpose = getAssertedValue("statusPurpose", args.statusPurpose);
|
|
@@ -973,7 +1551,7 @@ async function statusList2021ToVerifiableCredential(args, context) {
|
|
|
973
1551
|
proofFormat: veramoProofFormat,
|
|
974
1552
|
fetchRemoteContexts: true
|
|
975
1553
|
});
|
|
976
|
-
return
|
|
1554
|
+
return import_ssi_types7.CredentialMapper.toWrappedVerifiableCredential(verifiableCredential).original;
|
|
977
1555
|
}
|
|
978
1556
|
__name(statusList2021ToVerifiableCredential, "statusList2021ToVerifiableCredential");
|
|
979
1557
|
//# sourceMappingURL=index.cjs.map
|