Skip to content

Commit 64254e4

Browse files
committed
fix: typing and other minor issues while verifying Bitstring status list credential
Signed-off-by: Krishna Waske <[email protected]>
1 parent a722ab6 commit 64254e4

File tree

3 files changed

+86
-50
lines changed

3 files changed

+86
-50
lines changed

packages/core/src/modules/vc/models/credential/w3c-credential-status/W3cCredentialStatus.ts

Lines changed: 42 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,22 @@
11
import { plainToInstance } from 'class-transformer'
2-
import { IsString, validateOrReject } from 'class-validator'
2+
import { IsEnum, IsString, validateOrReject } from 'class-validator'
33

44
import { AgentContext } from '../../../../../agent/context'
55
import { CredoError } from '../../../../../error'
66
import { IsUri } from '../../../../../utils/validators'
77

8+
import { BitStringStatusListEntry } from './bitstring-status-list/BitStringStatusList'
9+
import { verifyBitStringCredentialStatus } from './bitstring-status-list/VerifyBitStringCredentialStatus'
10+
811
export interface W3cCredentialStatusOptions {
912
id: string
1013
type: string
1114
}
1215

16+
export enum W3cCredentialStatusSupportedTypes {
17+
BitstringStatusListEntry = 'BitstringStatusListEntry',
18+
}
19+
1320
export class W3cCredentialStatus {
1421
public constructor(options: W3cCredentialStatusOptions) {
1522
if (options) {
@@ -23,6 +30,7 @@ export class W3cCredentialStatus {
2330
public id!: string
2431

2532
@IsString()
33+
@IsEnum(W3cCredentialStatusSupportedTypes, { message: 'Invalid credential status type' })
2634
public type!: string
2735
}
2836

@@ -31,15 +39,43 @@ export const validateStatus = async (
3139
status: W3cCredentialStatus | W3cCredentialStatus[],
3240
agentContext: AgentContext
3341
): Promise<boolean> => {
34-
const entry = plainToInstance(W3cCredentialStatus, status)
42+
let entry
43+
44+
if (Array.isArray(status)) {
45+
agentContext.config.logger.debug('Credential status type is array')
46+
throw new CredoError(
47+
'Invalid credential status type. Currently only a single credentialStatus is supported per credential'
48+
)
49+
} else entry = status
50+
51+
switch (entry.type) {
52+
case W3cCredentialStatusSupportedTypes.BitstringStatusListEntry:
53+
agentContext.config.logger.debug('Credential status type is BitstringStatusListEntry')
54+
entry = plainToInstance(BitStringStatusListEntry, entry)
55+
break
56+
default:
57+
throw new CredoError(
58+
`Invalid credential status type. Supported types are: ${Object.values(W3cCredentialStatusSupportedTypes).join(
59+
', '
60+
)}`
61+
)
62+
}
3563

3664
try {
3765
await validateOrReject(entry)
66+
switch (entry.type) {
67+
case W3cCredentialStatusSupportedTypes.BitstringStatusListEntry:
68+
await verifyBitStringCredentialStatus(entry, agentContext)
69+
break
70+
default:
71+
throw new CredoError(
72+
`Invalid credential status type. Supported types are: ${Object.values(W3cCredentialStatusSupportedTypes).join(
73+
', '
74+
)}`
75+
)
76+
}
3877
return true
3978
} catch (errors) {
40-
agentContext.config.logger.debug(`Credential status validation failed: ${errors}`, {
41-
stack: errors,
42-
})
43-
throw new CredoError(`Invalid credential status type: ${errors}`)
79+
throw new CredoError(`Error while validating credential status`, errors)
4480
}
4581
}

packages/core/src/modules/vc/models/credential/w3c-credential-status/bitstring-status-list/BitStringStatusList.ts

Lines changed: 37 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@ import { Type } from 'class-transformer'
22
import { IsEnum, IsNumber, IsString } from 'class-validator'
33

44
import { JsonLdCredentialDetail, W3cCredentialSubject } from '../../../../../..'
5-
import { W3cCredential } from '../../W3cCredential'
5+
import { W3cCredential, W3cCredentialOptions } from '../../W3cCredential'
66
import { W3cCredentialStatus } from '../W3cCredentialStatus'
77

88
// The purpose can be anything apart from this as well
99
export enum BitstringStatusListCredentialStatusPurpose {
10-
'revocation' = 'revocation',
11-
'suspension' = 'suspension',
10+
Revocation = 'revocation',
11+
Suspension = 'suspension',
1212
}
1313

1414
export interface BitStringStatusListMessageOptions {
@@ -36,16 +36,23 @@ export class BitStringStatusListMessage {
3636
[key: string]: unknown | undefined
3737
}
3838

39+
/**
40+
* Status list Entry, used to check status of a credential being issued or verified during presentaton.
41+
*
42+
* @see https://www.w3.org/TR/vc-bitstring-status-list/#bitstringstatuslistentry
43+
*/
3944
export class BitStringStatusListEntry extends W3cCredentialStatus {
40-
public constructor(options: {
41-
id: string
42-
serviceEndpoint: string
43-
recipientKeys: string[]
44-
routingKeys?: string[]
45-
accept?: string[]
46-
priority?: number
47-
}) {
45+
public constructor(options: IBitStringStatusListEntryOptions) {
4846
super({ ...options, type: BitStringStatusListEntry.type })
47+
48+
if (options) {
49+
this.statusPurpose = options.statusPurpose
50+
this.statusListCredential = options.statusListCredential
51+
this.statusListIndex = options.statusListIndex
52+
53+
if (options.statusSize) this.statusSize = options.statusSize
54+
if (options.statusMessage) this.statusMessage = options.statusMessage
55+
}
4956
}
5057
public static type = 'BitstringStatusListEntry'
5158

@@ -75,12 +82,11 @@ export interface BitStringStatusListStatusMessage {
7582
[key: string]: unknown
7683
}
7784

78-
export interface IBitStringStatusListCredentialStatus {
85+
export interface IBitStringStatusListEntryOptions {
7986
id: string
80-
// Since currenlty we are only trying to support 'BitStringStatusListEntry'
8187
type: 'BitstringStatusListEntry'
8288
statusPurpose: BitstringStatusListCredentialStatusPurpose
83-
// Unique identifier for the specific credential
89+
// Unique identifier for specific credential
8490
statusListIndex: string
8591
// Must be url referencing to a VC of type 'BitstringStatusListCredential'
8692
statusListCredential: string
@@ -105,28 +111,33 @@ export class BitStringStatusListCredentialDetail extends JsonLdCredentialDetail
105111
public credential!: BitStringStatusListCredentialStatus
106112
}
107113

114+
/**
115+
* StatusListCredential describes the format of the verifiable credential that encapsulates the status list.
116+
*
117+
* @see https://www.w3.org/TR/vc-bitstring-status-list/#bitstringstatuslistcredential
118+
*/
108119
export class BitStringStatusListCredential extends W3cCredential {
109-
public constructor(options: {
110-
id: string
111-
serviceEndpoint: string
112-
recipientKeys: string[]
113-
routingKeys?: string[] | undefined
114-
accept?: string[]
115-
priority?: number
116-
issuer: string
117-
issuanceDate: string
118-
credentialSubject: BitStringStatusListCredentialSubject
119-
}) {
120+
public constructor(options: IBitStringStatusListCredentialOptions) {
120121
super({
121122
...options,
122-
type: ['VerifiableCredential', BitStringStatusListEntry.type],
123+
type: BitStringStatusListCredential.type,
123124
})
125+
126+
if (options) {
127+
this.credentialSubject = options.credentialSubject
128+
}
124129
}
130+
public static type = ['VerifiableCredential', 'BitstringStatusListCredential']
125131

126132
@IsString()
127133
public credentialSubject!: BitStringStatusListCredentialSubject
128134
}
129135

136+
export interface IBitStringStatusListCredentialOptions extends Omit<W3cCredentialOptions, 'credentialStatus'> {
137+
type: ['VerifiableCredential', 'BitstringStatusListCredential']
138+
credentialSubject: BitStringStatusListCredentialSubject
139+
}
140+
130141
// Define an interface for `credentialSubject`
131142
export interface BitStringStatusListCredentialSubject extends W3cCredentialSubject {
132143
type: 'BitstringStatusList'

packages/core/src/modules/vc/models/credential/w3c-credential-status/bitstring-status-list/VerifyBitStringCredentialStatus.ts

Lines changed: 7 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
1-
import type { BitStringStatusListCredentialStatus, BitStringStatusListCredential } from './BitStringStatusList'
1+
import type { BitStringStatusListCredential, BitStringStatusListEntry } from './BitStringStatusList'
22
import type { AgentContext } from '../../../../../../agent/context'
33

44
import * as pako from 'pako'
55

66
import { CredoError } from '../../../../../../error'
7-
import { validateStatus } from '../W3cCredentialStatus'
87

98
// Function to fetch and parse the bit string status list credential
109
const fetchBitStringStatusListCredential = async (
@@ -14,7 +13,7 @@ const fetchBitStringStatusListCredential = async (
1413
const response = await agentContext.config.agentDependencies.fetch(url, { method: 'GET' })
1514

1615
if (!response.ok) {
17-
throw new CredoError(`Failed to fetch bit string status list. HTTP Status: ${response.status}`)
16+
throw new CredoError(`Failed to fetch BitStringStatusListCredential status list. HTTP Status: ${response.status}`)
1817
}
1918

2019
try {
@@ -25,24 +24,14 @@ const fetchBitStringStatusListCredential = async (
2524
}
2625

2726
export const verifyBitStringCredentialStatus = async (
28-
credential: BitStringStatusListCredentialStatus,
27+
credentialStatus: BitStringStatusListEntry,
2928
agentContext: AgentContext
3029
) => {
31-
const { credentialStatus } = credential
32-
3330
if (Array.isArray(credentialStatus)) {
34-
throw new CredoError('Verifying credential status as an array for JSON-LD credentials is currently not supported')
35-
}
36-
37-
if (!credentialStatus || credentialStatus.statusListIndex === undefined) {
38-
throw new CredoError('Invalid credential status format')
39-
}
40-
41-
// Validate credentialStatus using the class-based approach
42-
const isValid = await validateStatus(credentialStatus, agentContext)
43-
44-
if (!isValid) {
45-
throw new CredoError('Invalid credential status type. Expected BitstringStatusList')
31+
agentContext.config.logger.debug('Credential status type is array')
32+
throw new CredoError(
33+
'Invalid credential status type. Currently only a single BitstringStatusListEntry is supported per credential'
34+
)
4635
}
4736

4837
// Fetch the bit string status list credential

0 commit comments

Comments
 (0)