@pagopa/io-wallet-oid4vp 0.4.2 → 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -50,6 +50,67 @@ const parsedRequestObject = await parseAuthorizeRequest({
50
50
  });
51
51
  ```
52
52
 
53
+ ### Generating an Authorization Response
54
+
55
+ ```typescript
56
+ import { createAuthorizationResponse, AuthorizationRequestObject } from '@pagopa/io-wallet-oid4vp';
57
+ import { ItWalletCredentialVerifierMetadata } from "@pagopa/io-wallet-oid-federation";
58
+
59
+ //Obtain the RP's metadata
60
+ const rpMetadata : ItWalletCredentialVerifierMetadata = {
61
+ ...
62
+ }
63
+
64
+ //Obtain a decoded Request Object from, e.g., parseAuthorizeRequest invocation
65
+ const requestObject: AuthorizationRequestObject = {
66
+ ...
67
+ }
68
+
69
+ //Obtain the signer
70
+ const signer = {
71
+ method : 'jwk',
72
+ publicJwk : {/*... jwk details*/},
73
+ alg : 'ES256'
74
+ }
75
+
76
+ //Obtain the vp_token
77
+ const vp_token = {
78
+ ... //VP token containing the attributes to disclose
79
+ }
80
+
81
+ //Prepare the callbacks
82
+ const callbacks = {
83
+ encryptJwe : async (jweEncryptor, data) => {
84
+ const result = encrypt(data, jweEncryptor)
85
+ return {
86
+ verified : result,
87
+ encryptionJwk : jweEncryptor
88
+ }
89
+ },
90
+ fetch : async (input, init) => {
91
+ ...//Fetch implementation
92
+ },
93
+ generateRandom : async (number) => new Uint8Array(number),
94
+ signJwt : async (jwtSigner, {header, payload}) => {
95
+ const str = `${b64url(JSON.stringify(header))}.${b64url(JSON.stringify(body))}`
96
+ const sig = signJwt(jwtSigner, str)
97
+ return `${str}.${sig}`
98
+ }
99
+ }
100
+
101
+ //Create the response
102
+
103
+ const resp = createAuthorizationResponse({
104
+ callbacks,
105
+ client_id : "JWK Thumbprint",
106
+ requestObject,
107
+ rpMetadata,
108
+ signer,
109
+ vp_token
110
+ })
111
+
112
+ ```
113
+
53
114
  ## API Reference
54
115
 
55
116
  ### AuthorizationRequestObject type and Zod parser
@@ -98,6 +159,57 @@ export async function parseAuthorizeRequest(options: ParseAuthorizeRequestOption
98
159
  ```
99
160
  This method receives a Request Object in JWT format, verifies the signature and returns the decoded Request Object.
100
161
 
162
+ ### createAuthorizationResponse
163
+ ```typescript
164
+ export interface CreateAuthorizationResponseOptions {
165
+ /**
166
+ * Callbacks for authorization response generation
167
+ */
168
+ callbacks: Pick<
169
+ CallbackContext,
170
+ "encryptJwe" | "fetch" | "generateRandom" | "signJwt"
171
+ >;
172
+
173
+ /**
174
+ * Thumbprint of the JWK in the cnf Wallet Attestation
175
+ */
176
+ client_id: string;
177
+
178
+ /**
179
+ * Optional expiration of the Authorization Response JWT, defaults to 10 minutes
180
+ */
181
+ exp?: number;
182
+
183
+ /**
184
+ * Presentation's Request Object
185
+ */
186
+ requestObject: AuthorizationRequestObject;
187
+
188
+ /**
189
+ * OpenID Federation Relying Party metadata
190
+ */
191
+ rpMetadata: ItWalletCredentialVerifierMetadata;
192
+
193
+ /**
194
+ * Signer created from the Wallet Instance's private key
195
+ */
196
+ signer: JwtSigner;
197
+
198
+ /**
199
+ * Array containing the vp_tokens of the credentials
200
+ * to present
201
+ */
202
+ vp_token: VpToken;
203
+ }
204
+
205
+ export async function createAuthorizationResponse(
206
+ options: CreateAuthorizationResponseOptions,
207
+ ) {
208
+ ...
209
+ }
210
+ ```
211
+ This method receives the RequestObject, its resolved VP Tokens and other necessary cryptographic and configuration data and returns a signed Authorization Response
212
+
101
213
  ### Errors
102
214
 
103
215
  ```typescript
@@ -124,4 +236,17 @@ export class ParseAuthorizeRequestError extends Oid4vpError {
124
236
  }
125
237
  }
126
238
  ```
127
- Error thrown by `parseAuthorizeRequest` when the passed request object has an invalid signature or unexpected errors are thrown.
239
+ Error thrown by `parseAuthorizeRequest` when the passed request object has an invalid signature or unexpected errors are thrown.
240
+
241
+ ```typescript
242
+ export class CreateAuthorizationResponseError extends Oid4vpError {
243
+ constructor(
244
+ message: string,
245
+ public readonly statusCode?: number,
246
+ ) {
247
+ super(message);
248
+ this.name = "CreateAuthorizationResponseError";
249
+ }
250
+ }
251
+ ```
252
+ Error thrown by `createAuthorizationResponse` in case there are unexpected errors.
package/dist/index.d.mts CHANGED
@@ -1,5 +1,9 @@
1
- import { CallbackContext, RequestDpopOptions } from '@openid4vc/oauth2';
1
+ import { CallbackContext, RequestDpopOptions, JwtSigner } from '@openid4vc/oauth2';
2
2
  import { z } from 'zod';
3
+ import * as _openid4vc_openid4vp from '@openid4vc/openid4vp';
4
+ import { VpToken } from '@openid4vc/openid4vp';
5
+ export { CreateOpenid4vpAuthorizationResponseOptions, CreateOpenid4vpAuthorizationResponseResult, VpToken, createOpenid4vpAuthorizationResponse } from '@openid4vc/openid4vp';
6
+ import { ItWalletCredentialVerifierMetadata } from '@pagopa/io-wallet-oid-federation';
3
7
 
4
8
  /**
5
9
  * Zod parser that describes a JWT payload
@@ -15,7 +19,7 @@ declare const zOpenid4vpAuthorizationRequest: z.ZodIntersection<z.ZodObject<{
15
19
  response_type: z.ZodLiteral<"vp_token">;
16
20
  response_uri: z.ZodOptional<z.ZodString>;
17
21
  scope: z.ZodOptional<z.ZodString>;
18
- state: z.ZodOptional<z.ZodString>;
22
+ state: z.ZodString;
19
23
  wallet_nonce: z.ZodOptional<z.ZodString>;
20
24
  }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
21
25
  client_id: z.ZodString;
@@ -27,7 +31,7 @@ declare const zOpenid4vpAuthorizationRequest: z.ZodIntersection<z.ZodObject<{
27
31
  response_type: z.ZodLiteral<"vp_token">;
28
32
  response_uri: z.ZodOptional<z.ZodString>;
29
33
  scope: z.ZodOptional<z.ZodString>;
30
- state: z.ZodOptional<z.ZodString>;
34
+ state: z.ZodString;
31
35
  wallet_nonce: z.ZodOptional<z.ZodString>;
32
36
  }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
33
37
  client_id: z.ZodString;
@@ -39,7 +43,7 @@ declare const zOpenid4vpAuthorizationRequest: z.ZodIntersection<z.ZodObject<{
39
43
  response_type: z.ZodLiteral<"vp_token">;
40
44
  response_uri: z.ZodOptional<z.ZodString>;
41
45
  scope: z.ZodOptional<z.ZodString>;
42
- state: z.ZodOptional<z.ZodString>;
46
+ state: z.ZodString;
43
47
  wallet_nonce: z.ZodOptional<z.ZodString>;
44
48
  }, z.ZodTypeAny, "passthrough">>, z.ZodObject<{
45
49
  iss: z.ZodOptional<z.ZodString>;
@@ -1102,6 +1106,48 @@ interface ParseAuthorizeRequestOptions {
1102
1106
  */
