diff --git a/apps/api-gateway/src/oid4vc-verification/dtos/create-intent-based-verification.dto.ts b/apps/api-gateway/src/oid4vc-verification/dtos/create-intent-based-verification.dto.ts index 10ca553d6..8d329ea7c 100644 --- a/apps/api-gateway/src/oid4vc-verification/dtos/create-intent-based-verification.dto.ts +++ b/apps/api-gateway/src/oid4vc-verification/dtos/create-intent-based-verification.dto.ts @@ -1,15 +1,8 @@ import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; import { IsDefined, IsEnum, IsOptional, IsString, ValidateNested } from 'class-validator'; import { Type } from 'class-transformer'; -import { SignerOption } from '@prisma/client'; import { ResponseMode } from '@credebl/enum/enum'; - -class RequestSignerDto { - @ApiProperty({ enum: SignerOption, example: SignerOption.DID }) - @IsDefined() - @IsEnum(SignerOption) - method: SignerOption; -} +import { RequestSignerDto } from './oid4vc-verifier-presentation.dto'; export class CreateIntentBasedVerificationDto { @ApiProperty({ description: 'Intent name to lookup template for', example: 'kyc-intent' }) diff --git a/apps/api-gateway/src/oid4vc-verification/dtos/oid4vc-verifier-presentation.dto.ts b/apps/api-gateway/src/oid4vc-verification/dtos/oid4vc-verifier-presentation.dto.ts index 1025a51b4..cf502af68 100644 --- a/apps/api-gateway/src/oid4vc-verification/dtos/oid4vc-verifier-presentation.dto.ts +++ b/apps/api-gateway/src/oid4vc-verification/dtos/oid4vc-verifier-presentation.dto.ts @@ -15,7 +15,7 @@ import { Matches } from 'class-validator'; import { Type } from 'class-transformer'; -import { ResponseMode } from '@credebl/enum/enum'; +import { ClientIdPrefix, ResponseMode } from '@credebl/enum/enum'; import { SignerOption } from '@prisma/client'; /** @@ -300,17 +300,27 @@ export class OnlyOneOfConstraint implements ValidatorConstraintInterface { } } +export class RequestSignerDto { + @ApiProperty({ enum: SignerOption, example: SignerOption.DID }) + @IsDefined() + @IsEnum(SignerOption) + method: SignerOption; + + @ApiPropertyOptional({ enum: ClientIdPrefix, example: ClientIdPrefix.X509Hash }) + @IsOptional() + @IsEnum(ClientIdPrefix) + clientIdPrefix?: ClientIdPrefix; +} + export class PresentationRequestDto { - @ApiPropertyOptional({ - example: { - method: 'DID' - }, - description: 'Signer option type' + @ApiProperty({ + type: RequestSignerDto, + description: 'Request signer option' }) - @IsOptional() - requestSigner?: { - method: SignerOption; - }; + @IsDefined() + @ValidateNested() + @Type(() => RequestSignerDto) + requestSigner: RequestSignerDto; @ApiPropertyOptional({ type: PresentationExchangeDto, diff --git a/apps/api-gateway/src/oid4vc-verification/oid4vc-verification.service.ts b/apps/api-gateway/src/oid4vc-verification/oid4vc-verification.service.ts index a8640e312..90c44d14b 100644 --- a/apps/api-gateway/src/oid4vc-verification/oid4vc-verification.service.ts +++ b/apps/api-gateway/src/oid4vc-verification/oid4vc-verification.service.ts @@ -26,8 +26,7 @@ export class Oid4vcVerificationService { userDetails: user ): Promise { const { intent, responseMode, requestSigner } = createIntentDto; - const signerOption = requestSigner?.method; - const payload = { orgId, verifierId, intent, responseMode, signerOption, userDetails }; + const payload = { orgId, verifierId, intent, responseMode, requestSigner, userDetails }; this.logger.debug( `[createIntentBasedVerificationPresentation] Called with orgId=${orgId}, verifierId=${verifierId}, intent=${intent}, user=${userDetails?.id}` ); diff --git a/apps/oid4vc-verification/interfaces/oid4vp-verification-sessions.interfaces.ts b/apps/oid4vc-verification/interfaces/oid4vp-verification-sessions.interfaces.ts index 381c96470..974b03986 100644 --- a/apps/oid4vc-verification/interfaces/oid4vp-verification-sessions.interfaces.ts +++ b/apps/oid4vc-verification/interfaces/oid4vp-verification-sessions.interfaces.ts @@ -1,4 +1,4 @@ -import { SignerMethodOption } from '@credebl/enum/enum'; +import { ClientIdPrefix, SignerMethodOption } from '@credebl/enum/enum'; export interface Oid4vpPresentationWh { id: string; @@ -19,6 +19,7 @@ export interface X5cSigner { method: SignerMethodOption.X5C; x5c: string[]; keyId: string; + clientIdPrefix?: ClientIdPrefix; } export type RequestSigner = DidSigner | X5cSigner; diff --git a/apps/oid4vc-verification/src/oid4vc-verification.controller.ts b/apps/oid4vc-verification/src/oid4vc-verification.controller.ts index cac03af7a..52ae1ee7d 100644 --- a/apps/oid4vc-verification/src/oid4vc-verification.controller.ts +++ b/apps/oid4vc-verification/src/oid4vc-verification.controller.ts @@ -1,7 +1,12 @@ import { Controller, Logger } from '@nestjs/common'; import { Oid4vpVerificationService } from './oid4vc-verification.service'; -import { SignerOption, user } from '@prisma/client'; -import { CreateVerifier, IPresentationRequest, UpdateVerifier } from '@credebl/common/interfaces/oid4vp-verification'; +import { user } from '@prisma/client'; +import { + CreateVerifier, + IPresentationRequest, + IRequestSigner, + UpdateVerifier +} from '@credebl/common/interfaces/oid4vp-verification'; import { MessagePattern } from '@nestjs/microservices'; import { VerificationSessionQuery } from '../interfaces/oid4vp-verifier.interfaces'; import { Oid4vpPresentationWh } from '../interfaces/oid4vp-verification-sessions.interfaces'; @@ -102,10 +107,10 @@ export class Oid4vpVerificationController { verifierId: string; intent: string; responseMode: string; - signerOption: SignerOption; + requestSigner: IRequestSigner; userDetails: user; }): Promise { - const { orgId, verifierId, intent, responseMode, signerOption, userDetails } = payload; + const { orgId, verifierId, intent, responseMode, requestSigner, userDetails } = payload; this.logger.debug( `[createIntentBasedVerificationPresentation] Received 'oid4vp-intent-based-verification-presentation' for orgId=${orgId}, verifierId=${verifierId}, intent=${intent}, user=${userDetails?.id ?? 'unknown'}` ); @@ -114,7 +119,7 @@ export class Oid4vpVerificationController { verifierId, intent, responseMode, - signerOption, + requestSigner, userDetails ); } diff --git a/apps/oid4vc-verification/src/oid4vc-verification.service.ts b/apps/oid4vc-verification/src/oid4vc-verification.service.ts index 1884abb7f..3c8862d19 100644 --- a/apps/oid4vc-verification/src/oid4vc-verification.service.ts +++ b/apps/oid4vc-verification/src/oid4vc-verification.service.ts @@ -21,7 +21,12 @@ import { ClientProxy, RpcException } from '@nestjs/microservices'; import { getAgentUrl } from '@credebl/common/common.utils'; import { SignerOption, user } from '@prisma/client'; import { map } from 'rxjs'; -import { CreateVerifier, UpdateVerifier, VerifierRecord } from '@credebl/common/interfaces/oid4vp-verification'; +import { + CreateVerifier, + IRequestSigner, + UpdateVerifier, + VerifierRecord +} from '@credebl/common/interfaces/oid4vp-verification'; import { buildUrlWithQuery } from '@credebl/common/cast.helper'; import { VerificationSessionQuery } from '../interfaces/oid4vp-verifier.interfaces'; import { BaseService } from 'libs/service/base.service'; @@ -249,7 +254,8 @@ export class Oid4vpVerificationService extends BaseService { requestSigner = { method: SignerMethodOption.X5C, // "x5c" x5c: [activeCertificate.certificateBase64], // array with PEM/DER base64 - keyId: activeCertificate.keyId + keyId: activeCertificate.keyId, + clientIdPrefix: sessionRequest.requestSigner.clientIdPrefix }; } else if (sessionRequest.requestSigner.method === SignerOption.X509_ED25519) { this.logger.debug('X5C based request signer method selected'); @@ -268,7 +274,8 @@ export class Oid4vpVerificationService extends BaseService { requestSigner = { method: SignerMethodOption.X5C, // "x5c" x5c: [activeCertificate.certificateBase64], // array with PEM/DER base64 - keyId: activeCertificate.keyId + keyId: activeCertificate.keyId, + clientIdPrefix: sessionRequest.requestSigner.clientIdPrefix }; } else { throw new BadRequestException(`Unsupported requestSigner method: ${sessionRequest.requestSigner.method}`); @@ -300,7 +307,7 @@ export class Oid4vpVerificationService extends BaseService { verifierId: string, intent: string, responseMode: string, - signerOption: SignerOption, + requestSigner: IRequestSigner, userDetails: user ): Promise { this.logger.debug( @@ -348,6 +355,7 @@ export class Oid4vpVerificationService extends BaseService { // Handle request signer based on method let resolvedSigner: RequestSigner | undefined; + const signerOption = requestSigner?.method; if (signerOption === SignerOption.DID) { resolvedSigner = { @@ -372,7 +380,8 @@ export class Oid4vpVerificationService extends BaseService { resolvedSigner = { method: SignerMethodOption.X5C, x5c: [activeCertificate.certificateBase64], - keyId: activeCertificate.keyId + keyId: activeCertificate.keyId, + clientIdPrefix: requestSigner.clientIdPrefix // Pass through clientIdPrefix if provided }; } else { throw new BadRequestException(`Unsupported requestSigner method: ${signerOption}`); diff --git a/libs/common/src/interfaces/oid4vp-verification.ts b/libs/common/src/interfaces/oid4vp-verification.ts index e93cdd81e..91f54da7f 100644 --- a/libs/common/src/interfaces/oid4vp-verification.ts +++ b/libs/common/src/interfaces/oid4vp-verification.ts @@ -1,3 +1,6 @@ +import { ClientIdPrefix } from '@credebl/enum/enum'; +import { SignerOption } from '@prisma/client'; + export interface ClientMetadata { client_name: string; logo_uri: string; @@ -36,7 +39,8 @@ export enum OpenId4VcVerificationPresentationState { * Request signer configuration for OID4VP verification presentations */ export interface IRequestSigner { - method: string; // SignerOption enum value: 'DID', 'X509_P256', 'X509_ED25519' + method: SignerOption; // SignerOption enum value: 'DID', 'X509_P256', 'X509_ED25519', + clientIdPrefix?: ClientIdPrefix; } /** diff --git a/libs/enum/src/enum.ts b/libs/enum/src/enum.ts index a0a8e0f0d..973820194 100755 --- a/libs/enum/src/enum.ts +++ b/libs/enum/src/enum.ts @@ -394,3 +394,8 @@ export enum NotificationStatus { DATA_PURGED_AND_NOTIFIED_WITH_FCM = 'DataPurgedAndNotifiedWithFCM', NOTIFICATION_CONSUMED = 'NotificationConsumed' } + +export enum ClientIdPrefix { + X509SanDns = 'x509_san_dns', + X509Hash = 'x509_hash' +}