@sphereon/ssi-sdk.vc-status-list 0.34.1-feature.SSISDK.17.bitstring.sl.8 → 0.34.1-feature.disable.test.8
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 +24 -281
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +8 -49
- package/dist/index.d.ts +8 -49
- package/dist/index.js +25 -282
- package/dist/index.js.map +1 -1
- package/package.json +7 -8
- package/src/functions.ts +10 -19
- package/src/impl/IStatusList.ts +2 -3
- package/src/impl/OAuthStatusList.ts +6 -9
- package/src/impl/StatusList2021.ts +3 -3
- package/src/impl/StatusListFactory.ts +0 -2
- package/src/types/index.ts +4 -48
- package/src/utils.ts +2 -3
- package/src/impl/BitstringStatusListImplementation.ts +0 -301
- package/src/types/BitstringStatusList.ts +0 -4
|
@@ -20,7 +20,7 @@ import { createSignedCbor, decodeStatusListCWT } from './encoding/cbor'
|
|
|
20
20
|
|
|
21
21
|
type IRequiredContext = IAgentContext<ICredentialPlugin & IJwtService & IIdentifierResolution & IKeyManager>
|
|
22
22
|
|
|
23
|
-
export const DEFAULT_BITS_PER_STATUS = 1 // 1 bit is sufficient for 0x00 - "VALID"
|
|
23
|
+
export const DEFAULT_BITS_PER_STATUS = 1 // 1 bit is sufficient for 0x00 - "VALID" 0x01 - "INVALID" saving space in the process
|
|
24
24
|
export const DEFAULT_LIST_LENGTH = 250000
|
|
25
25
|
export const DEFAULT_PROOF_FORMAT = 'jwt' as CredentialProofFormat
|
|
26
26
|
|
|
@@ -70,10 +70,6 @@ export class OAuthStatusListImplementation implements IStatusList {
|
|
|
70
70
|
throw new Error('Status list index out of bounds')
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
-
if (typeof value !== 'number') {
|
|
74
|
-
throw new Error('Status list values should be of type number')
|
|
75
|
-
}
|
|
76
|
-
|
|
77
73
|
statusList.setStatus(index, value)
|
|
78
74
|
const { statusListCredential: signedCredential, encodedList } = await this.createSignedStatusList(
|
|
79
75
|
proofFormat,
|
|
@@ -113,7 +109,8 @@ export class OAuthStatusListImplementation implements IStatusList {
|
|
|
113
109
|
|
|
114
110
|
const listToUpdate = StatusList.decompressStatusList(args.encodedList, bitsPerStatus ?? DEFAULT_BITS_PER_STATUS)
|
|
115
111
|
const index = typeof args.statusListIndex === 'number' ? args.statusListIndex : parseInt(args.statusListIndex)
|
|
116
|
-
|
|
112
|
+
// FIXME: See above.
|
|
113
|
+
listToUpdate.setStatus(index, args.value ? 1 : 0)
|
|
117
114
|
|
|
118
115
|
const { statusListCredential, encodedList } = await this.createSignedStatusList(
|
|
119
116
|
proofFormat ?? DEFAULT_PROOF_FORMAT,
|
|
@@ -141,7 +138,7 @@ export class OAuthStatusListImplementation implements IStatusList {
|
|
|
141
138
|
}
|
|
142
139
|
}
|
|
143
140
|
|
|
144
|
-
private buildContentType(proofFormat:
|
|
141
|
+
private buildContentType(proofFormat: 'jwt' | 'lds' | 'EthereumEip712Signature2021' | 'cbor' | undefined) {
|
|
145
142
|
return `application/statuslist+${proofFormat === 'cbor' ? 'cwt' : 'jwt'}`
|
|
146
143
|
}
|
|
147
144
|
|
|
@@ -156,7 +153,7 @@ export class OAuthStatusListImplementation implements IStatusList {
|
|
|
156
153
|
|
|
157
154
|
const index = typeof statusListIndex === 'number' ? statusListIndex : parseInt(statusListIndex)
|
|
158
155
|
if (index < 0 || index >= statusList.statusList.length) {
|
|
159
|
-
throw new Error(
|
|
156
|
+
throw new Error('Status list index out of bounds')
|
|
160
157
|
}
|
|
161
158
|
|
|
162
159
|
return statusList.getStatus(index)
|
|
@@ -187,7 +184,7 @@ export class OAuthStatusListImplementation implements IStatusList {
|
|
|
187
184
|
}
|
|
188
185
|
|
|
189
186
|
private async createSignedStatusList(
|
|
190
|
-
proofFormat:
|
|
187
|
+
proofFormat: 'jwt' | 'lds' | 'EthereumEip712Signature2021' | 'cbor',
|
|
191
188
|
context: IAgentContext<ICredentialPlugin & IJwtService & IIdentifierResolution & IKeyManager>,
|
|
192
189
|
statusList: StatusList,
|
|
193
190
|
issuerString: string,
|
|
@@ -24,7 +24,7 @@ import { Status2021 } from '../types'
|
|
|
24
24
|
import { assertValidProofType, getAssertedProperty, getAssertedValue, getAssertedValues } from '../utils'
|
|
25
25
|
|
|
26
26
|
export const DEFAULT_LIST_LENGTH = 250000
|
|
27
|
-
export const DEFAULT_PROOF_FORMAT = 'lds' as
|
|
27
|
+
export const DEFAULT_PROOF_FORMAT = 'lds' as VeramoProofFormat
|
|
28
28
|
|
|
29
29
|
export class StatusList2021Implementation implements IStatusList {
|
|
30
30
|
async createNewStatusList(
|
|
@@ -126,7 +126,7 @@ export class StatusList2021Implementation implements IStatusList {
|
|
|
126
126
|
const { issuer, id } = getAssertedValues(args)
|
|
127
127
|
const statusList = await StatusList.decode({ encodedList: args.encodedList })
|
|
128
128
|
const index = typeof args.statusListIndex === 'number' ? args.statusListIndex : parseInt(args.statusListIndex)
|
|
129
|
-
statusList.setStatus(index, args.value
|
|
129
|
+
statusList.setStatus(index, args.value)
|
|
130
130
|
|
|
131
131
|
const newEncodedList = await statusList.encode()
|
|
132
132
|
const credential = await this.createVerifiableCredential(
|
|
@@ -234,7 +234,7 @@ export class StatusList2021Implementation implements IStatusList {
|
|
|
234
234
|
return CredentialMapper.toWrappedVerifiableCredential(verifiableCredential as StatusListCredential).original as StatusListCredential
|
|
235
235
|
}
|
|
236
236
|
|
|
237
|
-
private buildContentType(proofFormat:
|
|
237
|
+
private buildContentType(proofFormat: 'jwt' | 'lds' | 'EthereumEip712Signature2021' | 'cbor' | undefined) {
|
|
238
238
|
switch (proofFormat) {
|
|
239
239
|
case 'jwt':
|
|
240
240
|
return `application/statuslist+jwt`
|
|
@@ -2,7 +2,6 @@ import type { IStatusList } from './IStatusList'
|
|
|
2
2
|
import { StatusList2021Implementation } from './StatusList2021'
|
|
3
3
|
import { OAuthStatusListImplementation } from './OAuthStatusList'
|
|
4
4
|
import { StatusListType } from '@sphereon/ssi-types'
|
|
5
|
-
import { BitstringStatusListImplementation } from './BitstringStatusListImplementation'
|
|
6
5
|
|
|
7
6
|
export class StatusListFactory {
|
|
8
7
|
private static instance: StatusListFactory
|
|
@@ -12,7 +11,6 @@ export class StatusListFactory {
|
|
|
12
11
|
this.implementations = new Map()
|
|
13
12
|
this.implementations.set(StatusListType.StatusList2021, new StatusList2021Implementation())
|
|
14
13
|
this.implementations.set(StatusListType.OAuthStatusList, new OAuthStatusListImplementation())
|
|
15
|
-
this.implementations.set(StatusListType.BitstringStatusList, new BitstringStatusListImplementation())
|
|
16
14
|
}
|
|
17
15
|
|
|
18
16
|
public static getInstance(): StatusListFactory {
|
package/src/types/index.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import type { IIdentifierResolution } from '@sphereon/ssi-sdk-ext.identifier-resolution'
|
|
2
2
|
import {
|
|
3
|
-
type CredentialProofFormat,
|
|
4
3
|
type ICredential,
|
|
5
4
|
type ICredentialStatus,
|
|
6
5
|
type IIssuer,
|
|
7
6
|
type IVerifiableCredential,
|
|
8
7
|
type OrPromise,
|
|
8
|
+
type CredentialProofFormat,
|
|
9
9
|
type StatusListCredential,
|
|
10
10
|
StatusListCredentialIdMode,
|
|
11
11
|
StatusListDriverType,
|
|
@@ -26,7 +26,6 @@ import { DataSource } from 'typeorm'
|
|
|
26
26
|
import type { BitsPerStatus } from '@sd-jwt/jwt-status-list'
|
|
27
27
|
import type { SdJwtVcPayload } from '@sd-jwt/sd-jwt-vc'
|
|
28
28
|
import type { StatusListOpts } from '@sphereon/oid4vci-common'
|
|
29
|
-
import { BitstringStatusPurpose } from '@4sure-tech/vc-bitstring-status-lists'
|
|
30
29
|
|
|
31
30
|
export enum StatusOAuth {
|
|
32
31
|
Valid = 0,
|
|
@@ -39,8 +38,6 @@ export enum Status2021 {
|
|
|
39
38
|
Invalid = 1,
|
|
40
39
|
}
|
|
41
40
|
|
|
42
|
-
export type BitstringStatus = number
|
|
43
|
-
|
|
44
41
|
export type StatusList2021Args = {
|
|
45
42
|
indexingDirection: StatusListIndexingDirection
|
|
46
43
|
statusPurpose?: StatusPurpose2021
|
|
@@ -52,14 +49,6 @@ export type OAuthStatusListArgs = {
|
|
|
52
49
|
expiresAt?: Date
|
|
53
50
|
}
|
|
54
51
|
|
|
55
|
-
export type BitstringStatusListArgs = {
|
|
56
|
-
statusPurpose: BitstringStatusPurpose
|
|
57
|
-
bitsPerStatus: number
|
|
58
|
-
ttl?: number
|
|
59
|
-
validFrom?: Date
|
|
60
|
-
validUntil?: Date
|
|
61
|
-
}
|
|
62
|
-
|
|
63
52
|
export type BaseCreateNewStatusListArgs = {
|
|
64
53
|
type: StatusListType
|
|
65
54
|
id: string
|
|
@@ -70,7 +59,6 @@ export type BaseCreateNewStatusListArgs = {
|
|
|
70
59
|
keyRef?: string
|
|
71
60
|
statusList2021?: StatusList2021Args
|
|
72
61
|
oauthStatusList?: OAuthStatusListArgs
|
|
73
|
-
bitstringStatusList?: BitstringStatusListArgs
|
|
74
62
|
driverType?: StatusListDriverType
|
|
75
63
|
}
|
|
76
64
|
|
|
@@ -83,18 +71,10 @@ export type UpdateOAuthStatusListArgs = {
|
|
|
83
71
|
expiresAt?: Date
|
|
84
72
|
}
|
|
85
73
|
|
|
86
|
-
export type UpdateBitstringStatusListArgs = {
|
|
87
|
-
statusPurpose: BitstringStatusPurpose
|
|
88
|
-
bitsPerStatus: number
|
|
89
|
-
validFrom?: Date
|
|
90
|
-
validUntil?: Date
|
|
91
|
-
ttl?: number
|
|
92
|
-
}
|
|
93
|
-
|
|
94
74
|
export interface UpdateStatusListFromEncodedListArgs {
|
|
95
75
|
type?: StatusListType
|
|
96
76
|
statusListIndex: number | string
|
|
97
|
-
value:
|
|
77
|
+
value: boolean
|
|
98
78
|
proofFormat?: CredentialProofFormat
|
|
99
79
|
keyRef?: string
|
|
100
80
|
correlationId?: string
|
|
@@ -103,14 +83,13 @@ export interface UpdateStatusListFromEncodedListArgs {
|
|
|
103
83
|
id: string
|
|
104
84
|
statusList2021?: UpdateStatusList2021Args
|
|
105
85
|
oauthStatusList?: UpdateOAuthStatusListArgs
|
|
106
|
-
bitstringStatusList?: UpdateBitstringStatusListArgs
|
|
107
86
|
}
|
|
108
87
|
|
|
109
88
|
export interface UpdateStatusListFromStatusListCredentialArgs {
|
|
110
89
|
statusListCredential: StatusListCredential // | CompactJWT
|
|
111
90
|
keyRef?: string
|
|
112
91
|
statusListIndex: number | string
|
|
113
|
-
value: number | Status2021 | StatusOAuth
|
|
92
|
+
value: number | Status2021 | StatusOAuth
|
|
114
93
|
}
|
|
115
94
|
|
|
116
95
|
export interface StatusListResult {
|
|
@@ -124,7 +103,6 @@ export interface StatusListResult {
|
|
|
124
103
|
issuer: string | IIssuer
|
|
125
104
|
statusList2021?: StatusList2021Details
|
|
126
105
|
oauthStatusList?: OAuthStatusDetails
|
|
127
|
-
bitstringStatusList?: BitstringStatusDetails
|
|
128
106
|
|
|
129
107
|
// These cannot be deduced from the VC, so they are present when callers pass in these values as params
|
|
130
108
|
correlationId?: string
|
|
@@ -142,14 +120,6 @@ interface OAuthStatusDetails {
|
|
|
142
120
|
expiresAt?: Date
|
|
143
121
|
}
|
|
144
122
|
|
|
145
|
-
interface BitstringStatusDetails {
|
|
146
|
-
statusPurpose: BitstringStatusPurpose
|
|
147
|
-
bitsPerStatus: number
|
|
148
|
-
validFrom?: Date
|
|
149
|
-
validUntil?: Date
|
|
150
|
-
ttl?: number
|
|
151
|
-
}
|
|
152
|
-
|
|
153
123
|
export interface StatusList2021EntryCredentialStatus extends ICredentialStatus {
|
|
154
124
|
type: 'StatusList2021Entry'
|
|
155
125
|
statusPurpose: StatusPurpose2021
|
|
@@ -165,16 +135,6 @@ export interface StatusListOAuthEntryCredentialStatus extends ICredentialStatus
|
|
|
165
135
|
expiresAt?: Date
|
|
166
136
|
}
|
|
167
137
|
|
|
168
|
-
export interface BitstringStatusListEntryCredentialStatus extends ICredentialStatus {
|
|
169
|
-
type: 'BitstringStatusListEntry'
|
|
170
|
-
statusPurpose: BitstringStatusPurpose | BitstringStatusPurpose[]
|
|
171
|
-
statusListIndex: string
|
|
172
|
-
statusListCredential: string
|
|
173
|
-
bitsPerStatus?: number
|
|
174
|
-
statusMessage?: Array<BitstringStatus>
|
|
175
|
-
statusReference?: string | string[]
|
|
176
|
-
}
|
|
177
|
-
|
|
178
138
|
export interface StatusList2021ToVerifiableCredentialArgs {
|
|
179
139
|
issuer: string | IIssuer
|
|
180
140
|
id: string
|
|
@@ -194,14 +154,12 @@ export interface CreateStatusListArgs {
|
|
|
194
154
|
length?: number
|
|
195
155
|
statusList2021?: StatusList2021Args
|
|
196
156
|
oauthStatusList?: OAuthStatusListArgs
|
|
197
|
-
bitstringStatusList?: BitstringStatusListArgs
|
|
198
157
|
}
|
|
199
158
|
|
|
200
159
|
export interface UpdateStatusListIndexArgs {
|
|
201
160
|
statusListCredential: StatusListCredential // | CompactJWT
|
|
202
161
|
statusListIndex: number | string
|
|
203
|
-
value: number | Status2021 | StatusOAuth
|
|
204
|
-
bitsPerStatus?: number
|
|
162
|
+
value: number | Status2021 | StatusOAuth
|
|
205
163
|
keyRef?: string
|
|
206
164
|
expiresAt?: Date
|
|
207
165
|
}
|
|
@@ -209,14 +167,12 @@ export interface UpdateStatusListIndexArgs {
|
|
|
209
167
|
export interface CheckStatusIndexArgs {
|
|
210
168
|
statusListCredential: StatusListCredential // | CompactJWT
|
|
211
169
|
statusListIndex: string | number
|
|
212
|
-
bitsPerStatus?: number
|
|
213
170
|
}
|
|
214
171
|
|
|
215
172
|
export interface ToStatusListDetailsArgs {
|
|
216
173
|
statusListPayload: StatusListCredential
|
|
217
174
|
correlationId?: string
|
|
218
175
|
driverType?: StatusListDriverType
|
|
219
|
-
bitsPerStatus?: number
|
|
220
176
|
}
|
|
221
177
|
|
|
222
178
|
/**
|
package/src/utils.ts
CHANGED
|
@@ -11,7 +11,7 @@ import { jwtDecode } from 'jwt-decode'
|
|
|
11
11
|
|
|
12
12
|
export function getAssertedStatusListType(type?: StatusListType) {
|
|
13
13
|
const assertedType = type ?? StatusListType.StatusList2021
|
|
14
|
-
if (![StatusListType.StatusList2021, StatusListType.OAuthStatusList
|
|
14
|
+
if (![StatusListType.StatusList2021, StatusListType.OAuthStatusList].includes(assertedType)) {
|
|
15
15
|
throw Error(`StatusList type ${assertedType} is not supported (yet)`)
|
|
16
16
|
}
|
|
17
17
|
return assertedType
|
|
@@ -39,9 +39,8 @@ export function getAssertedProperty<T extends object>(propertyName: string, obj:
|
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
const ValidProofTypeMap = new Map<StatusListType, CredentialProofFormat[]>([
|
|
42
|
-
[StatusListType.StatusList2021, ['jwt', 'lds']],
|
|
42
|
+
[StatusListType.StatusList2021, ['jwt', 'lds', 'EthereumEip712Signature2021']],
|
|
43
43
|
[StatusListType.OAuthStatusList, ['jwt', 'cbor']],
|
|
44
|
-
[StatusListType.BitstringStatusList, ['lds']],
|
|
45
44
|
])
|
|
46
45
|
|
|
47
46
|
export function assertValidProofType(type: StatusListType, proofFormat: CredentialProofFormat) {
|
|
@@ -1,301 +0,0 @@
|
|
|
1
|
-
import type { IAgentContext, ICredentialPlugin, ProofFormat as VeramoProofFormat } from '@veramo/core'
|
|
2
|
-
import type { IIdentifierResolution } from '@sphereon/ssi-sdk-ext.identifier-resolution'
|
|
3
|
-
import {
|
|
4
|
-
CredentialMapper,
|
|
5
|
-
type CredentialProofFormat,
|
|
6
|
-
DocumentFormat,
|
|
7
|
-
type IIssuer,
|
|
8
|
-
type StatusListCredential,
|
|
9
|
-
StatusListType,
|
|
10
|
-
} from '@sphereon/ssi-types'
|
|
11
|
-
|
|
12
|
-
import type { IStatusList } from './IStatusList'
|
|
13
|
-
import {
|
|
14
|
-
BitstringStatus,
|
|
15
|
-
CheckStatusIndexArgs,
|
|
16
|
-
CreateStatusListArgs,
|
|
17
|
-
StatusListResult,
|
|
18
|
-
ToStatusListDetailsArgs,
|
|
19
|
-
UpdateStatusListFromEncodedListArgs,
|
|
20
|
-
UpdateStatusListIndexArgs,
|
|
21
|
-
} from '../types'
|
|
22
|
-
|
|
23
|
-
import { assertValidProofType, getAssertedProperty, getAssertedValue, getAssertedValues } from '../utils'
|
|
24
|
-
import { BitstringStatusListCredential } from '../types/BitstringStatusList'
|
|
25
|
-
import { BitstreamStatusList, BitstringStatusPurpose, createStatusListCredential } from '@4sure-tech/vc-bitstring-status-lists'
|
|
26
|
-
|
|
27
|
-
export const DEFAULT_LIST_LENGTH = 131072 // W3C spec minimum
|
|
28
|
-
export const DEFAULT_PROOF_FORMAT = 'lds' as CredentialProofFormat
|
|
29
|
-
export const DEFAULT_STATUS_PURPOSE: BitstringStatusPurpose = 'revocation'
|
|
30
|
-
|
|
31
|
-
export class BitstringStatusListImplementation implements IStatusList {
|
|
32
|
-
async createNewStatusList(
|
|
33
|
-
args: CreateStatusListArgs,
|
|
34
|
-
context: IAgentContext<ICredentialPlugin & IIdentifierResolution>,
|
|
35
|
-
): Promise<StatusListResult> {
|
|
36
|
-
if (!args.bitstringStatusList) {
|
|
37
|
-
throw new Error('BitstringStatusList options are required for type BitstringStatusList')
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
const length = args?.length ?? DEFAULT_LIST_LENGTH
|
|
41
|
-
const proofFormat: CredentialProofFormat = args?.proofFormat ?? DEFAULT_PROOF_FORMAT
|
|
42
|
-
assertValidProofType(StatusListType.BitstringStatusList, proofFormat)
|
|
43
|
-
const veramoProofFormat: VeramoProofFormat = proofFormat as VeramoProofFormat
|
|
44
|
-
|
|
45
|
-
const { issuer, id } = args
|
|
46
|
-
const correlationId = getAssertedValue('correlationId', args.correlationId)
|
|
47
|
-
const { statusPurpose, bitsPerStatus, validFrom, validUntil, ttl } = args.bitstringStatusList
|
|
48
|
-
const statusListCredential = await this.createVerifiableCredential(
|
|
49
|
-
{
|
|
50
|
-
...args,
|
|
51
|
-
proofFormat: veramoProofFormat,
|
|
52
|
-
statusPurpose: statusPurpose ?? DEFAULT_STATUS_PURPOSE,
|
|
53
|
-
validFrom,
|
|
54
|
-
validUntil,
|
|
55
|
-
ttl,
|
|
56
|
-
},
|
|
57
|
-
context,
|
|
58
|
-
)
|
|
59
|
-
|
|
60
|
-
return {
|
|
61
|
-
encodedList: statusListCredential.credentialSubject.encodedList,
|
|
62
|
-
statusListCredential: statusListCredential,
|
|
63
|
-
bitstringStatusList: {
|
|
64
|
-
statusPurpose: statusPurpose ?? DEFAULT_STATUS_PURPOSE,
|
|
65
|
-
...(statusListCredential.validFrom && { validFrom: new Date(statusListCredential.validFrom) }),
|
|
66
|
-
...(statusListCredential.validUntil && { validUntil: new Date(statusListCredential.validUntil) }),
|
|
67
|
-
ttl,
|
|
68
|
-
bitsPerStatus,
|
|
69
|
-
},
|
|
70
|
-
length,
|
|
71
|
-
type: StatusListType.BitstringStatusList,
|
|
72
|
-
proofFormat,
|
|
73
|
-
id,
|
|
74
|
-
correlationId,
|
|
75
|
-
issuer,
|
|
76
|
-
statuslistContentType: this.buildContentType(proofFormat),
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
async updateStatusListIndex(
|
|
81
|
-
args: UpdateStatusListIndexArgs,
|
|
82
|
-
context: IAgentContext<ICredentialPlugin & IIdentifierResolution>,
|
|
83
|
-
): Promise<StatusListResult> {
|
|
84
|
-
if (!args.bitsPerStatus || args.bitsPerStatus < 1) {
|
|
85
|
-
return Promise.reject('bitsPerStatus must be set for bitstring status lists and must be 1 or higher. (updateStatusListIndex)')
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
const credential = args.statusListCredential
|
|
89
|
-
const uniform = CredentialMapper.toUniformCredential(credential)
|
|
90
|
-
const { issuer, credentialSubject } = uniform
|
|
91
|
-
const id = getAssertedValue('id', uniform.id)
|
|
92
|
-
const origEncodedList = getAssertedProperty('encodedList', credentialSubject)
|
|
93
|
-
|
|
94
|
-
const index = typeof args.statusListIndex === 'number' ? args.statusListIndex : parseInt(args.statusListIndex)
|
|
95
|
-
const statusList: BitstreamStatusList = await BitstreamStatusList.decode({ encodedList: origEncodedList, statusSize: args.bitsPerStatus })
|
|
96
|
-
statusList.setStatus(index, args.value)
|
|
97
|
-
|
|
98
|
-
const proofFormat = CredentialMapper.detectDocumentType(credential) === DocumentFormat.JWT ? 'jwt' : 'lds'
|
|
99
|
-
|
|
100
|
-
const credSubject = Array.isArray(credentialSubject) ? credentialSubject[0] : credentialSubject
|
|
101
|
-
|
|
102
|
-
const statusPurpose = getAssertedProperty('statusPurpose', credSubject)
|
|
103
|
-
|
|
104
|
-
const validFrom = uniform.validFrom ? new Date(uniform.validFrom) : undefined
|
|
105
|
-
const validUntil = uniform.validUntil ? new Date(uniform.validUntil) : undefined
|
|
106
|
-
const ttl = credSubject.ttl
|
|
107
|
-
|
|
108
|
-
const updatedCredential = await this.createVerifiableCredential(
|
|
109
|
-
{
|
|
110
|
-
...args,
|
|
111
|
-
id,
|
|
112
|
-
issuer,
|
|
113
|
-
statusList,
|
|
114
|
-
proofFormat: proofFormat,
|
|
115
|
-
statusPurpose,
|
|
116
|
-
ttl,
|
|
117
|
-
validFrom,
|
|
118
|
-
validUntil,
|
|
119
|
-
},
|
|
120
|
-
context,
|
|
121
|
-
)
|
|
122
|
-
|
|
123
|
-
return {
|
|
124
|
-
statusListCredential: updatedCredential,
|
|
125
|
-
encodedList: updatedCredential.credentialSubject.encodedList,
|
|
126
|
-
bitstringStatusList: {
|
|
127
|
-
statusPurpose,
|
|
128
|
-
...(updatedCredential.validFrom && { validFrom: new Date(updatedCredential.validFrom) }),
|
|
129
|
-
...(updatedCredential.validUntil && { validUntil: new Date(updatedCredential.validUntil) }),
|
|
130
|
-
bitsPerStatus: args.bitsPerStatus,
|
|
131
|
-
ttl,
|
|
132
|
-
},
|
|
133
|
-
length: statusList.getLength(),
|
|
134
|
-
type: StatusListType.BitstringStatusList,
|
|
135
|
-
proofFormat: proofFormat,
|
|
136
|
-
id,
|
|
137
|
-
issuer,
|
|
138
|
-
statuslistContentType: this.buildContentType(proofFormat),
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
async updateStatusListFromEncodedList(
|
|
143
|
-
args: UpdateStatusListFromEncodedListArgs,
|
|
144
|
-
context: IAgentContext<ICredentialPlugin & IIdentifierResolution>,
|
|
145
|
-
): Promise<StatusListResult> {
|
|
146
|
-
if (!args.bitstringStatusList) {
|
|
147
|
-
throw new Error('bitstringStatusList options required for type BitstringStatusList')
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
if (args.bitstringStatusList.bitsPerStatus < 1) {
|
|
151
|
-
return Promise.reject('bitsPerStatus must be set for bitstring status lists and must be 1 or higher. (updateStatusListFromEncodedList)')
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
const { statusPurpose, bitsPerStatus, ttl, validFrom, validUntil } = args.bitstringStatusList
|
|
155
|
-
|
|
156
|
-
const proofFormat: CredentialProofFormat = args?.proofFormat ?? DEFAULT_PROOF_FORMAT
|
|
157
|
-
assertValidProofType(StatusListType.BitstringStatusList, proofFormat)
|
|
158
|
-
const veramoProofFormat: VeramoProofFormat = proofFormat as VeramoProofFormat
|
|
159
|
-
|
|
160
|
-
const { issuer, id } = getAssertedValues(args)
|
|
161
|
-
const statusList: BitstreamStatusList = await BitstreamStatusList.decode({ encodedList: args.encodedList, statusSize: bitsPerStatus })
|
|
162
|
-
const index = typeof args.statusListIndex === 'number' ? args.statusListIndex : parseInt(args.statusListIndex)
|
|
163
|
-
statusList.setStatus(index, args.value)
|
|
164
|
-
|
|
165
|
-
const credential = await this.createVerifiableCredential(
|
|
166
|
-
{
|
|
167
|
-
id,
|
|
168
|
-
issuer,
|
|
169
|
-
statusList,
|
|
170
|
-
proofFormat: veramoProofFormat,
|
|
171
|
-
keyRef: args.keyRef,
|
|
172
|
-
statusPurpose,
|
|
173
|
-
validFrom,
|
|
174
|
-
validUntil,
|
|
175
|
-
ttl,
|
|
176
|
-
},
|
|
177
|
-
context,
|
|
178
|
-
)
|
|
179
|
-
|
|
180
|
-
return {
|
|
181
|
-
type: StatusListType.BitstringStatusList,
|
|
182
|
-
statusListCredential: credential,
|
|
183
|
-
encodedList: credential.credentialSubject.encodedList,
|
|
184
|
-
bitstringStatusList: {
|
|
185
|
-
statusPurpose,
|
|
186
|
-
bitsPerStatus,
|
|
187
|
-
...(credential.validFrom && { validFrom: new Date(credential.validFrom) }),
|
|
188
|
-
...(credential.validUntil && { validUntil: new Date(credential.validUntil) }),
|
|
189
|
-
ttl,
|
|
190
|
-
},
|
|
191
|
-
length: statusList.getLength(),
|
|
192
|
-
proofFormat: args.proofFormat ?? 'lds',
|
|
193
|
-
id: id,
|
|
194
|
-
issuer: issuer,
|
|
195
|
-
statuslistContentType: this.buildContentType(proofFormat),
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
async checkStatusIndex(args: CheckStatusIndexArgs): Promise<BitstringStatus> {
|
|
200
|
-
if (!args.bitsPerStatus || args.bitsPerStatus < 1) {
|
|
201
|
-
return Promise.reject('bitsPerStatus must be set for bitstring status lists and must be 1 or higher. (checkStatusIndex)')
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
const uniform = CredentialMapper.toUniformCredential(args.statusListCredential)
|
|
205
|
-
const { credentialSubject } = uniform
|
|
206
|
-
const encodedList = getAssertedProperty('encodedList', credentialSubject)
|
|
207
|
-
|
|
208
|
-
const statusSize = args.bitsPerStatus
|
|
209
|
-
const statusList = await BitstreamStatusList.decode({ encodedList, statusSize })
|
|
210
|
-
|
|
211
|
-
const numIndex = typeof args.statusListIndex === 'number' ? args.statusListIndex : parseInt(args.statusListIndex)
|
|
212
|
-
if (statusList.getLength() <= numIndex) {
|
|
213
|
-
throw new Error(`Status list index out of bounds, has ${statusList.getLength()} entries, requested ${numIndex}`)
|
|
214
|
-
}
|
|
215
|
-
return statusList.getStatus(numIndex)
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
async toStatusListDetails(args: ToStatusListDetailsArgs): Promise<StatusListResult> {
|
|
219
|
-
const { statusListPayload, bitsPerStatus } = args
|
|
220
|
-
if (!bitsPerStatus || bitsPerStatus < 1) {
|
|
221
|
-
return Promise.reject('bitsPerStatus must be set for bitstring status lists and must be 1 or higher. (toStatusListDetails)')
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
const uniform = CredentialMapper.toUniformCredential(statusListPayload)
|
|
225
|
-
const { issuer, credentialSubject } = uniform
|
|
226
|
-
const id = getAssertedValue('id', uniform.id)
|
|
227
|
-
const encodedList = getAssertedProperty('encodedList', credentialSubject)
|
|
228
|
-
const proofFormat: CredentialProofFormat = CredentialMapper.detectDocumentType(statusListPayload) === DocumentFormat.JWT ? 'jwt' : 'lds'
|
|
229
|
-
const credSubject = Array.isArray(credentialSubject) ? credentialSubject[0] : credentialSubject
|
|
230
|
-
const statusPurpose = getAssertedProperty('statusPurpose', credSubject)
|
|
231
|
-
const validFrom = uniform.validFrom ? new Date(uniform.validFrom) : undefined
|
|
232
|
-
const validUntil = uniform.validUntil ? new Date(uniform.validUntil) : undefined
|
|
233
|
-
const ttl = credSubject.ttl
|
|
234
|
-
const statuslistLength: number = BitstreamStatusList.getStatusListLength(encodedList, bitsPerStatus)
|
|
235
|
-
|
|
236
|
-
return {
|
|
237
|
-
id,
|
|
238
|
-
encodedList,
|
|
239
|
-
issuer,
|
|
240
|
-
type: StatusListType.BitstringStatusList,
|
|
241
|
-
proofFormat,
|
|
242
|
-
length: statuslistLength,
|
|
243
|
-
statusListCredential: statusListPayload,
|
|
244
|
-
statuslistContentType: this.buildContentType(proofFormat),
|
|
245
|
-
bitstringStatusList: {
|
|
246
|
-
statusPurpose,
|
|
247
|
-
bitsPerStatus,
|
|
248
|
-
validFrom,
|
|
249
|
-
validUntil,
|
|
250
|
-
ttl,
|
|
251
|
-
},
|
|
252
|
-
...(args.correlationId && { correlationId: args.correlationId }),
|
|
253
|
-
...(args.driverType && { driverType: args.driverType }),
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
private async createVerifiableCredential(
|
|
258
|
-
args: {
|
|
259
|
-
id: string
|
|
260
|
-
issuer: string | IIssuer
|
|
261
|
-
statusList?: BitstreamStatusList
|
|
262
|
-
proofFormat: VeramoProofFormat
|
|
263
|
-
statusPurpose: BitstringStatusPurpose
|
|
264
|
-
validFrom?: Date
|
|
265
|
-
validUntil?: Date
|
|
266
|
-
ttl?: number
|
|
267
|
-
keyRef?: string
|
|
268
|
-
},
|
|
269
|
-
context: IAgentContext<ICredentialPlugin & IIdentifierResolution>,
|
|
270
|
-
): Promise<BitstringStatusListCredential> {
|
|
271
|
-
const identifier = await context.agent.identifierManagedGet({
|
|
272
|
-
identifier: typeof args.issuer === 'string' ? args.issuer : args.issuer.id,
|
|
273
|
-
vmRelationship: 'assertionMethod',
|
|
274
|
-
offlineWhenNoDIDRegistered: true,
|
|
275
|
-
})
|
|
276
|
-
|
|
277
|
-
const unsignedCredential = await createStatusListCredential(args)
|
|
278
|
-
|
|
279
|
-
const verifiableCredential = await context.agent.createVerifiableCredential({
|
|
280
|
-
credential: unsignedCredential,
|
|
281
|
-
keyRef: args.keyRef ?? identifier.kmsKeyRef,
|
|
282
|
-
proofFormat: args.proofFormat,
|
|
283
|
-
fetchRemoteContexts: true,
|
|
284
|
-
})
|
|
285
|
-
|
|
286
|
-
return CredentialMapper.toWrappedVerifiableCredential(verifiableCredential as StatusListCredential).original as BitstringStatusListCredential
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
private buildContentType(proofFormat: CredentialProofFormat | undefined) {
|
|
290
|
-
switch (proofFormat) {
|
|
291
|
-
case 'jwt':
|
|
292
|
-
return `application/statuslist+jwt`
|
|
293
|
-
case 'cbor':
|
|
294
|
-
return `application/statuslist+cwt`
|
|
295
|
-
case 'lds':
|
|
296
|
-
return 'application/statuslist+ld+json'
|
|
297
|
-
default:
|
|
298
|
-
throw Error(`Unsupported content type '${proofFormat}' for status lists`)
|
|
299
|
-
}
|
|
300
|
-
}
|
|
301
|
-
}
|