Skip to content

Commit 9f66078

Browse files
committed
chore: add zod validator to di-vp-proof
Signed-off-by: Sebastian Dechant <763247+S3bb1@users.noreply.github.com>
1 parent d2adb26 commit 9f66078

2 files changed

Lines changed: 25 additions & 19 deletions

File tree

packages/openid4vci/src/formats/proof-type/di-vp/di-vp-proof-type.ts

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import type { CallbackContext } from '@openid4vc/oauth2'
2+
import { parseWithErrorHandling } from '@openid4vc/utils'
23
import { Openid4vciError } from '../../../error/Openid4vciError'
4+
import { DataIntegrityProof, zDataIntegrityProof } from './z-di-vp-proof-type'
35

46
export interface VerifyCredentialRequestDiVpProofOptions {
57
/**
@@ -39,21 +41,17 @@ export async function verifyCredentialRequestDiVpProof(options: VerifyCredential
3941
throw new Openid4vciError('Nonce used for credential request proof expired')
4042
}
4143

42-
const rawProof = options.vp.proof
43-
const proof = (Array.isArray(rawProof) ? rawProof[0] : rawProof) as Record<string, unknown> | undefined
44-
45-
if (!proof || typeof proof !== 'object') {
44+
const rawProof = (options.vp as { proof?: unknown }).proof
45+
if (rawProof === undefined) {
4646
throw new Openid4vciError(`di_vp proof is missing a 'proof' entry`)
4747
}
48-
if (proof.type !== 'DataIntegrityProof') {
49-
throw new Openid4vciError(`di_vp proof 'proof.type' must be 'DataIntegrityProof'`)
50-
}
51-
if (!proof.cryptosuite || typeof proof.cryptosuite !== 'string') {
52-
throw new Openid4vciError(`di_vp proof is missing required 'proof.cryptosuite'`)
53-
}
54-
if (proof.proofPurpose !== 'authentication') {
55-
throw new Openid4vciError(`di_vp proof 'proof.proofPurpose' must be 'authentication'`)
56-
}
48+
49+
const proof = parseWithErrorHandling(
50+
zDataIntegrityProof,
51+
Array.isArray(rawProof) ? rawProof[0] : rawProof,
52+
'di_vp proof contains an invalid proof entry'
53+
) satisfies DataIntegrityProof;
54+
5755
if (proof.domain !== options.credentialIssuer) {
5856
throw new Openid4vciError(`di_vp proof 'proof.domain' does not match the credential issuer identifier`)
5957
}
@@ -64,9 +62,6 @@ export async function verifyCredentialRequestDiVpProof(options: VerifyCredential
6462
} else if (proof.challenge !== undefined) {
6563
throw new Openid4vciError(`di_vp proof 'proof.challenge' must not be present when no nonce was issued`)
6664
}
67-
if (!proof.verificationMethod || typeof proof.verificationMethod !== 'string') {
68-
throw new Openid4vciError(`di_vp proof is missing required 'proof.verificationMethod'`)
69-
}
7065

7166
if (!options.callbacks.verifyDataIntegrityProof) {
7267
throw new Openid4vciError('Cannot verify di_vp proof: no verifyDataIntegrityProof callback configured')

packages/openid4vci/src/formats/proof-type/di-vp/z-di-vp-proof-type.ts

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,21 @@ export const zDiVpProofTypeIdentifier = z.literal('di_vp')
44
export const diVpProofTypeIdentifier = zDiVpProofTypeIdentifier.value
55
export type DiVpProofTypeIdentifier = z.infer<typeof zDiVpProofTypeIdentifier>
66

7-
// No JSON-LD/VC/DataIntegrity schema exists in this library and it's not this library's job to
8-
// validate that structure — that's the caller's job via its own stack. Loose passthrough is
9-
// intentional.
107
export const zCredentialRequestProofDiVp = z.object({
118
proof_type: zDiVpProofTypeIdentifier,
129
di_vp: z.record(z.string(), z.unknown()),
1310
})
11+
12+
export const zDataIntegrityProof = z
13+
.object({
14+
type: z.literal('DataIntegrityProof', { message: `di_vp proof 'proof.type' must be 'DataIntegrityProof'` }),
15+
cryptosuite: z.string({ message: `di_vp proof is missing required 'proof.cryptosuite'` }),
16+
proofPurpose: z.literal('authentication', {
17+
message: `di_vp proof 'proof.proofPurpose' must be 'authentication'`,
18+
}),
19+
domain: z.string(),
20+
challenge: z.string().optional(),
21+
verificationMethod: z.string({ message: `di_vp proof is missing required 'proof.verificationMethod'` }),
22+
})
23+
.loose()
24+
export type DataIntegrityProof = z.infer<typeof zDataIntegrityProof>

0 commit comments

Comments
 (0)