1103
1107
  declare function parseAuthorizeRequest(options: ParseAuthorizeRequestOptions): Promise<AuthorizationRequestObject>;
1104
1108
 
1109
+ interface CreateAuthorizationResponseOptions {
1110
+ /**
1111
+ * Callbacks for authorization response generation
1112
+ */
1113
+ callbacks: Pick<CallbackContext, "encryptJwe" | "fetch" | "generateRandom" | "signJwt">;
1114
+ /**
1115
+ * Thumbprint of the JWK in the cnf Wallet Attestation
1116
+ */
1117
+ client_id: string;
1118
+ /**
1119
+ * Optional expiration of the Authorization Response JWT, defaults to 10 minutes
1120
+ */
1121
+ exp?: number;
1122
+ /**
1123
+ * Presentation's Request Object
1124
+ */
1125
+ requestObject: AuthorizationRequestObject;
1126
+ /**
1127
+ * OpenID Federation Relying Party metadata
1128
+ */
1129
+ rpMetadata: ItWalletCredentialVerifierMetadata;
1130
+ /**
1131
+ * Signer created from the Wallet Instance's private key
1132
+ */
1133
+ signer: JwtSigner;
1134
+ /**
1135
+ * Array containing the vp_tokens of the credentials
1136
+ * to present
1137
+ */
1138
+ vp_token: VpToken;
1139
+ }
1140
+ /**
1141
+ * This method receives the RequestObject, its resolved VP Tokens and other necessary cryptographic and configuration data
1142
+ * and returns a signed and encrypted Presentation Response
1143
+ * @param options {@link CreateAuthorizationResponseOptions}
1144
+ * @returns An {@link CreateOpenid4vpAuthorizationResponseResult} representing
1145
+ * the encrypted and signed Presentation Response to the corresponding {@link AuthorizationRequestObject}
1146
+ * @throws An {@link CreateAuthorizationResponseError} in case of unexpected errors during response generation,
1147
+ * encryption, or signing
1148
+ */
1149
+ declare function createAuthorizationResponse(options: CreateAuthorizationResponseOptions): Promise<_openid4vc_openid4vp.CreateOpenid4vpAuthorizationResponseResult>;
1150
+
1105
1151
  /**
1106
1152
  * Generic error thrown during Oid4vp operations
1107
1153
  */
@@ -1118,5 +1164,13 @@ declare class ParseAuthorizeRequestError extends Oid4vpError {
1118
1164
  readonly statusCode?: number | undefined;
1119
1165
  constructor(message: string, statusCode?: number | undefined);
1120
1166
  }
1167
+ /**
1168
+ * Error thrown by {@link createAuthorizationResponse} in case there
1169
+ * are unexpected errors.
1170
+ */
1171
+ declare class CreateAuthorizationResponseError extends Oid4vpError {
1172
+ readonly statusCode?: number | undefined;
1173
+ constructor(message: string, statusCode?: number | undefined);
1174
+ }
1121
1175
 
1122
- export { type AuthorizationRequestObject, Oid4vpError, ParseAuthorizeRequestError, type ParseAuthorizeRequestOptions, parseAuthorizeRequest, zOpenid4vpAuthorizationRequest };
1176
+ export { type AuthorizationRequestObject, CreateAuthorizationResponseError, type CreateAuthorizationResponseOptions, Oid4vpError, ParseAuthorizeRequestError, type ParseAuthorizeRequestOptions, createAuthorizationResponse, parseAuthorizeRequest, zOpenid4vpAuthorizationRequest };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,9 @@
1
- import { CallbackContext, RequestDpopOptions } from '@openid4vc/oauth2';
1
+ import { CallbackContext, RequestDpopOptions, JwtSigner } from '@openid4vc/oauth2';
2
2
  import { z } from 'zod';
3
+ import * as _openid4vc_openid4vp from '@openid4vc/openid4vp';
4
+ import { VpToken } from '@openid4vc/openid4vp';
5
+ export { CreateOpenid4vpAuthorizationResponseOptions, CreateOpenid4vpAuthorizationResponseResult, VpToken, createOpenid4vpAuthorizationResponse } from '@openid4vc/openid4vp';
6
+ import { ItWalletCredentialVerifierMetadata } from '@pagopa/io-wallet-oid-federation';
3
7
 
4
8
  /**
5
9
  * Zod parser that describes a JWT payload
@@ -15,7 +19,7 @@ declare const zOpenid4vpAuthorizationRequest: z.ZodIntersection<z.ZodObject<{
15
19
  response_type: z.ZodLiteral<"vp_token">;
16
20
  response_uri: z.ZodOptional<z.ZodString>;
17
21
  scope: z.ZodOptional<z.ZodString>;
18
- state: z.ZodOptional<z.ZodString>;
22
+ state: z.ZodString;
19
23
  wallet_nonce: z.ZodOptional<z.ZodString>;
20
24
  }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
21
25
  client_id: z.ZodString;
@@ -27,7 +31,7 @@ declare const zOpenid4vpAuthorizationRequest: z.ZodIntersection<z.ZodObject<{
27
31
  response_type: z.ZodLiteral<"vp_token">;
28
32
  response_uri: z.ZodOptional<z.ZodString>;
29
33
  scope: z.ZodOptional<z.ZodString>;
30
- state: z.ZodOptional<z.ZodString>;
34
+ state: z.ZodString;
31
35
  wallet_nonce: z.ZodOptional<z.ZodString>;
32
36
  }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
33
37
  client_id: z.ZodString;
@@ -39,7 +43,7 @@ declare const zOpenid4vpAuthorizationRequest: z.ZodIntersection<z.ZodObject<{
39
43
  response_type: z.ZodLiteral<"vp_token">;
40
44
  response_uri: z.ZodOptional<z.ZodString>;
41
45
  scope: z.ZodOptional<z.ZodString>;
42
- state: z.ZodOptional<z.ZodString>;
46
+ state: z.ZodString;
43
47
  wallet_nonce: z.ZodOptional<z.ZodString>;
44
48
  }, z.ZodTypeAny, "passthrough">>, z.ZodObject<{
45
49
  iss: z.ZodOptional<z.ZodString>;
@@ -1102,6 +1106,48 @@ interface ParseAuthorizeRequestOptions {
1102
1106
  */
1103
1107
  declare function parseAuthorizeRequest(options: ParseAuthorizeRequestOptions): Promise<AuthorizationRequestObject>;
1104
1108
 
