@sphereon/ssi-sdk.vc-status-list-issuer 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.d.cts CHANGED
@@ -1,10 +1,67 @@
1
- import { StatusListManagementOptions } from '@sphereon/ssi-sdk.vc-status-list-issuer-drivers';
1
+ import { StatusListResult, IStatusListPlugin } from '@sphereon/ssi-sdk.vc-status-list';
2
+ import { StatusListManagementOptions, IStatusListDriver } from '@sphereon/ssi-sdk.vc-status-list-issuer-drivers';
2
3
  import { OrPromise } from '@sphereon/ssi-types';
3
4
  import { DataSource } from 'typeorm';
5
+ import { DataSources } from '@sphereon/ssi-sdk.agent-config';
6
+ import { IAgentPlugin } from '@veramo/core';
4
7
 
5
8
  type StatusListInstance = StatusListManagementOptions & {
6
9
  dataSource?: OrPromise<DataSource>;
7
10
  issuer?: string;
8
11
  };
12
+ interface IDriverAndStatusListResult {
13
+ slDriver: IStatusListDriver;
14
+ statusList: StatusListRef;
15
+ }
16
+ type StatusListRef = Pick<StatusListResult, 'id' | 'correlationId' | 'type' | 'oauthStatusList' | 'bitstringStatusList'>;
9
17
 
10
- export type { StatusListInstance };
18
+ declare class StatusListPlugin implements IAgentPlugin {
19
+ private readonly instances;
20
+ private readonly defaultStatusListId?;
21
+ private readonly allDataSources;
22
+ private initialized;
23
+ readonly methods: IStatusListPlugin;
24
+ constructor(opts: {
25
+ instances?: Array<StatusListInstance>;
26
+ defaultStatusListId?: string;
27
+ allDataSources?: DataSources;
28
+ autoCreateInstances?: boolean;
29
+ });
30
+ private init;
31
+ private slImportStatusLists;
32
+ private createStatusListInstance;
33
+ private getDriverForStatusListOption;
34
+ private slGetStatusList;
35
+ private selectDatasource;
36
+ private slCreateStatusList;
37
+ /**
38
+ * Selects bitsPerStatus from the used status list type when applicable
39
+ * @param sl
40
+ * @private
41
+ */
42
+ private selectBitsPerStatus;
43
+ /**
44
+ * Adds status information to a credential by either:
45
+ * 1. Using existing status ID from the credential if present
46
+ * 2. Using provided status list options
47
+ * 3. Falling back to the default status list ID
48
+ *
49
+ * @param args Contains credential and status options
50
+ * @param context Required agent context
51
+ * @returns Credential with added status information
52
+ */
53
+ private slAddStatusToCredential;
54
+ /**
55
+ * Adds status information to an SD-JWT credential by either:
56
+ * 1. Using existing status URI from the credential if present
57
+ * 2. Using provided status list options
58
+ * 3. Falling back to the default status list ID
59
+ *
60
+ * @param args Contains SD-JWT credential and status options
61
+ * @param context Required agent context
62
+ * @returns SD-JWT credential with added status information
63
+ */
64
+ private slAddStatusToSdJwtCredential;
65
+ }
66
+
67
+ export { type IDriverAndStatusListResult, type StatusListInstance, StatusListPlugin, type StatusListRef };
package/dist/index.d.ts CHANGED
@@ -1,10 +1,67 @@
1
- import { StatusListManagementOptions } from '@sphereon/ssi-sdk.vc-status-list-issuer-drivers';
1
+ import { StatusListResult, IStatusListPlugin } from '@sphereon/ssi-sdk.vc-status-list';
2
+ import { StatusListManagementOptions, IStatusListDriver } from '@sphereon/ssi-sdk.vc-status-list-issuer-drivers';
2
3
  import { OrPromise } from '@sphereon/ssi-types';
3
4
  import { DataSource } from 'typeorm';
