Skip to content

Commit 40ab713

Browse files
committed
chore: support for proofs array in credential request
1 parent 20aec3b commit 40ab713

1 file changed

Lines changed: 51 additions & 8 deletions

File tree

packages/issuer/lib/VcIssuer.ts

Lines changed: 51 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ import {
3434
OID4VCICredentialFormat,
3535
OpenId4VCIVersion,
3636
PRE_AUTH_GRANT_LITERAL,
37+
ProofOfPossession,
3738
QRCodeOpts,
3839
StatusListOpts,
3940
TokenErrorResponse,
@@ -675,16 +676,58 @@ export class VcIssuer {
675676
try {
676677
if (format && !supportedIssuanceFormats.includes(format)) {
677678
throw Error(`Format ${format} not supported yet`)
678-
} else if (typeof this._jwtVerifyCallback !== 'function' && typeof jwtVerifyCallback !== 'function') {
679-
throw new Error(JWT_VERIFY_CONFIG_ERROR)
680-
} else if (!credentialRequest.proof) {
681-
throw Error('Proof of possession is required. No proof value present in credential request')
682679
}
683680

684-
const jwtVerifyResult = jwtVerifyCallback
685-
? await jwtVerifyCallback(credentialRequest.proof)
686-
: // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
687-
await this._jwtVerifyCallback!(credentialRequest.proof)
681+
const verifyFn = jwtVerifyCallback ?? this._jwtVerifyCallback
682+
if (typeof verifyFn !== 'function') {
683+
throw Error(JWT_VERIFY_CONFIG_ERROR)
684+
}
685+
686+
const credReq = credentialRequest as CredentialRequestV1_0_15
687+
688+
// Validate request structure (mutually exclusive)
689+
if (credReq.proof && credReq.proofs) {
690+
throw Error('Credential request may not contain both proof and proofs parameters')
691+
}
692+
693+
// Normalize candidates into a single array
694+
const proofCandidates: Array<ProofOfPossession> = []
695+
696+
if (credReq.proof) {
697+
proofCandidates.push(credReq.proof)
698+
} else if (credReq.proofs) {
699+
// Handle "proofs": prioritize 'jwt' as it's the only fully supported type
700+
if (Array.isArray(credReq.proofs.jwt)) {
701+
proofCandidates.push(...credReq.proofs.jwt)
702+
}
703+
704+
// Check if there are no supported proofs found
705+
if (proofCandidates.length === 0) {
706+
const availableTypes = Object.keys(credReq.proofs).join(', ')
707+
throw Error(`No supported proof types found in request. Available: [${availableTypes}]`)
708+
}
709+
} else {
710+
throw Error('Proof of possession is required. No proof or proofs value present in credential request')
711+
}
712+
713+
// Execute verification
714+
let jwtVerifyResult: JwtVerifyResult | undefined
715+
const validationErrors: string[] = []
716+
717+
for (const proof of proofCandidates) {
718+
try {
719+
jwtVerifyResult = await verifyFn(proof)
720+
break
721+
} catch (error) {
722+
const msg = error instanceof Error ? error.message : String(error)
723+
validationErrors.push(msg)
724+
}
725+
}
726+
727+
// Check success
728+
if (!jwtVerifyResult) {
729+
throw Error(`Unable to verify any provided proofs. Errors: ${validationErrors.join('; ')}`)
730+
}
688731

689732
const { didDocument, did, jwt } = jwtVerifyResult
690733
const { header, payload } = jwt

0 commit comments

Comments
 (0)