1109
+ interface CreateAuthorizationResponseOptions {
1110
+ /**
1111
+ * Callbacks for authorization response generation
1112
+ */
1113
+ callbacks: Pick<CallbackContext, "encryptJwe" | "fetch" | "generateRandom" | "signJwt">;
1114
+ /**
1115
+ * Thumbprint of the JWK in the cnf Wallet Attestation
1116
+ */
1117
+ client_id: string;
1118
+ /**
1119
+ * Optional expiration of the Authorization Response JWT, defaults to 10 minutes
1120
+ */
1121
+ exp?: number;
1122
+ /**
1123
+ * Presentation's Request Object
1124
+ */
1125
+ requestObject: AuthorizationRequestObject;
1126
+ /**
1127
+ * OpenID Federation Relying Party metadata
1128
+ */
1129
+ rpMetadata: ItWalletCredentialVerifierMetadata;
1130
+ /**
1131
+ * Signer created from the Wallet Instance's private key
1132
+ */
1133
+ signer: JwtSigner;
1134
+ /**
1135
+ * Array containing the vp_tokens of the credentials
1136
+ * to present
1137
+ */
1138
+ vp_token: VpToken;
1139
+ }
1140
+ /**
1141
+ * This method receives the RequestObject, its resolved VP Tokens and other necessary cryptographic and configuration data
1142
+ * and returns a signed and encrypted Presentation Response
1143
+ * @param options {@link CreateAuthorizationResponseOptions}
1144
+ * @returns An {@link CreateOpenid4vpAuthorizationResponseResult} representing
1145
+ * the encrypted and signed Presentation Response to the corresponding {@link AuthorizationRequestObject}
1146
+ * @throws An {@link CreateAuthorizationResponseError} in case of unexpected errors during response generation,
1147
+ * encryption, or signing
1148
+ */
1149
+ declare function createAuthorizationResponse(options: CreateAuthorizationResponseOptions): Promise<_openid4vc_openid4vp.CreateOpenid4vpAuthorizationResponseResult>;
1150
+
1105
1151
  /**
1106
1152
  * Generic error thrown during Oid4vp operations
1107
1153
  */
@@ -1118,5 +1164,13 @@ declare class ParseAuthorizeRequestError extends Oid4vpError {
1118
1164
  readonly statusCode?: number | undefined;
1119
1165
  constructor(message: string, statusCode?: number | undefined);
1120
1166
  }
1167
+ /**
1168
+ * Error thrown by {@link createAuthorizationResponse} in case there
1169
+ * are unexpected errors.
1170
+ */
1171
+ declare class CreateAuthorizationResponseError extends Oid4vpError {
1172
+ readonly statusCode?: number | undefined;
1173
+ constructor(message: string, statusCode?: number | undefined);
1174
+ }
1121
1175
 
1122
- export { type AuthorizationRequestObject, Oid4vpError, ParseAuthorizeRequestError, type ParseAuthorizeRequestOptions, parseAuthorizeRequest, zOpenid4vpAuthorizationRequest };
1176
+ export { type AuthorizationRequestObject, CreateAuthorizationResponseError, type CreateAuthorizationResponseOptions, Oid4vpError, ParseAuthorizeRequestError, type ParseAuthorizeRequestOptions, createAuthorizationResponse, parseAuthorizeRequest, zOpenid4vpAuthorizationRequest };
package/dist/index.js CHANGED
@@ -20,8 +20,11 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/index.ts
21
21
  var index_exports = {};
22
22
  __export(index_exports, {
23
+ CreateAuthorizationResponseError: () => CreateAuthorizationResponseError,
23
24
  Oid4vpError: () => Oid4vpError,
24
25
  ParseAuthorizeRequestError: () => ParseAuthorizeRequestError,
26
+ createAuthorizationResponse: () => createAuthorizationResponse,
27
+ createOpenid4vpAuthorizationResponse: () => import_openid4vp2.createOpenid4vpAuthorizationResponse,
25
28
  parseAuthorizeRequest: () => parseAuthorizeRequest,
26
29
  zOpenid4vpAuthorizationRequest: () => zOpenid4vpAuthorizationRequest
27
30
  });
@@ -46,6 +49,13 @@ var ParseAuthorizeRequestError = class extends Oid4vpError {
46
49
  this.name = "ParseAuthorizeRequestError";
47
50
  }
48
51
  };
52
+ var CreateAuthorizationResponseError = class extends Oid4vpError {
53
+ constructor(message, statusCode) {
54
+ super(message);
55
+ this.statusCode = statusCode;
56
+ this.name = "CreateAuthorizationResponseError";
57
+ }
58
+ };
49
59
 
50
60
  // src/authorization-request/z-request-object.ts
51
61
  var import_oauth2 = require("@openid4vc/oauth2");
@@ -60,7 +70,7 @@ var zOpenid4vpAuthorizationRequest = import_zod.z.object({
60
70
  response_type: import_zod.z.literal("vp_token"),
61
71
  response_uri: import_zod.z.string().url().optional(),
62
72
  scope: import_zod.z.string().optional(),
63
- state: import_zod.z.string().optional(),
73
+ state: import_zod.z.string(),
64
74
  wallet_nonce: import_zod.z.string().optional()
65
75
  }).passthrough().and(import_oauth2.zJwtPayload);
66
76
 
@@ -92,10 +102,61 @@ async function parseAuthorizeRequest(options) {
92
102
  );
93
103
  }
94
104
  }
105
+
106
+ // src/authorization-response/create-authorization-response.ts
107
+ var import_openid4vp = require("@openid4vc/openid4vp");
108
+ var import_utils2 = require("@openid4vc/utils");
109
+ async function createAuthorizationResponse(options) {
110
+ try {
111
+ const openid_credential_verifier = options.rpMetadata;
112
+ const serverMetadata = {
113
+ authorization_encryption_alg_values_supported: [
114
+ openid_credential_verifier.authorization_encrypted_response_alg
115
+ ],
116
+ authorization_encryption_enc_values_supported: [
117
+ openid_credential_verifier.authorization_encrypted_response_enc
118
+ ],
119
+ authorization_signing_alg_values_supported: [
120
+ openid_credential_verifier.authorization_signed_response_alg
121
+ ]
122
+ };
123
+ return await (0, import_openid4vp.createOpenid4vpAuthorizationResponse)({
124
+ authorizationRequestPayload: options.requestObject,
125
+ authorizationResponsePayload: {
126
+ vp_token: options.vp_token
127
+ },
128
+ callbacks: options.callbacks,
129
+ clientMetadata: openid_credential_verifier,
130
+ jarm: {
131
+ audience: options.requestObject.client_id,
132
+ authorizationServer: options.client_id,
133
+ encryption: {
134
+ nonce: new TextDecoder().decode(
135
+ await options.callbacks.generateRandom(32)
136
+ )
137
+ },
138
+ expiresInSeconds: options.exp ?? (0, import_utils2.dateToSeconds)((0, import_utils2.addSecondsToDate)(/* @__PURE__ */ new Date(), 60 * 10)),
139
+ // default: 10 minutes
140
+ jwtSigner: options.signer,
141
+ serverMetadata
142
+ }
143
+ });
144
+ } catch (error) {
145
+ throw new CreateAuthorizationResponseError(
146
+ `Unexpected error during Request Object parsing: ${error instanceof Error ? error.message : String(error)}`
147
+ );
148
+ }
149
+ }
150
+
151
+ // src/index.ts
152
+ var import_openid4vp2 = require("@openid4vc/openid4vp");
95
153
  // Annotate the CommonJS export names for ESM import in node:
