Skip to content

Commit 3f74f85

Browse files
authored
Send OID4VP authorization requests in Requests (#898)
* feat: add dcql * feat: remove auto-selector * fix: correct input descriptor * test: adapt tests * fix: typo * test: correct runtime services no, credential count * test: skip some tests * test: prettier tests * chore: fix vulnerability * test: update service image * feat: presentation request requests * feat: remove event * refactor: split folder * fix: make expander work * feat: improve no match error msg * feat: adapt to new plan * refactor: prettier test * test: adapt test * chore: build schemas * chore: remove package override * test: correct services no
1 parent 4c9b987 commit 3f74f85

11 files changed

Lines changed: 292 additions & 84 deletions

File tree

packages/consumption/src/consumption/ConsumptionController.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import {
1111
ProposeAttributeRequestItem,
1212
ReadAttributeRequestItem,
1313
ShareAttributeRequestItem,
14+
ShareAuthorizationRequestRequestItem,
1415
ShareCredentialOfferRequestItem,
1516
TransferFileOwnershipRequestItem
1617
} from "@nmshd/content";
@@ -42,6 +43,7 @@ import {
4243
RequestItemProcessorRegistry,
4344
SettingsController,
4445
ShareAttributeRequestItemProcessor,
46+
ShareAuthorizationRequestRequestItemProcessor,
4547
ShareCredentialOfferRequestItemProcessor,
4648
TransferFileOwnershipRequestItemProcessor
4749
} from "../modules";
@@ -163,7 +165,8 @@ export class ConsumptionController {
163165
[AuthenticationRequestItem, GenericRequestItemProcessor],
164166
[FormFieldRequestItem, FormFieldRequestItemProcessor],
165167
[TransferFileOwnershipRequestItem, TransferFileOwnershipRequestItemProcessor],
166-
[ShareCredentialOfferRequestItem, ShareCredentialOfferRequestItemProcessor]
168+
[ShareCredentialOfferRequestItem, ShareCredentialOfferRequestItemProcessor],
169+
[ShareAuthorizationRequestRequestItem, ShareAuthorizationRequestRequestItemProcessor]
167170
]);
168171
}
169172

