diff --git a/src/configuration/authentication/VIDAuthenticationComponent.ts b/src/configuration/authentication/VIDAuthenticationComponent.ts index 89085ac..ec6dfda 100644 --- a/src/configuration/authentication/VIDAuthenticationComponent.ts +++ b/src/configuration/authentication/VIDAuthenticationComponent.ts @@ -11,8 +11,9 @@ import { CONSENT_ENTRYPOINT } from "../../authorization/constants"; import { GrantType } from "../../types/oid4vci"; import locale from "../locale"; import * as qrcode from 'qrcode'; -import { openidForPresentationReceivingService } from "../../services/instances"; +import { openidForPresentationReceivingService, verifierConfigurationService } from "../../services/instances"; import { UserAuthenticationMethod } from "../../types/UserAuthenticationMethod.enum"; +import { PresentationDefinitionTypeWithFormat } from "../verifier/VerifierConfigurationService"; export class VIDAuthenticationComponent extends AuthenticationComponent { @@ -115,8 +116,9 @@ export class VIDAuthenticationComponent extends AuthenticationComponent { } + const presentationDefinition = JSON.parse(JSON.stringify(verifierConfigurationService.getPresentationDefinitions().filter(pd => pd.id == "vid")[0])) as PresentationDefinitionTypeWithFormat; - const { url, stateId } = await openidForPresentationReceivingService.generateAuthorizationRequestURL({req, res}, "vid", config.url + CONSENT_ENTRYPOINT); + const { url, stateId } = await openidForPresentationReceivingService.generateAuthorizationRequestURL({req, res}, presentationDefinition, config.url + CONSENT_ENTRYPOINT); // attach the vid_auth_state with an authorization server state req.authorizationServerState.vid_auth_state = stateId; diff --git a/src/configuration/verifier/VerifierConfigurationService.ts b/src/configuration/verifier/VerifierConfigurationService.ts index bcf78fd..eeca6a1 100644 --- a/src/configuration/verifier/VerifierConfigurationService.ts +++ b/src/configuration/verifier/VerifierConfigurationService.ts @@ -4,6 +4,7 @@ import { authorizationServerMetadataConfiguration } from "../../authorizationSer import config from "../../../config"; import { VerifierConfigurationInterface } from "../../services/interfaces"; import { InputDescriptorType } from "@wwwallet/ssi-sdk"; +import "reflect-metadata"; export type PresentationDefinitionTypeWithFormat = { id: string; @@ -14,6 +15,7 @@ export type PresentationDefinitionTypeWithFormat = { @injectable() export class VerifierConfigurationService implements VerifierConfigurationInterface { + constructor() { } getPresentationDefinitions(): PresentationDefinitionTypeWithFormat[] { return [{ "id": "vid", // scope name diff --git a/src/services/OpenidForPresentationReceivingService.ts b/src/services/OpenidForPresentationReceivingService.ts index d588fa4..f59dae8 100644 --- a/src/services/OpenidForPresentationReceivingService.ts +++ b/src/services/OpenidForPresentationReceivingService.ts @@ -60,17 +60,12 @@ export class OpenidForPresentationsReceivingService implements OpenidForPresenta return payload; } - private async addVPtokenRequestSpecificAttributes(verifierStateId: string, payload: any, presentation_definition_id: string) { - const found = this.configurationService.getPresentationDefinitions().filter(pd => pd.id == presentation_definition_id); - console.log("Found = ", found[0]) - if (found.length > 0) { - const presentationDefinition = found[0]; - const verifierState = verifierStates.get(verifierStateId); - if (verifierState) { - verifierStates.set(verifierStateId, { ...verifierState, presentation_definition: presentationDefinition }) - payload = { ...payload, presentation_definition_uri: config.url + '/verification/definition?state=' + payload.state }; - return payload; - } + private async addVPtokenRequestSpecificAttributes(verifierStateId: string, payload: any, presentationDefinition: object) { + const verifierState = verifierStates.get(verifierStateId); + if (verifierState) { + verifierStates.set(verifierStateId, { ...verifierState, presentation_definition: presentationDefinition as any }) + payload = { ...payload, presentation_definition_uri: config.url + '/verification/definition?state=' + payload.state }; + return payload; } } @@ -87,7 +82,7 @@ export class OpenidForPresentationsReceivingService implements OpenidForPresenta } - async generateAuthorizationRequestURL(ctx: { req: Request, res: Response }, presentation_definition_id: string, callbackEndpoint?: string): Promise<{ url: URL; stateId: string }> { + async generateAuthorizationRequestURL(ctx: { req: Request, res: Response }, presentationDefinition: object, callbackEndpoint?: string): Promise<{ url: URL; stateId: string }> { const nonce = randomUUID(); const stateId = randomUUID(); nonces.set(nonce, stateId); @@ -106,7 +101,7 @@ export class OpenidForPresentationsReceivingService implements OpenidForPresenta const redirectUri = ctx.req?.authorizationServerState?.redirect_uri ?? "openid://cb"; verifierStates.set(stateId, { callbackEndpoint }); - payload = await this.addVPtokenRequestSpecificAttributes(stateId, payload, presentation_definition_id); + payload = await this.addVPtokenRequestSpecificAttributes(stateId, payload, presentationDefinition); console.log("Payload = ", payload) // const requestJwt = new SignJWT(payload) // .setExpirationTime('30s'); diff --git a/src/services/instances/index.ts b/src/services/instances/index.ts index 36c122e..89c216d 100644 --- a/src/services/instances/index.ts +++ b/src/services/instances/index.ts @@ -1,3 +1,4 @@ +import { VerifierConfigurationService } from "../../configuration/verifier/VerifierConfigurationService"; import { OpenidForCredentialIssuingAuthorizationServerService } from "../OpenidForCredentialIssuingAuthorizationServerService"; import { OpenidForPresentationsReceivingService } from "../OpenidForPresentationReceivingService"; import { appContainer } from "../inversify.config"; @@ -5,3 +6,4 @@ import { appContainer } from "../inversify.config"; export const openidForCredentialIssuingAuthorizationServerService = appContainer.resolve(OpenidForCredentialIssuingAuthorizationServerService); export const openidForPresentationReceivingService = appContainer.resolve(OpenidForPresentationsReceivingService); +export const verifierConfigurationService = appContainer.resolve(VerifierConfigurationService); \ No newline at end of file diff --git a/src/services/interfaces.ts b/src/services/interfaces.ts index 3f8070a..99c5acc 100644 --- a/src/services/interfaces.ts +++ b/src/services/interfaces.ts @@ -35,7 +35,7 @@ export interface OpenidForPresentationsReceivingInterface { - generateAuthorizationRequestURL(ctx: { req: Request, res: Response }, presentation_definition_id: string, directPostEndpoint?: string): Promise<{ url: URL; stateId: string }>; + generateAuthorizationRequestURL(ctx: { req: Request, res: Response }, presentationDefinition: object, directPostEndpoint?: string): Promise<{ url: URL; stateId: string }>; getPresentationDefinitionHandler(ctx: { req: Request, res: Response }): Promise; getPresentationByState(state: string): Promise<{ status: boolean, presentationClaims?: PresentationClaims, rawPresentation?: string }>; getPresentationById(id: string): Promise<{ status: boolean, presentationClaims?: PresentationClaims, rawPresentation?: string }>; diff --git a/src/verifier/verifierRouter.ts b/src/verifier/verifierRouter.ts index d6ee24f..8a877e7 100644 --- a/src/verifier/verifierRouter.ts +++ b/src/verifier/verifierRouter.ts @@ -9,6 +9,7 @@ import locale from "../configuration/locale"; import * as qrcode from 'qrcode'; import config from "../../config"; import base64url from "base64url"; +import { PresentationDefinitionTypeWithFormat } from "../configuration/verifier/VerifierConfigurationService"; const verifierRouter = Router(); // const verifiablePresentationRepository: Repository = AppDataSource.getRepository(VerifiablePresentationEntity); @@ -117,7 +118,7 @@ verifierRouter.use('/public/definitions/presentation-request/:presentation_defin }); } - const presentationDefinition = verifierConfiguration.getPresentationDefinitions().filter(pd => pd.id == presentation_definition_id)[0]; + const presentationDefinition = JSON.parse(JSON.stringify(verifierConfiguration.getPresentationDefinitions().filter(pd => pd.id == presentation_definition_id)[0])) as PresentationDefinitionTypeWithFormat; if (!presentationDefinition) { return res.render('error', { msg: "No presentation definition was found", @@ -141,13 +142,17 @@ verifierRouter.use('/public/definitions/presentation-request/:presentation_defin } })); // Filter existing paths to keep only those selected by the user and update presentationDefinition - const filteredConstraints = presentationDefinition.input_descriptors[0].constraints.fields.filter(field => - selectedPaths.has(field.path.join(',')) + const availableFields = presentationDefinition.input_descriptors[0].constraints.fields; + console.log("Available fields = ", availableFields) + const filteredFields = presentationDefinition.input_descriptors[0].constraints.fields.filter(field => + selectedPaths.has(field.path[0]) ); - presentationDefinition.input_descriptors[0].constraints.fields = filteredConstraints; + + console.log("filtered fields = ", filteredFields) + presentationDefinition.input_descriptors[0].constraints.fields = filteredFields; } - const { url } = await openidForPresentationReceivingService.generateAuthorizationRequestURL({req, res}, presentationDefinition.id, config.url + "/verifier/success"); + const { url } = await openidForPresentationReceivingService.generateAuthorizationRequestURL({req, res}, presentationDefinition, config.url + "/verifier/success"); let authorizationRequestQR = await new Promise((resolve) => { qrcode.toDataURL(url.toString(), { margin: 1, diff --git a/views/verifier/selectable_presentation.pug b/views/verifier/selectable_presentation.pug index 49349a0..d1f8198 100644 --- a/views/verifier/selectable_presentation.pug +++ b/views/verifier/selectable_presentation.pug @@ -20,7 +20,7 @@ block layout-content input(type='checkbox' id="personalIdentifier" name='fields' value='personalIdentifier') label(for='personalIdentifier') Personal Identifier .checkbox - input(type='checkbox' id="dateOfBirth" name='fields' value='dateOfBirth') - label(for='dateOfBirth') Date of Birth + input(type='checkbox' id="birthdate" name='fields' value='birthdate') + label(for='birthdate') Date of Birth button.btn.btn-primary(type='submit') Present link(rel="stylesheet" href="/styles/scan-qr-verifier.css") \ No newline at end of file