96
154
  0 && (module.exports = {
155
+ CreateAuthorizationResponseError,
97
156
  Oid4vpError,
98
157
  ParseAuthorizeRequestError,
158
+ createAuthorizationResponse,
159
+ createOpenid4vpAuthorizationResponse,
99
160
  parseAuthorizeRequest,
100
161
  zOpenid4vpAuthorizationRequest
101
162
  });
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/authorization-request/parse-authorization-request.ts","../src/errors.ts","../src/authorization-request/z-request-object.ts"],"sourcesContent":["export * from \"./authorization-request\";\nexport * from \"./errors\";\n","import {\n CallbackContext,\n Oauth2JwtParseError,\n RequestDpopOptions,\n decodeJwt,\n} from \"@openid4vc/oauth2\";\nimport { ValidationError } from \"@openid4vc/utils\";\n\nimport { ParseAuthorizeRequestError } from \"../errors\";\nimport {\n AuthorizationRequestObject,\n zOpenid4vpAuthorizationRequest,\n} from \"./z-request-object\";\n\nexport interface ParseAuthorizeRequestOptions {\n /**\n * Callback context for signature verification.\n */\n callbacks: Pick<CallbackContext, \"verifyJwt\">;\n\n /**\n * DPoP options\n */\n dpop: RequestDpopOptions;\n\n /**\n * The Authorization Request Object JWT.\n */\n requestObjectJwt: string;\n}\n\n/**\n * This method verifies a JWT containing a Request Object and returns its\n * decoded value for further processing\n * @param options {@link ParseAuthorizeRequestOptions}\n * @returns An {@link AuthorizationRequestObject} containing the RP required\n * credentials\n * @throws {@link ValidationError} in case there are errors validating the Request Object structure\n * @throws {@link Oauth2JwtParseError} in case the request object jwt is malformed (e.g missing header, bad encoding)\n * @throws {@link ParseAuthorizeRequestError} in case the JWT signature is invalid or there are unexpected errors\n */\nexport async function parseAuthorizeRequest(\n options: ParseAuthorizeRequestOptions,\n): Promise<AuthorizationRequestObject> {\n try {\n const decoded = decodeJwt({\n jwt: options.requestObjectJwt,\n payloadSchema: zOpenid4vpAuthorizationRequest,\n });\n const verificationResult = await options.callbacks.verifyJwt(\n options.dpop.signer,\n {\n compact: options.requestObjectJwt,\n header: decoded.header,\n payload: decoded.payload,\n },\n );\n\n if (!verificationResult.verified)\n throw new ParseAuthorizeRequestError(\n \"Error verifying Request Object signature\",\n );\n\n return decoded.payload;\n } catch (error) {\n if (\n error instanceof ValidationError ||\n error instanceof Oauth2JwtParseError\n )\n throw error;\n throw new ParseAuthorizeRequestError(\n `Unexpected error during Request Object parsing: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n}\n","/**\n * Generic error thrown during Oid4vp operations\n */\nexport class Oid4vpError extends Error {\n constructor(\n message: string,\n public readonly statusCode?: number,\n ) {\n super(message);\n this.name = \"Oid4vpError\";\n }\n}\n\n/**\n * Error thrown by {@link parseAuthorizeRequest} when the passed\n * request object has an invalid signature or unexpected errors\n * are thrown\n */\nexport class ParseAuthorizeRequestError extends Oid4vpError {\n constructor(\n message: string,\n public readonly statusCode?: number,\n ) {\n super(message);\n this.name = \"ParseAuthorizeRequestError\";\n }\n}\n","import { zJwtPayload } from \"@openid4vc/oauth2\";\nimport { z } from \"zod\";\n\n/**\n * Zod parser that describes a JWT payload\n * containing an OID4VP Request Object\n */\nexport const zOpenid4vpAuthorizationRequest = z\n .object({\n client_id: z.string(),\n dcql_query: z.record(z.string(), z.any()).optional(),\n nonce: z.string(),\n request_uri: z.string().url().optional(),\n request_uri_method: z.optional(z.string()),\n response_mode: z.literal(\"direct_post.jwt\"),\n response_type: z.literal(\"vp_token\"),\n response_uri: z.string().url().optional(),\n scope: z.string().optional(),\n state: z.string().optional(),\n wallet_nonce: z.string().optional(),\n })\n .passthrough()\n .and(zJwtPayload);\n\nexport type AuthorizationRequestObject = z.infer<\n typeof zOpenid4vpAuthorizationRequest\n>;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,IAAAA,iBAKO;AACP,mBAAgC;;;ACHzB,IAAM,cAAN,cAA0B,MAAM;AAAA,EACrC,YACE,SACgB,YAChB;AACA,UAAM,OAAO;AAFG;AAGhB,SAAK,OAAO;AAAA,EACd;AACF;AAOO,IAAM,6BAAN,cAAyC,YAAY;AAAA,EAC1D,YACE,SACgB,YAChB;AACA,UAAM,OAAO;AAFG;AAGhB,SAAK,OAAO;AAAA,EACd;AACF;;;AC1BA,oBAA4B;AAC5B,iBAAkB;AAMX,IAAM,iCAAiC,aAC3C,OAAO;AAAA,EACN,WAAW,aAAE,OAAO;AAAA,EACpB,YAAY,aAAE,OAAO,aAAE,OAAO,GAAG,aAAE,IAAI,CAAC,EAAE,SAAS;AAAA,EACnD,OAAO,aAAE,OAAO;AAAA,EAChB,aAAa,aAAE,OAAO,EAAE,IAAI,EAAE,SAAS;AAAA,EACvC,oBAAoB,aAAE,SAAS,aAAE,OAAO,CAAC;AAAA,EACzC,eAAe,aAAE,QAAQ,iBAAiB;AAAA,EAC1C,eAAe,aAAE,QAAQ,UAAU;AAAA,EACnC,cAAc,aAAE,OAAO,EAAE,IAAI,EAAE,SAAS;AAAA,EACxC,OAAO,aAAE,OAAO,EAAE,SAAS;AAAA,EAC3B,OAAO,aAAE,OAAO,EAAE,SAAS;AAAA,EAC3B,cAAc,aAAE,OAAO,EAAE,SAAS;AACpC,CAAC,EACA,YAAY,EACZ,IAAI,yBAAW;;;AFmBlB,eAAsB,sBACpB,SACqC;AACrC,MAAI;AACF,UAAM,cAAU,0BAAU;AAAA,MACxB,KAAK,QAAQ;AAAA,MACb,eAAe;AAAA,IACjB,CAAC;AACD,UAAM,qBAAqB,MAAM,QAAQ,UAAU;AAAA,MACjD,QAAQ,KAAK;AAAA,MACb;AAAA,QACE,SAAS,QAAQ;AAAA,QACjB,QAAQ,QAAQ;AAAA,QAChB,SAAS,QAAQ;AAAA,MACnB;AAAA,IACF;AAEA,QAAI,CAAC,mBAAmB;AACtB,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAEF,WAAO,QAAQ;AAAA,EACjB,SAAS,OAAO;AACd,QACE,iBAAiB,gCACjB,iBAAiB;AAEjB,YAAM;AACR,UAAM,IAAI;AAAA,MACR,mDAAmD,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAAA,IAC3G;AAAA,EACF;AACF;","names":["import_oauth2"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/authorization-request/parse-authorization-request.ts","../src/errors.ts","../src/authorization-request/z-request-object.ts","../src/authorization-response/create-authorization-response.ts"],"sourcesContent":["export * from \"./authorization-request\";\nexport * from \"./authorization-response\";\nexport * from \"./errors\";\n\nexport {\n type CreateOpenid4vpAuthorizationResponseOptions,\n type CreateOpenid4vpAuthorizationResponseResult,\n type VpToken,\n createOpenid4vpAuthorizationResponse,\n} from \"@openid4vc/openid4vp\";\n","import {\n CallbackContext,\n Oauth2JwtParseError,\n RequestDpopOptions,\n decodeJwt,\n} from \"@openid4vc/oauth2\";\nimport { ValidationError } from \"@openid4vc/utils\";\n\nimport { ParseAuthorizeRequestError } from \"../errors\";\nimport {\n AuthorizationRequestObject,\n zOpenid4vpAuthorizationRequest,\n} from \"./z-request-object\";\n\nexport interface ParseAuthorizeRequestOptions {\n /**\n * Callback context for signature verification.\n */\n callbacks: Pick<CallbackContext, \"verifyJwt\">;\n\n /**\n * DPoP options\n */\n dpop: RequestDpopOptions;\n\n /**\n * The Authorization Request Object JWT.\n */\n requestObjectJwt: string;\n}\n\n/**\n * This method verifies a JWT containing a Request Object and returns its\n * decoded value for further processing\n * @param options {@link ParseAuthorizeRequestOptions}\n * @returns An {@link AuthorizationRequestObject} containing the RP required\n * credentials\n * @throws {@link ValidationError} in case there are errors validating the Request Object structure\n * @throws {@link Oauth2JwtParseError} in case the request object jwt is malformed (e.g missing header, bad encoding)\n * @throws {@link ParseAuthorizeRequestError} in case the JWT signature is invalid or there are unexpected errors\n */\nexport async function parseAuthorizeRequest(\n options: ParseAuthorizeRequestOptions,\n): Promise<AuthorizationRequestObject> {\n try {\n const decoded = decodeJwt({\n jwt: options.requestObjectJwt,\n payloadSchema: zOpenid4vpAuthorizationRequest,\n });\n const verificationResult = await options.callbacks.verifyJwt(\n options.dpop.signer,\n {\n compact: options.requestObjectJwt,\n header: decoded.header,\n payload: decoded.payload,\n },\n );\n\n if (!verificationResult.verified)\n throw new ParseAuthorizeRequestError(\n \"Error verifying Request Object signature\",\n );\n\n return decoded.payload;\n } catch (error) {\n if (\n error instanceof ValidationError ||\n error instanceof Oauth2JwtParseError\n )\n throw error;\n throw new ParseAuthorizeRequestError(\n `Unexpected error during Request Object parsing: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n}\n","/**\n * Generic error thrown during Oid4vp operations\n */\nexport class Oid4vpError extends Error {\n constructor(\n message: string,\n public readonly statusCode?: number,\n ) {\n super(message);\n this.name = \"Oid4vpError\";\n }\n}\n\n/**\n * Error thrown by {@link parseAuthorizeRequest} when the passed\n * request object has an invalid signature or unexpected errors\n * are thrown\n */\nexport class ParseAuthorizeRequestError extends Oid4vpError {\n constructor(\n message: string,\n public readonly statusCode?: number,\n ) {\n super(message);\n this.name = \"ParseAuthorizeRequestError\";\n }\n}\n\n/**\n * Error thrown by {@link createAuthorizationResponse} in case there\n * are unexpected errors.\n */\nexport class CreateAuthorizationResponseError extends Oid4vpError {\n constructor(\n message: string,\n public readonly statusCode?: number,\n ) {\n super(message);\n this.name = \"CreateAuthorizationResponseError\";\n }\n}\n","import { zJwtPayload } from \"@openid4vc/oauth2\";\nimport { z } from \"zod\";\n\n/**\n * Zod parser that describes a JWT payload\n * containing an OID4VP Request Object\n */\nexport const zOpenid4vpAuthorizationRequest = z\n .object({\n client_id: z.string(),\n dcql_query: z.record(z.string(), z.any()).optional(),\n nonce: z.string(),\n request_uri: z.string().url().optional(),\n request_uri_method: z.optional(z.string()),\n response_mode: z.literal(\"direct_post.jwt\"),\n response_type: z.literal(\"vp_token\"),\n response_uri: z.string().url().optional(),\n scope: z.string().optional(),\n state: z.string(),\n wallet_nonce: z.string().optional(),\n })\n .passthrough()\n .and(zJwtPayload);\n\nexport type AuthorizationRequestObject = z.infer<\n typeof zOpenid4vpAuthorizationRequest\n>;\n","import { CallbackContext, JwtSigner } from \"@openid4vc/oauth2\";\nimport {\n CreateOpenid4vpAuthorizationResponseOptions,\n VpToken,\n createOpenid4vpAuthorizationResponse,\n} from \"@openid4vc/openid4vp\";\nimport { addSecondsToDate, dateToSeconds } from \"@openid4vc/utils\";\nimport { ItWalletCredentialVerifierMetadata } from \"@pagopa/io-wallet-oid-federation\";\n\nimport { AuthorizationRequestObject } from \"../authorization-request\";\nimport { CreateAuthorizationResponseError } from \"../errors\";\n\ntype JarmServerMetadata = NonNullable<\n CreateOpenid4vpAuthorizationResponseOptions[\"jarm\"]\n>[\"serverMetadata\"];\n\nexport interface CreateAuthorizationResponseOptions {\n /**\n * Callbacks for authorization response generation\n */\n callbacks: Pick<\n CallbackContext,\n \"encryptJwe\" | \"fetch\" | \"generateRandom\" | \"signJwt\"\n >;\n\n /**\n * Thumbprint of the JWK in the cnf Wallet Attestation\n */\n client_id: string;\n\n /**\n * Optional expiration of the Authorization Response JWT, defaults to 10 minutes\n */\n exp?: number;\n\n /**\n * Presentation's Request Object\n */\n requestObject: AuthorizationRequestObject;\n\n /**\n * OpenID Federation Relying Party metadata\n */\n rpMetadata: ItWalletCredentialVerifierMetadata;\n\n /**\n * Signer created from the Wallet Instance's private key\n */\n signer: JwtSigner;\n\n /**\n * Array containing the vp_tokens of the credentials\n * to present\n */\n vp_token: VpToken;\n}\n\n/**\n * This method receives the RequestObject, its resolved VP Tokens and other necessary cryptographic and configuration data\n * and returns a signed and encrypted Presentation Response\n * @param options {@link CreateAuthorizationResponseOptions}\n * @returns An {@link CreateOpenid4vpAuthorizationResponseResult} representing\n * the encrypted and signed Presentation Response to the corresponding {@link AuthorizationRequestObject}\n * @throws An {@link CreateAuthorizationResponseError} in case of unexpected errors during response generation,\n * encryption, or signing\n */\nexport async function createAuthorizationResponse(\n options: CreateAuthorizationResponseOptions,\n) {\n try {\n const openid_credential_verifier = options.rpMetadata;\n\n const serverMetadata: JarmServerMetadata = {\n authorization_encryption_alg_values_supported: [\n openid_credential_verifier.authorization_encrypted_response_alg,\n ],\n authorization_encryption_enc_values_supported: [\n openid_credential_verifier.authorization_encrypted_response_enc,\n ],\n authorization_signing_alg_values_supported: [\n openid_credential_verifier.authorization_signed_response_alg,\n ],\n };\n\n // NOTE: This method sets the state in the Authorization Response\n // using the corresponding value in the Request Object\n return await createOpenid4vpAuthorizationResponse({\n authorizationRequestPayload: options.requestObject,\n authorizationResponsePayload: {\n vp_token: options.vp_token,\n },\n callbacks: options.callbacks,\n clientMetadata: openid_credential_verifier,\n jarm: {\n audience: options.requestObject.client_id,\n authorizationServer: options.client_id,\n encryption: {\n nonce: new TextDecoder().decode(\n await options.callbacks.generateRandom(32),\n ),\n },\n expiresInSeconds:\n options.exp ?? dateToSeconds(addSecondsToDate(new Date(), 60 * 10)), // default: 10 minutes\n jwtSigner: options.signer,\n serverMetadata,\n },\n });\n } catch (error) {\n throw new CreateAuthorizationResponseError(\n `Unexpected error during Request Object parsing: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n}\n"],"mappings":"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","names":["import_oauth2","import_utils","import_openid4vp"]}
package/dist/index.mjs CHANGED
@@ -20,6 +20,13 @@ var ParseAuthorizeRequestError = class extends Oid4vpError {
20
20
  this.name = "ParseAuthorizeRequestError";
21
21
  }