5
+ import { DataSources } from '@sphereon/ssi-sdk.agent-config';
6
+ import { IAgentPlugin } from '@veramo/core';
4
7
 
5
8
  type StatusListInstance = StatusListManagementOptions & {
6
9
  dataSource?: OrPromise<DataSource>;
7
10
  issuer?: string;
8
11
  };
12
+ interface IDriverAndStatusListResult {
13
+ slDriver: IStatusListDriver;
14
+ statusList: StatusListRef;
15
+ }
16
+ type StatusListRef = Pick<StatusListResult, 'id' | 'correlationId' | 'type' | 'oauthStatusList' | 'bitstringStatusList'>;
9
17
 
10
- export type { StatusListInstance };
18
+ declare class StatusListPlugin implements IAgentPlugin {
19
+ private readonly instances;
20
+ private readonly defaultStatusListId?;
21
+ private readonly allDataSources;
22
+ private initialized;
23
+ readonly methods: IStatusListPlugin;
24
+ constructor(opts: {
25
+ instances?: Array<StatusListInstance>;
26
+ defaultStatusListId?: string;
27
+ allDataSources?: DataSources;
28
+ autoCreateInstances?: boolean;
29
+ });
30
+ private init;
31
+ private slImportStatusLists;
32
+ private createStatusListInstance;
33
+ private getDriverForStatusListOption;
34
+ private slGetStatusList;
35
+ private selectDatasource;
36
+ private slCreateStatusList;
37
+ /**
38
+ * Selects bitsPerStatus from the used status list type when applicable
39
+ * @param sl
40
+ * @private
41
+ */
42
+ private selectBitsPerStatus;
43
+ /**
44
+ * Adds status information to a credential by either:
45
+ * 1. Using existing status ID from the credential if present
46
+ * 2. Using provided status list options
47
+ * 3. Falling back to the default status list ID
48
+ *
49
+ * @param args Contains credential and status options
50
+ * @param context Required agent context
51
+ * @returns Credential with added status information
52
+ */
53
+ private slAddStatusToCredential;
54
+ /**
55
+ * Adds status information to an SD-JWT credential by either:
56
+ * 1. Using existing status URI from the credential if present
57
+ * 2. Using provided status list options
58
+ * 3. Falling back to the default status list ID
59
+ *
60
+ * @param args Contains SD-JWT credential and status options
61
+ * @param context Required agent context
62
+ * @returns SD-JWT credential with added status information
63
+ */
64
+ private slAddStatusToSdJwtCredential;
65
+ }
66
+
67
+ export { type IDriverAndStatusListResult, type StatusListInstance, StatusListPlugin, type StatusListRef };
package/dist/index.js CHANGED
@@ -1 +1,527 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
3
+
4
+ // src/agent/StatusListPlugin.ts
5
+ import { DataSources } from "@sphereon/ssi-sdk.agent-config";
6
+ import { createNewStatusList } from "@sphereon/ssi-sdk.vc-status-list";
7
+ import { getDriver as getDriver2 } from "@sphereon/ssi-sdk.vc-status-list-issuer-drivers";
8
+ import { Loggers as Loggers2 } from "@sphereon/ssi-types";
9
+
10
+ // src/functions.ts
11
+ import { getDriver } from "@sphereon/ssi-sdk.vc-status-list-issuer-drivers";
12
+ import debug from "debug";
13
+ import { Loggers } from "@sphereon/ssi-types";
14
+ var logger = Loggers.DEFAULT.get("sphereon:ssi-sdk:vc-status-list-issuer");
15
+ async function getDriverAndStatusList(statusListId, opts) {
16
+ const slDriver = opts?.driver ?? await getDriver({
17
+ id: statusListId,
18
+ dataSource: opts?.dataSource
19
+ });
20
+ const statusList = await slDriver.statusListStore.getStatusList({
21
+ id: statusListId
22
+ });
23
+ return {
24
+ slDriver,
25
+ statusList
26
+ };
27
+ }
28
+ __name(getDriverAndStatusList, "getDriverAndStatusList");
29
+ function getCredentialStatusListOpts(credential, opts) {
30
+ const statusListOpts = [
31
+ ...opts?.statusLists ?? []
32
+ ];
33
+ if (statusListOpts.length === 0 && credential.credentialStatus) {
34
+ if (Array.isArray(credential.credentialStatus)) {
35
+ for (const credStatus of credential.credentialStatus) {
36
+ if (credStatus.statusListCredential) {
37
+ statusListOpts.push({
38
+ statusListId: credStatus.statusListCredential,
39
+ statusListIndex: credStatus.statusListIndex,
40
+ statusListCorrelationId: credStatus.statusListCorrelationId,
41
+ statusEntryCorrelationId: credStatus.statusEntryCorrelationId
42
+ });
43
+ }
44
+ }
45
+ } else if (credential.credentialStatus.statusListCredential) {
46
+ statusListOpts.push({
47
+ statusListId: credential.credentialStatus.statusListCredential,
48
+ statusListIndex: credential.credentialStatus.statusListIndex,
49
+ statusListCorrelationId: credential.credentialStatus.statusListCorrelationId,
50
+ statusEntryCorrelationId: credential.credentialStatus.statusEntryCorrelationId
51
+ });
52
+ }
53
+ }
54
+ return statusListOpts;
55
+ }
56
+ __name(getCredentialStatusListOpts, "getCredentialStatusListOpts");
57
+ function getSdJwtStatusListOpts(credential, opts) {
58
+ const statusListOpts = [
59
+ ...opts?.statusLists ?? []
60
+ ];
61
+ if (statusListOpts.length === 0 && credential.status?.status_list) {
62
+ statusListOpts.push({
63
+ statusListId: credential.status.status_list.uri,
64
+ statusListIndex: credential.status.status_list.idx
65
+ });
66
+ }
67
+ return statusListOpts;
68
+ }
69
+ __name(getSdJwtStatusListOpts, "getSdJwtStatusListOpts");
70
+ async function processStatusListEntry(params) {
71
+ let existingEntry = void 0;
72
+ if (params.credentialId) {
73
+ existingEntry = await params.slDriver.getStatusListEntryByCredentialId({
74
+ statusListId: params.statusList.id,
75
+ credentialId: params.credentialId,
76
+ errorOnNotFound: false
77
+ });
78
+ if (existingEntry) {
79
+ debug(`Existing statusList entry and index ${existingEntry.statusListIndex} found for ${params.debugCredentialInfo}. Will reuse the index`);
80
+ }
81
+ }
82
+ let statusListIndex = existingEntry?.statusListIndex ?? params.currentIndex;
83
+ if (params.useIndexCondition(statusListIndex)) {
84
+ existingEntry = await params.slDriver.getStatusListEntryByIndex({
85
+ statusListId: params.statusList.id,
86
+ statusListIndex,
87
+ errorOnNotFound: false
88
+ });
89
+ logger.debug(`${!existingEntry && "no"} existing statusList entry and index ${existingEntry?.statusListIndex} for ${params.debugCredentialInfo}. Will reuse the index`);
90
+ if (existingEntry && params.credentialId && existingEntry.credentialId && existingEntry.credentialId !== params.credentialId && params.checkCredentialIdMismatch) {
91
+ params.checkCredentialIdMismatch(existingEntry, params.credentialId, statusListIndex);
92
+ }
93
+ } else {
94
+ debug(`Will generate a new random statusListIndex since the credential did not contain a statusListIndex for ${params.debugCredentialInfo}...`);
95
+ statusListIndex = await params.slDriver.getRandomNewStatusListIndex({
96
+ correlationId: params.statusList.correlationId
97
+ });
98
+ debug(`Random statusListIndex ${statusListIndex} assigned for ${params.debugCredentialInfo}`);
99
+ }
100
+ const updateArgs = {
101
+ statusListId: params.statusListId,
102
+ statusListIndex,
103
+ correlationId: params.statusEntryCorrelationId,
104
+ value: params.opts?.value ?? "0",
105
+ ...params.statusList.type === "BitstringStatusList" && {
106
+ bitsPerStatus: params.statusList.bitstringStatusList?.bitsPerStatus ?? 1
107
+ }
108
+ };
109
+ if (params.credentialId) {
110
+ updateArgs.credentialId = params.credentialId;
111
+ }
112
+ const updateResult = await params.slDriver.updateStatusListEntry(updateArgs);
113
+ return {
114
+ statusListIndex,
115
+ updateResult
116
+ };
117
+ }
118
+ __name(processStatusListEntry, "processStatusListEntry");
119
+ var createStatusList = /* @__PURE__ */ __name(async (args, dataSource, context) => {
120
+ let statusList;
121
+ try {
122
+ statusList = await context.agent.slGetStatusList({
123
+ ...args.id && {
124
+ id: args.id
125
+ },
126
+ ...args.correlationId && {
127
+ correlationId: args.correlationId
128
+ },
129
+ ...args.dbName && {
130
+ dbName: args.dbName
131
+ },
132
+ dataSource: await dataSource
133
+ });
134
+ } catch (e) {
135
+ const id = args.id;
136
+ const correlationId = args.correlationId;
137
+ if (!id || !correlationId) {
138
+ return Promise.reject(Error(`No correlation id and id provided for status list`));
139
+ }
140
+ statusList = await context.agent.slCreateStatusList(args);
141
+ }
142
+ return statusList;
143
+ }, "createStatusList");
144
+ var handleCredentialStatus = /* @__PURE__ */ __name(async (credential, credentialStatusOpts) => {
145
+ logger.debug(`Starting status update for credential ${credential.id ?? "without ID"}`);
146
+ const statusListOpts = getCredentialStatusListOpts(credential, credentialStatusOpts);
147
+ if (statusListOpts.length === 0) {
148
+ logger.debug("No status list options found, skipping update");
149
+ return;
150
+ }
151
+ const credentialId = credential.id ?? credentialStatusOpts?.credentialId;
152
+ for (const statusListOpt of statusListOpts) {
153
+ const statusListId = statusListOpt.statusListId;
154
+ if (!statusListId) {
155
+ logger.debug("Skipping status list option without ID");
156
+ continue;
157
+ }
158
+ logger.debug(`Processing status list ${statusListId} for credential ${credentialId ?? "without ID"}`);
159
+ const { slDriver, statusList } = await getDriverAndStatusList(statusListId, credentialStatusOpts);
160
+ const currentIndex = statusListOpt.statusListIndex ?? 0;
161
+ const { updateResult } = await processStatusListEntry({
162
+ statusListId,
163
+ statusList,
164
+ credentialId,
165
+ currentIndex,
166
+ statusEntryCorrelationId: statusListOpt.statusEntryCorrelationId,
167
+ opts: credentialStatusOpts,
168
+ slDriver,
169
+ debugCredentialInfo: `credential with id ${credentialId} and statusListId ${statusListId}`,
170
+ useIndexCondition: /* @__PURE__ */ __name((index) => Boolean(index), "useIndexCondition"),
171
+ checkCredentialIdMismatch: /* @__PURE__ */ __name((existingEntry, credentialId2, index) => {
172
+ throw Error(`A credential with new id (${credentialId2}) is issued, but its id does not match a registered statusListEntry id ${existingEntry.credentialId} for index ${index}`);
173
+ }, "checkCredentialIdMismatch")
174
+ });
175
+ if (!credential.credentialStatus || Array.isArray(credential.credentialStatus)) {
176
+ credential.credentialStatus = {
177
+ id: `${statusListId}`,
178
+ statusListCredential: statusListId,
179
+ ...updateResult.credentialStatus
180
+ };
181
+ }
182
+ }
183
+ logger.debug(`Completed status updates for credential ${credentialId ?? "without ID"}`);
184
+ }, "handleCredentialStatus");
185
+ var handleSdJwtCredentialStatus = /* @__PURE__ */ __name(async (credential, credentialStatusOpts) => {
186
+ logger.debug("Starting status update for SD\u2011JWT credential");
187
+ const statusListOpts = getSdJwtStatusListOpts(credential, credentialStatusOpts);
188
+ if (statusListOpts.length === 0) {
189
+ throw Error("No status list options available from credential or options");
190
+ }
191
+ for (const statusListOpt of statusListOpts) {
192
+ const statusListId = statusListOpt.statusListId;
193
+ if (!statusListId) {
194
+ logger.debug("Skipping status list option without ID");
195
+ continue;
196
+ }
197
+ logger.info(`Processing status list ${statusListId}`);
198
+ const { slDriver, statusList } = await getDriverAndStatusList(statusListId, credentialStatusOpts);
199
+ const currentIndex = statusListOpt.statusListIndex ?? 0;
200
+ const { statusListIndex } = await processStatusListEntry({
201
+ statusListId,
202
+ statusList,
203
+ currentIndex,
204
+ statusEntryCorrelationId: statusListOpt.statusEntryCorrelationId,
205
+ opts: credentialStatusOpts,
206
+ slDriver,
207
+ debugCredentialInfo: `credential with statusListId ${statusListId}`,
208
+ useIndexCondition: /* @__PURE__ */ __name((index) => index > 0, "useIndexCondition")
209
+ });
210
+ if (!credential.status) {
211
+ credential.status = {
212
+ status_list: {
213
+ uri: statusListId,
214
+ idx: statusListIndex
215
+ }
216
+ };
217
+ } else if (!credential.status.status_list) {
218
+ credential.status.status_list = {
219
+ uri: statusListId,
220
+ idx: statusListIndex
221
+ };
222
+ } else {
223
+ credential.status.status_list = {
224
+ uri: credential.status.status_list.uri || statusListId,
225
+ idx: statusListIndex
226
+ };
227
+ }
228
+ }
229
+ logger.debug("Completed SD\u2011JWT credential status update");
230
+ }, "handleSdJwtCredentialStatus");
231
+
232
+ // src/agent/StatusListPlugin.ts
233
+ var logger2 = Loggers2.DEFAULT.get("sphereon:ssi-sdk:vc-status-list");
234
+ var StatusListPlugin = class {
235
+ static {
236
+ __name(this, "StatusListPlugin");
237
+ }
238
+ instances = new Array();
239
+ defaultStatusListId;
240
+ allDataSources;
241
+ initialized = false;
242
+ methods = {
243
+ slAddStatusToCredential: this.slAddStatusToCredential.bind(this),
244
+ slAddStatusToSdJwtCredential: this.slAddStatusToSdJwtCredential.bind(this),
245
+ slCreateStatusList: this.slCreateStatusList.bind(this),
246
+ slGetStatusList: this.slGetStatusList.bind(this),
247
+ slImportStatusLists: this.slImportStatusLists.bind(this)
248
+ };
249
+ constructor(opts) {
250
+ this.instances = opts.instances ?? [];
251
+ const instanceId = opts.defaultStatusListId ?? opts.instances?.[0]?.id;
252
+ if (!instanceId) {
253
+ logger2.warning(`Could not deduce the default instance id from the status lists, so no default status list will be used. Please configure the default instance id in the agent configuration.`);
254
+ }
255
+ this.defaultStatusListId = instanceId;
256
+ this.allDataSources = opts.allDataSources ?? DataSources.singleInstance();
257
+ }
258
+ async init() {
259
+ if (!this.initialized) {
260
+ for (const dbName of this.allDataSources.getDbNames()) {
261
+ const driver = await getDriver2({
262
+ dbName,
263
+ dataSources: this.allDataSources
264
+ });
265
+ const statusLists = await driver.getStatusLists();
266
+ const instances = await Promise.all(statusLists.map((statusList) => {
267
+ const dataSource = this.allDataSources.getDbConnection(dbName);
268
+ return this.createStatusListInstance(statusList, dataSource, driver);
269
+ }));
270
+ this.instances.push(...instances);
271
+ }
272
+ this.initialized = true;
273
+ }
274
+ }
275
+ async slImportStatusLists(imports, context) {
276
+ await this.init();
277
+ for (const instanceImport of imports) {
278
+ const dataSource = this.allDataSources.getDbConnection(instanceImport.dbName ?? "default");
279
+ await createStatusList(instanceImport, dataSource, context);
280
+ }
281
+ return true;
282
+ }
283
+ createStatusListInstance(statusList, dataSource, driver) {
284
+ return {
285
+ id: statusList.id,
286
+ correlationId: statusList.correlationId,
287
+ issuer: typeof statusList.issuer === "string" ? statusList.issuer : statusList.issuer.id,
288
+ dataSource,
289
+ driverOptions: driver.getOptions(),
290
+ driverType: driver.getType()
291
+ };
292
+ }
293
+ async getDriverForStatusListOption(effectiveStatusListId, correlationId) {
294
+ let instance;
295
+ if (correlationId && correlationId.trim() !== "") {
296
+ instance = this.instances.find((inst) => inst.correlationId === correlationId);
297
+ } else {
298
+ instance = this.instances.find((inst) => inst.id === effectiveStatusListId);
299
+ }
300
+ if (!instance) {
301
+ throw Error(`Status list with identifier ${correlationId ?? effectiveStatusListId} is not managed by the status list plugin`);
302
+ }
303
+ if (!instance.dataSource && !instance.driverOptions?.dbName) {
304
+ throw Error(`Either a datasource or dbName needs to be supplied`);
305
+ }
306
+ const dataSource = instance.dataSource ? await instance.dataSource : await this.allDataSources.getDbConnection(instance.driverOptions.dbName);
307
+ const driver = correlationId && correlationId.trim() !== "" ? await getDriver2({
308
+ dataSource,
309
+ correlationId
310
+ }) : await getDriver2({
311
+ dataSource,
312
+ id: effectiveStatusListId
313
+ });
314
+ return driver;
315
+ }
316
+ async slGetStatusList(args) {
317
+ await this.init();
318
+ const sl = this.instances.find((instance) => instance.id === args.id || instance.correlationId === args.correlationId);
319
+ const dataSource = await this.selectDatasource({
320
+ dbName: args.dbName,
321
+ dataSource: args.dataSource ?? sl?.dataSource,
322
+ instance: sl
323
+ });
324
+ const driver = await getDriver2({
325
+ id: args.id ?? sl?.id,
326
+ correlationId: args.correlationId ?? sl?.correlationId,
327
+ dataSource
328
+ });
329
+ return await driver.getStatusList();
330
+ }
331
+ async selectDatasource(args) {
332
+ const dbName = args.dbName ?? this.allDataSources.getDbNames()[0];
333
+ if (args?.dataSource) {
334
+ return args.dataSource;
335
+ } else if (args.instance?.dataSource) {
336
+ return args.instance.dataSource;
337
+ } else if (args.dbName) {
338
+ return await this.allDataSources.getDbConnection(dbName);
339
+ } else {
340
+ return await this.allDataSources.getDbConnection(dbName);
341
+ }
342
+ }
343
+ async slCreateStatusList(args, context) {
344
+ await this.init();
345
+ const sl = await createNewStatusList(args, context);
346
+ const dataSource = await this.selectDatasource({
347
+ dbName: args.dbName,
348
+ dataSource: args.dataSource
349
+ });
350
+ const driver = await getDriver2({
351
+ id: sl.id,
352
+ correlationId: sl.correlationId,
353
+ dataSource
354
+ });
355
+ let statusListDetails = void 0;
356
+ try {
357
+ statusListDetails = await this.slGetStatusList(args);
358
+ } catch (e) {
359
+ }
360
+ if (statusListDetails && this.instances.find((instance) => instance.id === args.id || instance.correlationId === args.correlationId)) {
361
+ return Promise.reject(Error(`Status list with id ${args.id} or correlation id ${args.correlationId} already exists`));
362
+ } else {
363
+ statusListDetails = await driver.createStatusList({
364
+ statusListType: sl.type,
365
+ statusListCredential: sl.statusListCredential,
366
+ correlationId: sl.correlationId,
367
+ bitsPerStatus: this.selectBitsPerStatus(sl)
368
+ });
369
+ this.instances.push(this.createStatusListInstance(statusListDetails, dataSource, driver));
370
+ }
371
+ return statusListDetails;
372
+ }
373
+ /**
374
+ * Selects bitsPerStatus from the used status list type when applicable
375
+ * @param sl
376
+ * @private
377
+ */
378
+ selectBitsPerStatus(sl) {
379
+ if (sl.bitstringStatusList) {
380
+ return sl.bitstringStatusList.bitsPerStatus;
381
+ }
382
+ if (sl.oauthStatusList) {
383
+ return sl.oauthStatusList.bitsPerStatus;
384
+ }
385
+ return 1;
386
+ }
387
+ /**
388
+ * Adds status information to a credential by either:
389
+ * 1. Using existing status ID from the credential if present
390
+ * 2. Using provided status list options
391
+ * 3. Falling back to the default status list ID
392
+ *
393
+ * @param args Contains credential and status options
394
+ * @param context Required agent context
395
+ * @returns Credential with added status information
396
+ */
397
+ async slAddStatusToCredential(args, context) {
398
+ const { credential, ...rest } = args;
399
+ logger2.debug(`Adding status to credential ${credential.id ?? "without ID"}`);
400
+ await this.init();
401
+ const credentialStatus = credential.credentialStatus;
402
+ if (credentialStatus && (!rest.statusLists || rest.statusLists.length == 0)) {
403
+ let existingStatusId;
404
+ if (Array.isArray(credentialStatus)) {
405
+ for (const stat of credentialStatus) {
406
+ if (stat.id && stat.id.trim() !== "") {
407
+ existingStatusId = stat.id.split("#")[0];
408
+ break;
409
+ }
410
+ }
411
+ } else if (credentialStatus.id && credentialStatus.id.trim() !== "") {
412
+ existingStatusId = credentialStatus.id.split("#")[0];
413
+ }
414
+ if (existingStatusId) {
415
+ logger2.debug(`Using existing status ID ${existingStatusId} for credential ${credential.id ?? "without ID"}`);
416
+ const instance = this.instances.find((inst) => inst.id === existingStatusId);
417
+ if (!instance) {
418
+ throw Error(`Status list with id ${existingStatusId} is not managed by the status list plugin`);
419
+ }
420
+ if (!instance.dataSource && !instance.driverOptions?.dbName) {
421
+ throw Error(`Either a datasource or dbName needs to be supplied`);
422
+ }
423
+ const credentialId2 = credential.id ?? rest.credentialId;
424
+ const dataSource = instance.dataSource ? await instance.dataSource : await this.allDataSources.getDbConnection(instance.driverOptions.dbName);
425
+ const driver = await getDriver2({
426
+ dataSource,
427
+ id: existingStatusId
428
+ });
429
+ await handleCredentialStatus(credential, {
430
+ ...rest,
431
+ credentialId: credentialId2,
432
+ statusLists: [
433
+ {
434
+ statusListId: existingStatusId
435
+ }
436
+ ],
437
+ driver
438
+ });
439
+ return credential;
440
+ }
441
+ }
442
+ const statusListOpts = rest.statusLists?.length ? rest.statusLists : [];
443
+ logger2.debug(`Adding new status using ${statusListOpts.length} status list option(s)`);
444
+ const credentialId = credential.id ?? rest.credentialId;
445
+ for (const opt of statusListOpts) {
446
+ const effectiveStatusListId = opt.statusListId ?? this.defaultStatusListId;
447
+ if (!effectiveStatusListId) {
448
+ return Promise.reject(Error(`No status list ID provided and no default status list ID configured. Please provide a status list ID or configure a default status list ID in the agent configuration.`));
449
+ }
450
+ const driver = await this.getDriverForStatusListOption(effectiveStatusListId, opt.statusListCorrelationId);
451
+ await handleCredentialStatus(credential, {
452
+ ...rest,
453
+ credentialId,
454
+ statusLists: [
455
+ {
456
+ ...opt,
457
+ statusListId: effectiveStatusListId
458
+ }
459
+ ],
460
+ driver
461
+ });
462
+ }
463
+ logger2.debug(`Successfully added status information to credential ${credential.id ?? "without ID"}`);
464
+ return credential;
465
+ }
466
+ /**
467
+ * Adds status information to an SD-JWT credential by either:
468
+ * 1. Using existing status URI from the credential if present
469
+ * 2. Using provided status list options
470
+ * 3. Falling back to the default status list ID
471
+ *
472
+ * @param args Contains SD-JWT credential and status options
473
+ * @param context Required agent context
474
+ * @returns SD-JWT credential with added status information
475
+ */
476
+ async slAddStatusToSdJwtCredential(args, context) {
477
+ const { credential, ...rest } = args;
478
+ logger2.debug(`Adding status to SD-JWT credential`);
479
+ await this.init();
480
+ const credentialStatus = credential.status;
481
+ if (credentialStatus && (!rest.statusLists || rest.statusLists.length == 0)) {
482
+ let existingStatusUri;
483
+ if (credentialStatus.status_list && credentialStatus.status_list.uri && credentialStatus.status_list.uri.trim() !== "") {
484
+ existingStatusUri = credentialStatus.status_list.uri;
485
+ }
486
+ if (existingStatusUri) {
487
+ logger2.debug(`Using existing status URI ${existingStatusUri} for SD-JWT credential`);
488
+ const driver2 = await this.getDriverForStatusListOption(existingStatusUri);
489
+ await handleSdJwtCredentialStatus(credential, {
490
+ ...rest,
491
+ statusLists: [
492
+ {
493
+ ...rest.statusLists,
494
+ statusListId: existingStatusUri
495
+ }
496
+ ],
497
+ driver: driver2
498
+ });
499
+ return credential;
500
+ }
501
+ }
502
+ const statusListOpts = rest.statusLists?.length ? rest.statusLists : [];
503
+ logger2.info(`Adding new status using status list options with ID ${statusListOpts[0].statusListId ?? this.defaultStatusListId}`);
504
+ const firstOpt = statusListOpts[0];
505
+ const effectiveStatusListId = firstOpt.statusListId ?? this.defaultStatusListId;
506
+ if (!effectiveStatusListId) {
507
+ return Promise.reject(Error(`No status list ID provided and no default status list ID configured. Please provide a status list ID or configure a default status list ID in the agent configuration.`));
508
+ }
509
+ const driver = await this.getDriverForStatusListOption(effectiveStatusListId, firstOpt.statusListCorrelationId);
510
+ await handleSdJwtCredentialStatus(credential, {
511
+ ...rest,
512
+ statusLists: [
513
+ {
514
+ ...firstOpt,
515
+ statusListId: effectiveStatusListId
516
+ }
517
+ ],
518
+ driver
519
+ });
520
+ logger2.debug(`Successfully added status information to SD-JWT credential`);
521
+ return credential;
522
+ }
523
+ };
524
+ export {
525
+ StatusListPlugin
526
+ };
1
527
  //# sourceMappingURL=index.js.map