packages/consumption/src/modules/requests/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ export * from "./itemProcessors/RequestItemConstructor";
3030
export * from "./itemProcessors/RequestItemProcessorConstructor";
3131
export * from "./itemProcessors/RequestItemProcessorRegistry";
3232
export * from "./itemProcessors/shareAttribute/ShareAttributeRequestItemProcessor";
33+
export * from "./itemProcessors/shareAuthorizationRequest/AcceptShareAuthorizationRequestRequestItemParameters";
34+
export * from "./itemProcessors/shareAuthorizationRequest/ShareAuthorizationRequestRequestItemProcessor";
3335
export * from "./itemProcessors/shareCredentialOffer/ShareCredentialOfferRequestItemProcessor";
3436
export * from "./itemProcessors/transferFileOwnership/TransferFileOwnershipRequestItemProcessor";
3537
export * from "./local/LocalRequest";
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { Serializable, serialize, type, validate } from "@js-soft/ts-serval";
2+
import { OwnIdentityAttribute, OwnIdentityAttributeJSON } from "../../../attributes";
3+
import { AcceptRequestItemParametersJSON } from "../../incoming/decide/AcceptRequestItemParameters";
4+
5+
export interface AcceptShareAuthorizationRequestRequestItemParametersJSON extends AcceptRequestItemParametersJSON {
6+
attribute: OwnIdentityAttributeJSON;
7+
}
8+
9+
@type("AcceptShareAuthorizationRequestRequestItemParameters")
10+
export class AcceptShareAuthorizationRequestRequestItemParameters extends Serializable {
11+
@serialize()
12+
@validate()
13+
public attribute: OwnIdentityAttribute;
14+
15+
public static from(value: AcceptShareAuthorizationRequestRequestItemParametersJSON): AcceptShareAuthorizationRequestRequestItemParameters {
16+
return this.fromAny(value);
17+
}
18+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { AcceptResponseItem, ResponseItemResult, ShareAuthorizationRequestRequestItem } from "@nmshd/content";
2+
import { OwnIdentityAttribute } from "../../../attributes";
3+
import { GenericRequestItemProcessor } from "../GenericRequestItemProcessor";
4+
import { LocalRequestInfo } from "../IRequestItemProcessor";
5+
import { AcceptShareAuthorizationRequestRequestItemParametersJSON } from "./AcceptShareAuthorizationRequestRequestItemParameters";
6+
7+
export class ShareAuthorizationRequestRequestItemProcessor extends GenericRequestItemProcessor<ShareAuthorizationRequestRequestItem> {
8+
public override async accept(
9+
requestItem: ShareAuthorizationRequestRequestItem,
10+
params: AcceptShareAuthorizationRequestRequestItemParametersJSON,
11+
_requestInfo: LocalRequestInfo
12+
): Promise<AcceptResponseItem> {
13+
const resolvedAuthorizationRequest = await this.consumptionController.openId4Vc.resolveAuthorizationRequest(requestItem.authorizationRequestUrl);
14+
await this.consumptionController.openId4Vc.acceptAuthorizationRequest(resolvedAuthorizationRequest.authorizationRequest, OwnIdentityAttribute.from(params.attribute));
15+
16+
return AcceptResponseItem.from({ result: ResponseItemResult.Accepted });
17+
}
18+
}

packages/content/src/requests/RequestItem.ts

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import {
1919
IProposeAttributeRequestItem,
2020
IReadAttributeRequestItem,
2121
IShareAttributeRequestItem,
22+
IShareAuthorizationRequestRequestItem,
2223
IShareCredentialOfferRequestItem,
2324
ITransferFileOwnershipRequestItem,
2425
ProposeAttributeRequestItem,
@@ -27,6 +28,8 @@ import {
2728
ReadAttributeRequestItemJSON,
2829
ShareAttributeRequestItem,
2930
ShareAttributeRequestItemJSON,
31+
ShareAuthorizationRequestRequestItem,
32+
ShareAuthorizationRequestRequestItemJSON,
3033
ShareCredentialOfferRequestItem,
3134
ShareCredentialOfferRequestItemJSON,
3235
TransferFileOwnershipRequestItem,
@@ -65,7 +68,8 @@ export type RequestItemJSONDerivations =
6568
| AuthenticationRequestItemJSON
6669
| FormFieldRequestItemJSON
6770
| TransferFileOwnershipRequestItemJSON
68-
| ShareCredentialOfferRequestItemJSON;
71+
| ShareCredentialOfferRequestItemJSON
72+
| ShareAuthorizationRequestRequestItemJSON;
6973

7074
export interface IRequestItem extends ISerializable {
7175
/**
@@ -99,7 +103,8 @@ export type IRequestItemDerivations =
99103
| IAuthenticationRequestItem
100104
| IFormFieldRequestItem
101105
| ITransferFileOwnershipRequestItem
102-
| IShareCredentialOfferRequestItem;
106+
| IShareCredentialOfferRequestItem
107+
| IShareAuthorizationRequestRequestItem;
103108

104109
export abstract class RequestItem extends Serializable {
105110
@serialize()
@@ -130,7 +135,8 @@ export type RequestItemDerivations =
130135
| AuthenticationRequestItem
131136
| FormFieldRequestItem
132137
| TransferFileOwnershipRequestItem
133-
| ShareCredentialOfferRequestItem;
138+
| ShareCredentialOfferRequestItem
139+
| ShareAuthorizationRequestRequestItem;
134140

135141
export function isRequestItemDerivation(input: any): input is RequestItemDerivations {
136142
return (
@@ -144,6 +150,7 @@ export function isRequestItemDerivation(input: any): input is RequestItemDerivat
144150
input["@type"] === "AuthenticationRequestItem" ||
145151
input["@type"] === "FormFieldRequestItem" ||
146152
input["@type"] === "TransferFileOwnershipRequestItem" ||
147-
input["@type"] === "ShareCredentialOfferRequestItem"
153+
input["@type"] === "ShareCredentialOfferRequestItem" ||
154+
input["@type"] === "ShareAuthorizationRequestRequestItem"
148155
);
149156
}

packages/content/src/requests/items/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ export * from "./proposeAttribute/ProposeAttributeRequestItem";
1414
export * from "./readAttribute/ReadAttributeAcceptResponseItem";
1515
export * from "./readAttribute/ReadAttributeRequestItem";
1616
export * from "./shareAttribute/ShareAttributeRequestItem";
17+
export * from "./shareAuthorizationRequest/ShareAuthorizationRequestRequestItem";
1718
export * from "./shareCredentialOffer/ShareCredentialOfferRequestItem";
1819
export * from "./transferFileOwnership/TransferFileOwnershipAcceptResponseItem";
1920
export * from "./transferFileOwnership/TransferFileOwnershipRequestItem";
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import { serialize, type, validate } from "@js-soft/ts-serval";
2+
import { RequestItemJSON } from "../..";
3+
import { IRequestItem, RequestItem } from "../../RequestItem";
4+
5+
export interface ShareAuthorizationRequestRequestItemJSON extends RequestItemJSON {
6+
"@type": "ShareAuthorizationRequestRequestItem";
7+
authorizationRequestUrl: string;
8+
}
9+
10+
export interface IShareAuthorizationRequestRequestItem extends IRequestItem {
11+
authorizationRequestUrl: string;
12+
}
13+
14+
@type("ShareAuthorizationRequestRequestItem")
15+
export class ShareAuthorizationRequestRequestItem extends RequestItem implements IShareAuthorizationRequestRequestItem {
16+
@serialize()
17+
@validate()
18+
public authorizationRequestUrl: string;
19+
20+
public static from(
21+
value: IShareAuthorizationRequestRequestItem | Omit<ShareAuthorizationRequestRequestItemJSON, "@type"> | ShareAuthorizationRequestRequestItemJSON
22+
): ShareAuthorizationRequestRequestItem {
23+
return this.fromAny(value);
24+
}
25+
26+
public override toJSON(verbose?: boolean | undefined, serializeAsString?: boolean | undefined): ShareAuthorizationRequestRequestItemJSON {
27+
return super.toJSON(verbose, serializeAsString) as ShareAuthorizationRequestRequestItemJSON;
28+
}
29+
}

packages/runtime/src/dataViews/DataViewExpander.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ import {
4949
ResponseJSON,
5050
SexJSON,
5151
ShareAttributeRequestItemJSON,
52+
ShareAuthorizationRequestRequestItemJSON,
5253
ShareCredentialOfferRequestItemJSON,
5354
SurnameJSON,
5455
ThirdPartyRelationshipAttributeQueryJSON,
@@ -133,6 +134,7 @@ import {
133134
ResponseItemDVO,
134135
ResponseItemGroupDVO,
135136
ShareAttributeRequestItemDVO,
137+
ShareAuthorizationRequestRequestItemDVO,
136138
ShareCredentialOfferRequestItemDVO,
137139
ThirdPartyRelationshipAttributeQueryDVO,
138140
TransferFileOwnershipAcceptResponseItemDVO,
@@ -655,6 +657,24 @@ export class DataViewExpander {
655657
credentialResponses
656658
} as ShareCredentialOfferRequestItemDVO;
657659

660+
case "ShareAuthorizationRequestRequestItem":
661+
const shareAuthorizationRequestRequestItem = requestItem as ShareAuthorizationRequestRequestItemJSON;
662+
663+
const resolutionResult = await this.consumption.openId4Vc.resolveAuthorizationRequest({
664+
authorizationRequestUrl: shareAuthorizationRequestRequestItem.authorizationRequestUrl
665+
});
666+
const matchingCredentials = resolutionResult.isSuccess ? resolutionResult.value.matchingCredentials : [];
667+
668+
return {
669+
...shareAuthorizationRequestRequestItem,
670+
type: "ShareAuthorizationRequestRequestItemDVO",
671+
id: "",
672+
name: this.generateRequestItemName(requestItem["@type"], isDecidable),
673+
isDecidable: isDecidable && matchingCredentials.length > 0,
674+
response: responseItemDVO,
675+
matchingCredentials: await this.expandLocalAttributeDTOs(matchingCredentials)
676+
} as ShareAuthorizationRequestRequestItemDVO;
677+
658678
default:
659679
return {
660680
...requestItem,

packages/runtime/src/dataViews/content/RequestItemDVOs.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,3 +82,9 @@ export interface ShareCredentialOfferRequestItemDVO extends RequestItemDVO {
8282
credentialOfferUrl: string;
8383
credentialResponses?: OpenId4VciCredentialResponseJSON[];
8484
}
85+
86+
export interface ShareAuthorizationRequestRequestItemDVO extends RequestItemDVO {
87+
type: "ShareAuthorizationRequestRequestItemDVO";
88+
authorizationRequestUrl: string;
89+
matchingCredentials: LocalAttributeDVO[];
90+
}

packages/runtime/src/useCases/common/Schemas.ts

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,9 @@ export const CanCreateOutgoingRequestRequest: any = {
317317
},
318318
{
319319
"$ref": "#/definitions/ShareCredentialOfferRequestItemJSON"
320+
},
321+
{
322+
"$ref": "#/definitions/ShareAuthorizationRequestRequestItemJSON"
320323
}
321324
]
322325
},
@@ -2784,6 +2787,42 @@ export const CanCreateOutgoingRequestRequest: any = {
27842787
],
27852788
"additionalProperties": false
27862789
},
2790+
"ShareAuthorizationRequestRequestItemJSON": {
2791+
"type": "object",
2792+
"properties": {
2793+
"@type": {
2794+
"type": "string",
2795+
"const": "ShareAuthorizationRequestRequestItem"
2796+
},
2797+
"@context": {
2798+
"type": "string"
2799+
},
2800+
"@version": {
2801+
"type": "string"
2802+
},
2803+
"description": {
2804+
"type": "string",
2805+
"description": "The human-readable description of this item."
2806+
},
2807+
"metadata": {
2808+
"type": "object",
2809+
"description": "This property can be used to add some arbitrary metadata to this item. The content of this property will be copied into the response on the side of the recipient, so the sender can use it to identify the item as they receive the response."
2810+
},
2811+
"mustBeAccepted": {
2812+
"type": "boolean",
2813+
"description": "If set to `true`, the recipient has to accept this item if they want to accept the Request. If set to `false`, the recipient can decide whether they want to accept it or not."
2814+
},
2815+
"authorizationRequestUrl": {
2816+
"type": "string"
2817+
}
2818+
},
2819+
"required": [
2820+
"@type",
2821+
"authorizationRequestUrl",
2822+
"mustBeAccepted"
2823+
],
2824+
"additionalProperties": false
2825+
},
27872826
"AddressString": {
27882827
"type": "string",
27892828
"pattern": "did:e:((([A-Za-z0-9]+(-[A-Za-z0-9]+)*)\\.)+[a-z]{2,}|localhost):dids:[0-9a-f]{22}"
@@ -7192,6 +7231,9 @@ export const CreateOutgoingRequestRequest: any = {
71927231
},
71937232
{
71947233
"$ref": "#/definitions/ShareCredentialOfferRequestItemJSON"
7234+
},
7235+
{
7236+
"$ref": "#/definitions/ShareAuthorizationRequestRequestItemJSON"
71957237
}
71967238
]
71977239
},
@@ -9659,6 +9701,42 @@ export const CreateOutgoingRequestRequest: any = {
96599701
],
96609702
"additionalProperties": false
96619703
},
9704+
"ShareAuthorizationRequestRequestItemJSON": {
9705+
"type": "object",
9706+
"properties": {
9707+
"@type": {
9708+
"type": "string",
9709+
"const": "ShareAuthorizationRequestRequestItem"
9710+
},
9711+
"@context": {
9712+
"type": "string"
9713+
},
9714+
"@version": {
9715+
"type": "string"
9716+
},
9717+
"description": {
9718+
"type": "string",
9719+
"description": "The human-readable description of this item."
9720+
},
9721+
"metadata": {
9722+
"type": "object",
9723+
"description": "This property can be used to add some arbitrary metadata to this item. The content of this property will be copied into the response on the side of the recipient, so the sender can use it to identify the item as they receive the response."
9724+
},
9725+
"mustBeAccepted": {
9726+
"type": "boolean",
9727+
"description": "If set to `true`, the recipient has to accept this item if they want to accept the Request. If set to `false`, the recipient can decide whether they want to accept it or not."
9728+
},
9729+
"authorizationRequestUrl": {
9730+
"type": "string"
9731+
}
9732+
},
9733+
"required": [
9734+
"@type",
9735+
"authorizationRequestUrl",
9736+
"mustBeAccepted"
9737+
],
9738+
"additionalProperties": false
9739+
},
96629740
"AddressString": {
96639741
"type": "string",
96649742
"pattern": "did:e:((([A-Za-z0-9]+(-[A-Za-z0-9]+)*)\\.)+[a-z]{2,}|localhost):dids:[0-9a-f]{22}"
@@ -10320,6 +10398,9 @@ export const ReceivedIncomingRequestRequest: any = {
1032010398
},
1032110399
{
1032210400
"$ref": "#/definitions/ShareCredentialOfferRequestItemJSON"
10401+
},
10402+
{
10403+
"$ref": "#/definitions/ShareAuthorizationRequestRequestItemJSON"
1032310404
}
1032410405
]
1032510406
},
@@ -12787,6 +12868,42 @@ export const ReceivedIncomingRequestRequest: any = {
1278712868
],
1278812869
"additionalProperties": false
1278912870
},
12871+
"ShareAuthorizationRequestRequestItemJSON": {
12872+
"type": "object",
12873+
"properties": {
12874+
"@type": {
12875+
"type": "string",
12876+
"const": "ShareAuthorizationRequestRequestItem"
12877+
},
12878+
"@context": {
12879+
"type": "string"
12880+
},
12881+
"@version": {
12882+
"type": "string"
12883+
},
12884+
"description": {
12885+
"type": "string",
12886+
"description": "The human-readable description of this item."
12887+
},
12888+
"metadata": {
12889+
"type": "object",
12890+
"description": "This property can be used to add some arbitrary metadata to this item. The content of this property will be copied into the response on the side of the recipient, so the sender can use it to identify the item as they receive the response."
12891+
},
12892+
"mustBeAccepted": {
12893+
"type": "boolean",
12894+
"description": "If set to `true`, the recipient has to accept this item if they want to accept the Request. If set to `false`, the recipient can decide whether they want to accept it or not."
12895+
},
12896+
"authorizationRequestUrl": {
12897+
"type": "string"
12898+
}
12899+
},
12900+
"required": [
12901+
"@type",
12902+
"authorizationRequestUrl",
12903+
"mustBeAccepted"
12904+
],
12905+
"additionalProperties": false
12906+
},
1279012907
"MessageIdString": {
1279112908
"type": "string",
1279212909
"pattern": "MSG[A-Za-z0-9]{17}"

0 commit comments

Comments
 (0)