@sphereon/ssi-sdk.vc-status-list-issuer-drivers 0.32.1-next.54 → 0.33.1-feature.jose.vcdm.55
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 +316 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +114 -0
- package/dist/index.d.ts +114 -6
- package/dist/index.js +293 -20
- package/dist/index.js.map +1 -1
- package/package.json +30 -19
- package/src/drivers.ts +69 -33
- package/src/status-list-adapters.ts +38 -0
- package/src/types.ts +13 -6
- package/dist/drivers.d.ts +0 -74
- package/dist/drivers.d.ts.map +0 -1
- package/dist/drivers.js +0 -226
- package/dist/drivers.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/types.d.ts +0 -38
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js +0 -3
- package/dist/types.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,22 +1,295 @@
|
|
|
1
|
-
|
|
2
|
-
var
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
3
|
+
|
|
4
|
+
// src/drivers.ts
|
|
5
|
+
import { DataSources } from "@sphereon/ssi-sdk.agent-config";
|
|
6
|
+
import { StatusListStore } from "@sphereon/ssi-sdk.data-store";
|
|
7
|
+
import { statusListCredentialToDetails } from "@sphereon/ssi-sdk.vc-status-list";
|
|
8
|
+
import { StatusListCredentialIdMode, StatusListDriverType } from "@sphereon/ssi-types";
|
|
9
|
+
|
|
10
|
+
// src/status-list-adapters.ts
|
|
11
|
+
import { StatusListType } from "@sphereon/ssi-types";
|
|
12
|
+
import { OAuthStatusListEntity, StatusList2021Entity } from "@sphereon/ssi-sdk.data-store";
|
|
13
|
+
function statusListResultToEntity(result) {
|
|
14
|
+
const baseFields = {
|
|
15
|
+
id: result.id,
|
|
16
|
+
correlationId: result.correlationId,
|
|
17
|
+
driverType: result.driverType,
|
|
18
|
+
credentialIdMode: result.credentialIdMode,
|
|
19
|
+
length: result.length,
|
|
20
|
+
issuer: result.issuer,
|
|
21
|
+
type: result.type,
|
|
22
|
+
proofFormat: result.proofFormat,
|
|
23
|
+
statusListCredential: result.statusListCredential
|
|
24
|
+
};
|
|
25
|
+
if (result.type === StatusListType.StatusList2021) {
|
|
26
|
+
if (!result.statusList2021) {
|
|
27
|
+
throw new Error("Missing statusList2021 details");
|
|
28
|
+
}
|
|
29
|
+
return Object.assign(new StatusList2021Entity(), {
|
|
30
|
+
...baseFields,
|
|
31
|
+
indexingDirection: result.statusList2021.indexingDirection,
|
|
32
|
+
statusPurpose: result.statusList2021.statusPurpose
|
|
33
|
+
});
|
|
34
|
+
} else if (result.type === StatusListType.OAuthStatusList) {
|
|
35
|
+
if (!result.oauthStatusList) {
|
|
36
|
+
throw new Error("Missing oauthStatusList details");
|
|
37
|
+
}
|
|
38
|
+
return Object.assign(new OAuthStatusListEntity(), {
|
|
39
|
+
...baseFields,
|
|
40
|
+
bitsPerStatus: result.oauthStatusList.bitsPerStatus,
|
|
41
|
+
expiresAt: result.oauthStatusList.expiresAt
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
throw new Error(`Unsupported status list type: ${result.type}`);
|
|
45
|
+
}
|
|
46
|
+
__name(statusListResultToEntity, "statusListResultToEntity");
|
|
47
|
+
|
|
48
|
+
// src/drivers.ts
|
|
49
|
+
import { OAuthStatusListEntity as OAuthStatusListEntity2, StatusList2021Entity as StatusList2021Entity2 } from "@sphereon/ssi-sdk.data-store";
|
|
50
|
+
function getOptions(args) {
|
|
51
|
+
return {
|
|
52
|
+
id: args.id,
|
|
53
|
+
correlationId: args.correlationId,
|
|
54
|
+
driverType: StatusListDriverType.AGENT_TYPEORM,
|
|
55
|
+
driverOptions: {
|
|
56
|
+
dbName: args.dbName
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
__name(getOptions, "getOptions");
|
|
61
|
+
async function getDriver(args) {
|
|
62
|
+
const dbName = args.dbName ?? args.dataSource?.name;
|
|
63
|
+
if (!dbName) {
|
|
64
|
+
throw Error(`Please provide either a DB name or data source`);
|
|
65
|
+
}
|
|
66
|
+
const dataSources = args.dataSources ?? DataSources.singleInstance();
|
|
67
|
+
return await AgentDataSourceStatusListDriver.init(getOptions({
|
|
68
|
+
...args,
|
|
69
|
+
dbName
|
|
70
|
+
}), {
|
|
71
|
+
dataSource: args.dataSource ?? await dataSources.getDbConnection(dbName),
|
|
72
|
+
dataSources
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
__name(getDriver, "getDriver");
|
|
76
|
+
var AgentDataSourceStatusListDriver = class _AgentDataSourceStatusListDriver {
|
|
77
|
+
static {
|
|
78
|
+
__name(this, "AgentDataSourceStatusListDriver");
|
|
79
|
+
}
|
|
80
|
+
_dataSource;
|
|
81
|
+
_statusListStore;
|
|
82
|
+
options;
|
|
83
|
+
_statusListLength;
|
|
84
|
+
constructor(_dataSource, _statusListStore, options) {
|
|
85
|
+
this._dataSource = _dataSource;
|
|
86
|
+
this._statusListStore = _statusListStore;
|
|
87
|
+
this.options = options;
|
|
88
|
+
}
|
|
89
|
+
static async init(options, dbArgs) {
|
|
90
|
+
if (options.driverType !== StatusListDriverType.AGENT_TYPEORM) {
|
|
91
|
+
throw Error(`TypeORM driver can only be used when the TypeORM driver type is selected in the configuration. Got: ${options.driverType}`);
|
|
92
|
+
} else if (!options.driverOptions) {
|
|
93
|
+
throw Error(`TypeORM driver can only be used when the TypeORM options are provided.`);
|
|
94
|
+
}
|
|
95
|
+
let dataSource;
|
|
96
|
+
let statusListStore;
|
|
97
|
+
if (dbArgs?.dataSource) {
|
|
98
|
+
dataSource = dbArgs.dataSource;
|
|
99
|
+
} else if (options.driverOptions.dbName) {
|
|
100
|
+
if (dbArgs?.dataSources) {
|
|
101
|
+
dataSource = await dbArgs.dataSources.getDbConnection(options.driverOptions.dbName);
|
|
102
|
+
} else {
|
|
103
|
+
dataSource = await DataSources.singleInstance().getDbConnection(options.driverOptions.dbName);
|
|
104
|
+
}
|
|
105
|
+
} else {
|
|
106
|
+
return Promise.reject(Error(`Either a datasource or dbName needs to be provided`));
|
|
107
|
+
}
|
|
108
|
+
statusListStore = new StatusListStore(dataSource);
|
|
109
|
+
return new _AgentDataSourceStatusListDriver(dataSource, statusListStore, options);
|
|
110
|
+
}
|
|
111
|
+
get dataSource() {
|
|
112
|
+
if (!this._dataSource) {
|
|
113
|
+
throw Error(`Datasource not available yet for ${this.options.driverOptions?.dbName}`);
|
|
114
|
+
}
|
|
115
|
+
return this._dataSource;
|
|
116
|
+
}
|
|
117
|
+
get statusListStore() {
|
|
118
|
+
if (!this._statusListStore) {
|
|
119
|
+
this._statusListStore = new StatusListStore(this.dataSource);
|
|
120
|
+
}
|
|
121
|
+
return this._statusListStore;
|
|
122
|
+
}
|
|
123
|
+
getOptions() {
|
|
124
|
+
return this.options.driverOptions ?? {};
|
|
125
|
+
}
|
|
126
|
+
getType() {
|
|
127
|
+
return this.options.driverType;
|
|
128
|
+
}
|
|
129
|
+
async createStatusList(args) {
|
|
130
|
+
const correlationId = args.correlationId ?? this.options.correlationId;
|
|
131
|
+
if (!correlationId) {
|
|
132
|
+
throw Error("Either a correlationId needs to be set as an option, or it needs to be provided when creating a status list. None found");
|
|
133
|
+
}
|
|
134
|
+
const credentialIdMode = args.credentialIdMode ?? StatusListCredentialIdMode.ISSUANCE;
|
|
135
|
+
const details = await statusListCredentialToDetails({
|
|
136
|
+
...args,
|
|
137
|
+
correlationId,
|
|
138
|
+
driverType: this.getType()
|
|
139
|
+
});
|
|
140
|
+
await this.statusListStore.addStatusList({
|
|
141
|
+
...details,
|
|
142
|
+
credentialIdMode,
|
|
143
|
+
correlationId,
|
|
144
|
+
driverType: this.getType()
|
|
145
|
+
});
|
|
146
|
+
this._statusListLength = details.length;
|
|
147
|
+
return details;
|
|
148
|
+
}
|
|
149
|
+
async updateStatusList(args) {
|
|
150
|
+
const correlationId = args.correlationId ?? this.options.correlationId;
|
|
151
|
+
const details = await statusListCredentialToDetails({
|
|
152
|
+
...args,
|
|
153
|
+
correlationId,
|
|
154
|
+
driverType: this.getType()
|
|
155
|
+
});
|
|
156
|
+
const entity = await (await this.statusListStore.getStatusListRepo(args.type)).findOne({
|
|
157
|
+
where: [
|
|
158
|
+
{
|
|
159
|
+
id: details.id
|
|
160
|
+
},
|
|
161
|
+
{
|
|
162
|
+
correlationId
|
|
163
|
+
}
|
|
164
|
+
]
|
|
165
|
+
});
|
|
166
|
+
if (!entity) {
|
|
167
|
+
throw Error(`Status list ${details.id}, correlationId ${args.correlationId} could not be found`);
|
|
168
|
+
}
|
|
169
|
+
await this.statusListStore.updateStatusList({
|
|
170
|
+
...entity,
|
|
171
|
+
...details,
|
|
172
|
+
correlationId,
|
|
173
|
+
driverType: this.getType()
|
|
174
|
+
});
|
|
175
|
+
this._statusListLength = details.length;
|
|
176
|
+
return {
|
|
177
|
+
...entity,
|
|
178
|
+
...details
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
async deleteStatusList() {
|
|
182
|
+
await this.statusListStore.removeStatusList({
|
|
183
|
+
id: this.options.id,
|
|
184
|
+
correlationId: this.options.correlationId
|
|
185
|
+
});
|
|
186
|
+
return Promise.resolve(true);
|
|
187
|
+
}
|
|
188
|
+
isStatusList2021Entity(statusList) {
|
|
189
|
+
return statusList instanceof StatusList2021Entity2;
|
|
190
|
+
}
|
|
191
|
+
isOAuthStatusListEntity(statusList) {
|
|
192
|
+
return statusList instanceof OAuthStatusListEntity2;
|
|
193
|
+
}
|
|
194
|
+
async updateStatusListEntry(args) {
|
|
195
|
+
const statusList = args.statusList ? args.statusList : statusListResultToEntity(await this.getStatusList());
|
|
196
|
+
const statusListEntry = await this.statusListStore.updateStatusListEntry({
|
|
197
|
+
...args,
|
|
198
|
+
statusListId: statusList.id
|
|
199
|
+
});
|
|
200
|
+
if (this.isStatusList2021Entity(statusList)) {
|
|
201
|
+
return {
|
|
202
|
+
credentialStatus: {
|
|
203
|
+
id: `${statusList.id}#${statusListEntry.statusListIndex}`,
|
|
204
|
+
type: "StatusList2021Entry",
|
|
205
|
+
statusPurpose: statusList.statusPurpose ?? "revocation",
|
|
206
|
+
statusListIndex: "" + statusListEntry.statusListIndex,
|
|
207
|
+
statusListCredential: statusList.id
|
|
208
|
+
},
|
|
209
|
+
statusListEntry
|
|
210
|
+
};
|
|
211
|
+
} else if (this.isOAuthStatusListEntity(statusList)) {
|
|
212
|
+
return {
|
|
213
|
+
credentialStatus: {
|
|
214
|
+
id: `${statusList.id}#${statusListEntry.statusListIndex}`,
|
|
215
|
+
type: "OAuthStatusListEntry",
|
|
216
|
+
bitsPerStatus: statusList.bitsPerStatus,
|
|
217
|
+
statusListIndex: "" + statusListEntry.statusListIndex,
|
|
218
|
+
statusListCredential: statusList.id,
|
|
219
|
+
expiresAt: statusList.expiresAt
|
|
220
|
+
},
|
|
221
|
+
statusListEntry
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
throw new Error(`Unsupported status list type: ${typeof statusList}`);
|
|
225
|
+
}
|
|
226
|
+
async getStatusListEntryByCredentialId(args) {
|
|
227
|
+
return await this.statusListStore.getStatusListEntryByCredentialId(args);
|
|
228
|
+
}
|
|
229
|
+
async getStatusListEntryByIndex(args) {
|
|
230
|
+
return await this.statusListStore.getStatusListEntryByIndex(args);
|
|
231
|
+
}
|
|
232
|
+
async getRandomNewStatusListIndex(args) {
|
|
233
|
+
let result = -1;
|
|
234
|
+
let tries = 0;
|
|
235
|
+
while (result < 0) {
|
|
236
|
+
result = await this.getRandomNewStatusListIndexImpl(tries++, args);
|
|
237
|
+
}
|
|
238
|
+
return result;
|
|
239
|
+
}
|
|
240
|
+
async getRandomNewStatusListIndexImpl(tries, args) {
|
|
241
|
+
const statusListId = this.options.id;
|
|
242
|
+
const correlationId = args?.correlationId ?? this.options.correlationId;
|
|
243
|
+
if (tries >= 10) {
|
|
244
|
+
throw Error(`We could not find any random status list index that is available in the statuslist ${statusListId}`);
|
|
245
|
+
}
|
|
246
|
+
const length = await this.getStatusListLength(args);
|
|
247
|
+
const statusListIndex = Array.from({
|
|
248
|
+
length: 20
|
|
249
|
+
}, () => Math.floor(Math.random() * length));
|
|
250
|
+
const available = await this.statusListStore.availableStatusListEntries({
|
|
251
|
+
statusListId,
|
|
252
|
+
...correlationId && {
|
|
253
|
+
correlationId
|
|
254
|
+
},
|
|
255
|
+
statusListIndex
|
|
256
|
+
});
|
|
257
|
+
if (available.length > 0) {
|
|
258
|
+
return available[0];
|
|
259
|
+
}
|
|
260
|
+
return -1;
|
|
261
|
+
}
|
|
262
|
+
async getStatusListLength(args) {
|
|
263
|
+
if (!this._statusListLength) {
|
|
264
|
+
this._statusListLength = await this.getStatusList(args).then((details) => details.length);
|
|
265
|
+
}
|
|
266
|
+
return this._statusListLength;
|
|
267
|
+
}
|
|
268
|
+
async getStatusList(args) {
|
|
269
|
+
const id = this.options.id;
|
|
270
|
+
const correlationId = args?.correlationId ?? this.options.correlationId;
|
|
271
|
+
return await this.statusListStore.getStatusList({
|
|
272
|
+
id,
|
|
273
|
+
correlationId
|
|
274
|
+
}).then((statusListEntity) => statusListCredentialToDetails({
|
|
275
|
+
statusListCredential: statusListEntity.statusListCredential
|
|
276
|
+
}));
|
|
277
|
+
}
|
|
278
|
+
async getStatusLists() {
|
|
279
|
+
const statusLists = await this.statusListStore.getStatusLists({});
|
|
280
|
+
return Promise.all(statusLists.map(async (statusListEntity) => {
|
|
281
|
+
return statusListCredentialToDetails({
|
|
282
|
+
statusListCredential: statusListEntity.statusListCredential
|
|
283
|
+
});
|
|
284
|
+
}));
|
|
285
|
+
}
|
|
286
|
+
isStatusListIndexInUse() {
|
|
287
|
+
return Promise.resolve(false);
|
|
288
|
+
}
|
|
289
|
+
};
|
|
290
|
+
export {
|
|
291
|
+
AgentDataSourceStatusListDriver,
|
|
292
|
+
getDriver,
|
|
293
|
+
getOptions
|
|
15
294
|
};
|
|
16
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
/**
|
|
18
|
-
* @public
|
|
19
|
-
*/
|
|
20
|
-
__exportStar(require("./types"), exports);
|
|
21
|
-
__exportStar(require("./drivers"), exports);
|
|
22
295
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA;;GAEG;AACH,0CAAuB;AACvB,4CAAyB"}
|
|
1
|
+
{"version":3,"sources":["../src/drivers.ts","../src/status-list-adapters.ts"],"sourcesContent":["import { DataSources } from '@sphereon/ssi-sdk.agent-config'\nimport {\n IAddStatusListEntryArgs,\n IGetStatusListEntryByCredentialIdArgs,\n IGetStatusListEntryByIndexArgs,\n IStatusListEntity,\n IStatusListEntryEntity,\n StatusListEntity,\n StatusListStore,\n} from '@sphereon/ssi-sdk.data-store'\nimport {\n StatusList2021EntryCredentialStatus,\n statusListCredentialToDetails,\n StatusListOAuthEntryCredentialStatus,\n StatusListResult,\n} from '@sphereon/ssi-sdk.vc-status-list'\nimport { StatusListCredentialIdMode, StatusListDriverType, StatusListType, StatusListCredential } from '@sphereon/ssi-types'\nimport { DataSource } from 'typeorm'\nimport { IStatusListDriver } from './types'\nimport { statusListResultToEntity } from './status-list-adapters'\nimport { OAuthStatusListEntity, StatusList2021Entity } from '@sphereon/ssi-sdk.data-store'\n\nexport interface StatusListManagementOptions {\n id?: string\n correlationId?: string\n driverType: StatusListDriverType\n driverOptions?: DriverOptions\n}\n\nexport type DriverOptions = TypeORMOptions\n\nexport interface TypeORMOptions {\n dbName?: string\n}\n\nexport interface FilesystemOptions {\n path: string // The base path where statusList Credentials will be persisted. Should be a folder and thus not include the VC/StatusList itself\n}\n\nexport function getOptions(args: { id?: string; correlationId?: string; dbName: string }): StatusListManagementOptions {\n return {\n id: args.id,\n correlationId: args.correlationId,\n driverType: StatusListDriverType.AGENT_TYPEORM,\n driverOptions: { dbName: args.dbName },\n }\n}\n\nexport async function getDriver(args: {\n id?: string\n correlationId?: string\n dbName?: string\n dataSource?: DataSource\n dataSources?: DataSources\n}): Promise<IStatusListDriver> {\n const dbName = args.dbName ?? args.dataSource?.name\n if (!dbName) {\n throw Error(`Please provide either a DB name or data source`)\n }\n const dataSources = args.dataSources ?? DataSources.singleInstance()\n return await AgentDataSourceStatusListDriver.init(\n getOptions({\n ...args,\n dbName,\n }),\n { dataSource: args.dataSource ?? (await dataSources.getDbConnection(dbName)), dataSources },\n )\n}\n\nexport class AgentDataSourceStatusListDriver implements IStatusListDriver {\n private _statusListLength: number | undefined\n\n constructor(\n private _dataSource: DataSource,\n private _statusListStore: StatusListStore,\n private options: StatusListManagementOptions,\n ) {}\n\n public static async init(\n options: StatusListManagementOptions,\n dbArgs?: {\n dataSources?: DataSources\n dataSource?: DataSource\n },\n ): Promise<AgentDataSourceStatusListDriver> {\n if (options.driverType !== StatusListDriverType.AGENT_TYPEORM) {\n throw Error(`TypeORM driver can only be used when the TypeORM driver type is selected in the configuration. Got: ${options.driverType}`)\n } else if (!options.driverOptions) {\n throw Error(`TypeORM driver can only be used when the TypeORM options are provided.`)\n }\n let dataSource: DataSource\n let statusListStore: StatusListStore\n if (dbArgs?.dataSource) {\n dataSource = dbArgs.dataSource\n } else if (options.driverOptions.dbName) {\n if (dbArgs?.dataSources) {\n dataSource = await dbArgs.dataSources.getDbConnection(options.driverOptions.dbName)\n } else {\n dataSource = await DataSources.singleInstance().getDbConnection(options.driverOptions.dbName)\n }\n } else {\n return Promise.reject(Error(`Either a datasource or dbName needs to be provided`))\n }\n\n statusListStore = new StatusListStore(dataSource)\n return new AgentDataSourceStatusListDriver(dataSource, statusListStore, options)\n }\n\n get dataSource(): DataSource {\n if (!this._dataSource) {\n throw Error(`Datasource not available yet for ${this.options.driverOptions?.dbName}`)\n }\n return this._dataSource\n }\n\n get statusListStore(): StatusListStore {\n if (!this._statusListStore) {\n this._statusListStore = new StatusListStore(this.dataSource)\n }\n return this._statusListStore\n }\n\n getOptions(): DriverOptions {\n return this.options.driverOptions ?? {}\n }\n\n getType(): StatusListDriverType {\n return this.options.driverType\n }\n\n async createStatusList(args: {\n statusListCredential: StatusListCredential\n correlationId?: string\n credentialIdMode?: StatusListCredentialIdMode\n }): Promise<StatusListResult> {\n const correlationId = args.correlationId ?? this.options.correlationId\n if (!correlationId) {\n throw Error('Either a correlationId needs to be set as an option, or it needs to be provided when creating a status list. None found')\n }\n const credentialIdMode = args.credentialIdMode ?? StatusListCredentialIdMode.ISSUANCE\n const details = await statusListCredentialToDetails({ ...args, correlationId, driverType: this.getType() })\n\n // (StatusListStore does the duplicate entity check)\n await this.statusListStore.addStatusList({\n ...details,\n credentialIdMode,\n correlationId,\n driverType: this.getType(),\n })\n this._statusListLength = details.length\n return details\n }\n\n async updateStatusList(args: {\n statusListCredential: StatusListCredential\n correlationId: string\n type: StatusListType\n }): Promise<StatusListResult> {\n const correlationId = args.correlationId ?? this.options.correlationId\n const details = await statusListCredentialToDetails({ ...args, correlationId, driverType: this.getType() })\n const entity = await (\n await this.statusListStore.getStatusListRepo(args.type)\n ).findOne({\n where: [\n {\n id: details.id,\n },\n {\n correlationId,\n },\n ],\n })\n if (!entity) {\n throw Error(`Status list ${details.id}, correlationId ${args.correlationId} could not be found`)\n }\n await this.statusListStore.updateStatusList({\n ...entity,\n ...details,\n correlationId,\n driverType: this.getType(),\n })\n this._statusListLength = details.length\n return { ...entity, ...details }\n }\n\n async deleteStatusList(): Promise<boolean> {\n await this.statusListStore.removeStatusList({ id: this.options.id, correlationId: this.options.correlationId })\n return Promise.resolve(true)\n }\n\n private isStatusList2021Entity(statusList: StatusListEntity): statusList is StatusList2021Entity {\n return statusList instanceof StatusList2021Entity\n }\n\n private isOAuthStatusListEntity(statusList: StatusListEntity): statusList is OAuthStatusListEntity {\n return statusList instanceof OAuthStatusListEntity\n }\n\n async updateStatusListEntry(args: IAddStatusListEntryArgs): Promise<{\n credentialStatus: StatusList2021EntryCredentialStatus | StatusListOAuthEntryCredentialStatus\n statusListEntry: IStatusListEntryEntity\n }> {\n const statusList: StatusListEntity = args.statusList ? args.statusList : statusListResultToEntity(await this.getStatusList())\n const statusListEntry = await this.statusListStore.updateStatusListEntry({ ...args, statusListId: statusList.id })\n\n if (this.isStatusList2021Entity(statusList)) {\n return {\n credentialStatus: {\n id: `${statusList.id}#${statusListEntry.statusListIndex}`,\n type: 'StatusList2021Entry',\n statusPurpose: statusList.statusPurpose ?? 'revocation',\n statusListIndex: '' + statusListEntry.statusListIndex,\n statusListCredential: statusList.id,\n },\n statusListEntry,\n }\n } else if (this.isOAuthStatusListEntity(statusList)) {\n return {\n credentialStatus: {\n id: `${statusList.id}#${statusListEntry.statusListIndex}`,\n type: 'OAuthStatusListEntry',\n bitsPerStatus: statusList.bitsPerStatus,\n statusListIndex: '' + statusListEntry.statusListIndex,\n statusListCredential: statusList.id,\n expiresAt: statusList.expiresAt,\n },\n statusListEntry,\n }\n }\n\n throw new Error(`Unsupported status list type: ${typeof statusList}`)\n }\n\n async getStatusListEntryByCredentialId(args: IGetStatusListEntryByCredentialIdArgs): Promise<IStatusListEntryEntity | undefined> {\n return await this.statusListStore.getStatusListEntryByCredentialId(args)\n }\n\n async getStatusListEntryByIndex(args: IGetStatusListEntryByIndexArgs): Promise<IStatusListEntryEntity | undefined> {\n return await this.statusListStore.getStatusListEntryByIndex(args)\n }\n\n async getRandomNewStatusListIndex(args?: { correlationId?: string }): Promise<number> {\n let result = -1\n let tries = 0\n while (result < 0) {\n // no tries guard, because we will throw an error when they are exhausted anyway\n result = await this.getRandomNewStatusListIndexImpl(tries++, args)\n }\n return result\n }\n\n private async getRandomNewStatusListIndexImpl(tries: number, args?: { correlationId?: string }): Promise<number> {\n const statusListId = this.options.id\n const correlationId = args?.correlationId ?? this.options.correlationId\n if (tries >= 10) {\n throw Error(`We could not find any random status list index that is available in the statuslist ${statusListId}`)\n }\n // TODO: Check against DB\n const length = await this.getStatusListLength(args)\n const statusListIndex = Array.from({ length: 20 }, () => Math.floor(Math.random() * length))\n const available = await this.statusListStore.availableStatusListEntries({\n statusListId,\n ...(correlationId && { correlationId }),\n statusListIndex,\n })\n if (available.length > 0) {\n return available[0] // doesn't matter we pick the first element, as they are all random anyway\n }\n return -1\n }\n\n async getStatusListLength(args?: { correlationId?: string }): Promise<number> {\n if (!this._statusListLength) {\n this._statusListLength = await this.getStatusList(args).then((details) => details.length)\n }\n return this._statusListLength!\n }\n\n async getStatusList(args?: { correlationId?: string }): Promise<StatusListResult> {\n const id = this.options.id\n const correlationId = args?.correlationId ?? this.options.correlationId\n return await this.statusListStore\n .getStatusList({ id, correlationId })\n .then((statusListEntity: IStatusListEntity) => statusListCredentialToDetails({ statusListCredential: statusListEntity.statusListCredential! }))\n }\n\n async getStatusLists(): Promise<Array<StatusListResult>> {\n const statusLists = await this.statusListStore.getStatusLists({})\n return Promise.all(\n statusLists.map(async (statusListEntity) => {\n return statusListCredentialToDetails({\n statusListCredential: statusListEntity.statusListCredential!,\n })\n }),\n )\n }\n\n isStatusListIndexInUse(): Promise<boolean> {\n return Promise.resolve(false)\n }\n}\n","import { StatusListType } from '@sphereon/ssi-types'\nimport { OAuthStatusListEntity, StatusList2021Entity } from '@sphereon/ssi-sdk.data-store'\nimport { StatusListResult } from '@sphereon/ssi-sdk.vc-status-list'\n\nexport function statusListResultToEntity(result: StatusListResult): StatusList2021Entity | OAuthStatusListEntity {\n const baseFields = {\n id: result.id,\n correlationId: result.correlationId,\n driverType: result.driverType,\n credentialIdMode: result.credentialIdMode,\n length: result.length,\n issuer: result.issuer,\n type: result.type,\n proofFormat: result.proofFormat,\n statusListCredential: result.statusListCredential,\n }\n\n if (result.type === StatusListType.StatusList2021) {\n if (!result.statusList2021) {\n throw new Error('Missing statusList2021 details')\n }\n return Object.assign(new StatusList2021Entity(), {\n ...baseFields,\n indexingDirection: result.statusList2021.indexingDirection,\n statusPurpose: result.statusList2021.statusPurpose,\n })\n } else if (result.type === StatusListType.OAuthStatusList) {\n if (!result.oauthStatusList) {\n throw new Error('Missing oauthStatusList details')\n }\n return Object.assign(new OAuthStatusListEntity(), {\n ...baseFields,\n bitsPerStatus: result.oauthStatusList.bitsPerStatus,\n expiresAt: result.oauthStatusList.expiresAt,\n })\n }\n throw new Error(`Unsupported status list type: ${result.type}`)\n}\n"],"mappings":";;;;AAAA,SAASA,mBAAmB;AAC5B,SAOEC,uBACK;AACP,SAEEC,qCAGK;AACP,SAASC,4BAA4BC,4BAAkE;;;AChBvG,SAASC,sBAAsB;AAC/B,SAASC,uBAAuBC,4BAA4B;AAGrD,SAASC,yBAAyBC,QAAwB;AAC/D,QAAMC,aAAa;IACjBC,IAAIF,OAAOE;IACXC,eAAeH,OAAOG;IACtBC,YAAYJ,OAAOI;IACnBC,kBAAkBL,OAAOK;IACzBC,QAAQN,OAAOM;IACfC,QAAQP,OAAOO;IACfC,MAAMR,OAAOQ;IACbC,aAAaT,OAAOS;IACpBC,sBAAsBV,OAAOU;EAC/B;AAEA,MAAIV,OAAOQ,SAASG,eAAeC,gBAAgB;AACjD,QAAI,CAACZ,OAAOa,gBAAgB;AAC1B,YAAM,IAAIC,MAAM,gCAAA;IAClB;AACA,WAAOC,OAAOC,OAAO,IAAIC,qBAAAA,GAAwB;MAC/C,GAAGhB;MACHiB,mBAAmBlB,OAAOa,eAAeK;MACzCC,eAAenB,OAAOa,eAAeM;IACvC,CAAA;EACF,WAAWnB,OAAOQ,SAASG,eAAeS,iBAAiB;AACzD,QAAI,CAACpB,OAAOqB,iBAAiB;AAC3B,YAAM,IAAIP,MAAM,iCAAA;IAClB;AACA,WAAOC,OAAOC,OAAO,IAAIM,sBAAAA,GAAyB;MAChD,GAAGrB;MACHsB,eAAevB,OAAOqB,gBAAgBE;MACtCC,WAAWxB,OAAOqB,gBAAgBG;IACpC,CAAA;EACF;AACA,QAAM,IAAIV,MAAM,iCAAiCd,OAAOQ,IAAI,EAAE;AAChE;AAjCgBT;;;ADgBhB,SAAS0B,yBAAAA,wBAAuBC,wBAAAA,6BAA4B;AAmBrD,SAASC,WAAWC,MAA6D;AACtF,SAAO;IACLC,IAAID,KAAKC;IACTC,eAAeF,KAAKE;IACpBC,YAAYC,qBAAqBC;IACjCC,eAAe;MAAEC,QAAQP,KAAKO;IAAO;EACvC;AACF;AAPgBR;AAShB,eAAsBS,UAAUR,MAM/B;AACC,QAAMO,SAASP,KAAKO,UAAUP,KAAKS,YAAYC;AAC/C,MAAI,CAACH,QAAQ;AACX,UAAMI,MAAM,gDAAgD;EAC9D;AACA,QAAMC,cAAcZ,KAAKY,eAAeC,YAAYC,eAAc;AAClE,SAAO,MAAMC,gCAAgCC,KAC3CjB,WAAW;IACT,GAAGC;IACHO;EACF,CAAA,GACA;IAAEE,YAAYT,KAAKS,cAAe,MAAMG,YAAYK,gBAAgBV,MAAAA;IAAUK;EAAY,CAAA;AAE9F;AAnBsBJ;AAqBf,IAAMO,kCAAN,MAAMA,iCAAAA;EArEb,OAqEaA;;;;;;EACHG;EAERC,YACUC,aACAC,kBACAC,SACR;SAHQF,cAAAA;SACAC,mBAAAA;SACAC,UAAAA;EACP;EAEH,aAAoBN,KAClBM,SACAC,QAI0C;AAC1C,QAAID,QAAQnB,eAAeC,qBAAqBC,eAAe;AAC7D,YAAMM,MAAM,uGAAuGW,QAAQnB,UAAU,EAAE;IACzI,WAAW,CAACmB,QAAQhB,eAAe;AACjC,YAAMK,MAAM,wEAAwE;IACtF;AACA,QAAIF;AACJ,QAAIe;AACJ,QAAID,QAAQd,YAAY;AACtBA,mBAAac,OAAOd;IACtB,WAAWa,QAAQhB,cAAcC,QAAQ;AACvC,UAAIgB,QAAQX,aAAa;AACvBH,qBAAa,MAAMc,OAAOX,YAAYK,gBAAgBK,QAAQhB,cAAcC,MAAM;MACpF,OAAO;AACLE,qBAAa,MAAMI,YAAYC,eAAc,EAAGG,gBAAgBK,QAAQhB,cAAcC,MAAM;MAC9F;IACF,OAAO;AACL,aAAOkB,QAAQC,OAAOf,MAAM,oDAAoD,CAAA;IAClF;AAEAa,sBAAkB,IAAIG,gBAAgBlB,UAAAA;AACtC,WAAO,IAAIM,iCAAgCN,YAAYe,iBAAiBF,OAAAA;EAC1E;EAEA,IAAIb,aAAyB;AAC3B,QAAI,CAAC,KAAKW,aAAa;AACrB,YAAMT,MAAM,oCAAoC,KAAKW,QAAQhB,eAAeC,MAAAA,EAAQ;IACtF;AACA,WAAO,KAAKa;EACd;EAEA,IAAII,kBAAmC;AACrC,QAAI,CAAC,KAAKH,kBAAkB;AAC1B,WAAKA,mBAAmB,IAAIM,gBAAgB,KAAKlB,UAAU;IAC7D;AACA,WAAO,KAAKY;EACd;EAEAtB,aAA4B;AAC1B,WAAO,KAAKuB,QAAQhB,iBAAiB,CAAC;EACxC;EAEAsB,UAAgC;AAC9B,WAAO,KAAKN,QAAQnB;EACtB;EAEA,MAAM0B,iBAAiB7B,MAIO;AAC5B,UAAME,gBAAgBF,KAAKE,iBAAiB,KAAKoB,QAAQpB;AACzD,QAAI,CAACA,eAAe;AAClB,YAAMS,MAAM,yHAAA;IACd;AACA,UAAMmB,mBAAmB9B,KAAK8B,oBAAoBC,2BAA2BC;AAC7E,UAAMC,UAAU,MAAMC,8BAA8B;MAAE,GAAGlC;MAAME;MAAeC,YAAY,KAAKyB,QAAO;IAAG,CAAA;AAGzG,UAAM,KAAKJ,gBAAgBW,cAAc;MACvC,GAAGF;MACHH;MACA5B;MACAC,YAAY,KAAKyB,QAAO;IAC1B,CAAA;AACA,SAAKV,oBAAoBe,QAAQG;AACjC,WAAOH;EACT;EAEA,MAAMI,iBAAiBrC,MAIO;AAC5B,UAAME,gBAAgBF,KAAKE,iBAAiB,KAAKoB,QAAQpB;AACzD,UAAM+B,UAAU,MAAMC,8BAA8B;MAAE,GAAGlC;MAAME;MAAeC,YAAY,KAAKyB,QAAO;IAAG,CAAA;AACzG,UAAMU,SAAS,OACb,MAAM,KAAKd,gBAAgBe,kBAAkBvC,KAAKwC,IAAI,GACtDC,QAAQ;MACRC,OAAO;QACL;UACEzC,IAAIgC,QAAQhC;QACd;QACA;UACEC;QACF;;IAEJ,CAAA;AACA,QAAI,CAACoC,QAAQ;AACX,YAAM3B,MAAM,eAAesB,QAAQhC,EAAE,mBAAmBD,KAAKE,aAAa,qBAAqB;IACjG;AACA,UAAM,KAAKsB,gBAAgBa,iBAAiB;MAC1C,GAAGC;MACH,GAAGL;MACH/B;MACAC,YAAY,KAAKyB,QAAO;IAC1B,CAAA;AACA,SAAKV,oBAAoBe,QAAQG;AACjC,WAAO;MAAE,GAAGE;MAAQ,GAAGL;IAAQ;EACjC;EAEA,MAAMU,mBAAqC;AACzC,UAAM,KAAKnB,gBAAgBoB,iBAAiB;MAAE3C,IAAI,KAAKqB,QAAQrB;MAAIC,eAAe,KAAKoB,QAAQpB;IAAc,CAAA;AAC7G,WAAOuB,QAAQoB,QAAQ,IAAA;EACzB;EAEQC,uBAAuBC,YAAkE;AAC/F,WAAOA,sBAAsBC;EAC/B;EAEQC,wBAAwBF,YAAmE;AACjG,WAAOA,sBAAsBG;EAC/B;EAEA,MAAMC,sBAAsBnD,MAGzB;AACD,UAAM+C,aAA+B/C,KAAK+C,aAAa/C,KAAK+C,aAAaK,yBAAyB,MAAM,KAAKC,cAAa,CAAA;AAC1H,UAAMC,kBAAkB,MAAM,KAAK9B,gBAAgB2B,sBAAsB;MAAE,GAAGnD;MAAMuD,cAAcR,WAAW9C;IAAG,CAAA;AAEhH,QAAI,KAAK6C,uBAAuBC,UAAAA,GAAa;AAC3C,aAAO;QACLS,kBAAkB;UAChBvD,IAAI,GAAG8C,WAAW9C,EAAE,IAAIqD,gBAAgBG,eAAe;UACvDjB,MAAM;UACNkB,eAAeX,WAAWW,iBAAiB;UAC3CD,iBAAiB,KAAKH,gBAAgBG;UACtCE,sBAAsBZ,WAAW9C;QACnC;QACAqD;MACF;IACF,WAAW,KAAKL,wBAAwBF,UAAAA,GAAa;AACnD,aAAO;QACLS,kBAAkB;UAChBvD,IAAI,GAAG8C,WAAW9C,EAAE,IAAIqD,gBAAgBG,eAAe;UACvDjB,MAAM;UACNoB,eAAeb,WAAWa;UAC1BH,iBAAiB,KAAKH,gBAAgBG;UACtCE,sBAAsBZ,WAAW9C;UACjC4D,WAAWd,WAAWc;QACxB;QACAP;MACF;IACF;AAEA,UAAM,IAAI3C,MAAM,iCAAiC,OAAOoC,UAAAA,EAAY;EACtE;EAEA,MAAMe,iCAAiC9D,MAA0F;AAC/H,WAAO,MAAM,KAAKwB,gBAAgBsC,iCAAiC9D,IAAAA;EACrE;EAEA,MAAM+D,0BAA0B/D,MAAmF;AACjH,WAAO,MAAM,KAAKwB,gBAAgBuC,0BAA0B/D,IAAAA;EAC9D;EAEA,MAAMgE,4BAA4BhE,MAAoD;AACpF,QAAIiE,SAAS;AACb,QAAIC,QAAQ;AACZ,WAAOD,SAAS,GAAG;AAEjBA,eAAS,MAAM,KAAKE,gCAAgCD,SAASlE,IAAAA;IAC/D;AACA,WAAOiE;EACT;EAEA,MAAcE,gCAAgCD,OAAelE,MAAoD;AAC/G,UAAMuD,eAAe,KAAKjC,QAAQrB;AAClC,UAAMC,gBAAgBF,MAAME,iBAAiB,KAAKoB,QAAQpB;AAC1D,QAAIgE,SAAS,IAAI;AACf,YAAMvD,MAAM,sFAAsF4C,YAAAA,EAAc;IAClH;AAEA,UAAMnB,SAAS,MAAM,KAAKgC,oBAAoBpE,IAAAA;AAC9C,UAAMyD,kBAAkBY,MAAMC,KAAK;MAAElC,QAAQ;IAAG,GAAG,MAAMmC,KAAKC,MAAMD,KAAKE,OAAM,IAAKrC,MAAAA,CAAAA;AACpF,UAAMsC,YAAY,MAAM,KAAKlD,gBAAgBmD,2BAA2B;MACtEpB;MACA,GAAIrD,iBAAiB;QAAEA;MAAc;MACrCuD;IACF,CAAA;AACA,QAAIiB,UAAUtC,SAAS,GAAG;AACxB,aAAOsC,UAAU,CAAA;IACnB;AACA,WAAO;EACT;EAEA,MAAMN,oBAAoBpE,MAAoD;AAC5E,QAAI,CAAC,KAAKkB,mBAAmB;AAC3B,WAAKA,oBAAoB,MAAM,KAAKmC,cAAcrD,IAAAA,EAAM4E,KAAK,CAAC3C,YAAYA,QAAQG,MAAM;IAC1F;AACA,WAAO,KAAKlB;EACd;EAEA,MAAMmC,cAAcrD,MAA8D;AAChF,UAAMC,KAAK,KAAKqB,QAAQrB;AACxB,UAAMC,gBAAgBF,MAAME,iBAAiB,KAAKoB,QAAQpB;AAC1D,WAAO,MAAM,KAAKsB,gBACf6B,cAAc;MAAEpD;MAAIC;IAAc,CAAA,EAClC0E,KAAK,CAACC,qBAAwC3C,8BAA8B;MAAEyB,sBAAsBkB,iBAAiBlB;IAAsB,CAAA,CAAA;EAChJ;EAEA,MAAMmB,iBAAmD;AACvD,UAAMC,cAAc,MAAM,KAAKvD,gBAAgBsD,eAAe,CAAC,CAAA;AAC/D,WAAOrD,QAAQuD,IACbD,YAAYE,IAAI,OAAOJ,qBAAAA;AACrB,aAAO3C,8BAA8B;QACnCyB,sBAAsBkB,iBAAiBlB;MACzC,CAAA;IACF,CAAA,CAAA;EAEJ;EAEAuB,yBAA2C;AACzC,WAAOzD,QAAQoB,QAAQ,KAAA;EACzB;AACF;","names":["DataSources","StatusListStore","statusListCredentialToDetails","StatusListCredentialIdMode","StatusListDriverType","StatusListType","OAuthStatusListEntity","StatusList2021Entity","statusListResultToEntity","result","baseFields","id","correlationId","driverType","credentialIdMode","length","issuer","type","proofFormat","statusListCredential","StatusListType","StatusList2021","statusList2021","Error","Object","assign","StatusList2021Entity","indexingDirection","statusPurpose","OAuthStatusList","oauthStatusList","OAuthStatusListEntity","bitsPerStatus","expiresAt","OAuthStatusListEntity","StatusList2021Entity","getOptions","args","id","correlationId","driverType","StatusListDriverType","AGENT_TYPEORM","driverOptions","dbName","getDriver","dataSource","name","Error","dataSources","DataSources","singleInstance","AgentDataSourceStatusListDriver","init","getDbConnection","_statusListLength","constructor","_dataSource","_statusListStore","options","dbArgs","statusListStore","Promise","reject","StatusListStore","getType","createStatusList","credentialIdMode","StatusListCredentialIdMode","ISSUANCE","details","statusListCredentialToDetails","addStatusList","length","updateStatusList","entity","getStatusListRepo","type","findOne","where","deleteStatusList","removeStatusList","resolve","isStatusList2021Entity","statusList","StatusList2021Entity","isOAuthStatusListEntity","OAuthStatusListEntity","updateStatusListEntry","statusListResultToEntity","getStatusList","statusListEntry","statusListId","credentialStatus","statusListIndex","statusPurpose","statusListCredential","bitsPerStatus","expiresAt","getStatusListEntryByCredentialId","getStatusListEntryByIndex","getRandomNewStatusListIndex","result","tries","getRandomNewStatusListIndexImpl","getStatusListLength","Array","from","Math","floor","random","available","availableStatusListEntries","then","statusListEntity","getStatusLists","statusLists","all","map","isStatusListIndexInUse"]}
|
package/package.json
CHANGED
|
@@ -1,38 +1,50 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sphereon/ssi-sdk.vc-status-list-issuer-drivers",
|
|
3
3
|
"description": "Sphereon SSI-SDK plugin for Status List management, like StatusList2021. Issuer drivers module",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.33.1-feature.jose.vcdm.55+6f02f6f8",
|
|
5
5
|
"source": "src/index.ts",
|
|
6
|
-
"
|
|
7
|
-
"
|
|
6
|
+
"type": "module",
|
|
7
|
+
"main": "./dist/index.cjs",
|
|
8
|
+
"module": "./dist/index.js",
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
|
+
"exports": {
|
|
11
|
+
"react-native": "./dist/index.js",
|
|
12
|
+
"import": {
|
|
13
|
+
"types": "./dist/index.d.ts",
|
|
14
|
+
"import": "./dist/index.js"
|
|
15
|
+
},
|
|
16
|
+
"require": {
|
|
17
|
+
"types": "./dist/index.d.cts",
|
|
18
|
+
"require": "./dist/index.cjs"
|
|
19
|
+
}
|
|
20
|
+
},
|
|
8
21
|
"scripts": {
|
|
9
|
-
"build": "
|
|
10
|
-
"build:clean": "tsc --build --clean && tsc --build"
|
|
22
|
+
"build": "tsup --config ../../tsup.config.ts --tsconfig ../../tsconfig.tsup.json"
|
|
11
23
|
},
|
|
12
24
|
"dependencies": {
|
|
13
|
-
"@sphereon/ssi-express-support": "0.
|
|
14
|
-
"@sphereon/ssi-sdk-ext.did-utils": "0.
|
|
15
|
-
"@sphereon/ssi-sdk-ext.identifier-resolution": "0.
|
|
16
|
-
"@sphereon/ssi-sdk.agent-config": "0.
|
|
17
|
-
"@sphereon/ssi-sdk.core": "0.
|
|
18
|
-
"@sphereon/ssi-sdk.data-store": "0.
|
|
19
|
-
"@sphereon/ssi-sdk.vc-status-list": "0.
|
|
20
|
-
"@sphereon/ssi-types": "0.
|
|
25
|
+
"@sphereon/ssi-express-support": "0.33.1-feature.jose.vcdm.55+6f02f6f8",
|
|
26
|
+
"@sphereon/ssi-sdk-ext.did-utils": "0.28.1-feature.esm.cjs.18",
|
|
27
|
+
"@sphereon/ssi-sdk-ext.identifier-resolution": "0.28.1-feature.esm.cjs.18",
|
|
28
|
+
"@sphereon/ssi-sdk.agent-config": "0.33.1-feature.jose.vcdm.55+6f02f6f8",
|
|
29
|
+
"@sphereon/ssi-sdk.core": "0.33.1-feature.jose.vcdm.55+6f02f6f8",
|
|
30
|
+
"@sphereon/ssi-sdk.data-store": "0.33.1-feature.jose.vcdm.55+6f02f6f8",
|
|
31
|
+
"@sphereon/ssi-sdk.vc-status-list": "0.33.1-feature.jose.vcdm.55+6f02f6f8",
|
|
32
|
+
"@sphereon/ssi-types": "0.33.1-feature.jose.vcdm.55+6f02f6f8",
|
|
21
33
|
"@sphereon/vc-status-list": "7.0.0-next.0",
|
|
22
34
|
"@veramo/core": "4.2.0",
|
|
23
35
|
"debug": "^4.3.5",
|
|
24
|
-
"typeorm": "
|
|
36
|
+
"typeorm": "0.3.20",
|
|
25
37
|
"uint8arrays": "^3.1.1"
|
|
26
38
|
},
|
|
27
39
|
"devDependencies": {
|
|
28
40
|
"@sphereon/ssi-sdk.agent-config": "workspace:*",
|
|
29
41
|
"@types/debug": "^4.1.12",
|
|
30
42
|
"@types/node": "^20.17.1",
|
|
31
|
-
"typescript": "5.
|
|
43
|
+
"typescript": "5.8.3"
|
|
32
44
|
},
|
|
33
45
|
"files": [
|
|
34
|
-
"dist
|
|
35
|
-
"src
|
|
46
|
+
"dist",
|
|
47
|
+
"src",
|
|
36
48
|
"README.md",
|
|
37
49
|
"LICENSE"
|
|
38
50
|
],
|
|
@@ -48,6 +60,5 @@
|
|
|
48
60
|
"SSI",
|
|
49
61
|
"StatusList2021"
|
|
50
62
|
],
|
|
51
|
-
"
|
|
52
|
-
"gitHead": "3b988a2bb62a7c4534a2670ea3a0985fd93d00f2"
|
|
63
|
+
"gitHead": "6f02f6f83679198268c6e1ea956be24cc1017234"
|
|
53
64
|
}
|
package/src/drivers.ts
CHANGED
|
@@ -5,12 +5,20 @@ import {
|
|
|
5
5
|
IGetStatusListEntryByIndexArgs,
|
|
6
6
|
IStatusListEntity,
|
|
7
7
|
IStatusListEntryEntity,
|
|
8
|
+
StatusListEntity,
|
|
8
9
|
StatusListStore,
|
|
9
10
|
} from '@sphereon/ssi-sdk.data-store'
|
|
10
|
-
import {
|
|
11
|
-
|
|
11
|
+
import {
|
|
12
|
+
StatusList2021EntryCredentialStatus,
|
|
13
|
+
statusListCredentialToDetails,
|
|
14
|
+
StatusListOAuthEntryCredentialStatus,
|
|
15
|
+
StatusListResult,
|
|
16
|
+
} from '@sphereon/ssi-sdk.vc-status-list'
|
|
17
|
+
import { StatusListCredentialIdMode, StatusListDriverType, StatusListType, StatusListCredential } from '@sphereon/ssi-types'
|
|
12
18
|
import { DataSource } from 'typeorm'
|
|
13
19
|
import { IStatusListDriver } from './types'
|
|
20
|
+
import { statusListResultToEntity } from './status-list-adapters'
|
|
21
|
+
import { OAuthStatusListEntity, StatusList2021Entity } from '@sphereon/ssi-sdk.data-store'
|
|
14
22
|
|
|
15
23
|
export interface StatusListManagementOptions {
|
|
16
24
|
id?: string
|
|
@@ -121,46 +129,37 @@ export class AgentDataSourceStatusListDriver implements IStatusListDriver {
|
|
|
121
129
|
}
|
|
122
130
|
|
|
123
131
|
async createStatusList(args: {
|
|
124
|
-
statusListCredential:
|
|
132
|
+
statusListCredential: StatusListCredential
|
|
125
133
|
correlationId?: string
|
|
126
134
|
credentialIdMode?: StatusListCredentialIdMode
|
|
127
|
-
}): Promise<
|
|
135
|
+
}): Promise<StatusListResult> {
|
|
128
136
|
const correlationId = args.correlationId ?? this.options.correlationId
|
|
129
137
|
if (!correlationId) {
|
|
130
138
|
throw Error('Either a correlationId needs to be set as an option, or it needs to be provided when creating a status list. None found')
|
|
131
139
|
}
|
|
132
140
|
const credentialIdMode = args.credentialIdMode ?? StatusListCredentialIdMode.ISSUANCE
|
|
133
141
|
const details = await statusListCredentialToDetails({ ...args, correlationId, driverType: this.getType() })
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
).findOne({
|
|
137
|
-
where: [
|
|
138
|
-
{
|
|
139
|
-
id: details.id,
|
|
140
|
-
},
|
|
141
|
-
{
|
|
142
|
-
correlationId,
|
|
143
|
-
},
|
|
144
|
-
],
|
|
145
|
-
})
|
|
146
|
-
if (entity) {
|
|
147
|
-
throw Error(`Status list ${details.id}, correlationId ${args.correlationId} already exists`)
|
|
148
|
-
}
|
|
149
|
-
this._statusListLength = details.length
|
|
142
|
+
|
|
143
|
+
// (StatusListStore does the duplicate entity check)
|
|
150
144
|
await this.statusListStore.addStatusList({
|
|
151
145
|
...details,
|
|
152
146
|
credentialIdMode,
|
|
153
147
|
correlationId,
|
|
154
148
|
driverType: this.getType(),
|
|
155
149
|
})
|
|
150
|
+
this._statusListLength = details.length
|
|
156
151
|
return details
|
|
157
152
|
}
|
|
158
153
|
|
|
159
|
-
async updateStatusList(args: {
|
|
154
|
+
async updateStatusList(args: {
|
|
155
|
+
statusListCredential: StatusListCredential
|
|
156
|
+
correlationId: string
|
|
157
|
+
type: StatusListType
|
|
158
|
+
}): Promise<StatusListResult> {
|
|
160
159
|
const correlationId = args.correlationId ?? this.options.correlationId
|
|
161
160
|
const details = await statusListCredentialToDetails({ ...args, correlationId, driverType: this.getType() })
|
|
162
161
|
const entity = await (
|
|
163
|
-
await this.statusListStore.getStatusListRepo()
|
|
162
|
+
await this.statusListStore.getStatusListRepo(args.type)
|
|
164
163
|
).findOne({
|
|
165
164
|
where: [
|
|
166
165
|
{
|
|
@@ -189,21 +188,47 @@ export class AgentDataSourceStatusListDriver implements IStatusListDriver {
|
|
|
189
188
|
return Promise.resolve(true)
|
|
190
189
|
}
|
|
191
190
|
|
|
191
|
+
private isStatusList2021Entity(statusList: StatusListEntity): statusList is StatusList2021Entity {
|
|
192
|
+
return statusList instanceof StatusList2021Entity
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
private isOAuthStatusListEntity(statusList: StatusListEntity): statusList is OAuthStatusListEntity {
|
|
196
|
+
return statusList instanceof OAuthStatusListEntity
|
|
197
|
+
}
|
|
198
|
+
|
|
192
199
|
async updateStatusListEntry(args: IAddStatusListEntryArgs): Promise<{
|
|
193
|
-
credentialStatus: StatusList2021EntryCredentialStatus
|
|
200
|
+
credentialStatus: StatusList2021EntryCredentialStatus | StatusListOAuthEntryCredentialStatus
|
|
194
201
|
statusListEntry: IStatusListEntryEntity
|
|
195
202
|
}> {
|
|
196
|
-
const statusList =
|
|
203
|
+
const statusList: StatusListEntity = args.statusList ? args.statusList : statusListResultToEntity(await this.getStatusList())
|
|
204
|
+
const statusListEntry = await this.statusListStore.updateStatusListEntry({ ...args, statusListId: statusList.id })
|
|
197
205
|
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
206
|
+
if (this.isStatusList2021Entity(statusList)) {
|
|
207
|
+
return {
|
|
208
|
+
credentialStatus: {
|
|
209
|
+
id: `${statusList.id}#${statusListEntry.statusListIndex}`,
|
|
210
|
+
type: 'StatusList2021Entry',
|
|
211
|
+
statusPurpose: statusList.statusPurpose ?? 'revocation',
|
|
212
|
+
statusListIndex: '' + statusListEntry.statusListIndex,
|
|
213
|
+
statusListCredential: statusList.id,
|
|
214
|
+
},
|
|
215
|
+
statusListEntry,
|
|
216
|
+
}
|
|
217
|
+
} else if (this.isOAuthStatusListEntity(statusList)) {
|
|
218
|
+
return {
|
|
219
|
+
credentialStatus: {
|
|
220
|
+
id: `${statusList.id}#${statusListEntry.statusListIndex}`,
|
|
221
|
+
type: 'OAuthStatusListEntry',
|
|
222
|
+
bitsPerStatus: statusList.bitsPerStatus,
|
|
223
|
+
statusListIndex: '' + statusListEntry.statusListIndex,
|
|
224
|
+
statusListCredential: statusList.id,
|
|
225
|
+
expiresAt: statusList.expiresAt,
|
|
226
|
+
},
|
|
227
|
+
statusListEntry,
|
|
228
|
+
}
|
|
205
229
|
}
|
|
206
|
-
|
|
230
|
+
|
|
231
|
+
throw new Error(`Unsupported status list type: ${typeof statusList}`)
|
|
207
232
|
}
|
|
208
233
|
|
|
209
234
|
async getStatusListEntryByCredentialId(args: IGetStatusListEntryByCredentialIdArgs): Promise<IStatusListEntryEntity | undefined> {
|
|
@@ -251,7 +276,7 @@ export class AgentDataSourceStatusListDriver implements IStatusListDriver {
|
|
|
251
276
|
return this._statusListLength!
|
|
252
277
|
}
|
|
253
278
|
|
|
254
|
-
async getStatusList(args?: { correlationId?: string }): Promise<
|
|
279
|
+
async getStatusList(args?: { correlationId?: string }): Promise<StatusListResult> {
|
|
255
280
|
const id = this.options.id
|
|
256
281
|
const correlationId = args?.correlationId ?? this.options.correlationId
|
|
257
282
|
return await this.statusListStore
|
|
@@ -259,6 +284,17 @@ export class AgentDataSourceStatusListDriver implements IStatusListDriver {
|
|
|
259
284
|
.then((statusListEntity: IStatusListEntity) => statusListCredentialToDetails({ statusListCredential: statusListEntity.statusListCredential! }))
|
|
260
285
|
}
|
|
261
286
|
|
|
287
|
+
async getStatusLists(): Promise<Array<StatusListResult>> {
|
|
288
|
+
const statusLists = await this.statusListStore.getStatusLists({})
|
|
289
|
+
return Promise.all(
|
|
290
|
+
statusLists.map(async (statusListEntity) => {
|
|
291
|
+
return statusListCredentialToDetails({
|
|
292
|
+
statusListCredential: statusListEntity.statusListCredential!,
|
|
293
|
+
})
|
|
294
|
+
}),
|
|
295
|
+
)
|
|
296
|
+
}
|
|
297
|
+
|
|
262
298
|
isStatusListIndexInUse(): Promise<boolean> {
|
|
263
299
|
return Promise.resolve(false)
|
|
264
300
|
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { StatusListType } from '@sphereon/ssi-types'
|
|
2
|
+
import { OAuthStatusListEntity, StatusList2021Entity } from '@sphereon/ssi-sdk.data-store'
|
|
3
|
+
import { StatusListResult } from '@sphereon/ssi-sdk.vc-status-list'
|
|
4
|
+
|
|
5
|
+
export function statusListResultToEntity(result: StatusListResult): StatusList2021Entity | OAuthStatusListEntity {
|
|
6
|
+
const baseFields = {
|
|
7
|
+
id: result.id,
|
|
8
|
+
correlationId: result.correlationId,
|
|
9
|
+
driverType: result.driverType,
|
|
10
|
+
credentialIdMode: result.credentialIdMode,
|
|
11
|
+
length: result.length,
|
|
12
|
+
issuer: result.issuer,
|
|
13
|
+
type: result.type,
|
|
14
|
+
proofFormat: result.proofFormat,
|
|
15
|
+
statusListCredential: result.statusListCredential,
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
if (result.type === StatusListType.StatusList2021) {
|
|
19
|
+
if (!result.statusList2021) {
|
|
20
|
+
throw new Error('Missing statusList2021 details')
|
|
21
|
+
}
|
|
22
|
+
return Object.assign(new StatusList2021Entity(), {
|
|
23
|
+
...baseFields,
|
|
24
|
+
indexingDirection: result.statusList2021.indexingDirection,
|
|
25
|
+
statusPurpose: result.statusList2021.statusPurpose,
|
|
26
|
+
})
|
|
27
|
+
} else if (result.type === StatusListType.OAuthStatusList) {
|
|
28
|
+
if (!result.oauthStatusList) {
|
|
29
|
+
throw new Error('Missing oauthStatusList details')
|
|
30
|
+
}
|
|
31
|
+
return Object.assign(new OAuthStatusListEntity(), {
|
|
32
|
+
...baseFields,
|
|
33
|
+
bitsPerStatus: result.oauthStatusList.bitsPerStatus,
|
|
34
|
+
expiresAt: result.oauthStatusList.expiresAt,
|
|
35
|
+
})
|
|
36
|
+
}
|
|
37
|
+
throw new Error(`Unsupported status list type: ${result.type}`)
|
|
38
|
+
}
|