@pagopa/io-wallet-oauth2 0.5.0 → 0.6.0
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 +56 -0
- package/dist/index.d.mts +20 -19
- package/dist/index.d.ts +20 -19
- package/dist/index.js +55 -33
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +47 -20
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -244,6 +244,62 @@ export type AccessTokenResponse = {
|
|
|
244
244
|
async function fetchTokenResponse(options: FetchTokenResponseOptions): Promise<AccessTokenResponse>
|
|
245
245
|
```
|
|
246
246
|
|
|
247
|
+
### `getJwtFromFormPost`
|
|
248
|
+
|
|
249
|
+
```typescript
|
|
250
|
+
/**
|
|
251
|
+
* Options for extracting and decoding the JWT from a form_post.jwt response
|
|
252
|
+
*/
|
|
253
|
+
export interface GetJwtFromFormPostOptions<T> {
|
|
254
|
+
/**
|
|
255
|
+
* Raw HTML containing the autosubmitted form with the jwt response
|
|
256
|
+
*/
|
|
257
|
+
formData: string;
|
|
258
|
+
|
|
259
|
+
/**
|
|
260
|
+
* Schema for parsing and validating
|
|
261
|
+
*/
|
|
262
|
+
schema: z.ZodSchema<T>;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
/*
|
|
266
|
+
* Decode a form_post.jwt and return the final JWT.
|
|
267
|
+
* The formData here is in form_post.jwt format as defined in
|
|
268
|
+
* JWT Secured Authorization Response Mode for OAuth 2.0 (JARM)
|
|
269
|
+
<!DOCTYPE html>
|
|
270
|
+
<html>
|
|
271
|
+
<head>
|
|
272
|
+
<meta charset="utf-8" />
|
|
273
|
+
</head>
|
|
274
|
+
<body onload="document.forms[0].submit()">
|
|
275
|
+
<noscript>
|
|
276
|
+
<p>
|
|
277
|
+
<strong>Note:</strong> Since your browser does not support JavaScript, you must press the Continue button once to proceed.
|
|
278
|
+
</p>
|
|
279
|
+
</noscript>
|
|
280
|
+
<form action="iowalletexample//cb" method="post">
|
|
281
|
+
<div>
|
|
282
|
+
<input type="hidden" name="response" value="somevalue" />
|
|
283
|
+
</div>
|
|
284
|
+
<noscript>
|
|
285
|
+
<div>
|
|
286
|
+
<input type="submit" value="Continue" />
|
|
287
|
+
</div>
|
|
288
|
+
</noscript>
|
|
289
|
+
</form>
|
|
290
|
+
</body>
|
|
291
|
+
</html>
|
|
292
|
+
*/
|
|
293
|
+
export const getJwtFromFormPost = async <T>(
|
|
294
|
+
options: GetJwtFromFormPostOptions<T>,
|
|
295
|
+
): Promise<{
|
|
296
|
+
decodedJwt: DecodeJwtResult<undefined, z.ZodSchema<T>>;
|
|
297
|
+
jwt: string;
|
|
298
|
+
}> => {
|
|
299
|
+
...
|
|
300
|
+
}
|
|
301
|
+
```
|
|
302
|
+
|
|
247
303
|
### Errors
|
|
248
304
|
|
|
249
305
|
```typescript
|
package/dist/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as _openid4vc_oauth2 from '@openid4vc/oauth2';
|
|
2
|
-
import { CallbackContext, AuthorizationServerMetadata, RequestDpopOptions, Jwk, JwtSignerJwk, HttpMethod } from '@openid4vc/oauth2';
|
|
2
|
+
import { CallbackContext, AuthorizationServerMetadata, RequestDpopOptions, Jwk, JwtSignerJwk, DecodeJwtResult, HttpMethod } from '@openid4vc/oauth2';
|
|
3
3
|
export { CallbackContext, GenerateRandomCallback, HashAlgorithm, HttpMethod, Jwk, JwtSigner, JwtSignerJwk, Oauth2JwtParseError, RequestDpopOptions, SignJwtCallback, VerifyJwtCallback, decodeJwt } from '@openid4vc/oauth2';
|
|
4
4
|
import * as z from 'zod';
|
|
5
5
|
import z__default, { z as z$1 } from 'zod';
|
|
@@ -846,23 +846,6 @@ interface CreateClientAttestationPopJwtOptions {
|
|
|
846
846
|
}
|
|
847
847
|
declare function createClientAttestationPopJwt(options: CreateClientAttestationPopJwtOptions): Promise<string>;
|
|
848
848
|
|
|
849
|
-
/**
|
|
850
|
-
* HTTP Content-Type constants for OAuth2 requests
|
|
851
|
-
*/
|
|
852
|
-
declare const CONTENT_TYPES: {
|
|
853
|
-
readonly FORM_URLENCODED: "application/x-www-form-urlencoded";
|
|
854
|
-
readonly JSON: "application/json";
|
|
855
|
-
};
|
|
856
|
-
/**
|
|
857
|
-
* HTTP Header constants
|
|
858
|
-
*/
|
|
859
|
-
declare const HEADERS: {
|
|
860
|
-
readonly AUTHORIZATION: "Authorization";
|
|
861
|
-
readonly CONTENT_TYPE: "Content-Type";
|
|
862
|
-
readonly OAUTH_CLIENT_ATTESTATION: "OAuth-Client-Attestation";
|
|
863
|
-
readonly OAUTH_CLIENT_ATTESTATION_POP: "OAuth-Client-Attestation-PoP";
|
|
864
|
-
};
|
|
865
|
-
|
|
866
849
|
/**
|
|
867
850
|
* Generic error thrown on OAuth2 operations
|
|
868
851
|
*/
|
|
@@ -892,6 +875,24 @@ declare class FetchTokenResponseError extends Oauth2Error {
|
|
|
892
875
|
constructor(message: string, statusCode?: number | undefined);
|
|
893
876
|
}
|
|
894
877
|
|
|
878
|
+
/**
|
|
879
|
+
* Options for extracting and decoding the JWT from a form_post.jwt response
|
|
880
|
+
*/
|
|
881
|
+
interface GetJwtFromFormPostOptions<T> {
|
|
882
|
+
/**
|
|
883
|
+
* Raw HTML containing the autosubmitted form with the jwt response
|
|
884
|
+
*/
|
|
885
|
+
formData: string;
|
|
886
|
+
/**
|
|
887
|
+
* Schema for parsing and validating
|
|
888
|
+
*/
|
|
889
|
+
schema: z__default.ZodSchema<T>;
|
|
890
|
+
}
|
|
891
|
+
declare const getJwtFromFormPost: <T>(options: GetJwtFromFormPostOptions<T>) => Promise<{
|
|
892
|
+
decodedJwt: DecodeJwtResult<undefined, z__default.ZodSchema<T>>;
|
|
893
|
+
jwt: string;
|
|
894
|
+
}>;
|
|
895
|
+
|
|
895
896
|
declare enum PkceCodeChallengeMethod {
|
|
896
897
|
Plain = "plain",
|
|
897
898
|
S256 = "S256"
|
|
@@ -2364,4 +2365,4 @@ declare const zDpopJwtHeader: z__default.ZodObject<{
|
|
|
2364
2365
|
}, z__default.ZodTypeAny, "passthrough">>;
|
|
2365
2366
|
type DpopJwtHeader = z__default.infer<typeof zDpopJwtHeader>;
|
|
2366
2367
|
|
|
2367
|
-
export { type AccessTokenRequest, type AccessTokenResponse, type AuthorizationRequest,
|
|
2368
|
+
export { type AccessTokenRequest, type AccessTokenResponse, type AuthorizationRequest, type CreateClientAttestationPopJwtOptions, type CreatePkceOptions, type CreatePkceReturn, type CreatePushedAuthorizationRequestOptions, CreateTokenDPoPError, type CreateTokenDPoPOptions, type DpopJwtHeader, type DpopJwtPayload, FetchTokenResponseError, type FetchTokenResponseOptions, type GetJwtFromFormPostOptions, Oauth2Error, PkceCodeChallengeMethod, PushedAuthorizationRequestError, type PushedAuthorizationRequestSigned, type PushedAuthorizationResponse, type VerifiedClientAttestationPopJwt, type VerifyClientAttestationPopJwtOptions, type VerifyPkceOptions, createClientAttestationPopJwt, createPkce, createPushedAuthorizationRequest, createTokenDPoP, fetchPushedAuthorizationResponse, type fetchPushedAuthorizationResponseOptions, fetchTokenResponse, getJwtFromFormPost, toURLSearchParams, verifyClientAttestationPopJwt, verifyPkce, zAccessTokenRequest, zAccessTokenResponse, zAuthorizationRequest, zDpopJwtHeader, zDpopJwtPayload, zPushedAuthorizationRequestSigned, zPushedAuthorizationResponse };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as _openid4vc_oauth2 from '@openid4vc/oauth2';
|
|
2
|
-
import { CallbackContext, AuthorizationServerMetadata, RequestDpopOptions, Jwk, JwtSignerJwk, HttpMethod } from '@openid4vc/oauth2';
|
|
2
|
+
import { CallbackContext, AuthorizationServerMetadata, RequestDpopOptions, Jwk, JwtSignerJwk, DecodeJwtResult, HttpMethod } from '@openid4vc/oauth2';
|
|
3
3
|
export { CallbackContext, GenerateRandomCallback, HashAlgorithm, HttpMethod, Jwk, JwtSigner, JwtSignerJwk, Oauth2JwtParseError, RequestDpopOptions, SignJwtCallback, VerifyJwtCallback, decodeJwt } from '@openid4vc/oauth2';
|
|
4
4
|
import * as z from 'zod';
|
|
5
5
|
import z__default, { z as z$1 } from 'zod';
|
|
@@ -846,23 +846,6 @@ interface CreateClientAttestationPopJwtOptions {
|
|
|
846
846
|
}
|
|
847
847
|
declare function createClientAttestationPopJwt(options: CreateClientAttestationPopJwtOptions): Promise<string>;
|
|
848
848
|
|
|
849
|
-
/**
|
|
850
|
-
* HTTP Content-Type constants for OAuth2 requests
|
|
851
|
-
*/
|
|
852
|
-
declare const CONTENT_TYPES: {
|
|
853
|
-
readonly FORM_URLENCODED: "application/x-www-form-urlencoded";
|
|
854
|
-
readonly JSON: "application/json";
|
|
855
|
-
};
|
|
856
|
-
/**
|
|
857
|
-
* HTTP Header constants
|
|
858
|
-
*/
|
|
859
|
-
declare const HEADERS: {
|
|
860
|
-
readonly AUTHORIZATION: "Authorization";
|
|
861
|
-
readonly CONTENT_TYPE: "Content-Type";
|
|
862
|
-
readonly OAUTH_CLIENT_ATTESTATION: "OAuth-Client-Attestation";
|
|
863
|
-
readonly OAUTH_CLIENT_ATTESTATION_POP: "OAuth-Client-Attestation-PoP";
|
|
864
|
-
};
|
|
865
|
-
|
|
866
849
|
/**
|
|
867
850
|
* Generic error thrown on OAuth2 operations
|
|
868
851
|
*/
|
|
@@ -892,6 +875,24 @@ declare class FetchTokenResponseError extends Oauth2Error {
|
|
|
892
875
|
constructor(message: string, statusCode?: number | undefined);
|
|
893
876
|
}
|
|
894
877
|
|
|
878
|
+
/**
|
|
879
|
+
* Options for extracting and decoding the JWT from a form_post.jwt response
|
|
880
|
+
*/
|
|
881
|
+
interface GetJwtFromFormPostOptions<T> {
|
|
882
|
+
/**
|
|
883
|
+
* Raw HTML containing the autosubmitted form with the jwt response
|
|
884
|
+
*/
|
|
885
|
+
formData: string;
|
|
886
|
+
/**
|
|
887
|
+
* Schema for parsing and validating
|
|
888
|
+
*/
|
|
889
|
+
schema: z__default.ZodSchema<T>;
|
|
890
|
+
}
|
|
891
|
+
declare const getJwtFromFormPost: <T>(options: GetJwtFromFormPostOptions<T>) => Promise<{
|
|
892
|
+
decodedJwt: DecodeJwtResult<undefined, z__default.ZodSchema<T>>;
|
|
893
|
+
jwt: string;
|
|
894
|
+
}>;
|
|
895
|
+
|
|
895
896
|
declare enum PkceCodeChallengeMethod {
|
|
896
897
|
Plain = "plain",
|
|
897
898
|
S256 = "S256"
|
|
@@ -2364,4 +2365,4 @@ declare const zDpopJwtHeader: z__default.ZodObject<{
|
|
|
2364
2365
|
}, z__default.ZodTypeAny, "passthrough">>;
|
|
2365
2366
|
type DpopJwtHeader = z__default.infer<typeof zDpopJwtHeader>;
|
|
2366
2367
|
|
|
2367
|
-
export { type AccessTokenRequest, type AccessTokenResponse, type AuthorizationRequest,
|
|
2368
|
+
export { type AccessTokenRequest, type AccessTokenResponse, type AuthorizationRequest, type CreateClientAttestationPopJwtOptions, type CreatePkceOptions, type CreatePkceReturn, type CreatePushedAuthorizationRequestOptions, CreateTokenDPoPError, type CreateTokenDPoPOptions, type DpopJwtHeader, type DpopJwtPayload, FetchTokenResponseError, type FetchTokenResponseOptions, type GetJwtFromFormPostOptions, Oauth2Error, PkceCodeChallengeMethod, PushedAuthorizationRequestError, type PushedAuthorizationRequestSigned, type PushedAuthorizationResponse, type VerifiedClientAttestationPopJwt, type VerifyClientAttestationPopJwtOptions, type VerifyPkceOptions, createClientAttestationPopJwt, createPkce, createPushedAuthorizationRequest, createTokenDPoP, fetchPushedAuthorizationResponse, type fetchPushedAuthorizationResponseOptions, fetchTokenResponse, getJwtFromFormPost, toURLSearchParams, verifyClientAttestationPopJwt, verifyPkce, zAccessTokenRequest, zAccessTokenResponse, zAuthorizationRequest, zDpopJwtHeader, zDpopJwtPayload, zPushedAuthorizationRequestSigned, zPushedAuthorizationResponse };
|
package/dist/index.js
CHANGED
|
@@ -30,22 +30,21 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
30
30
|
// src/index.ts
|
|
31
31
|
var index_exports = {};
|
|
32
32
|
__export(index_exports, {
|
|
33
|
-
CONTENT_TYPES: () => CONTENT_TYPES,
|
|
34
33
|
CreateTokenDPoPError: () => CreateTokenDPoPError,
|
|
35
34
|
FetchTokenResponseError: () => FetchTokenResponseError,
|
|
36
|
-
|
|
37
|
-
HashAlgorithm: () => import_oauth25.HashAlgorithm,
|
|
35
|
+
HashAlgorithm: () => import_oauth26.HashAlgorithm,
|
|
38
36
|
Oauth2Error: () => Oauth2Error,
|
|
39
|
-
Oauth2JwtParseError: () =>
|
|
37
|
+
Oauth2JwtParseError: () => import_oauth26.Oauth2JwtParseError,
|
|
40
38
|
PkceCodeChallengeMethod: () => PkceCodeChallengeMethod,
|
|
41
39
|
PushedAuthorizationRequestError: () => PushedAuthorizationRequestError,
|
|
42
40
|
createClientAttestationPopJwt: () => createClientAttestationPopJwt,
|
|
43
41
|
createPkce: () => createPkce,
|
|
44
42
|
createPushedAuthorizationRequest: () => createPushedAuthorizationRequest,
|
|
45
43
|
createTokenDPoP: () => createTokenDPoP,
|
|
46
|
-
decodeJwt: () =>
|
|
44
|
+
decodeJwt: () => import_oauth26.decodeJwt,
|
|
47
45
|
fetchPushedAuthorizationResponse: () => fetchPushedAuthorizationResponse,
|
|
48
46
|
fetchTokenResponse: () => fetchTokenResponse,
|
|
47
|
+
getJwtFromFormPost: () => getJwtFromFormPost,
|
|
49
48
|
toURLSearchParams: () => toURLSearchParams,
|
|
50
49
|
verifyClientAttestationPopJwt: () => verifyClientAttestationPopJwt,
|
|
51
50
|
verifyPkce: () => verifyPkce,
|
|
@@ -63,18 +62,6 @@ module.exports = __toCommonJS(index_exports);
|
|
|
63
62
|
var import_utils = require("@openid4vc/utils");
|
|
64
63
|
var import_io_wallet_utils = require("@pagopa/io-wallet-utils");
|
|
65
64
|
|
|
66
|
-
// src/constants.ts
|
|
67
|
-
var CONTENT_TYPES = {
|
|
68
|
-
FORM_URLENCODED: "application/x-www-form-urlencoded",
|
|
69
|
-
JSON: "application/json"
|
|
70
|
-
};
|
|
71
|
-
var HEADERS = {
|
|
72
|
-
AUTHORIZATION: "Authorization",
|
|
73
|
-
CONTENT_TYPE: "Content-Type",
|
|
74
|
-
OAUTH_CLIENT_ATTESTATION: "OAuth-Client-Attestation",
|
|
75
|
-
OAUTH_CLIENT_ATTESTATION_POP: "OAuth-Client-Attestation-PoP"
|
|
76
|
-
};
|
|
77
|
-
|
|
78
65
|
// src/errors.ts
|
|
79
66
|
var Oauth2Error = class extends Error {
|
|
80
67
|
constructor(message, statusCode) {
|
|
@@ -146,9 +133,9 @@ async function fetchTokenResponse(options) {
|
|
|
146
133
|
const tokenResponse = await fetch(options.accessTokenEndpoint, {
|
|
147
134
|
body: toURLSearchParams(options.accessTokenRequest),
|
|
148
135
|
headers: {
|
|
149
|
-
[HEADERS.CONTENT_TYPE]: CONTENT_TYPES.FORM_URLENCODED,
|
|
150
|
-
[HEADERS.OAUTH_CLIENT_ATTESTATION]: options.walletAttestation,
|
|
151
|
-
[HEADERS.OAUTH_CLIENT_ATTESTATION_POP]: options.clientAttestationDPoP
|
|
136
|
+
[import_io_wallet_utils.HEADERS.CONTENT_TYPE]: import_io_wallet_utils.CONTENT_TYPES.FORM_URLENCODED,
|
|
137
|
+
[import_io_wallet_utils.HEADERS.OAUTH_CLIENT_ATTESTATION]: options.walletAttestation,
|
|
138
|
+
[import_io_wallet_utils.HEADERS.OAUTH_CLIENT_ATTESTATION_POP]: options.clientAttestationDPoP
|
|
152
139
|
},
|
|
153
140
|
method: "POST"
|
|
154
141
|
});
|
|
@@ -339,13 +326,13 @@ async function fetchPushedAuthorizationResponse(options) {
|
|
|
339
326
|
options.pushedAuthorizationRequestEndpoint,
|
|
340
327
|
{
|
|
341
328
|
body: new URLSearchParams({
|
|
342
|
-
|
|
329
|
+
client_id: options.pushedAuthorizationRequestSigned.client_id,
|
|
343
330
|
request: options.pushedAuthorizationRequestSigned.request
|
|
344
331
|
}),
|
|
345
332
|
headers: {
|
|
346
|
-
[HEADERS.CONTENT_TYPE]: CONTENT_TYPES.FORM_URLENCODED,
|
|
347
|
-
[HEADERS.OAUTH_CLIENT_ATTESTATION]: options.walletAttestation,
|
|
348
|
-
[HEADERS.OAUTH_CLIENT_ATTESTATION_POP]: options.clientAttestationDPoP
|
|
333
|
+
[import_io_wallet_utils2.HEADERS.CONTENT_TYPE]: import_io_wallet_utils2.CONTENT_TYPES.FORM_URLENCODED,
|
|
334
|
+
[import_io_wallet_utils2.HEADERS.OAUTH_CLIENT_ATTESTATION]: options.walletAttestation,
|
|
335
|
+
[import_io_wallet_utils2.HEADERS.OAUTH_CLIENT_ATTESTATION_POP]: options.clientAttestationDPoP
|
|
349
336
|
},
|
|
350
337
|
method: "POST"
|
|
351
338
|
}
|
|
@@ -463,17 +450,53 @@ async function createClientAttestationPopJwt(options) {
|
|
|
463
450
|
}
|
|
464
451
|
}
|
|
465
452
|
|
|
453
|
+
// src/jarm-form-post-jwt.ts
|
|
454
|
+
var import_oauth23 = require("@openid4vc/oauth2");
|
|
455
|
+
var getJwtFromFormPost = async (options) => {
|
|
456
|
+
const inputRegex = /<input[^<>]*>/gi;
|
|
457
|
+
const nameRegex = /name="response"/gi;
|
|
458
|
+
const valueRegex = /value="([^"]*)"/gi;
|
|
459
|
+
const lineExpressionRegex = /\r\n|\n\r|\n|\r|\s+/g;
|
|
460
|
+
let match = inputRegex.exec(options.formData);
|
|
461
|
+
while (match) {
|
|
462
|
+
let matchName = nameRegex.exec(match[0]);
|
|
463
|
+
while (matchName) {
|
|
464
|
+
let matchValue = valueRegex.exec(match[0]);
|
|
465
|
+
while (matchValue && matchValue[1]) {
|
|
466
|
+
const responseJwt = matchValue[1];
|
|
467
|
+
if (responseJwt) {
|
|
468
|
+
const jwt = responseJwt.replace(lineExpressionRegex, "");
|
|
469
|
+
const decodedJwt = (0, import_oauth23.decodeJwt)({
|
|
470
|
+
jwt,
|
|
471
|
+
payloadSchema: options.schema
|
|
472
|
+
});
|
|
473
|
+
return {
|
|
474
|
+
decodedJwt,
|
|
475
|
+
jwt
|
|
476
|
+
};
|
|
477
|
+
}
|
|
478
|
+
matchValue = valueRegex.exec(match[0]);
|
|
479
|
+
}
|
|
480
|
+
matchName = nameRegex.exec(match[0]);
|
|
481
|
+
}
|
|
482
|
+
match = inputRegex.exec(options.formData);
|
|
483
|
+
}
|
|
484
|
+
throw new Oauth2Error(
|
|
485
|
+
`Unable to obtain JWT from form_post.jwt. Form data: ${options.formData}`
|
|
486
|
+
);
|
|
487
|
+
};
|
|
488
|
+
|
|
466
489
|
// src/token-dpop/create-token-dpop.ts
|
|
467
|
-
var
|
|
490
|
+
var import_oauth25 = require("@openid4vc/oauth2");
|
|
468
491
|
var import_utils7 = require("@openid4vc/utils");
|
|
469
492
|
var import_js_base64 = require("js-base64");
|
|
470
493
|
|
|
471
494
|
// src/token-dpop/z-dpop.ts
|
|
472
|
-
var
|
|
495
|
+
var import_oauth24 = require("@openid4vc/oauth2");
|
|
473
496
|
var import_utils6 = require("@openid4vc/utils");
|
|
474
497
|
var import_zod3 = __toESM(require("zod"));
|
|
475
498
|
var zDpopJwtPayload = import_zod3.default.object({
|
|
476
|
-
...
|
|
499
|
+
...import_oauth24.zJwtPayload.shape,
|
|
477
500
|
ath: import_zod3.default.optional(import_zod3.default.string()),
|
|
478
501
|
htm: import_utils6.zHttpMethod,
|
|
479
502
|
htu: import_utils6.zHttpsUrl,
|
|
@@ -481,8 +504,8 @@ var zDpopJwtPayload = import_zod3.default.object({
|
|
|
481
504
|
jti: import_zod3.default.string()
|
|
482
505
|
}).passthrough();
|
|
483
506
|
var zDpopJwtHeader = import_zod3.default.object({
|
|
484
|
-
...
|
|
485
|
-
jwk:
|
|
507
|
+
...import_oauth24.zJwtHeader.shape,
|
|
508
|
+
jwk: import_oauth24.zJwk,
|
|
486
509
|
typ: import_zod3.default.literal("dpop+jwt")
|
|
487
510
|
}).passthrough();
|
|
488
511
|
|
|
@@ -492,7 +515,7 @@ async function createTokenDPoP(options) {
|
|
|
492
515
|
const ath = options.accessToken ? (0, import_utils7.encodeToBase64Url)(
|
|
493
516
|
await options.callbacks.hash(
|
|
494
517
|
(0, import_utils7.decodeUtf8String)(options.accessToken),
|
|
495
|
-
|
|
518
|
+
import_oauth25.HashAlgorithm.Sha256
|
|
496
519
|
)
|
|
497
520
|
) : void 0;
|
|
498
521
|
const jti = options.jti ?? (options.callbacks.generateRandom ? import_js_base64.Base64.fromUint8Array(
|
|
@@ -537,13 +560,11 @@ var htuFromRequestUrl = (requestUrl) => {
|
|
|
537
560
|
};
|
|
538
561
|
|
|
539
562
|
// src/index.ts
|
|
540
|
-
var
|
|
563
|
+
var import_oauth26 = require("@openid4vc/oauth2");
|
|
541
564
|
// Annotate the CommonJS export names for ESM import in node:
|
|
542
565
|
0 && (module.exports = {
|
|
543
|
-
CONTENT_TYPES,
|
|
544
566
|
CreateTokenDPoPError,
|
|
545
567
|
FetchTokenResponseError,
|
|
546
|
-
HEADERS,
|
|
547
568
|
HashAlgorithm,
|
|
548
569
|
Oauth2Error,
|
|
549
570
|
Oauth2JwtParseError,
|
|
@@ -556,6 +577,7 @@ var import_oauth25 = require("@openid4vc/oauth2");
|
|
|
556
577
|
decodeJwt,
|
|
557
578
|
fetchPushedAuthorizationResponse,
|
|
558
579
|
fetchTokenResponse,
|
|
580
|
+
getJwtFromFormPost,
|
|
559
581
|
toURLSearchParams,
|
|
560
582
|
verifyClientAttestationPopJwt,
|
|
561
583
|
verifyPkce,
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/access-token/fetch-token-response.ts","../src/constants.ts","../src/errors.ts","../src/access-token/z-token.ts","../src/authorization-request/create-authorization-request.ts","../src/pkce.ts","../src/authorization-request/fetch-authorization-response.ts","../src/authorization-request/z-authorization-request.ts","../src/client-attestation-pop.ts","../src/token-dpop/create-token-dpop.ts","../src/token-dpop/z-dpop.ts"],"sourcesContent":["export * from \"./access-token\";\nexport * from \"./authorization-request\";\nexport * from \"./client-attestation-pop\";\nexport * from \"./constants\";\nexport * from \"./errors\";\nexport * from \"./pkce\";\nexport * from \"./token-dpop\";\n\nexport {\n type CallbackContext,\n type GenerateRandomCallback,\n HashAlgorithm,\n type HttpMethod,\n type Jwk,\n type JwtSigner,\n type JwtSignerJwk,\n Oauth2JwtParseError,\n type RequestDpopOptions,\n type SignJwtCallback,\n type VerifyJwtCallback,\n decodeJwt,\n} from \"@openid4vc/oauth2\";\n","import { CallbackContext } from \"@openid4vc/oauth2\";\nimport {\n ValidationError,\n createFetcher,\n parseWithErrorHandling,\n} from \"@openid4vc/utils\";\nimport {\n UnexpectedStatusCodeError,\n hasStatusOrThrow,\n} from \"@pagopa/io-wallet-utils\";\n\nimport { CONTENT_TYPES, HEADERS } from \"../constants\";\nimport { FetchTokenResponseError } from \"../errors\";\nimport {\n AccessTokenRequest,\n AccessTokenResponse,\n zAccessTokenResponse,\n} from \"./z-token\";\n\nexport interface FetchTokenResponseOptions {\n /**\n * The endpoint URL where the access token request will be sent\n * This should be the authorization server's token endpoint\n */\n accessTokenEndpoint: string;\n\n /**\n * The access token request payload\n */\n accessTokenRequest: AccessTokenRequest;\n\n /**\n * Callbacks to use for requesting access token\n */\n callbacks: Pick<CallbackContext, \"fetch\">;\n\n /**\n * The client attestation Demonstration of Proof-of-Possession (DPoP) token\n * Used for OAuth-Client-Attestation-PoP header to prove possession of the client key\n */\n clientAttestationDPoP: string;\n\n /**\n * The wallet attestation JWT that proves the client's identity and capabilities\n * Used for OAuth-Client-Attestation header\n */\n walletAttestation: string;\n}\n\n/**\n * Sends an access token request to the authorization server and returns the response\n *\n * @param options - Configuration options for the access token request\n * @returns Promise that resolves to the parsed access token response\n * @throws {UnexpectedStatusCodeError} When the server returns a non-200 status code\n * @throws {ValidationError} When the response cannot be parsed as a valid access token response\n * @throws {FetchTokenResponseError} When an unexpected error occurs during the request\n */\n\nexport async function fetchTokenResponse(\n options: FetchTokenResponseOptions,\n): Promise<AccessTokenResponse> {\n try {\n const fetch = createFetcher(options.callbacks.fetch);\n const tokenResponse = await fetch(options.accessTokenEndpoint, {\n body: toURLSearchParams(options.accessTokenRequest),\n headers: {\n [HEADERS.CONTENT_TYPE]: CONTENT_TYPES.FORM_URLENCODED,\n [HEADERS.OAUTH_CLIENT_ATTESTATION]: options.walletAttestation,\n [HEADERS.OAUTH_CLIENT_ATTESTATION_POP]: options.clientAttestationDPoP,\n },\n method: \"POST\",\n });\n\n await hasStatusOrThrow(200, UnexpectedStatusCodeError)(tokenResponse);\n\n return parseWithErrorHandling(\n zAccessTokenResponse,\n await tokenResponse.json(),\n \"Failed to parse token response\",\n );\n } catch (error) {\n if (\n error instanceof UnexpectedStatusCodeError ||\n error instanceof ValidationError\n ) {\n throw error;\n }\n throw new FetchTokenResponseError(\n `Unexpected error during token respone: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n}\n\nexport function toURLSearchParams(data: AccessTokenRequest): URLSearchParams {\n const params = new URLSearchParams();\n\n Object.entries(data).forEach(([key, value]) => {\n if (value === undefined) return;\n\n params.append(\n key,\n typeof value === \"object\" ? JSON.stringify(value) : String(value),\n );\n });\n\n return params;\n}\n","/**\n * HTTP Content-Type constants for OAuth2 requests\n */\nexport const CONTENT_TYPES = {\n FORM_URLENCODED: \"application/x-www-form-urlencoded\",\n JSON: \"application/json\",\n} as const;\n\n/**\n * HTTP Header constants\n */\nexport const HEADERS = {\n AUTHORIZATION: \"Authorization\",\n CONTENT_TYPE: \"Content-Type\",\n OAUTH_CLIENT_ATTESTATION: \"OAuth-Client-Attestation\",\n OAUTH_CLIENT_ATTESTATION_POP: \"OAuth-Client-Attestation-PoP\",\n} as const;\n","/**\n * Generic error thrown on OAuth2 operations\n */\nexport class Oauth2Error extends Error {\n constructor(\n message: string,\n public readonly statusCode?: number,\n ) {\n super(message);\n this.name = \"Oauth2Error\";\n }\n}\n\n/**\n * Custom error thrown when pushed authorization request operations fail\n */\nexport class PushedAuthorizationRequestError extends Oauth2Error {\n constructor(\n message: string,\n public readonly statusCode?: number,\n ) {\n super(message);\n this.name = \"PushedAuthorizationRequestError\";\n }\n}\n\n/**\n * Error thrown in case {@link createTokenDPoP} is called without neither a custom jti\n * nor a generateRandom callback or when the signJwt callback throws\n */\nexport class CreateTokenDPoPError extends Oauth2Error {\n constructor(message: string) {\n super(message);\n this.name = \"CreateTokenDPoPError\";\n }\n}\n\n/**\n * Custom error thrown when pushed authorization request operations fail\n */\nexport class FetchTokenResponseError extends Oauth2Error {\n constructor(\n message: string,\n public readonly statusCode?: number,\n ) {\n super(message);\n this.name = \"fetchTokenResponseError\";\n }\n}\n","import { z } from \"zod\";\n\nexport const zAccessTokenRequest = z\n .object({\n // Authorization code flow\n code: z.optional(z.string()),\n\n code_verifier: z.optional(z.string()),\n grant_type: z.literal(\"authorization_code\").or(z.literal(\"refresh_token\")),\n\n redirect_uri: z.optional(z.string()),\n // Refresh token grant\n refresh_token: z.optional(z.string()),\n })\n .passthrough()\n .refine(\n ({ code, code_verifier, grant_type, redirect_uri }) =>\n grant_type === \"authorization_code\" &&\n (!code || !code_verifier || !redirect_uri),\n {\n message: `If 'grant_type' is 'authorization_code', 'code', 'code_verifier' and 'redirect_uri' must be provided`,\n },\n )\n .refine(\n ({ grant_type, refresh_token }) =>\n grant_type === \"refresh_token\" && !refresh_token,\n {\n message: `If 'grant_type' is 'refresh_token', 'refresh_token' must be provided`,\n },\n );\n\nexport type AccessTokenRequest = z.infer<typeof zAccessTokenRequest>;\n\nexport const zAccessTokenResponse = z\n .object({\n access_token: z.string(),\n authorization_details: z\n .array(\n z\n .object({\n credential_configuration_id: z.optional(z.string()),\n credential_identifiers: z.optional(z.array(z.string())),\n type: z.literal(\"openid_credential\"),\n })\n .passthrough(),\n )\n .optional(),\n expires_in: z.optional(z.number().int()),\n refresh_token: z.optional(z.string()),\n token_type: z.literal(\"DPoP\"),\n })\n .passthrough();\n\nexport type AccessTokenResponse = z.infer<typeof zAccessTokenResponse>;\n","import {\n AuthorizationServerMetadata,\n CallbackContext,\n RequestDpopOptions,\n} from \"@openid4vc/oauth2\";\nimport { encodeToBase64Url } from \"@openid4vc/utils\";\n\nimport { createPkce } from \"../pkce\";\nimport {\n AuthorizationRequest,\n PushedAuthorizationRequestSigned,\n} from \"./z-authorization-request\";\n\nconst JWT_EXPIRY_SECONDS = 3600; // 1 hour\nconst RANDOM_BYTES_SIZE = 32;\n\nexport interface CreatePushedAuthorizationRequestOptions {\n /**\n * It MUST be set to the identifier of the Credential Issuer.\n */\n audience: string;\n\n /**\n * Allows clients to specify their fine-grained authorization requirements using the expressiveness of JSON data structures\n */\n authorization_details: AuthorizationRequest[\"authorization_details\"];\n\n /**\n * Callback context mostly for crypto related functionality\n */\n callbacks: Pick<CallbackContext, \"generateRandom\" | \"hash\" | \"signJwt\">;\n\n /**\n * MUST be set to the thumbprint of the jwk value in the cnf parameter inside the Wallet Attestation.\n */\n clientId: string;\n\n codeChallengeMethodsSupported: AuthorizationServerMetadata[\"code_challenge_methods_supported\"];\n\n /**\n * DPoP options\n */\n dpop: RequestDpopOptions;\n\n /**\n * jti parameter to use for PAR. If not provided a value will generated automatically\n */\n jti?: string;\n\n /**\n * Code verifier to use for pkce. If not provided a value will generated when pkce is supported\n */\n pkceCodeVerifier?: string;\n\n /**\n * Redirect uri to include in the authorization request\n */\n redirectUri: string;\n\n /**\n * It MUST be one of the supported values (response_modes_supported) provided in the metadata of the Credential Issuer.\n */\n responseMode: string;\n\n /**\n * Scope to request for the authorization request\n */\n scope: string;\n\n /**\n * state parameter to use for PAR. If not provided a value will generated automatically\n */\n state?: string;\n}\n\nexport async function createPushedAuthorizationRequest(\n options: CreatePushedAuthorizationRequestOptions,\n): Promise<PushedAuthorizationRequestSigned> {\n // PKCE\n const pkce = await createPkce({\n allowedCodeChallengeMethods: options.codeChallengeMethodsSupported,\n callbacks: options.callbacks,\n codeVerifier: options.pkceCodeVerifier,\n });\n\n const authorizationRequest: AuthorizationRequest = {\n authorization_details: options.authorization_details,\n client_id: options.clientId,\n code_challenge: pkce.codeChallenge,\n code_challenge_method: pkce.codeChallengeMethod,\n redirect_uri: options.redirectUri,\n response_mode: options.responseMode,\n response_type: \"code\",\n scope: options.scope,\n state:\n options.state ??\n encodeToBase64Url(\n await options.callbacks.generateRandom(RANDOM_BYTES_SIZE),\n ),\n };\n\n const { dpop } = options;\n if (!dpop.signer.alg || !dpop.signer.publicJwk?.kid) {\n throw new Error(\"DPoP signer must have alg and publicJwk.kid properties\");\n }\n\n const iat = Math.floor(Date.now());\n const requestJwt = await options.callbacks.signJwt(dpop.signer, {\n header: {\n alg: dpop.signer.alg,\n kid: dpop.signer.publicJwk.kid,\n typ: \"jwt\",\n },\n payload: {\n aud: options.audience,\n exp: iat + JWT_EXPIRY_SECONDS,\n iat,\n iss: dpop.signer.publicJwk.kid,\n jti:\n options.jti ??\n encodeToBase64Url(\n await options.callbacks.generateRandom(RANDOM_BYTES_SIZE),\n ),\n ...authorizationRequest,\n },\n });\n\n return {\n client_id: options.clientId,\n request: requestJwt.jwt,\n };\n}\n","import {\n CallbackContext,\n HashAlgorithm,\n HashCallback,\n Oauth2Error,\n} from \"@openid4vc/oauth2\";\nimport { decodeUtf8String, encodeToBase64Url } from \"@openid4vc/utils\";\n\nexport enum PkceCodeChallengeMethod {\n Plain = \"plain\",\n S256 = \"S256\",\n}\n\nexport interface CreatePkceOptions {\n /**\n * Also allows string values so it can be directly passed from the\n * 'code_challenge_methods_supported' metadata parameter\n */\n allowedCodeChallengeMethods?: (PkceCodeChallengeMethod | string)[];\n\n callbacks: Pick<CallbackContext, \"generateRandom\" | \"hash\">;\n\n /**\n * Code verifier to use. If not provided a value will be generated.\n */\n codeVerifier?: string;\n}\n\nexport interface CreatePkceReturn {\n codeChallenge: string;\n codeChallengeMethod: PkceCodeChallengeMethod;\n codeVerifier: string;\n}\n\nexport async function createPkce(\n options: CreatePkceOptions,\n): Promise<CreatePkceReturn> {\n const allowedCodeChallengeMethods = options.allowedCodeChallengeMethods ?? [\n PkceCodeChallengeMethod.S256,\n PkceCodeChallengeMethod.Plain,\n ];\n\n if (allowedCodeChallengeMethods.length === 0) {\n throw new Oauth2Error(\n `Unable to create PKCE code verifier. 'allowedCodeChallengeMethods' is an empty array.`,\n );\n }\n\n const codeChallengeMethod = allowedCodeChallengeMethods.includes(\n PkceCodeChallengeMethod.S256,\n )\n ? PkceCodeChallengeMethod.S256\n : PkceCodeChallengeMethod.Plain;\n\n const codeVerifier =\n options.codeVerifier ??\n encodeToBase64Url(await options.callbacks.generateRandom(64));\n return {\n codeChallenge: await calculateCodeChallenge({\n codeChallengeMethod,\n codeVerifier,\n hashCallback: options.callbacks.hash,\n }),\n codeChallengeMethod,\n codeVerifier,\n };\n}\n\nexport interface VerifyPkceOptions {\n callbacks: Pick<CallbackContext, \"hash\">;\n\n codeChallenge: string;\n codeChallengeMethod: PkceCodeChallengeMethod;\n\n /**\n * secure random code verifier\n */\n codeVerifier: string;\n}\n\nexport async function verifyPkce(options: VerifyPkceOptions) {\n const calculatedCodeChallenge = await calculateCodeChallenge({\n codeChallengeMethod: options.codeChallengeMethod,\n codeVerifier: options.codeVerifier,\n hashCallback: options.callbacks.hash,\n });\n\n if (options.codeChallenge !== calculatedCodeChallenge) {\n throw new Oauth2Error(\n `Derived code challenge '${calculatedCodeChallenge}' from code_verifier '${options.codeVerifier}' using code challenge method '${options.codeChallengeMethod}' does not match the expected code challenge.`,\n );\n }\n}\n\nasync function calculateCodeChallenge(options: {\n codeChallengeMethod: PkceCodeChallengeMethod;\n codeVerifier: string;\n hashCallback: HashCallback;\n}) {\n if (options.codeChallengeMethod === PkceCodeChallengeMethod.Plain) {\n return options.codeVerifier;\n }\n\n if (options.codeChallengeMethod === PkceCodeChallengeMethod.S256) {\n return encodeToBase64Url(\n await options.hashCallback(\n decodeUtf8String(options.codeVerifier),\n HashAlgorithm.Sha256,\n ),\n );\n }\n\n throw new Oauth2Error(\n `Unsupported code challenge method ${options.codeChallengeMethod}`,\n );\n}\n","import { CallbackContext } from \"@openid4vc/oauth2\";\nimport { createFetcher } from \"@openid4vc/utils\";\nimport {\n UnexpectedStatusCodeError,\n ValidationError,\n hasStatusOrThrow,\n} from \"@pagopa/io-wallet-utils\";\n\nimport { CONTENT_TYPES, HEADERS } from \"../constants\";\nimport { PushedAuthorizationRequestError } from \"../errors\";\nimport {\n PushedAuthorizationRequestSigned,\n PushedAuthorizationResponse,\n zPushedAuthorizationResponse,\n} from \"./z-authorization-request\";\n\n/**\n * Configuration options for fetching pushed authorization response\n */\nexport interface fetchPushedAuthorizationResponseOptions {\n /**\n * Callback functions for making HTTP requests\n * Allows for custom fetch implementations\n */\n callbacks: Pick<CallbackContext, \"fetch\">;\n\n /**\n * The client attestation Demonstration of Proof-of-Possession (DPoP) token\n * Used for OAuth-Client-Attestation-PoP header to prove possession of the client key\n */\n clientAttestationDPoP: string;\n\n /**\n * The endpoint URL where the pushed authorization request will be sent\n * This should be the authorization server's PAR endpoint\n */\n pushedAuthorizationRequestEndpoint: string;\n\n /**\n * The signed pushed authorization request object containing client_id and request JWT\n * This object has been previously signed and is ready for transmission\n */\n pushedAuthorizationRequestSigned: PushedAuthorizationRequestSigned;\n\n /**\n * The wallet attestation JWT that proves the client's identity and capabilities\n * Used for OAuth-Client-Attestation header\n */\n walletAttestation: string;\n}\n\n/**\n * Sends a pushed authorization request to the authorization server and returns the response\n *\n * This function implements the IT Wallet Pushed Authorization Requests (PAR) specification,\n * sending the signed authorization request to the server and handling the response.\n *\n * @param options - Configuration options for the pushed authorization request\n * @returns Promise that resolves to the parsed pushed authorization response containing request_uri and expires_in\n * @throws {UnexpectedStatusCodeError} When the server returns a non-201 status code\n * @throws {ValidationError} When the response cannot be parsed or is invalid\n */\nexport async function fetchPushedAuthorizationResponse(\n options: fetchPushedAuthorizationResponseOptions,\n): Promise<PushedAuthorizationResponse> {\n try {\n const fetch = createFetcher(options.callbacks.fetch);\n const parResponse = await fetch(\n options.pushedAuthorizationRequestEndpoint,\n {\n body: new URLSearchParams({\n clientId: options.pushedAuthorizationRequestSigned.client_id,\n request: options.pushedAuthorizationRequestSigned.request,\n }),\n headers: {\n [HEADERS.CONTENT_TYPE]: CONTENT_TYPES.FORM_URLENCODED,\n [HEADERS.OAUTH_CLIENT_ATTESTATION]: options.walletAttestation,\n [HEADERS.OAUTH_CLIENT_ATTESTATION_POP]: options.clientAttestationDPoP,\n },\n method: \"POST\",\n },\n );\n\n await hasStatusOrThrow(201, UnexpectedStatusCodeError)(parResponse);\n\n const parResponseJson = await parResponse.json();\n\n const parsedParResponse =\n zPushedAuthorizationResponse.safeParse(parResponseJson);\n if (!parsedParResponse.success) {\n throw new ValidationError(\n `Failed to parse pushed authorization response`,\n parsedParResponse.error,\n );\n }\n\n return parsedParResponse.data;\n } catch (error) {\n if (\n error instanceof UnexpectedStatusCodeError ||\n error instanceof ValidationError\n ) {\n throw error;\n }\n throw new PushedAuthorizationRequestError(\n `Unexpected error during pushed authorization request: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n}\n","import z from \"zod\";\n\nexport const zAuthorizationRequest = z\n .object({\n authorization_details: z.array(\n z.object({\n credential_configuration_id: z.string(),\n type: z.literal(\"openid_credential\"),\n }),\n ),\n client_id: z.string(),\n code_challenge: z.string(),\n code_challenge_method: z.string(),\n issuer_state: z.optional(z.string()),\n redirect_uri: z.string().url().optional(),\n response_mode: z.string(),\n response_type: z.string(),\n scope: z.string(),\n state: z.string(),\n })\n .passthrough();\nexport type AuthorizationRequest = z.infer<typeof zAuthorizationRequest>;\n\nexport const zPushedAuthorizationRequestSigned = z\n .object({\n /*\n * MUST be set to the thumbprint of the jwk value in the cnf parameter inside the Wallet Attestation.\n */\n client_id: z.string(),\n /*\n * It MUST be a signed JWT. The private key corresponding to the public one in the cnf parameter inside the Wallet Attestation MUST be used for signing the Request Object.\n */\n request: z.string(),\n })\n .passthrough();\nexport type PushedAuthorizationRequestSigned = z.infer<\n typeof zPushedAuthorizationRequestSigned\n>;\n\nexport const zPushedAuthorizationResponse = z\n .object({\n expires_in: z.number().int(),\n request_uri: z.string(),\n })\n .passthrough();\nexport type PushedAuthorizationResponse = z.infer<\n typeof zPushedAuthorizationResponse\n>;\n","import {\n CallbackContext,\n ClientAttestationPopJwtHeader,\n ClientAttestationPopJwtPayload,\n Jwk,\n JwtSignerJwk,\n decodeJwt,\n verifyJwt,\n} from \"@openid4vc/oauth2\";\nimport {\n addSecondsToDate,\n dateToSeconds,\n encodeToBase64Url,\n} from \"@openid4vc/utils\";\n\nimport { Oauth2Error } from \"./errors\";\n\nexport interface VerifyClientAttestationPopJwtOptions {\n /**\n * The issuer identifier of the authorization server handling the client attestation\n */\n authorizationServer: string;\n\n /**\n * Callbacks used for verifying client attestation pop jwt.\n */\n callbacks: Pick<CallbackContext, \"verifyJwt\">;\n\n /**\n * The compact client attestation pop jwt.\n */\n clientAttestationPopJwt: string;\n\n /**\n * The public JWK to verify the client attestation pop jwt.\n */\n clientAttestationPublicJwk: Jwk;\n\n /**\n * Expected nonce in the payload. If not provided the nonce won't be validated.\n */\n expectedNonce?: string;\n\n /**\n * Date to use for expiration. If not provided current date will be used.\n */\n now?: Date;\n}\n\nexport type VerifiedClientAttestationPopJwt = Awaited<\n ReturnType<typeof verifyClientAttestationPopJwt>\n>;\nexport async function verifyClientAttestationPopJwt(\n options: VerifyClientAttestationPopJwtOptions,\n) {\n try {\n const { header, payload } = decodeJwt({\n jwt: options.clientAttestationPopJwt,\n });\n\n if (payload.aud !== options.authorizationServer) {\n throw new Oauth2Error(\n `Client Attestation Pop jwt contains 'aud' value '${payload.aud}', but expected authorization server identifier '${options.authorizationServer}'`,\n );\n }\n\n const { signer } = await verifyJwt({\n compact: options.clientAttestationPopJwt,\n errorMessage: \"client attestation pop jwt verification failed\",\n expectedNonce: options.expectedNonce,\n header,\n now: options.now,\n payload,\n signer: {\n alg: header.alg,\n method: \"jwk\",\n publicJwk: options.clientAttestationPublicJwk,\n },\n verifyJwtCallback: options.callbacks.verifyJwt,\n });\n\n return {\n header,\n payload,\n signer,\n };\n } catch (error) {\n if (error instanceof Oauth2Error) throw error;\n throw new Oauth2Error(\n `Error creating client attestation pop jwt : ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n}\n\nexport interface CreateClientAttestationPopJwtOptions {\n /**\n * The audience authorization server identifier\n */\n authorizationServer: string;\n\n /**\n * Callback used for dpop\n * generateRandom is mandatory if jti is not provided\n */\n callbacks: Partial<Pick<CallbackContext, \"generateRandom\">> &\n Pick<CallbackContext, \"signJwt\">;\n\n /**\n * The client attestation to create the Pop for\n */\n clientAttestation: string;\n\n /**\n * Expiration time of the JWT. If not provided 1 minute will be added to the `issuedAt`\n */\n expiresAt?: Date;\n\n /**\n * Creation time of the JWT. If not provided the current date will be used\n */\n issuedAt?: Date;\n\n /**\n * Optional jti to set in the payload. If not provided a random one will be generated\n */\n jti?: string;\n\n /**\n * The signer of jwt. Only jwk signer allowed.\n *\n * If not provided, the signer will be derived based on the\n * `cnf.jwk` and `alg` in the client attestation.\n */\n signer?: JwtSignerJwk;\n}\n\nexport async function createClientAttestationPopJwt(\n options: CreateClientAttestationPopJwtOptions,\n) {\n try {\n const clientAttestation = decodeJwt({\n jwt: options.clientAttestation,\n });\n\n const jwk = clientAttestation.payload.cnf?.jwk;\n if (!jwk) {\n throw new Oauth2Error(\n \"Client attestation does not contain 'cnf.jwk', cannot create client attestation pop jwt\",\n );\n }\n\n const sub = clientAttestation.payload.sub;\n if (!sub || typeof sub !== \"string\") {\n throw new Oauth2Error(\n \"Client attestation does not contain 'sub', cannot create client attestation pop jwt\",\n );\n }\n\n const signer = options.signer ?? {\n alg: clientAttestation.header.alg,\n method: \"jwk\",\n publicJwk: jwk,\n };\n\n const header = {\n alg: signer.alg,\n typ: \"oauth-client-attestation-pop+jwt\",\n } satisfies ClientAttestationPopJwtHeader;\n\n const issuedAt = options.issuedAt ?? new Date();\n const expiresAt = options.expiresAt ?? addSecondsToDate(issuedAt, 1 * 60);\n const jti =\n options.jti ??\n (options.callbacks.generateRandom\n ? encodeToBase64Url(await options.callbacks.generateRandom(32))\n : undefined);\n\n if (!jti) {\n throw new Oauth2Error(\n \"Error: neither a default jti nor a generateRandom callback have been provided\",\n );\n }\n\n const payload = {\n aud: options.authorizationServer,\n exp: dateToSeconds(expiresAt),\n iat: dateToSeconds(issuedAt),\n iss: sub,\n jti,\n } satisfies ClientAttestationPopJwtPayload;\n\n const { jwt } = await options.callbacks.signJwt(signer, {\n header,\n payload,\n });\n\n return jwt;\n } catch (error) {\n if (error instanceof Oauth2Error) throw error;\n throw new Oauth2Error(\n `Error creating client attestation pop jwt : ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n}\n","import {\n CallbackContext,\n HashAlgorithm,\n HttpMethod,\n JwtSignerJwk,\n} from \"@openid4vc/oauth2\";\nimport {\n ValidationError,\n dateToSeconds,\n decodeUtf8String,\n encodeToBase64Url,\n parseWithErrorHandling,\n} from \"@openid4vc/utils\";\nimport { Base64 } from \"js-base64\";\n\nimport { CreateTokenDPoPError } from \"../errors\";\nimport {\n DpopJwtHeader,\n DpopJwtPayload,\n zDpopJwtHeader,\n zDpopJwtPayload,\n} from \"./z-dpop\";\n\n/**\n * Options for Token Request DPoP generation\n */\nexport interface CreateTokenDPoPOptions {\n /**\n * The access token to which the dpop jwt should be bound. Required\n * when the dpop will be sent along with an access token.\n */\n accessToken?: string;\n\n /**\n * Object containing callbacks for DPoP generation and signature\n */\n callbacks: Partial<Pick<CallbackContext, \"generateRandom\">> &\n Pick<CallbackContext, \"hash\" | \"signJwt\">;\n\n /**\n * Creation time of the JWT. If not provided the current date will be used\n */\n issuedAt?: Date;\n\n /**\n * jti claim for the DPoP JWT. If not provided, a random one will be generated\n * if a generateRandom callback is provided\n */\n jti?: string;\n\n /**\n * The signer of the dpop jwt. Only jwk signer allowed.\n */\n signer: JwtSignerJwk;\n\n /**\n * The request for which to create the dpop jwt\n */\n tokenRequest: {\n method: HttpMethod;\n url: string;\n };\n}\n\n/**\n * Creates a signed Token DPoP with the given cryptographic material and data.\n * It is used to create DPoP proofs for token requests and credential requests.\n * @param options {@link CreateTokenDPoPOptions}\n * @returns A Promise that resolves with an object containing the signed DPoP JWT and\n * its corresponding public JWK\n * @throws {@link CreateTokenDPoPError} in case neither a default jti nor a generateRandom\n * callback have been provided or the signJwt callback throws\n */\nexport async function createTokenDPoP(options: CreateTokenDPoPOptions) {\n try {\n // Calculate access token hash\n const ath = options.accessToken\n ? encodeToBase64Url(\n await options.callbacks.hash(\n decodeUtf8String(options.accessToken),\n HashAlgorithm.Sha256,\n ),\n )\n : undefined;\n\n const jti =\n options.jti ??\n (options.callbacks.generateRandom\n ? Base64.fromUint8Array(\n await options.callbacks.generateRandom(32),\n true,\n )\n : undefined);\n\n if (!jti) {\n throw new CreateTokenDPoPError(\n \"Error: neither a default jti nor a generateRandom callback have been provided\",\n );\n }\n\n const header = parseWithErrorHandling(zDpopJwtHeader, {\n alg: options.signer.alg,\n jwk: options.signer.publicJwk,\n typ: \"dpop+jwt\",\n } satisfies DpopJwtHeader);\n\n const payload = parseWithErrorHandling(zDpopJwtPayload, {\n ath,\n htm: options.tokenRequest.method,\n htu: htuFromRequestUrl(options.tokenRequest.url),\n iat: dateToSeconds(options.issuedAt),\n jti,\n } satisfies DpopJwtPayload);\n\n return options.callbacks.signJwt(options.signer, {\n header,\n payload,\n });\n } catch (error) {\n if (\n error instanceof CreateTokenDPoPError ||\n error instanceof ValidationError\n ) {\n throw error;\n }\n throw new CreateTokenDPoPError(\n `Error during jwt signature, details: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n}\n\nconst htuFromRequestUrl = (requestUrl: string) => {\n const htu = new URL(requestUrl);\n htu.search = \"\";\n htu.hash = \"\";\n\n return htu.toString();\n};\n","import { zJwk, zJwtHeader, zJwtPayload } from \"@openid4vc/oauth2\";\nimport { zHttpMethod, zHttpsUrl, zInteger } from \"@openid4vc/utils\";\nimport z from \"zod\";\n\nexport const zDpopJwtPayload = z\n .object({\n ...zJwtPayload.shape,\n ath: z.optional(z.string()),\n htm: zHttpMethod,\n htu: zHttpsUrl,\n iat: zInteger,\n\n jti: z.string(),\n })\n .passthrough();\nexport type DpopJwtPayload = z.infer<typeof zDpopJwtPayload>;\n\nexport const zDpopJwtHeader = z\n .object({\n ...zJwtHeader.shape,\n jwk: zJwk,\n typ: z.literal(\"dpop+jwt\"),\n })\n .passthrough();\nexport type DpopJwtHeader = z.infer<typeof zDpopJwtHeader>;\n"],"mappings":"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","names":["import_utils","import_utils","PkceCodeChallengeMethod","import_utils","import_io_wallet_utils","import_zod","z","import_oauth2","import_utils","import_oauth2","import_utils","import_oauth2","import_utils","import_zod","z","import_oauth2"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/access-token/fetch-token-response.ts","../src/errors.ts","../src/access-token/z-token.ts","../src/authorization-request/create-authorization-request.ts","../src/pkce.ts","../src/authorization-request/fetch-authorization-response.ts","../src/authorization-request/z-authorization-request.ts","../src/client-attestation-pop.ts","../src/jarm-form-post-jwt.ts","../src/token-dpop/create-token-dpop.ts","../src/token-dpop/z-dpop.ts"],"sourcesContent":["export * from \"./access-token\";\nexport * from \"./authorization-request\";\nexport * from \"./client-attestation-pop\";\nexport * from \"./errors\";\nexport * from \"./jarm-form-post-jwt\";\nexport * from \"./pkce\";\nexport * from \"./token-dpop\";\n\nexport {\n type CallbackContext,\n type GenerateRandomCallback,\n HashAlgorithm,\n type HttpMethod,\n type Jwk,\n type JwtSigner,\n type JwtSignerJwk,\n Oauth2JwtParseError,\n type RequestDpopOptions,\n type SignJwtCallback,\n type VerifyJwtCallback,\n decodeJwt,\n} from \"@openid4vc/oauth2\";\n","import { CallbackContext } from \"@openid4vc/oauth2\";\nimport {\n ValidationError,\n createFetcher,\n parseWithErrorHandling,\n} from \"@openid4vc/utils\";\nimport {\n CONTENT_TYPES,\n HEADERS,\n UnexpectedStatusCodeError,\n hasStatusOrThrow,\n} from \"@pagopa/io-wallet-utils\";\n\nimport { FetchTokenResponseError } from \"../errors\";\nimport {\n AccessTokenRequest,\n AccessTokenResponse,\n zAccessTokenResponse,\n} from \"./z-token\";\n\nexport interface FetchTokenResponseOptions {\n /**\n * The endpoint URL where the access token request will be sent\n * This should be the authorization server's token endpoint\n */\n accessTokenEndpoint: string;\n\n /**\n * The access token request payload\n */\n accessTokenRequest: AccessTokenRequest;\n\n /**\n * Callbacks to use for requesting access token\n */\n callbacks: Pick<CallbackContext, \"fetch\">;\n\n /**\n * The client attestation Demonstration of Proof-of-Possession (DPoP) token\n * Used for OAuth-Client-Attestation-PoP header to prove possession of the client key\n */\n clientAttestationDPoP: string;\n\n /**\n * The wallet attestation JWT that proves the client's identity and capabilities\n * Used for OAuth-Client-Attestation header\n */\n walletAttestation: string;\n}\n\n/**\n * Sends an access token request to the authorization server and returns the response\n *\n * @param options - Configuration options for the access token request\n * @returns Promise that resolves to the parsed access token response\n * @throws {UnexpectedStatusCodeError} When the server returns a non-200 status code\n * @throws {ValidationError} When the response cannot be parsed as a valid access token response\n * @throws {FetchTokenResponseError} When an unexpected error occurs during the request\n */\n\nexport async function fetchTokenResponse(\n options: FetchTokenResponseOptions,\n): Promise<AccessTokenResponse> {\n try {\n const fetch = createFetcher(options.callbacks.fetch);\n const tokenResponse = await fetch(options.accessTokenEndpoint, {\n body: toURLSearchParams(options.accessTokenRequest),\n headers: {\n [HEADERS.CONTENT_TYPE]: CONTENT_TYPES.FORM_URLENCODED,\n [HEADERS.OAUTH_CLIENT_ATTESTATION]: options.walletAttestation,\n [HEADERS.OAUTH_CLIENT_ATTESTATION_POP]: options.clientAttestationDPoP,\n },\n method: \"POST\",\n });\n\n await hasStatusOrThrow(200, UnexpectedStatusCodeError)(tokenResponse);\n\n return parseWithErrorHandling(\n zAccessTokenResponse,\n await tokenResponse.json(),\n \"Failed to parse token response\",\n );\n } catch (error) {\n if (\n error instanceof UnexpectedStatusCodeError ||\n error instanceof ValidationError\n ) {\n throw error;\n }\n throw new FetchTokenResponseError(\n `Unexpected error during token respone: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n}\n\nexport function toURLSearchParams(data: AccessTokenRequest): URLSearchParams {\n const params = new URLSearchParams();\n\n Object.entries(data).forEach(([key, value]) => {\n if (value === undefined) return;\n\n params.append(\n key,\n typeof value === \"object\" ? JSON.stringify(value) : String(value),\n );\n });\n\n return params;\n}\n","/**\n * Generic error thrown on OAuth2 operations\n */\nexport class Oauth2Error extends Error {\n constructor(\n message: string,\n public readonly statusCode?: number,\n ) {\n super(message);\n this.name = \"Oauth2Error\";\n }\n}\n\n/**\n * Custom error thrown when pushed authorization request operations fail\n */\nexport class PushedAuthorizationRequestError extends Oauth2Error {\n constructor(\n message: string,\n public readonly statusCode?: number,\n ) {\n super(message);\n this.name = \"PushedAuthorizationRequestError\";\n }\n}\n\n/**\n * Error thrown in case {@link createTokenDPoP} is called without neither a custom jti\n * nor a generateRandom callback or when the signJwt callback throws\n */\nexport class CreateTokenDPoPError extends Oauth2Error {\n constructor(message: string) {\n super(message);\n this.name = \"CreateTokenDPoPError\";\n }\n}\n\n/**\n * Custom error thrown when pushed authorization request operations fail\n */\nexport class FetchTokenResponseError extends Oauth2Error {\n constructor(\n message: string,\n public readonly statusCode?: number,\n ) {\n super(message);\n this.name = \"fetchTokenResponseError\";\n }\n}\n","import { z } from \"zod\";\n\nexport const zAccessTokenRequest = z\n .object({\n // Authorization code flow\n code: z.optional(z.string()),\n\n code_verifier: z.optional(z.string()),\n grant_type: z.literal(\"authorization_code\").or(z.literal(\"refresh_token\")),\n\n redirect_uri: z.optional(z.string()),\n // Refresh token grant\n refresh_token: z.optional(z.string()),\n })\n .passthrough()\n .refine(\n ({ code, code_verifier, grant_type, redirect_uri }) =>\n grant_type === \"authorization_code\" &&\n (!code || !code_verifier || !redirect_uri),\n {\n message: `If 'grant_type' is 'authorization_code', 'code', 'code_verifier' and 'redirect_uri' must be provided`,\n },\n )\n .refine(\n ({ grant_type, refresh_token }) =>\n grant_type === \"refresh_token\" && !refresh_token,\n {\n message: `If 'grant_type' is 'refresh_token', 'refresh_token' must be provided`,\n },\n );\n\nexport type AccessTokenRequest = z.infer<typeof zAccessTokenRequest>;\n\nexport const zAccessTokenResponse = z\n .object({\n access_token: z.string(),\n authorization_details: z\n .array(\n z\n .object({\n credential_configuration_id: z.optional(z.string()),\n credential_identifiers: z.optional(z.array(z.string())),\n type: z.literal(\"openid_credential\"),\n })\n .passthrough(),\n )\n .optional(),\n expires_in: z.optional(z.number().int()),\n refresh_token: z.optional(z.string()),\n token_type: z.literal(\"DPoP\"),\n })\n .passthrough();\n\nexport type AccessTokenResponse = z.infer<typeof zAccessTokenResponse>;\n","import {\n AuthorizationServerMetadata,\n CallbackContext,\n RequestDpopOptions,\n} from \"@openid4vc/oauth2\";\nimport { encodeToBase64Url } from \"@openid4vc/utils\";\n\nimport { createPkce } from \"../pkce\";\nimport {\n AuthorizationRequest,\n PushedAuthorizationRequestSigned,\n} from \"./z-authorization-request\";\n\nconst JWT_EXPIRY_SECONDS = 3600; // 1 hour\nconst RANDOM_BYTES_SIZE = 32;\n\nexport interface CreatePushedAuthorizationRequestOptions {\n /**\n * It MUST be set to the identifier of the Credential Issuer.\n */\n audience: string;\n\n /**\n * Allows clients to specify their fine-grained authorization requirements using the expressiveness of JSON data structures\n */\n authorization_details: AuthorizationRequest[\"authorization_details\"];\n\n /**\n * Callback context mostly for crypto related functionality\n */\n callbacks: Pick<CallbackContext, \"generateRandom\" | \"hash\" | \"signJwt\">;\n\n /**\n * MUST be set to the thumbprint of the jwk value in the cnf parameter inside the Wallet Attestation.\n */\n clientId: string;\n\n codeChallengeMethodsSupported: AuthorizationServerMetadata[\"code_challenge_methods_supported\"];\n\n /**\n * DPoP options\n */\n dpop: RequestDpopOptions;\n\n /**\n * jti parameter to use for PAR. If not provided a value will generated automatically\n */\n jti?: string;\n\n /**\n * Code verifier to use for pkce. If not provided a value will generated when pkce is supported\n */\n pkceCodeVerifier?: string;\n\n /**\n * Redirect uri to include in the authorization request\n */\n redirectUri: string;\n\n /**\n * It MUST be one of the supported values (response_modes_supported) provided in the metadata of the Credential Issuer.\n */\n responseMode: string;\n\n /**\n * Scope to request for the authorization request\n */\n scope: string;\n\n /**\n * state parameter to use for PAR. If not provided a value will generated automatically\n */\n state?: string;\n}\n\nexport async function createPushedAuthorizationRequest(\n options: CreatePushedAuthorizationRequestOptions,\n): Promise<PushedAuthorizationRequestSigned> {\n // PKCE\n const pkce = await createPkce({\n allowedCodeChallengeMethods: options.codeChallengeMethodsSupported,\n callbacks: options.callbacks,\n codeVerifier: options.pkceCodeVerifier,\n });\n\n const authorizationRequest: AuthorizationRequest = {\n authorization_details: options.authorization_details,\n client_id: options.clientId,\n code_challenge: pkce.codeChallenge,\n code_challenge_method: pkce.codeChallengeMethod,\n redirect_uri: options.redirectUri,\n response_mode: options.responseMode,\n response_type: \"code\",\n scope: options.scope,\n state:\n options.state ??\n encodeToBase64Url(\n await options.callbacks.generateRandom(RANDOM_BYTES_SIZE),\n ),\n };\n\n const { dpop } = options;\n if (!dpop.signer.alg || !dpop.signer.publicJwk?.kid) {\n throw new Error(\"DPoP signer must have alg and publicJwk.kid properties\");\n }\n\n const iat = Math.floor(Date.now());\n const requestJwt = await options.callbacks.signJwt(dpop.signer, {\n header: {\n alg: dpop.signer.alg,\n kid: dpop.signer.publicJwk.kid,\n typ: \"jwt\",\n },\n payload: {\n aud: options.audience,\n exp: iat + JWT_EXPIRY_SECONDS,\n iat,\n iss: dpop.signer.publicJwk.kid,\n jti:\n options.jti ??\n encodeToBase64Url(\n await options.callbacks.generateRandom(RANDOM_BYTES_SIZE),\n ),\n ...authorizationRequest,\n },\n });\n\n return {\n client_id: options.clientId,\n request: requestJwt.jwt,\n };\n}\n","import {\n CallbackContext,\n HashAlgorithm,\n HashCallback,\n Oauth2Error,\n} from \"@openid4vc/oauth2\";\nimport { decodeUtf8String, encodeToBase64Url } from \"@openid4vc/utils\";\n\nexport enum PkceCodeChallengeMethod {\n Plain = \"plain\",\n S256 = \"S256\",\n}\n\nexport interface CreatePkceOptions {\n /**\n * Also allows string values so it can be directly passed from the\n * 'code_challenge_methods_supported' metadata parameter\n */\n allowedCodeChallengeMethods?: (PkceCodeChallengeMethod | string)[];\n\n callbacks: Pick<CallbackContext, \"generateRandom\" | \"hash\">;\n\n /**\n * Code verifier to use. If not provided a value will be generated.\n */\n codeVerifier?: string;\n}\n\nexport interface CreatePkceReturn {\n codeChallenge: string;\n codeChallengeMethod: PkceCodeChallengeMethod;\n codeVerifier: string;\n}\n\nexport async function createPkce(\n options: CreatePkceOptions,\n): Promise<CreatePkceReturn> {\n const allowedCodeChallengeMethods = options.allowedCodeChallengeMethods ?? [\n PkceCodeChallengeMethod.S256,\n PkceCodeChallengeMethod.Plain,\n ];\n\n if (allowedCodeChallengeMethods.length === 0) {\n throw new Oauth2Error(\n `Unable to create PKCE code verifier. 'allowedCodeChallengeMethods' is an empty array.`,\n );\n }\n\n const codeChallengeMethod = allowedCodeChallengeMethods.includes(\n PkceCodeChallengeMethod.S256,\n )\n ? PkceCodeChallengeMethod.S256\n : PkceCodeChallengeMethod.Plain;\n\n const codeVerifier =\n options.codeVerifier ??\n encodeToBase64Url(await options.callbacks.generateRandom(64));\n return {\n codeChallenge: await calculateCodeChallenge({\n codeChallengeMethod,\n codeVerifier,\n hashCallback: options.callbacks.hash,\n }),\n codeChallengeMethod,\n codeVerifier,\n };\n}\n\nexport interface VerifyPkceOptions {\n callbacks: Pick<CallbackContext, \"hash\">;\n\n codeChallenge: string;\n codeChallengeMethod: PkceCodeChallengeMethod;\n\n /**\n * secure random code verifier\n */\n codeVerifier: string;\n}\n\nexport async function verifyPkce(options: VerifyPkceOptions) {\n const calculatedCodeChallenge = await calculateCodeChallenge({\n codeChallengeMethod: options.codeChallengeMethod,\n codeVerifier: options.codeVerifier,\n hashCallback: options.callbacks.hash,\n });\n\n if (options.codeChallenge !== calculatedCodeChallenge) {\n throw new Oauth2Error(\n `Derived code challenge '${calculatedCodeChallenge}' from code_verifier '${options.codeVerifier}' using code challenge method '${options.codeChallengeMethod}' does not match the expected code challenge.`,\n );\n }\n}\n\nasync function calculateCodeChallenge(options: {\n codeChallengeMethod: PkceCodeChallengeMethod;\n codeVerifier: string;\n hashCallback: HashCallback;\n}) {\n if (options.codeChallengeMethod === PkceCodeChallengeMethod.Plain) {\n return options.codeVerifier;\n }\n\n if (options.codeChallengeMethod === PkceCodeChallengeMethod.S256) {\n return encodeToBase64Url(\n await options.hashCallback(\n decodeUtf8String(options.codeVerifier),\n HashAlgorithm.Sha256,\n ),\n );\n }\n\n throw new Oauth2Error(\n `Unsupported code challenge method ${options.codeChallengeMethod}`,\n );\n}\n","import { CallbackContext } from \"@openid4vc/oauth2\";\nimport { createFetcher } from \"@openid4vc/utils\";\nimport {\n CONTENT_TYPES,\n HEADERS,\n UnexpectedStatusCodeError,\n ValidationError,\n hasStatusOrThrow,\n} from \"@pagopa/io-wallet-utils\";\n\nimport { PushedAuthorizationRequestError } from \"../errors\";\nimport {\n PushedAuthorizationRequestSigned,\n PushedAuthorizationResponse,\n zPushedAuthorizationResponse,\n} from \"./z-authorization-request\";\n\n/**\n * Configuration options for fetching pushed authorization response\n */\nexport interface fetchPushedAuthorizationResponseOptions {\n /**\n * Callback functions for making HTTP requests\n * Allows for custom fetch implementations\n */\n callbacks: Pick<CallbackContext, \"fetch\">;\n\n /**\n * The client attestation Demonstration of Proof-of-Possession (DPoP) token\n * Used for OAuth-Client-Attestation-PoP header to prove possession of the client key\n */\n clientAttestationDPoP: string;\n\n /**\n * The endpoint URL where the pushed authorization request will be sent\n * This should be the authorization server's PAR endpoint\n */\n pushedAuthorizationRequestEndpoint: string;\n\n /**\n * The signed pushed authorization request object containing client_id and request JWT\n * This object has been previously signed and is ready for transmission\n */\n pushedAuthorizationRequestSigned: PushedAuthorizationRequestSigned;\n\n /**\n * The wallet attestation JWT that proves the client's identity and capabilities\n * Used for OAuth-Client-Attestation header\n */\n walletAttestation: string;\n}\n\n/**\n * Sends a pushed authorization request to the authorization server and returns the response\n *\n * This function implements the IT Wallet Pushed Authorization Requests (PAR) specification,\n * sending the signed authorization request to the server and handling the response.\n *\n * @param options - Configuration options for the pushed authorization request\n * @returns Promise that resolves to the parsed pushed authorization response containing request_uri and expires_in\n * @throws {UnexpectedStatusCodeError} When the server returns a non-201 status code\n * @throws {ValidationError} When the response cannot be parsed or is invalid\n */\nexport async function fetchPushedAuthorizationResponse(\n options: fetchPushedAuthorizationResponseOptions,\n): Promise<PushedAuthorizationResponse> {\n try {\n const fetch = createFetcher(options.callbacks.fetch);\n const parResponse = await fetch(\n options.pushedAuthorizationRequestEndpoint,\n {\n body: new URLSearchParams({\n client_id: options.pushedAuthorizationRequestSigned.client_id,\n request: options.pushedAuthorizationRequestSigned.request,\n }),\n headers: {\n [HEADERS.CONTENT_TYPE]: CONTENT_TYPES.FORM_URLENCODED,\n [HEADERS.OAUTH_CLIENT_ATTESTATION]: options.walletAttestation,\n [HEADERS.OAUTH_CLIENT_ATTESTATION_POP]: options.clientAttestationDPoP,\n },\n method: \"POST\",\n },\n );\n\n await hasStatusOrThrow(201, UnexpectedStatusCodeError)(parResponse);\n\n const parResponseJson = await parResponse.json();\n\n const parsedParResponse =\n zPushedAuthorizationResponse.safeParse(parResponseJson);\n if (!parsedParResponse.success) {\n throw new ValidationError(\n `Failed to parse pushed authorization response`,\n parsedParResponse.error,\n );\n }\n\n return parsedParResponse.data;\n } catch (error) {\n if (\n error instanceof UnexpectedStatusCodeError ||\n error instanceof ValidationError\n ) {\n throw error;\n }\n throw new PushedAuthorizationRequestError(\n `Unexpected error during pushed authorization request: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n}\n","import z from \"zod\";\n\nexport const zAuthorizationRequest = z\n .object({\n authorization_details: z.array(\n z.object({\n credential_configuration_id: z.string(),\n type: z.literal(\"openid_credential\"),\n }),\n ),\n client_id: z.string(),\n code_challenge: z.string(),\n code_challenge_method: z.string(),\n issuer_state: z.optional(z.string()),\n redirect_uri: z.string().url().optional(),\n response_mode: z.string(),\n response_type: z.string(),\n scope: z.string(),\n state: z.string(),\n })\n .passthrough();\nexport type AuthorizationRequest = z.infer<typeof zAuthorizationRequest>;\n\nexport const zPushedAuthorizationRequestSigned = z\n .object({\n /*\n * MUST be set to the thumbprint of the jwk value in the cnf parameter inside the Wallet Attestation.\n */\n client_id: z.string(),\n /*\n * It MUST be a signed JWT. The private key corresponding to the public one in the cnf parameter inside the Wallet Attestation MUST be used for signing the Request Object.\n */\n request: z.string(),\n })\n .passthrough();\nexport type PushedAuthorizationRequestSigned = z.infer<\n typeof zPushedAuthorizationRequestSigned\n>;\n\nexport const zPushedAuthorizationResponse = z\n .object({\n expires_in: z.number().int(),\n request_uri: z.string(),\n })\n .passthrough();\nexport type PushedAuthorizationResponse = z.infer<\n typeof zPushedAuthorizationResponse\n>;\n","import {\n CallbackContext,\n ClientAttestationPopJwtHeader,\n ClientAttestationPopJwtPayload,\n Jwk,\n JwtSignerJwk,\n decodeJwt,\n verifyJwt,\n} from \"@openid4vc/oauth2\";\nimport {\n addSecondsToDate,\n dateToSeconds,\n encodeToBase64Url,\n} from \"@openid4vc/utils\";\n\nimport { Oauth2Error } from \"./errors\";\n\nexport interface VerifyClientAttestationPopJwtOptions {\n /**\n * The issuer identifier of the authorization server handling the client attestation\n */\n authorizationServer: string;\n\n /**\n * Callbacks used for verifying client attestation pop jwt.\n */\n callbacks: Pick<CallbackContext, \"verifyJwt\">;\n\n /**\n * The compact client attestation pop jwt.\n */\n clientAttestationPopJwt: string;\n\n /**\n * The public JWK to verify the client attestation pop jwt.\n */\n clientAttestationPublicJwk: Jwk;\n\n /**\n * Expected nonce in the payload. If not provided the nonce won't be validated.\n */\n expectedNonce?: string;\n\n /**\n * Date to use for expiration. If not provided current date will be used.\n */\n now?: Date;\n}\n\nexport type VerifiedClientAttestationPopJwt = Awaited<\n ReturnType<typeof verifyClientAttestationPopJwt>\n>;\nexport async function verifyClientAttestationPopJwt(\n options: VerifyClientAttestationPopJwtOptions,\n) {\n try {\n const { header, payload } = decodeJwt({\n jwt: options.clientAttestationPopJwt,\n });\n\n if (payload.aud !== options.authorizationServer) {\n throw new Oauth2Error(\n `Client Attestation Pop jwt contains 'aud' value '${payload.aud}', but expected authorization server identifier '${options.authorizationServer}'`,\n );\n }\n\n const { signer } = await verifyJwt({\n compact: options.clientAttestationPopJwt,\n errorMessage: \"client attestation pop jwt verification failed\",\n expectedNonce: options.expectedNonce,\n header,\n now: options.now,\n payload,\n signer: {\n alg: header.alg,\n method: \"jwk\",\n publicJwk: options.clientAttestationPublicJwk,\n },\n verifyJwtCallback: options.callbacks.verifyJwt,\n });\n\n return {\n header,\n payload,\n signer,\n };\n } catch (error) {\n if (error instanceof Oauth2Error) throw error;\n throw new Oauth2Error(\n `Error creating client attestation pop jwt : ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n}\n\nexport interface CreateClientAttestationPopJwtOptions {\n /**\n * The audience authorization server identifier\n */\n authorizationServer: string;\n\n /**\n * Callback used for dpop\n * generateRandom is mandatory if jti is not provided\n */\n callbacks: Partial<Pick<CallbackContext, \"generateRandom\">> &\n Pick<CallbackContext, \"signJwt\">;\n\n /**\n * The client attestation to create the Pop for\n */\n clientAttestation: string;\n\n /**\n * Expiration time of the JWT. If not provided 1 minute will be added to the `issuedAt`\n */\n expiresAt?: Date;\n\n /**\n * Creation time of the JWT. If not provided the current date will be used\n */\n issuedAt?: Date;\n\n /**\n * Optional jti to set in the payload. If not provided a random one will be generated\n */\n jti?: string;\n\n /**\n * The signer of jwt. Only jwk signer allowed.\n *\n * If not provided, the signer will be derived based on the\n * `cnf.jwk` and `alg` in the client attestation.\n */\n signer?: JwtSignerJwk;\n}\n\nexport async function createClientAttestationPopJwt(\n options: CreateClientAttestationPopJwtOptions,\n) {\n try {\n const clientAttestation = decodeJwt({\n jwt: options.clientAttestation,\n });\n\n const jwk = clientAttestation.payload.cnf?.jwk;\n if (!jwk) {\n throw new Oauth2Error(\n \"Client attestation does not contain 'cnf.jwk', cannot create client attestation pop jwt\",\n );\n }\n\n const sub = clientAttestation.payload.sub;\n if (!sub || typeof sub !== \"string\") {\n throw new Oauth2Error(\n \"Client attestation does not contain 'sub', cannot create client attestation pop jwt\",\n );\n }\n\n const signer = options.signer ?? {\n alg: clientAttestation.header.alg,\n method: \"jwk\",\n publicJwk: jwk,\n };\n\n const header = {\n alg: signer.alg,\n typ: \"oauth-client-attestation-pop+jwt\",\n } satisfies ClientAttestationPopJwtHeader;\n\n const issuedAt = options.issuedAt ?? new Date();\n const expiresAt = options.expiresAt ?? addSecondsToDate(issuedAt, 1 * 60);\n const jti =\n options.jti ??\n (options.callbacks.generateRandom\n ? encodeToBase64Url(await options.callbacks.generateRandom(32))\n : undefined);\n\n if (!jti) {\n throw new Oauth2Error(\n \"Error: neither a default jti nor a generateRandom callback have been provided\",\n );\n }\n\n const payload = {\n aud: options.authorizationServer,\n exp: dateToSeconds(expiresAt),\n iat: dateToSeconds(issuedAt),\n iss: sub,\n jti,\n } satisfies ClientAttestationPopJwtPayload;\n\n const { jwt } = await options.callbacks.signJwt(signer, {\n header,\n payload,\n });\n\n return jwt;\n } catch (error) {\n if (error instanceof Oauth2Error) throw error;\n throw new Oauth2Error(\n `Error creating client attestation pop jwt : ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n}\n","import { DecodeJwtResult, decodeJwt } from \"@openid4vc/oauth2\";\nimport z from \"zod\";\n\nimport { Oauth2Error } from \"./errors\";\n\n/**\n * Options for extracting and decoding the JWT from a form_post.jwt response\n */\nexport interface GetJwtFromFormPostOptions<T> {\n /**\n * Raw HTML containing the autosubmitted form with the jwt response\n */\n formData: string;\n\n /**\n * Schema for parsing and validating\n */\n schema: z.ZodSchema<T>;\n}\n\n/*\n * Decode a form_post.jwt and return the final JWT.\n * The formData here is in form_post.jwt format as defined in\n * JWT Secured Authorization Response Mode for OAuth 2.0 (JARM)\n <!DOCTYPE html>\n <html>\n <head>\n <meta charset=\"utf-8\" />\n </head>\n <body onload=\"document.forms[0].submit()\">\n <noscript>\n <p>\n <strong>Note:</strong> Since your browser does not support JavaScript, you must press the Continue button once to proceed.\n </p>\n </noscript>\n <form action=\"iowalletexample//cb\" method=\"post\"> \n <div>\n <input type=\"hidden\" name=\"response\" value=\"somevalue\" />\n </div>\n <noscript>\n <div>\n <input type=\"submit\" value=\"Continue\" />\n </div>\n </noscript>\n </form>\n </body>\n </html>\n */\nexport const getJwtFromFormPost = async <T>(\n options: GetJwtFromFormPostOptions<T>,\n): Promise<{\n decodedJwt: DecodeJwtResult<undefined, z.ZodSchema<T>>;\n jwt: string;\n}> => {\n const inputRegex = /<input[^<>]*>/gi;\n const nameRegex = /name=\"response\"/gi;\n const valueRegex = /value=\"([^\"]*)\"/gi;\n const lineExpressionRegex = /\\r\\n|\\n\\r|\\n|\\r|\\s+/g;\n\n let match = inputRegex.exec(options.formData);\n while (match) {\n let matchName = nameRegex.exec(match[0]);\n while (matchName) {\n let matchValue = valueRegex.exec(match[0]);\n while (matchValue && matchValue[1]) {\n const responseJwt = matchValue[1];\n\n if (responseJwt) {\n const jwt = responseJwt.replace(lineExpressionRegex, \"\");\n const decodedJwt = decodeJwt({\n jwt,\n payloadSchema: options.schema,\n });\n return {\n decodedJwt,\n jwt,\n };\n }\n\n matchValue = valueRegex.exec(match[0]);\n }\n matchName = nameRegex.exec(match[0]);\n }\n\n match = inputRegex.exec(options.formData);\n }\n\n throw new Oauth2Error(\n `Unable to obtain JWT from form_post.jwt. Form data: ${options.formData}`,\n );\n};\n","import {\n CallbackContext,\n HashAlgorithm,\n HttpMethod,\n JwtSignerJwk,\n} from \"@openid4vc/oauth2\";\nimport {\n ValidationError,\n dateToSeconds,\n decodeUtf8String,\n encodeToBase64Url,\n parseWithErrorHandling,\n} from \"@openid4vc/utils\";\nimport { Base64 } from \"js-base64\";\n\nimport { CreateTokenDPoPError } from \"../errors\";\nimport {\n DpopJwtHeader,\n DpopJwtPayload,\n zDpopJwtHeader,\n zDpopJwtPayload,\n} from \"./z-dpop\";\n\n/**\n * Options for Token Request DPoP generation\n */\nexport interface CreateTokenDPoPOptions {\n /**\n * The access token to which the dpop jwt should be bound. Required\n * when the dpop will be sent along with an access token.\n */\n accessToken?: string;\n\n /**\n * Object containing callbacks for DPoP generation and signature\n */\n callbacks: Partial<Pick<CallbackContext, \"generateRandom\">> &\n Pick<CallbackContext, \"hash\" | \"signJwt\">;\n\n /**\n * Creation time of the JWT. If not provided the current date will be used\n */\n issuedAt?: Date;\n\n /**\n * jti claim for the DPoP JWT. If not provided, a random one will be generated\n * if a generateRandom callback is provided\n */\n jti?: string;\n\n /**\n * The signer of the dpop jwt. Only jwk signer allowed.\n */\n signer: JwtSignerJwk;\n\n /**\n * The request for which to create the dpop jwt\n */\n tokenRequest: {\n method: HttpMethod;\n url: string;\n };\n}\n\n/**\n * Creates a signed Token DPoP with the given cryptographic material and data.\n * It is used to create DPoP proofs for token requests and credential requests.\n * @param options {@link CreateTokenDPoPOptions}\n * @returns A Promise that resolves with an object containing the signed DPoP JWT and\n * its corresponding public JWK\n * @throws {@link CreateTokenDPoPError} in case neither a default jti nor a generateRandom\n * callback have been provided or the signJwt callback throws\n */\nexport async function createTokenDPoP(options: CreateTokenDPoPOptions) {\n try {\n // Calculate access token hash\n const ath = options.accessToken\n ? encodeToBase64Url(\n await options.callbacks.hash(\n decodeUtf8String(options.accessToken),\n HashAlgorithm.Sha256,\n ),\n )\n : undefined;\n\n const jti =\n options.jti ??\n (options.callbacks.generateRandom\n ? Base64.fromUint8Array(\n await options.callbacks.generateRandom(32),\n true,\n )\n : undefined);\n\n if (!jti) {\n throw new CreateTokenDPoPError(\n \"Error: neither a default jti nor a generateRandom callback have been provided\",\n );\n }\n\n const header = parseWithErrorHandling(zDpopJwtHeader, {\n alg: options.signer.alg,\n jwk: options.signer.publicJwk,\n typ: \"dpop+jwt\",\n } satisfies DpopJwtHeader);\n\n const payload = parseWithErrorHandling(zDpopJwtPayload, {\n ath,\n htm: options.tokenRequest.method,\n htu: htuFromRequestUrl(options.tokenRequest.url),\n iat: dateToSeconds(options.issuedAt),\n jti,\n } satisfies DpopJwtPayload);\n\n return options.callbacks.signJwt(options.signer, {\n header,\n payload,\n });\n } catch (error) {\n if (\n error instanceof CreateTokenDPoPError ||\n error instanceof ValidationError\n ) {\n throw error;\n }\n throw new CreateTokenDPoPError(\n `Error during jwt signature, details: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n}\n\nconst htuFromRequestUrl = (requestUrl: string) => {\n const htu = new URL(requestUrl);\n htu.search = \"\";\n htu.hash = \"\";\n\n return htu.toString();\n};\n","import { zJwk, zJwtHeader, zJwtPayload } from \"@openid4vc/oauth2\";\nimport { zHttpMethod, zHttpsUrl, zInteger } from \"@openid4vc/utils\";\nimport z from \"zod\";\n\nexport const zDpopJwtPayload = z\n .object({\n ...zJwtPayload.shape,\n ath: z.optional(z.string()),\n htm: zHttpMethod,\n htu: zHttpsUrl,\n iat: zInteger,\n\n jti: z.string(),\n })\n .passthrough();\nexport type DpopJwtPayload = z.infer<typeof zDpopJwtPayload>;\n\nexport const zDpopJwtHeader = z\n .object({\n ...zJwtHeader.shape,\n jwk: zJwk,\n typ: z.literal(\"dpop+jwt\"),\n })\n .passthrough();\nexport type DpopJwtHeader = z.infer<typeof zDpopJwtHeader>;\n"],"mappings":"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","names":["import_utils","import_utils","PkceCodeChallengeMethod","import_utils","import_io_wallet_utils","import_zod","z","import_oauth2","import_utils","import_oauth2","import_oauth2","import_utils","import_oauth2","import_utils","import_zod","z","import_oauth2"]}
|
package/dist/index.mjs
CHANGED
|
@@ -5,22 +5,12 @@ import {
|
|
|
5
5
|
parseWithErrorHandling
|
|
6
6
|
} from "@openid4vc/utils";
|
|
7
7
|
import {
|
|
8
|
+
CONTENT_TYPES,
|
|
9
|
+
HEADERS,
|
|
8
10
|
UnexpectedStatusCodeError,
|
|
9
11
|
hasStatusOrThrow
|
|
10
12
|
} from "@pagopa/io-wallet-utils";
|
|
11
13
|
|
|
12
|
-
// src/constants.ts
|
|
13
|
-
var CONTENT_TYPES = {
|
|
14
|
-
FORM_URLENCODED: "application/x-www-form-urlencoded",
|
|
15
|
-
JSON: "application/json"
|
|
16
|
-
};
|
|
17
|
-
var HEADERS = {
|
|
18
|
-
AUTHORIZATION: "Authorization",
|
|
19
|
-
CONTENT_TYPE: "Content-Type",
|
|
20
|
-
OAUTH_CLIENT_ATTESTATION: "OAuth-Client-Attestation",
|
|
21
|
-
OAUTH_CLIENT_ATTESTATION_POP: "OAuth-Client-Attestation-PoP"
|
|
22
|
-
};
|
|
23
|
-
|
|
24
14
|
// src/errors.ts
|
|
25
15
|
var Oauth2Error = class extends Error {
|
|
26
16
|
constructor(message, statusCode) {
|
|
@@ -245,6 +235,8 @@ async function createPushedAuthorizationRequest(options) {
|
|
|
245
235
|
// src/authorization-request/fetch-authorization-response.ts
|
|
246
236
|
import { createFetcher as createFetcher2 } from "@openid4vc/utils";
|
|
247
237
|
import {
|
|
238
|
+
CONTENT_TYPES as CONTENT_TYPES2,
|
|
239
|
+
HEADERS as HEADERS2,
|
|
248
240
|
UnexpectedStatusCodeError as UnexpectedStatusCodeError2,
|
|
249
241
|
ValidationError as ValidationError2,
|
|
250
242
|
hasStatusOrThrow as hasStatusOrThrow2
|
|
@@ -292,13 +284,13 @@ async function fetchPushedAuthorizationResponse(options) {
|
|
|
292
284
|
options.pushedAuthorizationRequestEndpoint,
|
|
293
285
|
{
|
|
294
286
|
body: new URLSearchParams({
|
|
295
|
-
|
|
287
|
+
client_id: options.pushedAuthorizationRequestSigned.client_id,
|
|
296
288
|
request: options.pushedAuthorizationRequestSigned.request
|
|
297
289
|
}),
|
|
298
290
|
headers: {
|
|
299
|
-
[
|
|
300
|
-
[
|
|
301
|
-
[
|
|
291
|
+
[HEADERS2.CONTENT_TYPE]: CONTENT_TYPES2.FORM_URLENCODED,
|
|
292
|
+
[HEADERS2.OAUTH_CLIENT_ATTESTATION]: options.walletAttestation,
|
|
293
|
+
[HEADERS2.OAUTH_CLIENT_ATTESTATION_POP]: options.clientAttestationDPoP
|
|
302
294
|
},
|
|
303
295
|
method: "POST"
|
|
304
296
|
}
|
|
@@ -423,6 +415,42 @@ async function createClientAttestationPopJwt(options) {
|
|
|
423
415
|
}
|
|
424
416
|
}
|
|
425
417
|
|
|
418
|
+
// src/jarm-form-post-jwt.ts
|
|
419
|
+
import { decodeJwt as decodeJwt2 } from "@openid4vc/oauth2";
|
|
420
|
+
var getJwtFromFormPost = async (options) => {
|
|
421
|
+
const inputRegex = /<input[^<>]*>/gi;
|
|
422
|
+
const nameRegex = /name="response"/gi;
|
|
423
|
+
const valueRegex = /value="([^"]*)"/gi;
|
|
424
|
+
const lineExpressionRegex = /\r\n|\n\r|\n|\r|\s+/g;
|
|
425
|
+
let match = inputRegex.exec(options.formData);
|
|
426
|
+
while (match) {
|
|
427
|
+
let matchName = nameRegex.exec(match[0]);
|
|
428
|
+
while (matchName) {
|
|
429
|
+
let matchValue = valueRegex.exec(match[0]);
|
|
430
|
+
while (matchValue && matchValue[1]) {
|
|
431
|
+
const responseJwt = matchValue[1];
|
|
432
|
+
if (responseJwt) {
|
|
433
|
+
const jwt = responseJwt.replace(lineExpressionRegex, "");
|
|
434
|
+
const decodedJwt = decodeJwt2({
|
|
435
|
+
jwt,
|
|
436
|
+
payloadSchema: options.schema
|
|
437
|
+
});
|
|
438
|
+
return {
|
|
439
|
+
decodedJwt,
|
|
440
|
+
jwt
|
|
441
|
+
};
|
|
442
|
+
}
|
|
443
|
+
matchValue = valueRegex.exec(match[0]);
|
|
444
|
+
}
|
|
445
|
+
matchName = nameRegex.exec(match[0]);
|
|
446
|
+
}
|
|
447
|
+
match = inputRegex.exec(options.formData);
|
|
448
|
+
}
|
|
449
|
+
throw new Oauth2Error(
|
|
450
|
+
`Unable to obtain JWT from form_post.jwt. Form data: ${options.formData}`
|
|
451
|
+
);
|
|
452
|
+
};
|
|
453
|
+
|
|
426
454
|
// src/token-dpop/create-token-dpop.ts
|
|
427
455
|
import {
|
|
428
456
|
HashAlgorithm as HashAlgorithm2
|
|
@@ -508,13 +536,11 @@ var htuFromRequestUrl = (requestUrl) => {
|
|
|
508
536
|
import {
|
|
509
537
|
HashAlgorithm as HashAlgorithm3,
|
|
510
538
|
Oauth2JwtParseError,
|
|
511
|
-
decodeJwt as
|
|
539
|
+
decodeJwt as decodeJwt3
|
|
512
540
|
} from "@openid4vc/oauth2";
|
|
513
541
|
export {
|
|
514
|
-
CONTENT_TYPES,
|
|
515
542
|
CreateTokenDPoPError,
|
|
516
543
|
FetchTokenResponseError,
|
|
517
|
-
HEADERS,
|
|
518
544
|
HashAlgorithm3 as HashAlgorithm,
|
|
519
545
|
Oauth2Error,
|
|
520
546
|
Oauth2JwtParseError,
|
|
@@ -524,9 +550,10 @@ export {
|
|
|
524
550
|
createPkce,
|
|
525
551
|
createPushedAuthorizationRequest,
|
|
526
552
|
createTokenDPoP,
|
|
527
|
-
|
|
553
|
+
decodeJwt3 as decodeJwt,
|
|
528
554
|
fetchPushedAuthorizationResponse,
|
|
529
555
|
fetchTokenResponse,
|
|
556
|
+
getJwtFromFormPost,
|
|
530
557
|
toURLSearchParams,
|
|
531
558
|
verifyClientAttestationPopJwt,
|
|
532
559
|
verifyPkce,
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/access-token/fetch-token-response.ts","../src/constants.ts","../src/errors.ts","../src/access-token/z-token.ts","../src/authorization-request/create-authorization-request.ts","../src/pkce.ts","../src/authorization-request/fetch-authorization-response.ts","../src/authorization-request/z-authorization-request.ts","../src/client-attestation-pop.ts","../src/token-dpop/create-token-dpop.ts","../src/token-dpop/z-dpop.ts","../src/index.ts"],"sourcesContent":["import { CallbackContext } from \"@openid4vc/oauth2\";\nimport {\n ValidationError,\n createFetcher,\n parseWithErrorHandling,\n} from \"@openid4vc/utils\";\nimport {\n UnexpectedStatusCodeError,\n hasStatusOrThrow,\n} from \"@pagopa/io-wallet-utils\";\n\nimport { CONTENT_TYPES, HEADERS } from \"../constants\";\nimport { FetchTokenResponseError } from \"../errors\";\nimport {\n AccessTokenRequest,\n AccessTokenResponse,\n zAccessTokenResponse,\n} from \"./z-token\";\n\nexport interface FetchTokenResponseOptions {\n /**\n * The endpoint URL where the access token request will be sent\n * This should be the authorization server's token endpoint\n */\n accessTokenEndpoint: string;\n\n /**\n * The access token request payload\n */\n accessTokenRequest: AccessTokenRequest;\n\n /**\n * Callbacks to use for requesting access token\n */\n callbacks: Pick<CallbackContext, \"fetch\">;\n\n /**\n * The client attestation Demonstration of Proof-of-Possession (DPoP) token\n * Used for OAuth-Client-Attestation-PoP header to prove possession of the client key\n */\n clientAttestationDPoP: string;\n\n /**\n * The wallet attestation JWT that proves the client's identity and capabilities\n * Used for OAuth-Client-Attestation header\n */\n walletAttestation: string;\n}\n\n/**\n * Sends an access token request to the authorization server and returns the response\n *\n * @param options - Configuration options for the access token request\n * @returns Promise that resolves to the parsed access token response\n * @throws {UnexpectedStatusCodeError} When the server returns a non-200 status code\n * @throws {ValidationError} When the response cannot be parsed as a valid access token response\n * @throws {FetchTokenResponseError} When an unexpected error occurs during the request\n */\n\nexport async function fetchTokenResponse(\n options: FetchTokenResponseOptions,\n): Promise<AccessTokenResponse> {\n try {\n const fetch = createFetcher(options.callbacks.fetch);\n const tokenResponse = await fetch(options.accessTokenEndpoint, {\n body: toURLSearchParams(options.accessTokenRequest),\n headers: {\n [HEADERS.CONTENT_TYPE]: CONTENT_TYPES.FORM_URLENCODED,\n [HEADERS.OAUTH_CLIENT_ATTESTATION]: options.walletAttestation,\n [HEADERS.OAUTH_CLIENT_ATTESTATION_POP]: options.clientAttestationDPoP,\n },\n method: \"POST\",\n });\n\n await hasStatusOrThrow(200, UnexpectedStatusCodeError)(tokenResponse);\n\n return parseWithErrorHandling(\n zAccessTokenResponse,\n await tokenResponse.json(),\n \"Failed to parse token response\",\n );\n } catch (error) {\n if (\n error instanceof UnexpectedStatusCodeError ||\n error instanceof ValidationError\n ) {\n throw error;\n }\n throw new FetchTokenResponseError(\n `Unexpected error during token respone: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n}\n\nexport function toURLSearchParams(data: AccessTokenRequest): URLSearchParams {\n const params = new URLSearchParams();\n\n Object.entries(data).forEach(([key, value]) => {\n if (value === undefined) return;\n\n params.append(\n key,\n typeof value === \"object\" ? JSON.stringify(value) : String(value),\n );\n });\n\n return params;\n}\n","/**\n * HTTP Content-Type constants for OAuth2 requests\n */\nexport const CONTENT_TYPES = {\n FORM_URLENCODED: \"application/x-www-form-urlencoded\",\n JSON: \"application/json\",\n} as const;\n\n/**\n * HTTP Header constants\n */\nexport const HEADERS = {\n AUTHORIZATION: \"Authorization\",\n CONTENT_TYPE: \"Content-Type\",\n OAUTH_CLIENT_ATTESTATION: \"OAuth-Client-Attestation\",\n OAUTH_CLIENT_ATTESTATION_POP: \"OAuth-Client-Attestation-PoP\",\n} as const;\n","/**\n * Generic error thrown on OAuth2 operations\n */\nexport class Oauth2Error extends Error {\n constructor(\n message: string,\n public readonly statusCode?: number,\n ) {\n super(message);\n this.name = \"Oauth2Error\";\n }\n}\n\n/**\n * Custom error thrown when pushed authorization request operations fail\n */\nexport class PushedAuthorizationRequestError extends Oauth2Error {\n constructor(\n message: string,\n public readonly statusCode?: number,\n ) {\n super(message);\n this.name = \"PushedAuthorizationRequestError\";\n }\n}\n\n/**\n * Error thrown in case {@link createTokenDPoP} is called without neither a custom jti\n * nor a generateRandom callback or when the signJwt callback throws\n */\nexport class CreateTokenDPoPError extends Oauth2Error {\n constructor(message: string) {\n super(message);\n this.name = \"CreateTokenDPoPError\";\n }\n}\n\n/**\n * Custom error thrown when pushed authorization request operations fail\n */\nexport class FetchTokenResponseError extends Oauth2Error {\n constructor(\n message: string,\n public readonly statusCode?: number,\n ) {\n super(message);\n this.name = \"fetchTokenResponseError\";\n }\n}\n","import { z } from \"zod\";\n\nexport const zAccessTokenRequest = z\n .object({\n // Authorization code flow\n code: z.optional(z.string()),\n\n code_verifier: z.optional(z.string()),\n grant_type: z.literal(\"authorization_code\").or(z.literal(\"refresh_token\")),\n\n redirect_uri: z.optional(z.string()),\n // Refresh token grant\n refresh_token: z.optional(z.string()),\n })\n .passthrough()\n .refine(\n ({ code, code_verifier, grant_type, redirect_uri }) =>\n grant_type === \"authorization_code\" &&\n (!code || !code_verifier || !redirect_uri),\n {\n message: `If 'grant_type' is 'authorization_code', 'code', 'code_verifier' and 'redirect_uri' must be provided`,\n },\n )\n .refine(\n ({ grant_type, refresh_token }) =>\n grant_type === \"refresh_token\" && !refresh_token,\n {\n message: `If 'grant_type' is 'refresh_token', 'refresh_token' must be provided`,\n },\n );\n\nexport type AccessTokenRequest = z.infer<typeof zAccessTokenRequest>;\n\nexport const zAccessTokenResponse = z\n .object({\n access_token: z.string(),\n authorization_details: z\n .array(\n z\n .object({\n credential_configuration_id: z.optional(z.string()),\n credential_identifiers: z.optional(z.array(z.string())),\n type: z.literal(\"openid_credential\"),\n })\n .passthrough(),\n )\n .optional(),\n expires_in: z.optional(z.number().int()),\n refresh_token: z.optional(z.string()),\n token_type: z.literal(\"DPoP\"),\n })\n .passthrough();\n\nexport type AccessTokenResponse = z.infer<typeof zAccessTokenResponse>;\n","import {\n AuthorizationServerMetadata,\n CallbackContext,\n RequestDpopOptions,\n} from \"@openid4vc/oauth2\";\nimport { encodeToBase64Url } from \"@openid4vc/utils\";\n\nimport { createPkce } from \"../pkce\";\nimport {\n AuthorizationRequest,\n PushedAuthorizationRequestSigned,\n} from \"./z-authorization-request\";\n\nconst JWT_EXPIRY_SECONDS = 3600; // 1 hour\nconst RANDOM_BYTES_SIZE = 32;\n\nexport interface CreatePushedAuthorizationRequestOptions {\n /**\n * It MUST be set to the identifier of the Credential Issuer.\n */\n audience: string;\n\n /**\n * Allows clients to specify their fine-grained authorization requirements using the expressiveness of JSON data structures\n */\n authorization_details: AuthorizationRequest[\"authorization_details\"];\n\n /**\n * Callback context mostly for crypto related functionality\n */\n callbacks: Pick<CallbackContext, \"generateRandom\" | \"hash\" | \"signJwt\">;\n\n /**\n * MUST be set to the thumbprint of the jwk value in the cnf parameter inside the Wallet Attestation.\n */\n clientId: string;\n\n codeChallengeMethodsSupported: AuthorizationServerMetadata[\"code_challenge_methods_supported\"];\n\n /**\n * DPoP options\n */\n dpop: RequestDpopOptions;\n\n /**\n * jti parameter to use for PAR. If not provided a value will generated automatically\n */\n jti?: string;\n\n /**\n * Code verifier to use for pkce. If not provided a value will generated when pkce is supported\n */\n pkceCodeVerifier?: string;\n\n /**\n * Redirect uri to include in the authorization request\n */\n redirectUri: string;\n\n /**\n * It MUST be one of the supported values (response_modes_supported) provided in the metadata of the Credential Issuer.\n */\n responseMode: string;\n\n /**\n * Scope to request for the authorization request\n */\n scope: string;\n\n /**\n * state parameter to use for PAR. If not provided a value will generated automatically\n */\n state?: string;\n}\n\nexport async function createPushedAuthorizationRequest(\n options: CreatePushedAuthorizationRequestOptions,\n): Promise<PushedAuthorizationRequestSigned> {\n // PKCE\n const pkce = await createPkce({\n allowedCodeChallengeMethods: options.codeChallengeMethodsSupported,\n callbacks: options.callbacks,\n codeVerifier: options.pkceCodeVerifier,\n });\n\n const authorizationRequest: AuthorizationRequest = {\n authorization_details: options.authorization_details,\n client_id: options.clientId,\n code_challenge: pkce.codeChallenge,\n code_challenge_method: pkce.codeChallengeMethod,\n redirect_uri: options.redirectUri,\n response_mode: options.responseMode,\n response_type: \"code\",\n scope: options.scope,\n state:\n options.state ??\n encodeToBase64Url(\n await options.callbacks.generateRandom(RANDOM_BYTES_SIZE),\n ),\n };\n\n const { dpop } = options;\n if (!dpop.signer.alg || !dpop.signer.publicJwk?.kid) {\n throw new Error(\"DPoP signer must have alg and publicJwk.kid properties\");\n }\n\n const iat = Math.floor(Date.now());\n const requestJwt = await options.callbacks.signJwt(dpop.signer, {\n header: {\n alg: dpop.signer.alg,\n kid: dpop.signer.publicJwk.kid,\n typ: \"jwt\",\n },\n payload: {\n aud: options.audience,\n exp: iat + JWT_EXPIRY_SECONDS,\n iat,\n iss: dpop.signer.publicJwk.kid,\n jti:\n options.jti ??\n encodeToBase64Url(\n await options.callbacks.generateRandom(RANDOM_BYTES_SIZE),\n ),\n ...authorizationRequest,\n },\n });\n\n return {\n client_id: options.clientId,\n request: requestJwt.jwt,\n };\n}\n","import {\n CallbackContext,\n HashAlgorithm,\n HashCallback,\n Oauth2Error,\n} from \"@openid4vc/oauth2\";\nimport { decodeUtf8String, encodeToBase64Url } from \"@openid4vc/utils\";\n\nexport enum PkceCodeChallengeMethod {\n Plain = \"plain\",\n S256 = \"S256\",\n}\n\nexport interface CreatePkceOptions {\n /**\n * Also allows string values so it can be directly passed from the\n * 'code_challenge_methods_supported' metadata parameter\n */\n allowedCodeChallengeMethods?: (PkceCodeChallengeMethod | string)[];\n\n callbacks: Pick<CallbackContext, \"generateRandom\" | \"hash\">;\n\n /**\n * Code verifier to use. If not provided a value will be generated.\n */\n codeVerifier?: string;\n}\n\nexport interface CreatePkceReturn {\n codeChallenge: string;\n codeChallengeMethod: PkceCodeChallengeMethod;\n codeVerifier: string;\n}\n\nexport async function createPkce(\n options: CreatePkceOptions,\n): Promise<CreatePkceReturn> {\n const allowedCodeChallengeMethods = options.allowedCodeChallengeMethods ?? [\n PkceCodeChallengeMethod.S256,\n PkceCodeChallengeMethod.Plain,\n ];\n\n if (allowedCodeChallengeMethods.length === 0) {\n throw new Oauth2Error(\n `Unable to create PKCE code verifier. 'allowedCodeChallengeMethods' is an empty array.`,\n );\n }\n\n const codeChallengeMethod = allowedCodeChallengeMethods.includes(\n PkceCodeChallengeMethod.S256,\n )\n ? PkceCodeChallengeMethod.S256\n : PkceCodeChallengeMethod.Plain;\n\n const codeVerifier =\n options.codeVerifier ??\n encodeToBase64Url(await options.callbacks.generateRandom(64));\n return {\n codeChallenge: await calculateCodeChallenge({\n codeChallengeMethod,\n codeVerifier,\n hashCallback: options.callbacks.hash,\n }),\n codeChallengeMethod,\n codeVerifier,\n };\n}\n\nexport interface VerifyPkceOptions {\n callbacks: Pick<CallbackContext, \"hash\">;\n\n codeChallenge: string;\n codeChallengeMethod: PkceCodeChallengeMethod;\n\n /**\n * secure random code verifier\n */\n codeVerifier: string;\n}\n\nexport async function verifyPkce(options: VerifyPkceOptions) {\n const calculatedCodeChallenge = await calculateCodeChallenge({\n codeChallengeMethod: options.codeChallengeMethod,\n codeVerifier: options.codeVerifier,\n hashCallback: options.callbacks.hash,\n });\n\n if (options.codeChallenge !== calculatedCodeChallenge) {\n throw new Oauth2Error(\n `Derived code challenge '${calculatedCodeChallenge}' from code_verifier '${options.codeVerifier}' using code challenge method '${options.codeChallengeMethod}' does not match the expected code challenge.`,\n );\n }\n}\n\nasync function calculateCodeChallenge(options: {\n codeChallengeMethod: PkceCodeChallengeMethod;\n codeVerifier: string;\n hashCallback: HashCallback;\n}) {\n if (options.codeChallengeMethod === PkceCodeChallengeMethod.Plain) {\n return options.codeVerifier;\n }\n\n if (options.codeChallengeMethod === PkceCodeChallengeMethod.S256) {\n return encodeToBase64Url(\n await options.hashCallback(\n decodeUtf8String(options.codeVerifier),\n HashAlgorithm.Sha256,\n ),\n );\n }\n\n throw new Oauth2Error(\n `Unsupported code challenge method ${options.codeChallengeMethod}`,\n );\n}\n","import { CallbackContext } from \"@openid4vc/oauth2\";\nimport { createFetcher } from \"@openid4vc/utils\";\nimport {\n UnexpectedStatusCodeError,\n ValidationError,\n hasStatusOrThrow,\n} from \"@pagopa/io-wallet-utils\";\n\nimport { CONTENT_TYPES, HEADERS } from \"../constants\";\nimport { PushedAuthorizationRequestError } from \"../errors\";\nimport {\n PushedAuthorizationRequestSigned,\n PushedAuthorizationResponse,\n zPushedAuthorizationResponse,\n} from \"./z-authorization-request\";\n\n/**\n * Configuration options for fetching pushed authorization response\n */\nexport interface fetchPushedAuthorizationResponseOptions {\n /**\n * Callback functions for making HTTP requests\n * Allows for custom fetch implementations\n */\n callbacks: Pick<CallbackContext, \"fetch\">;\n\n /**\n * The client attestation Demonstration of Proof-of-Possession (DPoP) token\n * Used for OAuth-Client-Attestation-PoP header to prove possession of the client key\n */\n clientAttestationDPoP: string;\n\n /**\n * The endpoint URL where the pushed authorization request will be sent\n * This should be the authorization server's PAR endpoint\n */\n pushedAuthorizationRequestEndpoint: string;\n\n /**\n * The signed pushed authorization request object containing client_id and request JWT\n * This object has been previously signed and is ready for transmission\n */\n pushedAuthorizationRequestSigned: PushedAuthorizationRequestSigned;\n\n /**\n * The wallet attestation JWT that proves the client's identity and capabilities\n * Used for OAuth-Client-Attestation header\n */\n walletAttestation: string;\n}\n\n/**\n * Sends a pushed authorization request to the authorization server and returns the response\n *\n * This function implements the IT Wallet Pushed Authorization Requests (PAR) specification,\n * sending the signed authorization request to the server and handling the response.\n *\n * @param options - Configuration options for the pushed authorization request\n * @returns Promise that resolves to the parsed pushed authorization response containing request_uri and expires_in\n * @throws {UnexpectedStatusCodeError} When the server returns a non-201 status code\n * @throws {ValidationError} When the response cannot be parsed or is invalid\n */\nexport async function fetchPushedAuthorizationResponse(\n options: fetchPushedAuthorizationResponseOptions,\n): Promise<PushedAuthorizationResponse> {\n try {\n const fetch = createFetcher(options.callbacks.fetch);\n const parResponse = await fetch(\n options.pushedAuthorizationRequestEndpoint,\n {\n body: new URLSearchParams({\n clientId: options.pushedAuthorizationRequestSigned.client_id,\n request: options.pushedAuthorizationRequestSigned.request,\n }),\n headers: {\n [HEADERS.CONTENT_TYPE]: CONTENT_TYPES.FORM_URLENCODED,\n [HEADERS.OAUTH_CLIENT_ATTESTATION]: options.walletAttestation,\n [HEADERS.OAUTH_CLIENT_ATTESTATION_POP]: options.clientAttestationDPoP,\n },\n method: \"POST\",\n },\n );\n\n await hasStatusOrThrow(201, UnexpectedStatusCodeError)(parResponse);\n\n const parResponseJson = await parResponse.json();\n\n const parsedParResponse =\n zPushedAuthorizationResponse.safeParse(parResponseJson);\n if (!parsedParResponse.success) {\n throw new ValidationError(\n `Failed to parse pushed authorization response`,\n parsedParResponse.error,\n );\n }\n\n return parsedParResponse.data;\n } catch (error) {\n if (\n error instanceof UnexpectedStatusCodeError ||\n error instanceof ValidationError\n ) {\n throw error;\n }\n throw new PushedAuthorizationRequestError(\n `Unexpected error during pushed authorization request: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n}\n","import z from \"zod\";\n\nexport const zAuthorizationRequest = z\n .object({\n authorization_details: z.array(\n z.object({\n credential_configuration_id: z.string(),\n type: z.literal(\"openid_credential\"),\n }),\n ),\n client_id: z.string(),\n code_challenge: z.string(),\n code_challenge_method: z.string(),\n issuer_state: z.optional(z.string()),\n redirect_uri: z.string().url().optional(),\n response_mode: z.string(),\n response_type: z.string(),\n scope: z.string(),\n state: z.string(),\n })\n .passthrough();\nexport type AuthorizationRequest = z.infer<typeof zAuthorizationRequest>;\n\nexport const zPushedAuthorizationRequestSigned = z\n .object({\n /*\n * MUST be set to the thumbprint of the jwk value in the cnf parameter inside the Wallet Attestation.\n */\n client_id: z.string(),\n /*\n * It MUST be a signed JWT. The private key corresponding to the public one in the cnf parameter inside the Wallet Attestation MUST be used for signing the Request Object.\n */\n request: z.string(),\n })\n .passthrough();\nexport type PushedAuthorizationRequestSigned = z.infer<\n typeof zPushedAuthorizationRequestSigned\n>;\n\nexport const zPushedAuthorizationResponse = z\n .object({\n expires_in: z.number().int(),\n request_uri: z.string(),\n })\n .passthrough();\nexport type PushedAuthorizationResponse = z.infer<\n typeof zPushedAuthorizationResponse\n>;\n","import {\n CallbackContext,\n ClientAttestationPopJwtHeader,\n ClientAttestationPopJwtPayload,\n Jwk,\n JwtSignerJwk,\n decodeJwt,\n verifyJwt,\n} from \"@openid4vc/oauth2\";\nimport {\n addSecondsToDate,\n dateToSeconds,\n encodeToBase64Url,\n} from \"@openid4vc/utils\";\n\nimport { Oauth2Error } from \"./errors\";\n\nexport interface VerifyClientAttestationPopJwtOptions {\n /**\n * The issuer identifier of the authorization server handling the client attestation\n */\n authorizationServer: string;\n\n /**\n * Callbacks used for verifying client attestation pop jwt.\n */\n callbacks: Pick<CallbackContext, \"verifyJwt\">;\n\n /**\n * The compact client attestation pop jwt.\n */\n clientAttestationPopJwt: string;\n\n /**\n * The public JWK to verify the client attestation pop jwt.\n */\n clientAttestationPublicJwk: Jwk;\n\n /**\n * Expected nonce in the payload. If not provided the nonce won't be validated.\n */\n expectedNonce?: string;\n\n /**\n * Date to use for expiration. If not provided current date will be used.\n */\n now?: Date;\n}\n\nexport type VerifiedClientAttestationPopJwt = Awaited<\n ReturnType<typeof verifyClientAttestationPopJwt>\n>;\nexport async function verifyClientAttestationPopJwt(\n options: VerifyClientAttestationPopJwtOptions,\n) {\n try {\n const { header, payload } = decodeJwt({\n jwt: options.clientAttestationPopJwt,\n });\n\n if (payload.aud !== options.authorizationServer) {\n throw new Oauth2Error(\n `Client Attestation Pop jwt contains 'aud' value '${payload.aud}', but expected authorization server identifier '${options.authorizationServer}'`,\n );\n }\n\n const { signer } = await verifyJwt({\n compact: options.clientAttestationPopJwt,\n errorMessage: \"client attestation pop jwt verification failed\",\n expectedNonce: options.expectedNonce,\n header,\n now: options.now,\n payload,\n signer: {\n alg: header.alg,\n method: \"jwk\",\n publicJwk: options.clientAttestationPublicJwk,\n },\n verifyJwtCallback: options.callbacks.verifyJwt,\n });\n\n return {\n header,\n payload,\n signer,\n };\n } catch (error) {\n if (error instanceof Oauth2Error) throw error;\n throw new Oauth2Error(\n `Error creating client attestation pop jwt : ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n}\n\nexport interface CreateClientAttestationPopJwtOptions {\n /**\n * The audience authorization server identifier\n */\n authorizationServer: string;\n\n /**\n * Callback used for dpop\n * generateRandom is mandatory if jti is not provided\n */\n callbacks: Partial<Pick<CallbackContext, \"generateRandom\">> &\n Pick<CallbackContext, \"signJwt\">;\n\n /**\n * The client attestation to create the Pop for\n */\n clientAttestation: string;\n\n /**\n * Expiration time of the JWT. If not provided 1 minute will be added to the `issuedAt`\n */\n expiresAt?: Date;\n\n /**\n * Creation time of the JWT. If not provided the current date will be used\n */\n issuedAt?: Date;\n\n /**\n * Optional jti to set in the payload. If not provided a random one will be generated\n */\n jti?: string;\n\n /**\n * The signer of jwt. Only jwk signer allowed.\n *\n * If not provided, the signer will be derived based on the\n * `cnf.jwk` and `alg` in the client attestation.\n */\n signer?: JwtSignerJwk;\n}\n\nexport async function createClientAttestationPopJwt(\n options: CreateClientAttestationPopJwtOptions,\n) {\n try {\n const clientAttestation = decodeJwt({\n jwt: options.clientAttestation,\n });\n\n const jwk = clientAttestation.payload.cnf?.jwk;\n if (!jwk) {\n throw new Oauth2Error(\n \"Client attestation does not contain 'cnf.jwk', cannot create client attestation pop jwt\",\n );\n }\n\n const sub = clientAttestation.payload.sub;\n if (!sub || typeof sub !== \"string\") {\n throw new Oauth2Error(\n \"Client attestation does not contain 'sub', cannot create client attestation pop jwt\",\n );\n }\n\n const signer = options.signer ?? {\n alg: clientAttestation.header.alg,\n method: \"jwk\",\n publicJwk: jwk,\n };\n\n const header = {\n alg: signer.alg,\n typ: \"oauth-client-attestation-pop+jwt\",\n } satisfies ClientAttestationPopJwtHeader;\n\n const issuedAt = options.issuedAt ?? new Date();\n const expiresAt = options.expiresAt ?? addSecondsToDate(issuedAt, 1 * 60);\n const jti =\n options.jti ??\n (options.callbacks.generateRandom\n ? encodeToBase64Url(await options.callbacks.generateRandom(32))\n : undefined);\n\n if (!jti) {\n throw new Oauth2Error(\n \"Error: neither a default jti nor a generateRandom callback have been provided\",\n );\n }\n\n const payload = {\n aud: options.authorizationServer,\n exp: dateToSeconds(expiresAt),\n iat: dateToSeconds(issuedAt),\n iss: sub,\n jti,\n } satisfies ClientAttestationPopJwtPayload;\n\n const { jwt } = await options.callbacks.signJwt(signer, {\n header,\n payload,\n });\n\n return jwt;\n } catch (error) {\n if (error instanceof Oauth2Error) throw error;\n throw new Oauth2Error(\n `Error creating client attestation pop jwt : ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n}\n","import {\n CallbackContext,\n HashAlgorithm,\n HttpMethod,\n JwtSignerJwk,\n} from \"@openid4vc/oauth2\";\nimport {\n ValidationError,\n dateToSeconds,\n decodeUtf8String,\n encodeToBase64Url,\n parseWithErrorHandling,\n} from \"@openid4vc/utils\";\nimport { Base64 } from \"js-base64\";\n\nimport { CreateTokenDPoPError } from \"../errors\";\nimport {\n DpopJwtHeader,\n DpopJwtPayload,\n zDpopJwtHeader,\n zDpopJwtPayload,\n} from \"./z-dpop\";\n\n/**\n * Options for Token Request DPoP generation\n */\nexport interface CreateTokenDPoPOptions {\n /**\n * The access token to which the dpop jwt should be bound. Required\n * when the dpop will be sent along with an access token.\n */\n accessToken?: string;\n\n /**\n * Object containing callbacks for DPoP generation and signature\n */\n callbacks: Partial<Pick<CallbackContext, \"generateRandom\">> &\n Pick<CallbackContext, \"hash\" | \"signJwt\">;\n\n /**\n * Creation time of the JWT. If not provided the current date will be used\n */\n issuedAt?: Date;\n\n /**\n * jti claim for the DPoP JWT. If not provided, a random one will be generated\n * if a generateRandom callback is provided\n */\n jti?: string;\n\n /**\n * The signer of the dpop jwt. Only jwk signer allowed.\n */\n signer: JwtSignerJwk;\n\n /**\n * The request for which to create the dpop jwt\n */\n tokenRequest: {\n method: HttpMethod;\n url: string;\n };\n}\n\n/**\n * Creates a signed Token DPoP with the given cryptographic material and data.\n * It is used to create DPoP proofs for token requests and credential requests.\n * @param options {@link CreateTokenDPoPOptions}\n * @returns A Promise that resolves with an object containing the signed DPoP JWT and\n * its corresponding public JWK\n * @throws {@link CreateTokenDPoPError} in case neither a default jti nor a generateRandom\n * callback have been provided or the signJwt callback throws\n */\nexport async function createTokenDPoP(options: CreateTokenDPoPOptions) {\n try {\n // Calculate access token hash\n const ath = options.accessToken\n ? encodeToBase64Url(\n await options.callbacks.hash(\n decodeUtf8String(options.accessToken),\n HashAlgorithm.Sha256,\n ),\n )\n : undefined;\n\n const jti =\n options.jti ??\n (options.callbacks.generateRandom\n ? Base64.fromUint8Array(\n await options.callbacks.generateRandom(32),\n true,\n )\n : undefined);\n\n if (!jti) {\n throw new CreateTokenDPoPError(\n \"Error: neither a default jti nor a generateRandom callback have been provided\",\n );\n }\n\n const header = parseWithErrorHandling(zDpopJwtHeader, {\n alg: options.signer.alg,\n jwk: options.signer.publicJwk,\n typ: \"dpop+jwt\",\n } satisfies DpopJwtHeader);\n\n const payload = parseWithErrorHandling(zDpopJwtPayload, {\n ath,\n htm: options.tokenRequest.method,\n htu: htuFromRequestUrl(options.tokenRequest.url),\n iat: dateToSeconds(options.issuedAt),\n jti,\n } satisfies DpopJwtPayload);\n\n return options.callbacks.signJwt(options.signer, {\n header,\n payload,\n });\n } catch (error) {\n if (\n error instanceof CreateTokenDPoPError ||\n error instanceof ValidationError\n ) {\n throw error;\n }\n throw new CreateTokenDPoPError(\n `Error during jwt signature, details: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n}\n\nconst htuFromRequestUrl = (requestUrl: string) => {\n const htu = new URL(requestUrl);\n htu.search = \"\";\n htu.hash = \"\";\n\n return htu.toString();\n};\n","import { zJwk, zJwtHeader, zJwtPayload } from \"@openid4vc/oauth2\";\nimport { zHttpMethod, zHttpsUrl, zInteger } from \"@openid4vc/utils\";\nimport z from \"zod\";\n\nexport const zDpopJwtPayload = z\n .object({\n ...zJwtPayload.shape,\n ath: z.optional(z.string()),\n htm: zHttpMethod,\n htu: zHttpsUrl,\n iat: zInteger,\n\n jti: z.string(),\n })\n .passthrough();\nexport type DpopJwtPayload = z.infer<typeof zDpopJwtPayload>;\n\nexport const zDpopJwtHeader = z\n .object({\n ...zJwtHeader.shape,\n jwk: zJwk,\n typ: z.literal(\"dpop+jwt\"),\n })\n .passthrough();\nexport type DpopJwtHeader = z.infer<typeof zDpopJwtHeader>;\n","export * from \"./access-token\";\nexport * from \"./authorization-request\";\nexport * from \"./client-attestation-pop\";\nexport * from \"./constants\";\nexport * from \"./errors\";\nexport * from \"./pkce\";\nexport * from \"./token-dpop\";\n\nexport {\n type CallbackContext,\n type GenerateRandomCallback,\n HashAlgorithm,\n type HttpMethod,\n type Jwk,\n type JwtSigner,\n type JwtSignerJwk,\n Oauth2JwtParseError,\n type RequestDpopOptions,\n type SignJwtCallback,\n type VerifyJwtCallback,\n decodeJwt,\n} from \"@openid4vc/oauth2\";\n"],"mappings":"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","names":["encodeToBase64Url","Oauth2Error","PkceCodeChallengeMethod","encodeToBase64Url","createFetcher","UnexpectedStatusCodeError","ValidationError","hasStatusOrThrow","z","createFetcher","hasStatusOrThrow","UnexpectedStatusCodeError","ValidationError","encodeToBase64Url","encodeToBase64Url","HashAlgorithm","ValidationError","dateToSeconds","decodeUtf8String","encodeToBase64Url","parseWithErrorHandling","z","encodeToBase64Url","decodeUtf8String","HashAlgorithm","parseWithErrorHandling","dateToSeconds","ValidationError","HashAlgorithm","decodeJwt"]}
|
|
1
|
+
{"version":3,"sources":["../src/access-token/fetch-token-response.ts","../src/errors.ts","../src/access-token/z-token.ts","../src/authorization-request/create-authorization-request.ts","../src/pkce.ts","../src/authorization-request/fetch-authorization-response.ts","../src/authorization-request/z-authorization-request.ts","../src/client-attestation-pop.ts","../src/jarm-form-post-jwt.ts","../src/token-dpop/create-token-dpop.ts","../src/token-dpop/z-dpop.ts","../src/index.ts"],"sourcesContent":["import { CallbackContext } from \"@openid4vc/oauth2\";\nimport {\n ValidationError,\n createFetcher,\n parseWithErrorHandling,\n} from \"@openid4vc/utils\";\nimport {\n CONTENT_TYPES,\n HEADERS,\n UnexpectedStatusCodeError,\n hasStatusOrThrow,\n} from \"@pagopa/io-wallet-utils\";\n\nimport { FetchTokenResponseError } from \"../errors\";\nimport {\n AccessTokenRequest,\n AccessTokenResponse,\n zAccessTokenResponse,\n} from \"./z-token\";\n\nexport interface FetchTokenResponseOptions {\n /**\n * The endpoint URL where the access token request will be sent\n * This should be the authorization server's token endpoint\n */\n accessTokenEndpoint: string;\n\n /**\n * The access token request payload\n */\n accessTokenRequest: AccessTokenRequest;\n\n /**\n * Callbacks to use for requesting access token\n */\n callbacks: Pick<CallbackContext, \"fetch\">;\n\n /**\n * The client attestation Demonstration of Proof-of-Possession (DPoP) token\n * Used for OAuth-Client-Attestation-PoP header to prove possession of the client key\n */\n clientAttestationDPoP: string;\n\n /**\n * The wallet attestation JWT that proves the client's identity and capabilities\n * Used for OAuth-Client-Attestation header\n */\n walletAttestation: string;\n}\n\n/**\n * Sends an access token request to the authorization server and returns the response\n *\n * @param options - Configuration options for the access token request\n * @returns Promise that resolves to the parsed access token response\n * @throws {UnexpectedStatusCodeError} When the server returns a non-200 status code\n * @throws {ValidationError} When the response cannot be parsed as a valid access token response\n * @throws {FetchTokenResponseError} When an unexpected error occurs during the request\n */\n\nexport async function fetchTokenResponse(\n options: FetchTokenResponseOptions,\n): Promise<AccessTokenResponse> {\n try {\n const fetch = createFetcher(options.callbacks.fetch);\n const tokenResponse = await fetch(options.accessTokenEndpoint, {\n body: toURLSearchParams(options.accessTokenRequest),\n headers: {\n [HEADERS.CONTENT_TYPE]: CONTENT_TYPES.FORM_URLENCODED,\n [HEADERS.OAUTH_CLIENT_ATTESTATION]: options.walletAttestation,\n [HEADERS.OAUTH_CLIENT_ATTESTATION_POP]: options.clientAttestationDPoP,\n },\n method: \"POST\",\n });\n\n await hasStatusOrThrow(200, UnexpectedStatusCodeError)(tokenResponse);\n\n return parseWithErrorHandling(\n zAccessTokenResponse,\n await tokenResponse.json(),\n \"Failed to parse token response\",\n );\n } catch (error) {\n if (\n error instanceof UnexpectedStatusCodeError ||\n error instanceof ValidationError\n ) {\n throw error;\n }\n throw new FetchTokenResponseError(\n `Unexpected error during token respone: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n}\n\nexport function toURLSearchParams(data: AccessTokenRequest): URLSearchParams {\n const params = new URLSearchParams();\n\n Object.entries(data).forEach(([key, value]) => {\n if (value === undefined) return;\n\n params.append(\n key,\n typeof value === \"object\" ? JSON.stringify(value) : String(value),\n );\n });\n\n return params;\n}\n","/**\n * Generic error thrown on OAuth2 operations\n */\nexport class Oauth2Error extends Error {\n constructor(\n message: string,\n public readonly statusCode?: number,\n ) {\n super(message);\n this.name = \"Oauth2Error\";\n }\n}\n\n/**\n * Custom error thrown when pushed authorization request operations fail\n */\nexport class PushedAuthorizationRequestError extends Oauth2Error {\n constructor(\n message: string,\n public readonly statusCode?: number,\n ) {\n super(message);\n this.name = \"PushedAuthorizationRequestError\";\n }\n}\n\n/**\n * Error thrown in case {@link createTokenDPoP} is called without neither a custom jti\n * nor a generateRandom callback or when the signJwt callback throws\n */\nexport class CreateTokenDPoPError extends Oauth2Error {\n constructor(message: string) {\n super(message);\n this.name = \"CreateTokenDPoPError\";\n }\n}\n\n/**\n * Custom error thrown when pushed authorization request operations fail\n */\nexport class FetchTokenResponseError extends Oauth2Error {\n constructor(\n message: string,\n public readonly statusCode?: number,\n ) {\n super(message);\n this.name = \"fetchTokenResponseError\";\n }\n}\n","import { z } from \"zod\";\n\nexport const zAccessTokenRequest = z\n .object({\n // Authorization code flow\n code: z.optional(z.string()),\n\n code_verifier: z.optional(z.string()),\n grant_type: z.literal(\"authorization_code\").or(z.literal(\"refresh_token\")),\n\n redirect_uri: z.optional(z.string()),\n // Refresh token grant\n refresh_token: z.optional(z.string()),\n })\n .passthrough()\n .refine(\n ({ code, code_verifier, grant_type, redirect_uri }) =>\n grant_type === \"authorization_code\" &&\n (!code || !code_verifier || !redirect_uri),\n {\n message: `If 'grant_type' is 'authorization_code', 'code', 'code_verifier' and 'redirect_uri' must be provided`,\n },\n )\n .refine(\n ({ grant_type, refresh_token }) =>\n grant_type === \"refresh_token\" && !refresh_token,\n {\n message: `If 'grant_type' is 'refresh_token', 'refresh_token' must be provided`,\n },\n );\n\nexport type AccessTokenRequest = z.infer<typeof zAccessTokenRequest>;\n\nexport const zAccessTokenResponse = z\n .object({\n access_token: z.string(),\n authorization_details: z\n .array(\n z\n .object({\n credential_configuration_id: z.optional(z.string()),\n credential_identifiers: z.optional(z.array(z.string())),\n type: z.literal(\"openid_credential\"),\n })\n .passthrough(),\n )\n .optional(),\n expires_in: z.optional(z.number().int()),\n refresh_token: z.optional(z.string()),\n token_type: z.literal(\"DPoP\"),\n })\n .passthrough();\n\nexport type AccessTokenResponse = z.infer<typeof zAccessTokenResponse>;\n","import {\n AuthorizationServerMetadata,\n CallbackContext,\n RequestDpopOptions,\n} from \"@openid4vc/oauth2\";\nimport { encodeToBase64Url } from \"@openid4vc/utils\";\n\nimport { createPkce } from \"../pkce\";\nimport {\n AuthorizationRequest,\n PushedAuthorizationRequestSigned,\n} from \"./z-authorization-request\";\n\nconst JWT_EXPIRY_SECONDS = 3600; // 1 hour\nconst RANDOM_BYTES_SIZE = 32;\n\nexport interface CreatePushedAuthorizationRequestOptions {\n /**\n * It MUST be set to the identifier of the Credential Issuer.\n */\n audience: string;\n\n /**\n * Allows clients to specify their fine-grained authorization requirements using the expressiveness of JSON data structures\n */\n authorization_details: AuthorizationRequest[\"authorization_details\"];\n\n /**\n * Callback context mostly for crypto related functionality\n */\n callbacks: Pick<CallbackContext, \"generateRandom\" | \"hash\" | \"signJwt\">;\n\n /**\n * MUST be set to the thumbprint of the jwk value in the cnf parameter inside the Wallet Attestation.\n */\n clientId: string;\n\n codeChallengeMethodsSupported: AuthorizationServerMetadata[\"code_challenge_methods_supported\"];\n\n /**\n * DPoP options\n */\n dpop: RequestDpopOptions;\n\n /**\n * jti parameter to use for PAR. If not provided a value will generated automatically\n */\n jti?: string;\n\n /**\n * Code verifier to use for pkce. If not provided a value will generated when pkce is supported\n */\n pkceCodeVerifier?: string;\n\n /**\n * Redirect uri to include in the authorization request\n */\n redirectUri: string;\n\n /**\n * It MUST be one of the supported values (response_modes_supported) provided in the metadata of the Credential Issuer.\n */\n responseMode: string;\n\n /**\n * Scope to request for the authorization request\n */\n scope: string;\n\n /**\n * state parameter to use for PAR. If not provided a value will generated automatically\n */\n state?: string;\n}\n\nexport async function createPushedAuthorizationRequest(\n options: CreatePushedAuthorizationRequestOptions,\n): Promise<PushedAuthorizationRequestSigned> {\n // PKCE\n const pkce = await createPkce({\n allowedCodeChallengeMethods: options.codeChallengeMethodsSupported,\n callbacks: options.callbacks,\n codeVerifier: options.pkceCodeVerifier,\n });\n\n const authorizationRequest: AuthorizationRequest = {\n authorization_details: options.authorization_details,\n client_id: options.clientId,\n code_challenge: pkce.codeChallenge,\n code_challenge_method: pkce.codeChallengeMethod,\n redirect_uri: options.redirectUri,\n response_mode: options.responseMode,\n response_type: \"code\",\n scope: options.scope,\n state:\n options.state ??\n encodeToBase64Url(\n await options.callbacks.generateRandom(RANDOM_BYTES_SIZE),\n ),\n };\n\n const { dpop } = options;\n if (!dpop.signer.alg || !dpop.signer.publicJwk?.kid) {\n throw new Error(\"DPoP signer must have alg and publicJwk.kid properties\");\n }\n\n const iat = Math.floor(Date.now());\n const requestJwt = await options.callbacks.signJwt(dpop.signer, {\n header: {\n alg: dpop.signer.alg,\n kid: dpop.signer.publicJwk.kid,\n typ: \"jwt\",\n },\n payload: {\n aud: options.audience,\n exp: iat + JWT_EXPIRY_SECONDS,\n iat,\n iss: dpop.signer.publicJwk.kid,\n jti:\n options.jti ??\n encodeToBase64Url(\n await options.callbacks.generateRandom(RANDOM_BYTES_SIZE),\n ),\n ...authorizationRequest,\n },\n });\n\n return {\n client_id: options.clientId,\n request: requestJwt.jwt,\n };\n}\n","import {\n CallbackContext,\n HashAlgorithm,\n HashCallback,\n Oauth2Error,\n} from \"@openid4vc/oauth2\";\nimport { decodeUtf8String, encodeToBase64Url } from \"@openid4vc/utils\";\n\nexport enum PkceCodeChallengeMethod {\n Plain = \"plain\",\n S256 = \"S256\",\n}\n\nexport interface CreatePkceOptions {\n /**\n * Also allows string values so it can be directly passed from the\n * 'code_challenge_methods_supported' metadata parameter\n */\n allowedCodeChallengeMethods?: (PkceCodeChallengeMethod | string)[];\n\n callbacks: Pick<CallbackContext, \"generateRandom\" | \"hash\">;\n\n /**\n * Code verifier to use. If not provided a value will be generated.\n */\n codeVerifier?: string;\n}\n\nexport interface CreatePkceReturn {\n codeChallenge: string;\n codeChallengeMethod: PkceCodeChallengeMethod;\n codeVerifier: string;\n}\n\nexport async function createPkce(\n options: CreatePkceOptions,\n): Promise<CreatePkceReturn> {\n const allowedCodeChallengeMethods = options.allowedCodeChallengeMethods ?? [\n PkceCodeChallengeMethod.S256,\n PkceCodeChallengeMethod.Plain,\n ];\n\n if (allowedCodeChallengeMethods.length === 0) {\n throw new Oauth2Error(\n `Unable to create PKCE code verifier. 'allowedCodeChallengeMethods' is an empty array.`,\n );\n }\n\n const codeChallengeMethod = allowedCodeChallengeMethods.includes(\n PkceCodeChallengeMethod.S256,\n )\n ? PkceCodeChallengeMethod.S256\n : PkceCodeChallengeMethod.Plain;\n\n const codeVerifier =\n options.codeVerifier ??\n encodeToBase64Url(await options.callbacks.generateRandom(64));\n return {\n codeChallenge: await calculateCodeChallenge({\n codeChallengeMethod,\n codeVerifier,\n hashCallback: options.callbacks.hash,\n }),\n codeChallengeMethod,\n codeVerifier,\n };\n}\n\nexport interface VerifyPkceOptions {\n callbacks: Pick<CallbackContext, \"hash\">;\n\n codeChallenge: string;\n codeChallengeMethod: PkceCodeChallengeMethod;\n\n /**\n * secure random code verifier\n */\n codeVerifier: string;\n}\n\nexport async function verifyPkce(options: VerifyPkceOptions) {\n const calculatedCodeChallenge = await calculateCodeChallenge({\n codeChallengeMethod: options.codeChallengeMethod,\n codeVerifier: options.codeVerifier,\n hashCallback: options.callbacks.hash,\n });\n\n if (options.codeChallenge !== calculatedCodeChallenge) {\n throw new Oauth2Error(\n `Derived code challenge '${calculatedCodeChallenge}' from code_verifier '${options.codeVerifier}' using code challenge method '${options.codeChallengeMethod}' does not match the expected code challenge.`,\n );\n }\n}\n\nasync function calculateCodeChallenge(options: {\n codeChallengeMethod: PkceCodeChallengeMethod;\n codeVerifier: string;\n hashCallback: HashCallback;\n}) {\n if (options.codeChallengeMethod === PkceCodeChallengeMethod.Plain) {\n return options.codeVerifier;\n }\n\n if (options.codeChallengeMethod === PkceCodeChallengeMethod.S256) {\n return encodeToBase64Url(\n await options.hashCallback(\n decodeUtf8String(options.codeVerifier),\n HashAlgorithm.Sha256,\n ),\n );\n }\n\n throw new Oauth2Error(\n `Unsupported code challenge method ${options.codeChallengeMethod}`,\n );\n}\n","import { CallbackContext } from \"@openid4vc/oauth2\";\nimport { createFetcher } from \"@openid4vc/utils\";\nimport {\n CONTENT_TYPES,\n HEADERS,\n UnexpectedStatusCodeError,\n ValidationError,\n hasStatusOrThrow,\n} from \"@pagopa/io-wallet-utils\";\n\nimport { PushedAuthorizationRequestError } from \"../errors\";\nimport {\n PushedAuthorizationRequestSigned,\n PushedAuthorizationResponse,\n zPushedAuthorizationResponse,\n} from \"./z-authorization-request\";\n\n/**\n * Configuration options for fetching pushed authorization response\n */\nexport interface fetchPushedAuthorizationResponseOptions {\n /**\n * Callback functions for making HTTP requests\n * Allows for custom fetch implementations\n */\n callbacks: Pick<CallbackContext, \"fetch\">;\n\n /**\n * The client attestation Demonstration of Proof-of-Possession (DPoP) token\n * Used for OAuth-Client-Attestation-PoP header to prove possession of the client key\n */\n clientAttestationDPoP: string;\n\n /**\n * The endpoint URL where the pushed authorization request will be sent\n * This should be the authorization server's PAR endpoint\n */\n pushedAuthorizationRequestEndpoint: string;\n\n /**\n * The signed pushed authorization request object containing client_id and request JWT\n * This object has been previously signed and is ready for transmission\n */\n pushedAuthorizationRequestSigned: PushedAuthorizationRequestSigned;\n\n /**\n * The wallet attestation JWT that proves the client's identity and capabilities\n * Used for OAuth-Client-Attestation header\n */\n walletAttestation: string;\n}\n\n/**\n * Sends a pushed authorization request to the authorization server and returns the response\n *\n * This function implements the IT Wallet Pushed Authorization Requests (PAR) specification,\n * sending the signed authorization request to the server and handling the response.\n *\n * @param options - Configuration options for the pushed authorization request\n * @returns Promise that resolves to the parsed pushed authorization response containing request_uri and expires_in\n * @throws {UnexpectedStatusCodeError} When the server returns a non-201 status code\n * @throws {ValidationError} When the response cannot be parsed or is invalid\n */\nexport async function fetchPushedAuthorizationResponse(\n options: fetchPushedAuthorizationResponseOptions,\n): Promise<PushedAuthorizationResponse> {\n try {\n const fetch = createFetcher(options.callbacks.fetch);\n const parResponse = await fetch(\n options.pushedAuthorizationRequestEndpoint,\n {\n body: new URLSearchParams({\n client_id: options.pushedAuthorizationRequestSigned.client_id,\n request: options.pushedAuthorizationRequestSigned.request,\n }),\n headers: {\n [HEADERS.CONTENT_TYPE]: CONTENT_TYPES.FORM_URLENCODED,\n [HEADERS.OAUTH_CLIENT_ATTESTATION]: options.walletAttestation,\n [HEADERS.OAUTH_CLIENT_ATTESTATION_POP]: options.clientAttestationDPoP,\n },\n method: \"POST\",\n },\n );\n\n await hasStatusOrThrow(201, UnexpectedStatusCodeError)(parResponse);\n\n const parResponseJson = await parResponse.json();\n\n const parsedParResponse =\n zPushedAuthorizationResponse.safeParse(parResponseJson);\n if (!parsedParResponse.success) {\n throw new ValidationError(\n `Failed to parse pushed authorization response`,\n parsedParResponse.error,\n );\n }\n\n return parsedParResponse.data;\n } catch (error) {\n if (\n error instanceof UnexpectedStatusCodeError ||\n error instanceof ValidationError\n ) {\n throw error;\n }\n throw new PushedAuthorizationRequestError(\n `Unexpected error during pushed authorization request: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n}\n","import z from \"zod\";\n\nexport const zAuthorizationRequest = z\n .object({\n authorization_details: z.array(\n z.object({\n credential_configuration_id: z.string(),\n type: z.literal(\"openid_credential\"),\n }),\n ),\n client_id: z.string(),\n code_challenge: z.string(),\n code_challenge_method: z.string(),\n issuer_state: z.optional(z.string()),\n redirect_uri: z.string().url().optional(),\n response_mode: z.string(),\n response_type: z.string(),\n scope: z.string(),\n state: z.string(),\n })\n .passthrough();\nexport type AuthorizationRequest = z.infer<typeof zAuthorizationRequest>;\n\nexport const zPushedAuthorizationRequestSigned = z\n .object({\n /*\n * MUST be set to the thumbprint of the jwk value in the cnf parameter inside the Wallet Attestation.\n */\n client_id: z.string(),\n /*\n * It MUST be a signed JWT. The private key corresponding to the public one in the cnf parameter inside the Wallet Attestation MUST be used for signing the Request Object.\n */\n request: z.string(),\n })\n .passthrough();\nexport type PushedAuthorizationRequestSigned = z.infer<\n typeof zPushedAuthorizationRequestSigned\n>;\n\nexport const zPushedAuthorizationResponse = z\n .object({\n expires_in: z.number().int(),\n request_uri: z.string(),\n })\n .passthrough();\nexport type PushedAuthorizationResponse = z.infer<\n typeof zPushedAuthorizationResponse\n>;\n","import {\n CallbackContext,\n ClientAttestationPopJwtHeader,\n ClientAttestationPopJwtPayload,\n Jwk,\n JwtSignerJwk,\n decodeJwt,\n verifyJwt,\n} from \"@openid4vc/oauth2\";\nimport {\n addSecondsToDate,\n dateToSeconds,\n encodeToBase64Url,\n} from \"@openid4vc/utils\";\n\nimport { Oauth2Error } from \"./errors\";\n\nexport interface VerifyClientAttestationPopJwtOptions {\n /**\n * The issuer identifier of the authorization server handling the client attestation\n */\n authorizationServer: string;\n\n /**\n * Callbacks used for verifying client attestation pop jwt.\n */\n callbacks: Pick<CallbackContext, \"verifyJwt\">;\n\n /**\n * The compact client attestation pop jwt.\n */\n clientAttestationPopJwt: string;\n\n /**\n * The public JWK to verify the client attestation pop jwt.\n */\n clientAttestationPublicJwk: Jwk;\n\n /**\n * Expected nonce in the payload. If not provided the nonce won't be validated.\n */\n expectedNonce?: string;\n\n /**\n * Date to use for expiration. If not provided current date will be used.\n */\n now?: Date;\n}\n\nexport type VerifiedClientAttestationPopJwt = Awaited<\n ReturnType<typeof verifyClientAttestationPopJwt>\n>;\nexport async function verifyClientAttestationPopJwt(\n options: VerifyClientAttestationPopJwtOptions,\n) {\n try {\n const { header, payload } = decodeJwt({\n jwt: options.clientAttestationPopJwt,\n });\n\n if (payload.aud !== options.authorizationServer) {\n throw new Oauth2Error(\n `Client Attestation Pop jwt contains 'aud' value '${payload.aud}', but expected authorization server identifier '${options.authorizationServer}'`,\n );\n }\n\n const { signer } = await verifyJwt({\n compact: options.clientAttestationPopJwt,\n errorMessage: \"client attestation pop jwt verification failed\",\n expectedNonce: options.expectedNonce,\n header,\n now: options.now,\n payload,\n signer: {\n alg: header.alg,\n method: \"jwk\",\n publicJwk: options.clientAttestationPublicJwk,\n },\n verifyJwtCallback: options.callbacks.verifyJwt,\n });\n\n return {\n header,\n payload,\n signer,\n };\n } catch (error) {\n if (error instanceof Oauth2Error) throw error;\n throw new Oauth2Error(\n `Error creating client attestation pop jwt : ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n}\n\nexport interface CreateClientAttestationPopJwtOptions {\n /**\n * The audience authorization server identifier\n */\n authorizationServer: string;\n\n /**\n * Callback used for dpop\n * generateRandom is mandatory if jti is not provided\n */\n callbacks: Partial<Pick<CallbackContext, \"generateRandom\">> &\n Pick<CallbackContext, \"signJwt\">;\n\n /**\n * The client attestation to create the Pop for\n */\n clientAttestation: string;\n\n /**\n * Expiration time of the JWT. If not provided 1 minute will be added to the `issuedAt`\n */\n expiresAt?: Date;\n\n /**\n * Creation time of the JWT. If not provided the current date will be used\n */\n issuedAt?: Date;\n\n /**\n * Optional jti to set in the payload. If not provided a random one will be generated\n */\n jti?: string;\n\n /**\n * The signer of jwt. Only jwk signer allowed.\n *\n * If not provided, the signer will be derived based on the\n * `cnf.jwk` and `alg` in the client attestation.\n */\n signer?: JwtSignerJwk;\n}\n\nexport async function createClientAttestationPopJwt(\n options: CreateClientAttestationPopJwtOptions,\n) {\n try {\n const clientAttestation = decodeJwt({\n jwt: options.clientAttestation,\n });\n\n const jwk = clientAttestation.payload.cnf?.jwk;\n if (!jwk) {\n throw new Oauth2Error(\n \"Client attestation does not contain 'cnf.jwk', cannot create client attestation pop jwt\",\n );\n }\n\n const sub = clientAttestation.payload.sub;\n if (!sub || typeof sub !== \"string\") {\n throw new Oauth2Error(\n \"Client attestation does not contain 'sub', cannot create client attestation pop jwt\",\n );\n }\n\n const signer = options.signer ?? {\n alg: clientAttestation.header.alg,\n method: \"jwk\",\n publicJwk: jwk,\n };\n\n const header = {\n alg: signer.alg,\n typ: \"oauth-client-attestation-pop+jwt\",\n } satisfies ClientAttestationPopJwtHeader;\n\n const issuedAt = options.issuedAt ?? new Date();\n const expiresAt = options.expiresAt ?? addSecondsToDate(issuedAt, 1 * 60);\n const jti =\n options.jti ??\n (options.callbacks.generateRandom\n ? encodeToBase64Url(await options.callbacks.generateRandom(32))\n : undefined);\n\n if (!jti) {\n throw new Oauth2Error(\n \"Error: neither a default jti nor a generateRandom callback have been provided\",\n );\n }\n\n const payload = {\n aud: options.authorizationServer,\n exp: dateToSeconds(expiresAt),\n iat: dateToSeconds(issuedAt),\n iss: sub,\n jti,\n } satisfies ClientAttestationPopJwtPayload;\n\n const { jwt } = await options.callbacks.signJwt(signer, {\n header,\n payload,\n });\n\n return jwt;\n } catch (error) {\n if (error instanceof Oauth2Error) throw error;\n throw new Oauth2Error(\n `Error creating client attestation pop jwt : ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n}\n","import { DecodeJwtResult, decodeJwt } from \"@openid4vc/oauth2\";\nimport z from \"zod\";\n\nimport { Oauth2Error } from \"./errors\";\n\n/**\n * Options for extracting and decoding the JWT from a form_post.jwt response\n */\nexport interface GetJwtFromFormPostOptions<T> {\n /**\n * Raw HTML containing the autosubmitted form with the jwt response\n */\n formData: string;\n\n /**\n * Schema for parsing and validating\n */\n schema: z.ZodSchema<T>;\n}\n\n/*\n * Decode a form_post.jwt and return the final JWT.\n * The formData here is in form_post.jwt format as defined in\n * JWT Secured Authorization Response Mode for OAuth 2.0 (JARM)\n <!DOCTYPE html>\n <html>\n <head>\n <meta charset=\"utf-8\" />\n </head>\n <body onload=\"document.forms[0].submit()\">\n <noscript>\n <p>\n <strong>Note:</strong> Since your browser does not support JavaScript, you must press the Continue button once to proceed.\n </p>\n </noscript>\n <form action=\"iowalletexample//cb\" method=\"post\"> \n <div>\n <input type=\"hidden\" name=\"response\" value=\"somevalue\" />\n </div>\n <noscript>\n <div>\n <input type=\"submit\" value=\"Continue\" />\n </div>\n </noscript>\n </form>\n </body>\n </html>\n */\nexport const getJwtFromFormPost = async <T>(\n options: GetJwtFromFormPostOptions<T>,\n): Promise<{\n decodedJwt: DecodeJwtResult<undefined, z.ZodSchema<T>>;\n jwt: string;\n}> => {\n const inputRegex = /<input[^<>]*>/gi;\n const nameRegex = /name=\"response\"/gi;\n const valueRegex = /value=\"([^\"]*)\"/gi;\n const lineExpressionRegex = /\\r\\n|\\n\\r|\\n|\\r|\\s+/g;\n\n let match = inputRegex.exec(options.formData);\n while (match) {\n let matchName = nameRegex.exec(match[0]);\n while (matchName) {\n let matchValue = valueRegex.exec(match[0]);\n while (matchValue && matchValue[1]) {\n const responseJwt = matchValue[1];\n\n if (responseJwt) {\n const jwt = responseJwt.replace(lineExpressionRegex, \"\");\n const decodedJwt = decodeJwt({\n jwt,\n payloadSchema: options.schema,\n });\n return {\n decodedJwt,\n jwt,\n };\n }\n\n matchValue = valueRegex.exec(match[0]);\n }\n matchName = nameRegex.exec(match[0]);\n }\n\n match = inputRegex.exec(options.formData);\n }\n\n throw new Oauth2Error(\n `Unable to obtain JWT from form_post.jwt. Form data: ${options.formData}`,\n );\n};\n","import {\n CallbackContext,\n HashAlgorithm,\n HttpMethod,\n JwtSignerJwk,\n} from \"@openid4vc/oauth2\";\nimport {\n ValidationError,\n dateToSeconds,\n decodeUtf8String,\n encodeToBase64Url,\n parseWithErrorHandling,\n} from \"@openid4vc/utils\";\nimport { Base64 } from \"js-base64\";\n\nimport { CreateTokenDPoPError } from \"../errors\";\nimport {\n DpopJwtHeader,\n DpopJwtPayload,\n zDpopJwtHeader,\n zDpopJwtPayload,\n} from \"./z-dpop\";\n\n/**\n * Options for Token Request DPoP generation\n */\nexport interface CreateTokenDPoPOptions {\n /**\n * The access token to which the dpop jwt should be bound. Required\n * when the dpop will be sent along with an access token.\n */\n accessToken?: string;\n\n /**\n * Object containing callbacks for DPoP generation and signature\n */\n callbacks: Partial<Pick<CallbackContext, \"generateRandom\">> &\n Pick<CallbackContext, \"hash\" | \"signJwt\">;\n\n /**\n * Creation time of the JWT. If not provided the current date will be used\n */\n issuedAt?: Date;\n\n /**\n * jti claim for the DPoP JWT. If not provided, a random one will be generated\n * if a generateRandom callback is provided\n */\n jti?: string;\n\n /**\n * The signer of the dpop jwt. Only jwk signer allowed.\n */\n signer: JwtSignerJwk;\n\n /**\n * The request for which to create the dpop jwt\n */\n tokenRequest: {\n method: HttpMethod;\n url: string;\n };\n}\n\n/**\n * Creates a signed Token DPoP with the given cryptographic material and data.\n * It is used to create DPoP proofs for token requests and credential requests.\n * @param options {@link CreateTokenDPoPOptions}\n * @returns A Promise that resolves with an object containing the signed DPoP JWT and\n * its corresponding public JWK\n * @throws {@link CreateTokenDPoPError} in case neither a default jti nor a generateRandom\n * callback have been provided or the signJwt callback throws\n */\nexport async function createTokenDPoP(options: CreateTokenDPoPOptions) {\n try {\n // Calculate access token hash\n const ath = options.accessToken\n ? encodeToBase64Url(\n await options.callbacks.hash(\n decodeUtf8String(options.accessToken),\n HashAlgorithm.Sha256,\n ),\n )\n : undefined;\n\n const jti =\n options.jti ??\n (options.callbacks.generateRandom\n ? Base64.fromUint8Array(\n await options.callbacks.generateRandom(32),\n true,\n )\n : undefined);\n\n if (!jti) {\n throw new CreateTokenDPoPError(\n \"Error: neither a default jti nor a generateRandom callback have been provided\",\n );\n }\n\n const header = parseWithErrorHandling(zDpopJwtHeader, {\n alg: options.signer.alg,\n jwk: options.signer.publicJwk,\n typ: \"dpop+jwt\",\n } satisfies DpopJwtHeader);\n\n const payload = parseWithErrorHandling(zDpopJwtPayload, {\n ath,\n htm: options.tokenRequest.method,\n htu: htuFromRequestUrl(options.tokenRequest.url),\n iat: dateToSeconds(options.issuedAt),\n jti,\n } satisfies DpopJwtPayload);\n\n return options.callbacks.signJwt(options.signer, {\n header,\n payload,\n });\n } catch (error) {\n if (\n error instanceof CreateTokenDPoPError ||\n error instanceof ValidationError\n ) {\n throw error;\n }\n throw new CreateTokenDPoPError(\n `Error during jwt signature, details: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n}\n\nconst htuFromRequestUrl = (requestUrl: string) => {\n const htu = new URL(requestUrl);\n htu.search = \"\";\n htu.hash = \"\";\n\n return htu.toString();\n};\n","import { zJwk, zJwtHeader, zJwtPayload } from \"@openid4vc/oauth2\";\nimport { zHttpMethod, zHttpsUrl, zInteger } from \"@openid4vc/utils\";\nimport z from \"zod\";\n\nexport const zDpopJwtPayload = z\n .object({\n ...zJwtPayload.shape,\n ath: z.optional(z.string()),\n htm: zHttpMethod,\n htu: zHttpsUrl,\n iat: zInteger,\n\n jti: z.string(),\n })\n .passthrough();\nexport type DpopJwtPayload = z.infer<typeof zDpopJwtPayload>;\n\nexport const zDpopJwtHeader = z\n .object({\n ...zJwtHeader.shape,\n jwk: zJwk,\n typ: z.literal(\"dpop+jwt\"),\n })\n .passthrough();\nexport type DpopJwtHeader = z.infer<typeof zDpopJwtHeader>;\n","export * from \"./access-token\";\nexport * from \"./authorization-request\";\nexport * from \"./client-attestation-pop\";\nexport * from \"./errors\";\nexport * from \"./jarm-form-post-jwt\";\nexport * from \"./pkce\";\nexport * from \"./token-dpop\";\n\nexport {\n type CallbackContext,\n type GenerateRandomCallback,\n HashAlgorithm,\n type HttpMethod,\n type Jwk,\n type JwtSigner,\n type JwtSignerJwk,\n Oauth2JwtParseError,\n type RequestDpopOptions,\n type SignJwtCallback,\n type VerifyJwtCallback,\n decodeJwt,\n} from \"@openid4vc/oauth2\";\n"],"mappings":"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","names":["encodeToBase64Url","Oauth2Error","PkceCodeChallengeMethod","encodeToBase64Url","createFetcher","CONTENT_TYPES","HEADERS","UnexpectedStatusCodeError","ValidationError","hasStatusOrThrow","z","createFetcher","HEADERS","CONTENT_TYPES","hasStatusOrThrow","UnexpectedStatusCodeError","ValidationError","encodeToBase64Url","encodeToBase64Url","decodeJwt","decodeJwt","HashAlgorithm","ValidationError","dateToSeconds","decodeUtf8String","encodeToBase64Url","parseWithErrorHandling","z","encodeToBase64Url","decodeUtf8String","HashAlgorithm","parseWithErrorHandling","dateToSeconds","ValidationError","HashAlgorithm","decodeJwt"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pagopa/io-wallet-oauth2",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"files": [
|
|
5
5
|
"dist"
|
|
6
6
|
],
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"@openid4vc/utils": "0.3.0-alpha-20250714110838",
|
|
31
31
|
"zod": "^3.24.2",
|
|
32
32
|
"js-base64": "^3.7.8",
|
|
33
|
-
"@pagopa/io-wallet-utils": "0.
|
|
33
|
+
"@pagopa/io-wallet-utils": "0.6.0"
|
|
34
34
|
},
|
|
35
35
|
"scripts": {
|
|
36
36
|
"build": "tsup src/index.ts --format cjs,esm --dts --sourcemap",
|