From 87a8dc8c44ff10128bff7a467be476228487e7df Mon Sep 17 00:00:00 2001 From: mkuhn Date: Wed, 10 Dec 2025 15:58:03 +0100 Subject: [PATCH 1/5] feat: presentation request requests --- .../src/consumption/ConsumptionController.ts | 5 +- ...estRequestItemProcessedByRecipientEvent.ts | 16 +++++ .../src/modules/requests/events/index.ts | 1 + .../consumption/src/modules/requests/index.ts | 3 +- ...uthorizationRequestRequestItemProcessor.ts | 56 +++++++++++++++++ ...hareCredentialOfferRequestItemProcessor.ts | 0 packages/content/src/requests/RequestItem.ts | 15 +++-- packages/content/src/requests/items/index.ts | 3 +- .../ShareAuthorizationRequestRequestItem.ts | 29 +++++++++ .../ShareCredentialOfferRequestItem.ts | 0 .../runtime/src/dataViews/DataViewExpander.ts | 24 ++++++++ .../src/dataViews/content/RequestItemDVOs.ts | 6 ++ .../test/consumption/openid4vc.test.ts | 60 +++++++++++++++++++ 13 files changed, 211 insertions(+), 7 deletions(-) create mode 100644 packages/consumption/src/modules/requests/events/ShareAuthorizationRequestRequestItemProcessedByRecipientEvent.ts create mode 100644 packages/consumption/src/modules/requests/itemProcessors/openid4vc/ShareAuthorizationRequestRequestItemProcessor.ts rename packages/consumption/src/modules/requests/itemProcessors/{shareCredentialOffer => openid4vc}/ShareCredentialOfferRequestItemProcessor.ts (100%) create mode 100644 packages/content/src/requests/items/openid4vc/ShareAuthorizationRequestRequestItem.ts rename packages/content/src/requests/items/{shareCredentialOffer => openid4vc}/ShareCredentialOfferRequestItem.ts (100%) diff --git a/packages/consumption/src/consumption/ConsumptionController.ts b/packages/consumption/src/consumption/ConsumptionController.ts index d116e4dd9..5feefa0c2 100644 --- a/packages/consumption/src/consumption/ConsumptionController.ts +++ b/packages/consumption/src/consumption/ConsumptionController.ts @@ -11,6 +11,7 @@ import { ProposeAttributeRequestItem, ReadAttributeRequestItem, ShareAttributeRequestItem, + ShareAuthorizationRequestRequestItem, ShareCredentialOfferRequestItem, TransferFileOwnershipRequestItem } from "@nmshd/content"; @@ -45,6 +46,7 @@ import { ShareCredentialOfferRequestItemProcessor, TransferFileOwnershipRequestItemProcessor } from "../modules"; +import { ShareAuthorizationRequestRequestItemProcessor } from "../modules/requests/itemProcessors/openid4vc/ShareAuthorizationRequestRequestItemProcessor"; import { ConsumptionConfig } from "./ConsumptionConfig"; export class ConsumptionController { @@ -163,7 +165,8 @@ export class ConsumptionController { [AuthenticationRequestItem, GenericRequestItemProcessor], [FormFieldRequestItem, FormFieldRequestItemProcessor], [TransferFileOwnershipRequestItem, TransferFileOwnershipRequestItemProcessor], - [ShareCredentialOfferRequestItem, ShareCredentialOfferRequestItemProcessor] + [ShareCredentialOfferRequestItem, ShareCredentialOfferRequestItemProcessor], + [ShareAuthorizationRequestRequestItem, ShareAuthorizationRequestRequestItemProcessor] ]); } diff --git a/packages/consumption/src/modules/requests/events/ShareAuthorizationRequestRequestItemProcessedByRecipientEvent.ts b/packages/consumption/src/modules/requests/events/ShareAuthorizationRequestRequestItemProcessedByRecipientEvent.ts new file mode 100644 index 000000000..1896a9f7b --- /dev/null +++ b/packages/consumption/src/modules/requests/events/ShareAuthorizationRequestRequestItemProcessedByRecipientEvent.ts @@ -0,0 +1,16 @@ +import { CoreAddress } from "@nmshd/core-types"; +import { TransportDataEvent } from "@nmshd/transport"; + +export interface ShareAuthorizationRequestRequestItemProcessedByRecipientEventData { + authorizationRequestUrl: string; + accepted: boolean; + peer: CoreAddress; +} + +export class ShareAuthorizationRequestRequestItemProcessedByRecipientEvent extends TransportDataEvent { + public static readonly namespace = "consumption.shareAuthorizationRequestRequestItemProcessedByRecipient"; + + public constructor(eventTargetAddress: string, data: ShareAuthorizationRequestRequestItemProcessedByRecipientEventData) { + super(ShareAuthorizationRequestRequestItemProcessedByRecipientEvent.namespace, eventTargetAddress, data); + } +} diff --git a/packages/consumption/src/modules/requests/events/index.ts b/packages/consumption/src/modules/requests/events/index.ts index 36068ce3f..ef9dd5c9e 100644 --- a/packages/consumption/src/modules/requests/events/index.ts +++ b/packages/consumption/src/modules/requests/events/index.ts @@ -3,4 +3,5 @@ export * from "./IncomingRequestStatusChangedEvent"; export * from "./OutgoingRequestCreatedAndCompletedEvent"; export * from "./OutgoingRequestCreatedEvent"; export * from "./OutgoingRequestStatusChangedEvent"; +export * from "./ShareAuthorizationRequestRequestItemProcessedByRecipientEvent"; export * from "./ShareCredentialOfferRequestItemProcessedByRecipientEvent"; diff --git a/packages/consumption/src/modules/requests/index.ts b/packages/consumption/src/modules/requests/index.ts index 985d56e91..32f7aaeb2 100644 --- a/packages/consumption/src/modules/requests/index.ts +++ b/packages/consumption/src/modules/requests/index.ts @@ -18,6 +18,8 @@ export * from "./itemProcessors/formField/AcceptFormFieldRequestItemParameters"; export * from "./itemProcessors/formField/FormFieldRequestItemProcessor"; export * from "./itemProcessors/GenericRequestItemProcessor"; export * from "./itemProcessors/IRequestItemProcessor"; +export * from "./itemProcessors/openid4vc/ShareAuthorizationRequestRequestItemProcessor"; +export * from "./itemProcessors/openid4vc/ShareCredentialOfferRequestItemProcessor"; export * from "./itemProcessors/proposeAttribute/AcceptProposeAttributeRequestItemParameters"; export * from "./itemProcessors/proposeAttribute/ProposeAttributeRequestItemProcessor"; export { @@ -30,7 +32,6 @@ export * from "./itemProcessors/RequestItemConstructor"; export * from "./itemProcessors/RequestItemProcessorConstructor"; export * from "./itemProcessors/RequestItemProcessorRegistry"; export * from "./itemProcessors/shareAttribute/ShareAttributeRequestItemProcessor"; -export * from "./itemProcessors/shareCredentialOffer/ShareCredentialOfferRequestItemProcessor"; export * from "./itemProcessors/transferFileOwnership/TransferFileOwnershipRequestItemProcessor"; export * from "./local/LocalRequest"; export * from "./local/LocalRequestStatus"; diff --git a/packages/consumption/src/modules/requests/itemProcessors/openid4vc/ShareAuthorizationRequestRequestItemProcessor.ts b/packages/consumption/src/modules/requests/itemProcessors/openid4vc/ShareAuthorizationRequestRequestItemProcessor.ts new file mode 100644 index 000000000..7df80bcf6 --- /dev/null +++ b/packages/consumption/src/modules/requests/itemProcessors/openid4vc/ShareAuthorizationRequestRequestItemProcessor.ts @@ -0,0 +1,56 @@ +import { AcceptResponseItem, RejectResponseItem, ResponseItemResult, ShareAuthorizationRequestRequestItem } from "@nmshd/content"; +import { ConsumptionCoreErrors } from "../../../../consumption/ConsumptionCoreErrors"; +import { ValidationResult } from "../../../common/ValidationResult"; +import { ShareAuthorizationRequestRequestItemProcessedByRecipientEvent } from "../../events"; +import { AcceptRequestItemParametersJSON } from "../../incoming/decide/AcceptRequestItemParameters"; +import { GenericRequestItemProcessor } from "../GenericRequestItemProcessor"; +import { LocalRequestInfo } from "../IRequestItemProcessor"; + +export class ShareAuthorizationRequestRequestItemProcessor extends GenericRequestItemProcessor { + public override async canAccept( + requestItem: ShareAuthorizationRequestRequestItem, + _params: AcceptRequestItemParametersJSON, + _requestInfo: LocalRequestInfo + ): Promise { + try { + const resolvedAuthorizationRequest = await this.consumptionController.openId4Vc.resolveAuthorizationRequest(requestItem.authorizationRequestUrl); + if (resolvedAuthorizationRequest.matchingCredentials.length === 0) { + return ValidationResult.error( + ConsumptionCoreErrors.requests.invalidRequestItem( + `The authorization request at URL '${requestItem.authorizationRequestUrl}' can't be fulfilled with currently available credentials.` + ) + ); + } + return ValidationResult.success(); + } catch (error) { + return ValidationResult.error( + ConsumptionCoreErrors.requests.invalidRequestItem( + `The authorization request at URL '${requestItem.authorizationRequestUrl}' could not be processed. Cause: ${error}` + ) + ); + } + } + + public override async accept( + requestItem: ShareAuthorizationRequestRequestItem, + _params: AcceptRequestItemParametersJSON, + _requestInfo: LocalRequestInfo + ): Promise { + const resolvedAuthorizationRequest = await this.consumptionController.openId4Vc.resolveAuthorizationRequest(requestItem.authorizationRequestUrl); + await this.consumptionController.openId4Vc.acceptAuthorizationRequest(resolvedAuthorizationRequest.authorizationRequest); + + return AcceptResponseItem.from({ result: ResponseItemResult.Accepted }); + } + + public override applyIncomingResponseItem( + responseItem: AcceptResponseItem | RejectResponseItem, + requestItem: ShareAuthorizationRequestRequestItem, + requestInfo: LocalRequestInfo + ): ShareAuthorizationRequestRequestItemProcessedByRecipientEvent { + return new ShareAuthorizationRequestRequestItemProcessedByRecipientEvent(this.currentIdentityAddress.toString(), { + authorizationRequestUrl: requestItem.authorizationRequestUrl, + accepted: responseItem.result === ResponseItemResult.Accepted, + peer: requestInfo.peer + }); + } +} diff --git a/packages/consumption/src/modules/requests/itemProcessors/shareCredentialOffer/ShareCredentialOfferRequestItemProcessor.ts b/packages/consumption/src/modules/requests/itemProcessors/openid4vc/ShareCredentialOfferRequestItemProcessor.ts similarity index 100% rename from packages/consumption/src/modules/requests/itemProcessors/shareCredentialOffer/ShareCredentialOfferRequestItemProcessor.ts rename to packages/consumption/src/modules/requests/itemProcessors/openid4vc/ShareCredentialOfferRequestItemProcessor.ts diff --git a/packages/content/src/requests/RequestItem.ts b/packages/content/src/requests/RequestItem.ts index 27bb7fbab..7db0cc5a3 100644 --- a/packages/content/src/requests/RequestItem.ts +++ b/packages/content/src/requests/RequestItem.ts @@ -19,6 +19,7 @@ import { IProposeAttributeRequestItem, IReadAttributeRequestItem, IShareAttributeRequestItem, + IShareAuthorizationRequestRequestItem, IShareCredentialOfferRequestItem, ITransferFileOwnershipRequestItem, ProposeAttributeRequestItem, @@ -27,6 +28,8 @@ import { ReadAttributeRequestItemJSON, ShareAttributeRequestItem, ShareAttributeRequestItemJSON, + ShareAuthorizationRequestRequestItem, + ShareAuthorizationRequestRequestItemJSON, ShareCredentialOfferRequestItem, ShareCredentialOfferRequestItemJSON, TransferFileOwnershipRequestItem, @@ -65,7 +68,8 @@ export type RequestItemJSONDerivations = | AuthenticationRequestItemJSON | FormFieldRequestItemJSON | TransferFileOwnershipRequestItemJSON - | ShareCredentialOfferRequestItemJSON; + | ShareCredentialOfferRequestItemJSON + | ShareAuthorizationRequestRequestItemJSON; export interface IRequestItem extends ISerializable { /** @@ -99,7 +103,8 @@ export type IRequestItemDerivations = | IAuthenticationRequestItem | IFormFieldRequestItem | ITransferFileOwnershipRequestItem - | IShareCredentialOfferRequestItem; + | IShareCredentialOfferRequestItem + | IShareAuthorizationRequestRequestItem; export abstract class RequestItem extends Serializable { @serialize() @@ -130,7 +135,8 @@ export type RequestItemDerivations = | AuthenticationRequestItem | FormFieldRequestItem | TransferFileOwnershipRequestItem - | ShareCredentialOfferRequestItem; + | ShareCredentialOfferRequestItem + | ShareAuthorizationRequestRequestItem; export function isRequestItemDerivation(input: any): input is RequestItemDerivations { return ( @@ -144,6 +150,7 @@ export function isRequestItemDerivation(input: any): input is RequestItemDerivat input["@type"] === "AuthenticationRequestItem" || input["@type"] === "FormFieldRequestItem" || input["@type"] === "TransferFileOwnershipRequestItem" || - input["@type"] === "ShareCredentialOfferRequestItem" + input["@type"] === "ShareCredentialOfferRequestItem" || + input["@type"] === "ShareAuthorizationRequestRequestItem" ); } diff --git a/packages/content/src/requests/items/index.ts b/packages/content/src/requests/items/index.ts index 9428c0c81..70197a0c3 100644 --- a/packages/content/src/requests/items/index.ts +++ b/packages/content/src/requests/items/index.ts @@ -9,11 +9,12 @@ export * from "./deleteAttribute/DeleteAttributeRequestItem"; export * from "./formField/FormFieldAcceptResponseItem"; export * from "./formField/FormFieldRequestItem"; export * from "./formField/settings"; +export * from "./openid4vc/ShareAuthorizationRequestRequestItem"; +export * from "./openid4vc/ShareCredentialOfferRequestItem"; export * from "./proposeAttribute/ProposeAttributeAcceptResponseItem"; export * from "./proposeAttribute/ProposeAttributeRequestItem"; export * from "./readAttribute/ReadAttributeAcceptResponseItem"; export * from "./readAttribute/ReadAttributeRequestItem"; export * from "./shareAttribute/ShareAttributeRequestItem"; -export * from "./shareCredentialOffer/ShareCredentialOfferRequestItem"; export * from "./transferFileOwnership/TransferFileOwnershipAcceptResponseItem"; export * from "./transferFileOwnership/TransferFileOwnershipRequestItem"; diff --git a/packages/content/src/requests/items/openid4vc/ShareAuthorizationRequestRequestItem.ts b/packages/content/src/requests/items/openid4vc/ShareAuthorizationRequestRequestItem.ts new file mode 100644 index 000000000..17028b6ae --- /dev/null +++ b/packages/content/src/requests/items/openid4vc/ShareAuthorizationRequestRequestItem.ts @@ -0,0 +1,29 @@ +import { serialize, type, validate } from "@js-soft/ts-serval"; +import { RequestItemJSON } from "../.."; +import { IRequestItem, RequestItem } from "../../RequestItem"; + +export interface ShareAuthorizationRequestRequestItemJSON extends RequestItemJSON { + "@type": "ShareAuthorizationRequestRequestItem"; + authorizationRequestUrl: string; +} + +export interface IShareAuthorizationRequestRequestItem extends IRequestItem { + authorizationRequestUrl: string; +} + +@type("ShareAuthorizationRequestRequestItem") +export class ShareAuthorizationRequestRequestItem extends RequestItem implements IShareAuthorizationRequestRequestItem { + @serialize() + @validate() + public authorizationRequestUrl: string; + + public static from( + value: IShareAuthorizationRequestRequestItem | Omit | ShareAuthorizationRequestRequestItemJSON + ): ShareAuthorizationRequestRequestItem { + return this.fromAny(value); + } + + public override toJSON(verbose?: boolean | undefined, serializeAsString?: boolean | undefined): ShareAuthorizationRequestRequestItemJSON { + return super.toJSON(verbose, serializeAsString) as ShareAuthorizationRequestRequestItemJSON; + } +} diff --git a/packages/content/src/requests/items/shareCredentialOffer/ShareCredentialOfferRequestItem.ts b/packages/content/src/requests/items/openid4vc/ShareCredentialOfferRequestItem.ts similarity index 100% rename from packages/content/src/requests/items/shareCredentialOffer/ShareCredentialOfferRequestItem.ts rename to packages/content/src/requests/items/openid4vc/ShareCredentialOfferRequestItem.ts diff --git a/packages/runtime/src/dataViews/DataViewExpander.ts b/packages/runtime/src/dataViews/DataViewExpander.ts index 0b6c9a671..c57a04f63 100644 --- a/packages/runtime/src/dataViews/DataViewExpander.ts +++ b/packages/runtime/src/dataViews/DataViewExpander.ts @@ -49,6 +49,7 @@ import { ResponseJSON, SexJSON, ShareAttributeRequestItemJSON, + ShareAuthorizationRequestRequestItemJSON, ShareCredentialOfferRequestItemJSON, SurnameJSON, ThirdPartyRelationshipAttributeQueryJSON, @@ -133,6 +134,7 @@ import { ResponseItemDVO, ResponseItemGroupDVO, ShareAttributeRequestItemDVO, + ShareAuthorizationRequestRequestItemDVO, ShareCredentialOfferRequestItemDVO, ThirdPartyRelationshipAttributeQueryDVO, TransferFileOwnershipAcceptResponseItemDVO, @@ -655,6 +657,28 @@ export class DataViewExpander { credentialResponses } as ShareCredentialOfferRequestItemDVO; + case "ShareAuthorizationRequestRequestItem": + const shareAuthorizationRequestRequestItem = requestItem as ShareAuthorizationRequestRequestItemJSON; + + const matchingCredentials = await (async () => { + try { + return (await this.consumptionController.openId4Vc.resolveAuthorizationRequest(shareAuthorizationRequestRequestItem.authorizationRequestUrl)) + .matchingCredentials; + } catch { + return; + } + })(); + + return { + ...shareAuthorizationRequestRequestItem, + type: "ShareAuthorizationRequestRequestItemDVO", + id: "", + name: this.generateRequestItemName(requestItem["@type"], isDecidable), + isDecidable: isDecidable && !!credentialResponses, + response: responseItemDVO, + matchingCredentials + } as ShareAuthorizationRequestRequestItemDVO; + default: return { ...requestItem, diff --git a/packages/runtime/src/dataViews/content/RequestItemDVOs.ts b/packages/runtime/src/dataViews/content/RequestItemDVOs.ts index ff22c5901..75d10aac8 100644 --- a/packages/runtime/src/dataViews/content/RequestItemDVOs.ts +++ b/packages/runtime/src/dataViews/content/RequestItemDVOs.ts @@ -82,3 +82,9 @@ export interface ShareCredentialOfferRequestItemDVO extends RequestItemDVO { credentialOfferUrl: string; credentialResponses?: OpenId4VciCredentialResponseJSON[]; } + +export interface ShareAuthorizationRequestRequestItemDVO extends RequestItemDVO { + type: "ShareAuthorizationRequestRequestItemDVO"; + authorizationRequestUrl: string; + matchingCredentials?: LocalAttributeDVO[]; +} diff --git a/packages/runtime/test/consumption/openid4vc.test.ts b/packages/runtime/test/consumption/openid4vc.test.ts index 640fdaad2..25fe8c23a 100644 --- a/packages/runtime/test/consumption/openid4vc.test.ts +++ b/packages/runtime/test/consumption/openid4vc.test.ts @@ -336,6 +336,66 @@ describe("custom openid4vc service", () => { expect(presentationResult.value.status).toBe(200); }); + test("request presentation using requests", async () => { + const createPresentationResponse = await axiosInstance.post("/presentation/presentationRequests", { + pex: { + id: "anId", + purpose: "To prove you work here", + + // eslint-disable-next-line @typescript-eslint/naming-convention + input_descriptors: [ + { + id: "EmployeeIdCard", + format: { + // eslint-disable-next-line @typescript-eslint/naming-convention + "vc+sd-jwt": { + // eslint-disable-next-line @typescript-eslint/naming-convention + "sd-jwt_alg_values": ["RS256", "PS256", "HS256", "ES256", "ES256K", "RS384", "PS384", "HS384", "ES384", "RS512", "PS512", "HS512", "ES512", "EdDSA"] + } + }, + constraints: { + fields: [ + { + path: ["$.vct"], + filter: { + type: "string", + pattern: "EmployeeIdCard" + } + } + ] + } + } + ] + }, + version: "v1.draft21" + }); + expect(createPresentationResponse.status).toBe(200); + const createPresentationResponseData = await createPresentationResponse.data; + const authorizationRequestUrl = createPresentationResponseData.result.presentationRequest as string; + const authorizationRequestId = authorizationRequestUrl.split("%2F").at(-1)?.slice(0, 36); + + await exchangeAndAcceptRequestByMessage( + runtimeServices1, + runtimeServices2, + { + content: { + items: [ + { + "@type": "ShareAuthorizationRequestRequestItem", + authorizationRequestUrl, + mustBeAccepted: true + } + ] + }, + peer: (await runtimeServices2.transport.account.getIdentityInfo()).value.address + }, + [{ accept: true }] + ); + + const verificationStatus = (await axiosInstance.get(`/presentation/presentationRequests/${authorizationRequestId}/verificationSessionState`)).data.result; + expect(verificationStatus).toBe("ResponseVerified"); + }); + async function startOid4VcComposeStack() { let baseUrl = process.env.NMSHD_TEST_BASEURL!; let addressGenerationHostnameOverride: string | undefined; From c2693fe961b7e4ab02db4692135e5b61ca70de7b Mon Sep 17 00:00:00 2001 From: mkuhn Date: Wed, 10 Dec 2025 16:00:19 +0100 Subject: [PATCH 2/5] feat: remove event --- ...equestRequestItemProcessedByRecipientEvent.ts | 16 ---------------- .../src/modules/requests/events/index.ts | 1 - ...reAuthorizationRequestRequestItemProcessor.ts | 15 +-------------- 3 files changed, 1 insertion(+), 31 deletions(-) delete mode 100644 packages/consumption/src/modules/requests/events/ShareAuthorizationRequestRequestItemProcessedByRecipientEvent.ts diff --git a/packages/consumption/src/modules/requests/events/ShareAuthorizationRequestRequestItemProcessedByRecipientEvent.ts b/packages/consumption/src/modules/requests/events/ShareAuthorizationRequestRequestItemProcessedByRecipientEvent.ts deleted file mode 100644 index 1896a9f7b..000000000 --- a/packages/consumption/src/modules/requests/events/ShareAuthorizationRequestRequestItemProcessedByRecipientEvent.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { CoreAddress } from "@nmshd/core-types"; -import { TransportDataEvent } from "@nmshd/transport"; - -export interface ShareAuthorizationRequestRequestItemProcessedByRecipientEventData { - authorizationRequestUrl: string; - accepted: boolean; - peer: CoreAddress; -} - -export class ShareAuthorizationRequestRequestItemProcessedByRecipientEvent extends TransportDataEvent { - public static readonly namespace = "consumption.shareAuthorizationRequestRequestItemProcessedByRecipient"; - - public constructor(eventTargetAddress: string, data: ShareAuthorizationRequestRequestItemProcessedByRecipientEventData) { - super(ShareAuthorizationRequestRequestItemProcessedByRecipientEvent.namespace, eventTargetAddress, data); - } -} diff --git a/packages/consumption/src/modules/requests/events/index.ts b/packages/consumption/src/modules/requests/events/index.ts index ef9dd5c9e..36068ce3f 100644 --- a/packages/consumption/src/modules/requests/events/index.ts +++ b/packages/consumption/src/modules/requests/events/index.ts @@ -3,5 +3,4 @@ export * from "./IncomingRequestStatusChangedEvent"; export * from "./OutgoingRequestCreatedAndCompletedEvent"; export * from "./OutgoingRequestCreatedEvent"; export * from "./OutgoingRequestStatusChangedEvent"; -export * from "./ShareAuthorizationRequestRequestItemProcessedByRecipientEvent"; export * from "./ShareCredentialOfferRequestItemProcessedByRecipientEvent"; diff --git a/packages/consumption/src/modules/requests/itemProcessors/openid4vc/ShareAuthorizationRequestRequestItemProcessor.ts b/packages/consumption/src/modules/requests/itemProcessors/openid4vc/ShareAuthorizationRequestRequestItemProcessor.ts index 7df80bcf6..1e289c59a 100644 --- a/packages/consumption/src/modules/requests/itemProcessors/openid4vc/ShareAuthorizationRequestRequestItemProcessor.ts +++ b/packages/consumption/src/modules/requests/itemProcessors/openid4vc/ShareAuthorizationRequestRequestItemProcessor.ts @@ -1,7 +1,6 @@ -import { AcceptResponseItem, RejectResponseItem, ResponseItemResult, ShareAuthorizationRequestRequestItem } from "@nmshd/content"; +import { AcceptResponseItem, ResponseItemResult, ShareAuthorizationRequestRequestItem } from "@nmshd/content"; import { ConsumptionCoreErrors } from "../../../../consumption/ConsumptionCoreErrors"; import { ValidationResult } from "../../../common/ValidationResult"; -import { ShareAuthorizationRequestRequestItemProcessedByRecipientEvent } from "../../events"; import { AcceptRequestItemParametersJSON } from "../../incoming/decide/AcceptRequestItemParameters"; import { GenericRequestItemProcessor } from "../GenericRequestItemProcessor"; import { LocalRequestInfo } from "../IRequestItemProcessor"; @@ -41,16 +40,4 @@ export class ShareAuthorizationRequestRequestItemProcessor extends GenericReques return AcceptResponseItem.from({ result: ResponseItemResult.Accepted }); } - - public override applyIncomingResponseItem( - responseItem: AcceptResponseItem | RejectResponseItem, - requestItem: ShareAuthorizationRequestRequestItem, - requestInfo: LocalRequestInfo - ): ShareAuthorizationRequestRequestItemProcessedByRecipientEvent { - return new ShareAuthorizationRequestRequestItemProcessedByRecipientEvent(this.currentIdentityAddress.toString(), { - authorizationRequestUrl: requestItem.authorizationRequestUrl, - accepted: responseItem.result === ResponseItemResult.Accepted, - peer: requestInfo.peer - }); - } } From 6bc3c32a6048129d1febd33c2cb6bacc2311df92 Mon Sep 17 00:00:00 2001 From: mkuhn Date: Wed, 10 Dec 2025 16:10:34 +0100 Subject: [PATCH 3/5] refactor: split folder --- packages/consumption/src/consumption/ConsumptionController.ts | 2 +- packages/consumption/src/modules/requests/index.ts | 4 ++-- .../ShareAuthorizationRequestRequestItemProcessor.ts | 0 .../ShareCredentialOfferRequestItemProcessor.ts | 0 packages/content/src/requests/items/index.ts | 4 ++-- .../ShareAuthorizationRequestRequestItem.ts | 0 .../ShareCredentialOfferRequestItem.ts | 0 7 files changed, 5 insertions(+), 5 deletions(-) rename packages/consumption/src/modules/requests/itemProcessors/{openid4vc => shareAuthorizationRequest}/ShareAuthorizationRequestRequestItemProcessor.ts (100%) rename packages/consumption/src/modules/requests/itemProcessors/{openid4vc => shareCredentialOffer}/ShareCredentialOfferRequestItemProcessor.ts (100%) rename packages/content/src/requests/items/{openid4vc => shareAuthorizationRequest}/ShareAuthorizationRequestRequestItem.ts (100%) rename packages/content/src/requests/items/{openid4vc => shareCredentialOffer}/ShareCredentialOfferRequestItem.ts (100%) diff --git a/packages/consumption/src/consumption/ConsumptionController.ts b/packages/consumption/src/consumption/ConsumptionController.ts index 5feefa0c2..9a26c0fc9 100644 --- a/packages/consumption/src/consumption/ConsumptionController.ts +++ b/packages/consumption/src/consumption/ConsumptionController.ts @@ -43,10 +43,10 @@ import { RequestItemProcessorRegistry, SettingsController, ShareAttributeRequestItemProcessor, + ShareAuthorizationRequestRequestItemProcessor, ShareCredentialOfferRequestItemProcessor, TransferFileOwnershipRequestItemProcessor } from "../modules"; -import { ShareAuthorizationRequestRequestItemProcessor } from "../modules/requests/itemProcessors/openid4vc/ShareAuthorizationRequestRequestItemProcessor"; import { ConsumptionConfig } from "./ConsumptionConfig"; export class ConsumptionController { diff --git a/packages/consumption/src/modules/requests/index.ts b/packages/consumption/src/modules/requests/index.ts index 32f7aaeb2..c553a2ded 100644 --- a/packages/consumption/src/modules/requests/index.ts +++ b/packages/consumption/src/modules/requests/index.ts @@ -18,8 +18,6 @@ export * from "./itemProcessors/formField/AcceptFormFieldRequestItemParameters"; export * from "./itemProcessors/formField/FormFieldRequestItemProcessor"; export * from "./itemProcessors/GenericRequestItemProcessor"; export * from "./itemProcessors/IRequestItemProcessor"; -export * from "./itemProcessors/openid4vc/ShareAuthorizationRequestRequestItemProcessor"; -export * from "./itemProcessors/openid4vc/ShareCredentialOfferRequestItemProcessor"; export * from "./itemProcessors/proposeAttribute/AcceptProposeAttributeRequestItemParameters"; export * from "./itemProcessors/proposeAttribute/ProposeAttributeRequestItemProcessor"; export { @@ -32,6 +30,8 @@ export * from "./itemProcessors/RequestItemConstructor"; export * from "./itemProcessors/RequestItemProcessorConstructor"; export * from "./itemProcessors/RequestItemProcessorRegistry"; export * from "./itemProcessors/shareAttribute/ShareAttributeRequestItemProcessor"; +export * from "./itemProcessors/shareAuthorizationRequest/ShareAuthorizationRequestRequestItemProcessor"; +export * from "./itemProcessors/shareCredentialOffer/ShareCredentialOfferRequestItemProcessor"; export * from "./itemProcessors/transferFileOwnership/TransferFileOwnershipRequestItemProcessor"; export * from "./local/LocalRequest"; export * from "./local/LocalRequestStatus"; diff --git a/packages/consumption/src/modules/requests/itemProcessors/openid4vc/ShareAuthorizationRequestRequestItemProcessor.ts b/packages/consumption/src/modules/requests/itemProcessors/shareAuthorizationRequest/ShareAuthorizationRequestRequestItemProcessor.ts similarity index 100% rename from packages/consumption/src/modules/requests/itemProcessors/openid4vc/ShareAuthorizationRequestRequestItemProcessor.ts rename to packages/consumption/src/modules/requests/itemProcessors/shareAuthorizationRequest/ShareAuthorizationRequestRequestItemProcessor.ts diff --git a/packages/consumption/src/modules/requests/itemProcessors/openid4vc/ShareCredentialOfferRequestItemProcessor.ts b/packages/consumption/src/modules/requests/itemProcessors/shareCredentialOffer/ShareCredentialOfferRequestItemProcessor.ts similarity index 100% rename from packages/consumption/src/modules/requests/itemProcessors/openid4vc/ShareCredentialOfferRequestItemProcessor.ts rename to packages/consumption/src/modules/requests/itemProcessors/shareCredentialOffer/ShareCredentialOfferRequestItemProcessor.ts diff --git a/packages/content/src/requests/items/index.ts b/packages/content/src/requests/items/index.ts index 70197a0c3..cb814d952 100644 --- a/packages/content/src/requests/items/index.ts +++ b/packages/content/src/requests/items/index.ts @@ -9,12 +9,12 @@ export * from "./deleteAttribute/DeleteAttributeRequestItem"; export * from "./formField/FormFieldAcceptResponseItem"; export * from "./formField/FormFieldRequestItem"; export * from "./formField/settings"; -export * from "./openid4vc/ShareAuthorizationRequestRequestItem"; -export * from "./openid4vc/ShareCredentialOfferRequestItem"; export * from "./proposeAttribute/ProposeAttributeAcceptResponseItem"; export * from "./proposeAttribute/ProposeAttributeRequestItem"; export * from "./readAttribute/ReadAttributeAcceptResponseItem"; export * from "./readAttribute/ReadAttributeRequestItem"; export * from "./shareAttribute/ShareAttributeRequestItem"; +export * from "./shareAuthorizationRequest/ShareAuthorizationRequestRequestItem"; +export * from "./shareCredentialOffer/ShareCredentialOfferRequestItem"; export * from "./transferFileOwnership/TransferFileOwnershipAcceptResponseItem"; export * from "./transferFileOwnership/TransferFileOwnershipRequestItem"; diff --git a/packages/content/src/requests/items/openid4vc/ShareAuthorizationRequestRequestItem.ts b/packages/content/src/requests/items/shareAuthorizationRequest/ShareAuthorizationRequestRequestItem.ts similarity index 100% rename from packages/content/src/requests/items/openid4vc/ShareAuthorizationRequestRequestItem.ts rename to packages/content/src/requests/items/shareAuthorizationRequest/ShareAuthorizationRequestRequestItem.ts diff --git a/packages/content/src/requests/items/openid4vc/ShareCredentialOfferRequestItem.ts b/packages/content/src/requests/items/shareCredentialOffer/ShareCredentialOfferRequestItem.ts similarity index 100% rename from packages/content/src/requests/items/openid4vc/ShareCredentialOfferRequestItem.ts rename to packages/content/src/requests/items/shareCredentialOffer/ShareCredentialOfferRequestItem.ts From b12e8581dfc4091c6e4f892530889bbd0af067e0 Mon Sep 17 00:00:00 2001 From: mkuhn Date: Wed, 10 Dec 2025 16:33:46 +0100 Subject: [PATCH 4/5] fix: make expander work --- .../runtime/src/dataViews/DataViewExpander.ts | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/packages/runtime/src/dataViews/DataViewExpander.ts b/packages/runtime/src/dataViews/DataViewExpander.ts index c57a04f63..2a846ece1 100644 --- a/packages/runtime/src/dataViews/DataViewExpander.ts +++ b/packages/runtime/src/dataViews/DataViewExpander.ts @@ -660,23 +660,19 @@ export class DataViewExpander { case "ShareAuthorizationRequestRequestItem": const shareAuthorizationRequestRequestItem = requestItem as ShareAuthorizationRequestRequestItemJSON; - const matchingCredentials = await (async () => { - try { - return (await this.consumptionController.openId4Vc.resolveAuthorizationRequest(shareAuthorizationRequestRequestItem.authorizationRequestUrl)) - .matchingCredentials; - } catch { - return; - } - })(); + const resolutionResult = await this.consumption.openId4Vc.resolveAuthorizationRequest({ + authorizationRequestUrl: shareAuthorizationRequestRequestItem.authorizationRequestUrl + }); + const matchingCredentials = resolutionResult.isSuccess ? resolutionResult.value.matchingCredentials : []; return { ...shareAuthorizationRequestRequestItem, type: "ShareAuthorizationRequestRequestItemDVO", id: "", name: this.generateRequestItemName(requestItem["@type"], isDecidable), - isDecidable: isDecidable && !!credentialResponses, + isDecidable: isDecidable && matchingCredentials.length > 0, response: responseItemDVO, - matchingCredentials + matchingCredentials: await this.expandLocalAttributeDTOs(matchingCredentials) } as ShareAuthorizationRequestRequestItemDVO; default: From f0b82c59422306d3716c5bb6d7e932d72ec3565f Mon Sep 17 00:00:00 2001 From: mkuhn Date: Wed, 10 Dec 2025 16:34:40 +0100 Subject: [PATCH 5/5] feat: improve no match error msg --- .../ShareAuthorizationRequestRequestItemProcessor.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/consumption/src/modules/requests/itemProcessors/shareAuthorizationRequest/ShareAuthorizationRequestRequestItemProcessor.ts b/packages/consumption/src/modules/requests/itemProcessors/shareAuthorizationRequest/ShareAuthorizationRequestRequestItemProcessor.ts index 1e289c59a..5754bcbe8 100644 --- a/packages/consumption/src/modules/requests/itemProcessors/shareAuthorizationRequest/ShareAuthorizationRequestRequestItemProcessor.ts +++ b/packages/consumption/src/modules/requests/itemProcessors/shareAuthorizationRequest/ShareAuthorizationRequestRequestItemProcessor.ts @@ -16,7 +16,7 @@ export class ShareAuthorizationRequestRequestItemProcessor extends GenericReques if (resolvedAuthorizationRequest.matchingCredentials.length === 0) { return ValidationResult.error( ConsumptionCoreErrors.requests.invalidRequestItem( - `The authorization request at URL '${requestItem.authorizationRequestUrl}' can't be fulfilled with currently available credentials.` + `The authorization request at URL '${requestItem.authorizationRequestUrl}' can't be fulfilled with the credentials currently in the wallet.` ) ); }