22
22
  };
23
+ var CreateAuthorizationResponseError = class extends Oid4vpError {
24
+ constructor(message, statusCode) {
25
+ super(message);
26
+ this.statusCode = statusCode;
27
+ this.name = "CreateAuthorizationResponseError";
28
+ }
29
+ };
23
30
 
24
31
  // src/authorization-request/z-request-object.ts
25
32
  import { zJwtPayload } from "@openid4vc/oauth2";
@@ -34,7 +41,7 @@ var zOpenid4vpAuthorizationRequest = z.object({
34
41
  response_type: z.literal("vp_token"),
35
42
  response_uri: z.string().url().optional(),
36
43
  scope: z.string().optional(),
37
- state: z.string().optional(),
44
+ state: z.string(),
38
45
  wallet_nonce: z.string().optional()
39
46
  }).passthrough().and(zJwtPayload);
40
47
 
@@ -66,9 +73,64 @@ async function parseAuthorizeRequest(options) {
66
73
  );
67
74
  }
68
75
  }
76
+
77
+ // src/authorization-response/create-authorization-response.ts
78
+ import {
79
+ createOpenid4vpAuthorizationResponse
80
+ } from "@openid4vc/openid4vp";
81
+ import { addSecondsToDate, dateToSeconds } from "@openid4vc/utils";
82
+ async function createAuthorizationResponse(options) {
83
+ try {
84
+ const openid_credential_verifier = options.rpMetadata;
85
+ const serverMetadata = {
86
+ authorization_encryption_alg_values_supported: [
87
+ openid_credential_verifier.authorization_encrypted_response_alg
88
+ ],
89
+ authorization_encryption_enc_values_supported: [
90
+ openid_credential_verifier.authorization_encrypted_response_enc
91
+ ],
92
+ authorization_signing_alg_values_supported: [
93
+ openid_credential_verifier.authorization_signed_response_alg
94
+ ]
95
+ };
96
+ return await createOpenid4vpAuthorizationResponse({
97
+ authorizationRequestPayload: options.requestObject,
98
+ authorizationResponsePayload: {
99
+ vp_token: options.vp_token
100
+ },
101
+ callbacks: options.callbacks,
102
+ clientMetadata: openid_credential_verifier,
103
+ jarm: {
104
+ audience: options.requestObject.client_id,
105
+ authorizationServer: options.client_id,
106
+ encryption: {
107
+ nonce: new TextDecoder().decode(
108
+ await options.callbacks.generateRandom(32)
109
+ )
110
+ },
111
+ expiresInSeconds: options.exp ?? dateToSeconds(addSecondsToDate(/* @__PURE__ */ new Date(), 60 * 10)),
112
+ // default: 10 minutes
113
+ jwtSigner: options.signer,
114
+ serverMetadata
115
+ }
116
+ });
117
+ } catch (error) {
118
+ throw new CreateAuthorizationResponseError(
119
+ `Unexpected error during Request Object parsing: ${error instanceof Error ? error.message : String(error)}`
120
+ );
121
+ }
122
+ }
123
+
124
+ // src/index.ts
125
+ import {
126
+ createOpenid4vpAuthorizationResponse as createOpenid4vpAuthorizationResponse2
127
+ } from "@openid4vc/openid4vp";
69
128
  export {
129
+ CreateAuthorizationResponseError,
70
130
  Oid4vpError,
71
131
  ParseAuthorizeRequestError,
132
+ createAuthorizationResponse,
133
+ createOpenid4vpAuthorizationResponse2 as createOpenid4vpAuthorizationResponse,
72
134
  parseAuthorizeRequest,
73
135
  zOpenid4vpAuthorizationRequest
74
136
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/authorization-request/parse-authorization-request.ts","../src/errors.ts","../src/authorization-request/z-request-object.ts"],"sourcesContent":["import {\n CallbackContext,\n Oauth2JwtParseError,\n RequestDpopOptions,\n decodeJwt,\n} from \"@openid4vc/oauth2\";\nimport { ValidationError } from \"@openid4vc/utils\";\n\nimport { ParseAuthorizeRequestError } from \"../errors\";\nimport {\n AuthorizationRequestObject,\n zOpenid4vpAuthorizationRequest,\n} from \"./z-request-object\";\n\nexport interface ParseAuthorizeRequestOptions {\n /**\n * Callback context for signature verification.\n */\n callbacks: Pick<CallbackContext, \"verifyJwt\">;\n\n /**\n * DPoP options\n */\n dpop: RequestDpopOptions;\n\n /**\n * The Authorization Request Object JWT.\n */\n requestObjectJwt: string;\n}\n\n/**\n * This method verifies a JWT containing a Request Object and returns its\n * decoded value for further processing\n * @param options {@link ParseAuthorizeRequestOptions}\n * @returns An {@link AuthorizationRequestObject} containing the RP required\n * credentials\n * @throws {@link ValidationError} in case there are errors validating the Request Object structure\n * @throws {@link Oauth2JwtParseError} in case the request object jwt is malformed (e.g missing header, bad encoding)\n * @throws {@link ParseAuthorizeRequestError} in case the JWT signature is invalid or there are unexpected errors\n */\nexport async function parseAuthorizeRequest(\n options: ParseAuthorizeRequestOptions,\n): Promise<AuthorizationRequestObject> {\n try {\n const decoded = decodeJwt({\n jwt: options.requestObjectJwt,\n payloadSchema: zOpenid4vpAuthorizationRequest,\n });\n const verificationResult = await options.callbacks.verifyJwt(\n options.dpop.signer,\n {\n compact: options.requestObjectJwt,\n header: decoded.header,\n payload: decoded.payload,\n },\n );\n\n if (!verificationResult.verified)\n throw new ParseAuthorizeRequestError(\n \"Error verifying Request Object signature\",\n );\n\n return decoded.payload;\n } catch (error) {\n if (\n error instanceof ValidationError ||\n error instanceof Oauth2JwtParseError\n )\n throw error;\n throw new ParseAuthorizeRequestError(\n `Unexpected error during Request Object parsing: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n}\n","/**\n * Generic error thrown during Oid4vp operations\n */\nexport class Oid4vpError extends Error {\n constructor(\n message: string,\n public readonly statusCode?: number,\n ) {\n super(message);\n this.name = \"Oid4vpError\";\n }\n}\n\n/**\n * Error thrown by {@link parseAuthorizeRequest} when the passed\n * request object has an invalid signature or unexpected errors\n * are thrown\n */\nexport class ParseAuthorizeRequestError extends Oid4vpError {\n constructor(\n message: string,\n public readonly statusCode?: number,\n ) {\n super(message);\n this.name = \"ParseAuthorizeRequestError\";\n }\n}\n","import { zJwtPayload } from \"@openid4vc/oauth2\";\nimport { z } from \"zod\";\n\n/**\n * Zod parser that describes a JWT payload\n * containing an OID4VP Request Object\n */\nexport const zOpenid4vpAuthorizationRequest = z\n .object({\n client_id: z.string(),\n dcql_query: z.record(z.string(), z.any()).optional(),\n nonce: z.string(),\n request_uri: z.string().url().optional(),\n request_uri_method: z.optional(z.string()),\n response_mode: z.literal(\"direct_post.jwt\"),\n response_type: z.literal(\"vp_token\"),\n response_uri: z.string().url().optional(),\n scope: z.string().optional(),\n state: z.string().optional(),\n wallet_nonce: z.string().optional(),\n })\n .passthrough()\n .and(zJwtPayload);\n\nexport type AuthorizationRequestObject = z.infer<\n typeof zOpenid4vpAuthorizationRequest\n>;\n"],"mappings":";AAAA;AAAA,EAEE;AAAA,EAEA;AAAA,OACK;AACP,SAAS,uBAAuB;;;ACHzB,IAAM,cAAN,cAA0B,MAAM;AAAA,EACrC,YACE,SACgB,YAChB;AACA,UAAM,OAAO;AAFG;AAGhB,SAAK,OAAO;AAAA,EACd;AACF;AAOO,IAAM,6BAAN,cAAyC,YAAY;AAAA,EAC1D,YACE,SACgB,YAChB;AACA,UAAM,OAAO;AAFG;AAGhB,SAAK,OAAO;AAAA,EACd;AACF;;;AC1BA,SAAS,mBAAmB;AAC5B,SAAS,SAAS;AAMX,IAAM,iCAAiC,EAC3C,OAAO;AAAA,EACN,WAAW,EAAE,OAAO;AAAA,EACpB,YAAY,EAAE,OAAO,EAAE,OAAO,GAAG,EAAE,IAAI,CAAC,EAAE,SAAS;AAAA,EACnD,OAAO,EAAE,OAAO;AAAA,EAChB,aAAa,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS;AAAA,EACvC,oBAAoB,EAAE,SAAS,EAAE,OAAO,CAAC;AAAA,EACzC,eAAe,EAAE,QAAQ,iBAAiB;AAAA,EAC1C,eAAe,EAAE,QAAQ,UAAU;AAAA,EACnC,cAAc,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS;AAAA,EACxC,OAAO,EAAE,OAAO,EAAE,SAAS;AAAA,EAC3B,OAAO,EAAE,OAAO,EAAE,SAAS;AAAA,EAC3B,cAAc,EAAE,OAAO,EAAE,SAAS;AACpC,CAAC,EACA,YAAY,EACZ,IAAI,WAAW;;;AFmBlB,eAAsB,sBACpB,SACqC;AACrC,MAAI;AACF,UAAM,UAAU,UAAU;AAAA,MACxB,KAAK,QAAQ;AAAA,MACb,eAAe;AAAA,IACjB,CAAC;AACD,UAAM,qBAAqB,MAAM,QAAQ,UAAU;AAAA,MACjD,QAAQ,KAAK;AAAA,MACb;AAAA,QACE,SAAS,QAAQ;AAAA,QACjB,QAAQ,QAAQ;AAAA,QAChB,SAAS,QAAQ;AAAA,MACnB;AAAA,IACF;AAEA,QAAI,CAAC,mBAAmB;AACtB,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAEF,WAAO,QAAQ;AAAA,EACjB,SAAS,OAAO;AACd,QACE,iBAAiB,mBACjB,iBAAiB;AAEjB,YAAM;AACR,UAAM,IAAI;AAAA,MACR,mDAAmD,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAAA,IAC3G;AAAA,EACF;AACF;","names":[]}
1
+ {"version":3,"sources":["../src/authorization-request/parse-authorization-request.ts","../src/errors.ts","../src/authorization-request/z-request-object.ts","../src/authorization-response/create-authorization-response.ts","../src/index.ts"],"sourcesContent":["import {\n CallbackContext,\n Oauth2JwtParseError,\n RequestDpopOptions,\n decodeJwt,\n} from \"@openid4vc/oauth2\";\nimport { ValidationError } from \"@openid4vc/utils\";\n\nimport { ParseAuthorizeRequestError } from \"../errors\";\nimport {\n AuthorizationRequestObject,\n zOpenid4vpAuthorizationRequest,\n} from \"./z-request-object\";\n\nexport interface ParseAuthorizeRequestOptions {\n /**\n * Callback context for signature verification.\n */\n callbacks: Pick<CallbackContext, \"verifyJwt\">;\n\n /**\n * DPoP options\n */\n dpop: RequestDpopOptions;\n\n /**\n * The Authorization Request Object JWT.\n */\n requestObjectJwt: string;\n}\n\n/**\n * This method verifies a JWT containing a Request Object and returns its\n * decoded value for further processing\n * @param options {@link ParseAuthorizeRequestOptions}\n * @returns An {@link AuthorizationRequestObject} containing the RP required\n * credentials\n * @throws {@link ValidationError} in case there are errors validating the Request Object structure\n * @throws {@link Oauth2JwtParseError} in case the request object jwt is malformed (e.g missing header, bad encoding)\n * @throws {@link ParseAuthorizeRequestError} in case the JWT signature is invalid or there are unexpected errors\n */\nexport async function parseAuthorizeRequest(\n options: ParseAuthorizeRequestOptions,\n): Promise<AuthorizationRequestObject> {\n try {\n const decoded = decodeJwt({\n jwt: options.requestObjectJwt,\n payloadSchema: zOpenid4vpAuthorizationRequest,\n });\n const verificationResult = await options.callbacks.verifyJwt(\n options.dpop.signer,\n {\n compact: options.requestObjectJwt,\n header: decoded.header,\n payload: decoded.payload,\n },\n );\n\n if (!verificationResult.verified)\n throw new ParseAuthorizeRequestError(\n \"Error verifying Request Object signature\",\n );\n\n return decoded.payload;\n } catch (error) {\n if (\n error instanceof ValidationError ||\n error instanceof Oauth2JwtParseError\n )\n throw error;\n throw new ParseAuthorizeRequestError(\n `Unexpected error during Request Object parsing: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n}\n","/**\n * Generic error thrown during Oid4vp operations\n */\nexport class Oid4vpError extends Error {\n constructor(\n message: string,\n public readonly statusCode?: number,\n ) {\n super(message);\n this.name = \"Oid4vpError\";\n }\n}\n\n/**\n * Error thrown by {@link parseAuthorizeRequest} when the passed\n * request object has an invalid signature or unexpected errors\n * are thrown\n */\nexport class ParseAuthorizeRequestError extends Oid4vpError {\n constructor(\n message: string,\n public readonly statusCode?: number,\n ) {\n super(message);\n this.name = \"ParseAuthorizeRequestError\";\n }\n}\n\n/**\n * Error thrown by {@link createAuthorizationResponse} in case there\n * are unexpected errors.\n */\nexport class CreateAuthorizationResponseError extends Oid4vpError {\n constructor(\n message: string,\n public readonly statusCode?: number,\n ) {\n super(message);\n this.name = \"CreateAuthorizationResponseError\";\n }\n}\n","import { zJwtPayload } from \"@openid4vc/oauth2\";\nimport { z } from \"zod\";\n\n/**\n * Zod parser that describes a JWT payload\n * containing an OID4VP Request Object\n */\nexport const zOpenid4vpAuthorizationRequest = z\n .object({\n client_id: z.string(),\n dcql_query: z.record(z.string(), z.any()).optional(),\n nonce: z.string(),\n request_uri: z.string().url().optional(),\n request_uri_method: z.optional(z.string()),\n response_mode: z.literal(\"direct_post.jwt\"),\n response_type: z.literal(\"vp_token\"),\n response_uri: z.string().url().optional(),\n scope: z.string().optional(),\n state: z.string(),\n wallet_nonce: z.string().optional(),\n })\n .passthrough()\n .and(zJwtPayload);\n\nexport type AuthorizationRequestObject = z.infer<\n typeof zOpenid4vpAuthorizationRequest\n>;\n","import { CallbackContext, JwtSigner } from \"@openid4vc/oauth2\";\nimport {\n CreateOpenid4vpAuthorizationResponseOptions,\n VpToken,\n createOpenid4vpAuthorizationResponse,\n} from \"@openid4vc/openid4vp\";\nimport { addSecondsToDate, dateToSeconds } from \"@openid4vc/utils\";\nimport { ItWalletCredentialVerifierMetadata } from \"@pagopa/io-wallet-oid-federation\";\n\nimport { AuthorizationRequestObject } from \"../authorization-request\";\nimport { CreateAuthorizationResponseError } from \"../errors\";\n\ntype JarmServerMetadata = NonNullable<\n CreateOpenid4vpAuthorizationResponseOptions[\"jarm\"]\n>[\"serverMetadata\"];\n\nexport interface CreateAuthorizationResponseOptions {\n /**\n * Callbacks for authorization response generation\n */\n callbacks: Pick<\n CallbackContext,\n \"encryptJwe\" | \"fetch\" | \"generateRandom\" | \"signJwt\"\n >;\n\n /**\n * Thumbprint of the JWK in the cnf Wallet Attestation\n */\n client_id: string;\n\n /**\n * Optional expiration of the Authorization Response JWT, defaults to 10 minutes\n */\n exp?: number;\n\n /**\n * Presentation's Request Object\n */\n requestObject: AuthorizationRequestObject;\n\n /**\n * OpenID Federation Relying Party metadata\n */\n rpMetadata: ItWalletCredentialVerifierMetadata;\n\n /**\n * Signer created from the Wallet Instance's private key\n */\n signer: JwtSigner;\n\n /**\n * Array containing the vp_tokens of the credentials\n * to present\n */\n vp_token: VpToken;\n}\n\n/**\n * This method receives the RequestObject, its resolved VP Tokens and other necessary cryptographic and configuration data\n * and returns a signed and encrypted Presentation Response\n * @param options {@link CreateAuthorizationResponseOptions}\n * @returns An {@link CreateOpenid4vpAuthorizationResponseResult} representing\n * the encrypted and signed Presentation Response to the corresponding {@link AuthorizationRequestObject}\n * @throws An {@link CreateAuthorizationResponseError} in case of unexpected errors during response generation,\n * encryption, or signing\n */\nexport async function createAuthorizationResponse(\n options: CreateAuthorizationResponseOptions,\n) {\n try {\n const openid_credential_verifier = options.rpMetadata;\n\n const serverMetadata: JarmServerMetadata = {\n authorization_encryption_alg_values_supported: [\n openid_credential_verifier.authorization_encrypted_response_alg,\n ],\n authorization_encryption_enc_values_supported: [\n openid_credential_verifier.authorization_encrypted_response_enc,\n ],\n authorization_signing_alg_values_supported: [\n openid_credential_verifier.authorization_signed_response_alg,\n ],\n };\n\n // NOTE: This method sets the state in the Authorization Response\n // using the corresponding value in the Request Object\n return await createOpenid4vpAuthorizationResponse({\n authorizationRequestPayload: options.requestObject,\n authorizationResponsePayload: {\n vp_token: options.vp_token,\n },\n callbacks: options.callbacks,\n clientMetadata: openid_credential_verifier,\n jarm: {\n audience: options.requestObject.client_id,\n authorizationServer: options.client_id,\n encryption: {\n nonce: new TextDecoder().decode(\n await options.callbacks.generateRandom(32),\n ),\n },\n expiresInSeconds:\n options.exp ?? dateToSeconds(addSecondsToDate(new Date(), 60 * 10)), // default: 10 minutes\n jwtSigner: options.signer,\n serverMetadata,\n },\n });\n } catch (error) {\n throw new CreateAuthorizationResponseError(\n `Unexpected error during Request Object parsing: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n}\n","export * from \"./authorization-request\";\nexport * from \"./authorization-response\";\nexport * from \"./errors\";\n\nexport {\n type CreateOpenid4vpAuthorizationResponseOptions,\n type CreateOpenid4vpAuthorizationResponseResult,\n type VpToken,\n createOpenid4vpAuthorizationResponse,\n} from \"@openid4vc/openid4vp\";\n"],"mappings":"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","names":["createOpenid4vpAuthorizationResponse"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pagopa/io-wallet-oid4vp",
3
- "version": "0.4.2",
3
+ "version": "0.5.1",
4
4
  "files": [
5
5
  "dist"
6
6
  ],
@@ -29,13 +29,15 @@
29
29
  "@openid4vc/oauth2": "0.3.0-alpha-20250714110838",
30
30
  "@openid4vc/utils": "0.3.0-alpha-20250714110838",
31
31
  "@openid4vc/openid4vp": "0.3.0-alpha-20250714110838",
32
- "zod": "^3.24.2"
32
+ "zod": "^3.24.2",
33
+ "@pagopa/io-wallet-oid-federation": ""
33
34
  },
34
35
  "devDependencies": {
35
- "jose": "^6.1.0"
36
+ "jose": "^6.1.0",
37
+ "js-base64": "^3.7.8"
36
38
  },
37
39
  "scripts": {
38
- "build": "tsup src/index.ts --format cjs,esm --dts --clean --sourcemap",
40
+ "build": "tsup src/index.ts --format cjs,esm --dts --sourcemap",
39
41
  "test": "vitest"
40
42
  }
41
43
  }