@openid4vc/oauth2 0.3.0-alpha-20251107130226 → 0.3.0-alpha-20251107132439
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/dist/index.cjs +240 -13
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +269 -70
- package/dist/index.d.mts +269 -70
- package/dist/index.mjs +235 -14
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -530,6 +530,149 @@ var Oauth2ServerErrorResponseError = class extends Oauth2Error {
|
|
|
530
530
|
}
|
|
531
531
|
};
|
|
532
532
|
|
|
533
|
+
//#endregion
|
|
534
|
+
//#region src/common/jwt/z-jwe.ts
|
|
535
|
+
const zCompactJwe = zod.z.string().regex(/^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]*\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$/, { message: "Not a valid compact jwe" });
|
|
536
|
+
|
|
537
|
+
//#endregion
|
|
538
|
+
//#region src/jar/z-jar-authorization-request.ts
|
|
539
|
+
const zJarAuthorizationRequest = zod.z.object({
|
|
540
|
+
request: zod.z.optional(zod.z.string()),
|
|
541
|
+
request_uri: zod.z.optional(__openid4vc_utils.zHttpsUrl),
|
|
542
|
+
client_id: zod.z.optional(zod.z.string())
|
|
543
|
+
}).loose();
|
|
544
|
+
function validateJarRequestParams(options) {
|
|
545
|
+
const { jarRequestParams } = options;
|
|
546
|
+
if (jarRequestParams.request && jarRequestParams.request_uri) throw new Oauth2ServerErrorResponseError({
|
|
547
|
+
error: Oauth2ErrorCodes.InvalidRequestObject,
|
|
548
|
+
error_description: "request and request_uri cannot both be present in a JAR request"
|
|
549
|
+
});
|
|
550
|
+
if (!jarRequestParams.request && !jarRequestParams.request_uri) throw new Oauth2ServerErrorResponseError({
|
|
551
|
+
error: Oauth2ErrorCodes.InvalidRequestObject,
|
|
552
|
+
error_description: "request or request_uri must be present"
|
|
553
|
+
});
|
|
554
|
+
return jarRequestParams;
|
|
555
|
+
}
|
|
556
|
+
function isJarAuthorizationRequest(request) {
|
|
557
|
+
return "request" in request || "request_uri" in request;
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
//#endregion
|
|
561
|
+
//#region src/jar/z-jar-request-object.ts
|
|
562
|
+
const zJarRequestObjectPayload = zod.z.object({
|
|
563
|
+
...zJwtPayload.shape,
|
|
564
|
+
client_id: zod.z.string()
|
|
565
|
+
}).loose();
|
|
566
|
+
const zSignedAuthorizationRequestJwtHeaderTyp = zod.z.literal("oauth-authz-req+jwt");
|
|
567
|
+
const signedAuthorizationRequestJwtHeaderTyp = zSignedAuthorizationRequestJwtHeaderTyp.value;
|
|
568
|
+
const zJwtAuthorizationRequestJwtHeaderTyp = zod.z.literal("jwt");
|
|
569
|
+
const jwtAuthorizationRequestJwtHeaderTyp = zJwtAuthorizationRequestJwtHeaderTyp.value;
|
|
570
|
+
|
|
571
|
+
//#endregion
|
|
572
|
+
//#region src/jar/handle-jar-request/verify-jar-request.ts
|
|
573
|
+
/**
|
|
574
|
+
* Parse a JAR (JWT Secured Authorization Request) request by validating and optionally fetch from uri.
|
|
575
|
+
*
|
|
576
|
+
* @param options - The input parameters
|
|
577
|
+
* @param options.jarRequestParams - The JAR authorization request parameters
|
|
578
|
+
* @param options.callbacks - Context containing the relevant Jose crypto operations
|
|
579
|
+
* @returns An object containing the transmission method ('value' or 'reference') and the JWT request object.
|
|
580
|
+
*/
|
|
581
|
+
async function parseJarRequest(options) {
|
|
582
|
+
const { callbacks } = options;
|
|
583
|
+
const jarRequestParams = {
|
|
584
|
+
...validateJarRequestParams(options),
|
|
585
|
+
...options.jarRequestParams
|
|
586
|
+
};
|
|
587
|
+
return {
|
|
588
|
+
sendBy: jarRequestParams.request ? "value" : "reference",
|
|
589
|
+
authorizationRequestJwt: jarRequestParams.request ?? await fetchJarRequestObject({
|
|
590
|
+
requestUri: jarRequestParams.request_uri,
|
|
591
|
+
fetch: callbacks.fetch
|
|
592
|
+
})
|
|
593
|
+
};
|
|
594
|
+
}
|
|
595
|
+
/**
|
|
596
|
+
* Verifies a JAR (JWT Secured Authorization Request) request by validating and verifying signatures.
|
|
597
|
+
*
|
|
598
|
+
* @param options - The input parameters
|
|
599
|
+
* @param options.jarRequestParams - The JAR authorization request parameters
|
|
600
|
+
* @param options.callbacks - Context containing the relevant Jose crypto operations
|
|
601
|
+
* @returns The verified authorization request parameters and metadata
|
|
602
|
+
*/
|
|
603
|
+
async function verifyJarRequest(options) {
|
|
604
|
+
const { jarRequestParams, authorizationRequestJwt, callbacks, jwtSigner } = options;
|
|
605
|
+
if (zCompactJwe.safeParse(authorizationRequestJwt).success) throw new Oauth2ServerErrorResponseError({
|
|
606
|
+
error: Oauth2ErrorCodes.InvalidRequestObject,
|
|
607
|
+
error_description: "Encrypted JWE request objects are not supported."
|
|
608
|
+
});
|
|
609
|
+
if (!zCompactJwt.safeParse(authorizationRequestJwt).success) throw new Oauth2ServerErrorResponseError({
|
|
610
|
+
error: Oauth2ErrorCodes.InvalidRequestObject,
|
|
611
|
+
error_description: "JAR request object is not a valid JWT."
|
|
612
|
+
});
|
|
613
|
+
const { authorizationRequestPayload, signer, jwt } = await verifyJarRequestObject({
|
|
614
|
+
authorizationRequestJwt,
|
|
615
|
+
callbacks,
|
|
616
|
+
jwtSigner
|
|
617
|
+
});
|
|
618
|
+
if (!authorizationRequestPayload.client_id) throw new Oauth2ServerErrorResponseError({
|
|
619
|
+
error: Oauth2ErrorCodes.InvalidRequestObject,
|
|
620
|
+
error_description: "Jar Request Object is missing the required \"client_id\" field."
|
|
621
|
+
});
|
|
622
|
+
if (jarRequestParams.client_id !== authorizationRequestPayload.client_id) throw new Oauth2ServerErrorResponseError({
|
|
623
|
+
error: Oauth2ErrorCodes.InvalidRequest,
|
|
624
|
+
error_description: "client_id does not match the request object client_id."
|
|
625
|
+
});
|
|
626
|
+
return {
|
|
627
|
+
jwt,
|
|
628
|
+
authorizationRequestPayload,
|
|
629
|
+
signer
|
|
630
|
+
};
|
|
631
|
+
}
|
|
632
|
+
async function fetchJarRequestObject(options) {
|
|
633
|
+
const { requestUri, fetch } = options;
|
|
634
|
+
const response = await (0, __openid4vc_utils.createFetcher)(fetch)(requestUri, {
|
|
635
|
+
method: "get",
|
|
636
|
+
headers: {
|
|
637
|
+
Accept: `${__openid4vc_utils.ContentType.OAuthAuthorizationRequestJwt}, ${__openid4vc_utils.ContentType.Jwt};q=0.9, text/plain`,
|
|
638
|
+
"Content-Type": __openid4vc_utils.ContentType.XWwwFormUrlencoded
|
|
639
|
+
}
|
|
640
|
+
}).catch(() => {
|
|
641
|
+
throw new Oauth2ServerErrorResponseError({
|
|
642
|
+
error_description: `Fetching request_object from request_uri '${requestUri}' failed`,
|
|
643
|
+
error: Oauth2ErrorCodes.InvalidRequestUri
|
|
644
|
+
});
|
|
645
|
+
});
|
|
646
|
+
if (!response.ok) throw new Oauth2ServerErrorResponseError({
|
|
647
|
+
error_description: `Fetching request_object from request_uri '${requestUri}' failed with status code '${response.status}'.`,
|
|
648
|
+
error: Oauth2ErrorCodes.InvalidRequestUri
|
|
649
|
+
});
|
|
650
|
+
return await response.text();
|
|
651
|
+
}
|
|
652
|
+
async function verifyJarRequestObject(options) {
|
|
653
|
+
const { authorizationRequestJwt, callbacks, jwtSigner } = options;
|
|
654
|
+
const jwt = decodeJwt({
|
|
655
|
+
jwt: authorizationRequestJwt,
|
|
656
|
+
payloadSchema: zJarRequestObjectPayload
|
|
657
|
+
});
|
|
658
|
+
const { signer } = await verifyJwt({
|
|
659
|
+
verifyJwtCallback: callbacks.verifyJwt,
|
|
660
|
+
compact: authorizationRequestJwt,
|
|
661
|
+
header: jwt.header,
|
|
662
|
+
payload: jwt.payload,
|
|
663
|
+
signer: jwtSigner
|
|
664
|
+
});
|
|
665
|
+
if (jwt.header.typ !== signedAuthorizationRequestJwtHeaderTyp && jwt.header.typ !== jwtAuthorizationRequestJwtHeaderTyp) throw new Oauth2ServerErrorResponseError({
|
|
666
|
+
error: Oauth2ErrorCodes.InvalidRequestObject,
|
|
667
|
+
error_description: `Invalid Jar Request Object typ header. Expected "oauth-authz-req+jwt" or "jwt", received "${jwt.header.typ}".`
|
|
668
|
+
});
|
|
669
|
+
return {
|
|
670
|
+
signer,
|
|
671
|
+
jwt,
|
|
672
|
+
authorizationRequestPayload: jwt.payload
|
|
673
|
+
};
|
|
674
|
+
}
|
|
675
|
+
|
|
533
676
|
//#endregion
|
|
534
677
|
//#region src/client-attestation/z-client-attestation.ts
|
|
535
678
|
const zOauthClientAttestationHeader = zod.default.literal("OAuth-Client-Attestation");
|
|
@@ -897,12 +1040,29 @@ const zPushedAuthorizationResponse = zod.default.object({
|
|
|
897
1040
|
*
|
|
898
1041
|
* @throws {Oauth2ServerErrorResponseError}
|
|
899
1042
|
*/
|
|
900
|
-
function parsePushedAuthorizationRequest(options) {
|
|
901
|
-
const
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
1043
|
+
async function parsePushedAuthorizationRequest(options) {
|
|
1044
|
+
const parsed = (0, __openid4vc_utils.parseWithErrorHandling)(zod.default.union([zAuthorizationRequest, zJarAuthorizationRequest]), options.authorizationRequest, "Invalid authorization request. Could not parse authorization request or jar.");
|
|
1045
|
+
let parsedAuthorizationRequest;
|
|
1046
|
+
let authorizationRequestJwt;
|
|
1047
|
+
if (isJarAuthorizationRequest(parsed)) {
|
|
1048
|
+
const parsedJar = await parseJarRequest({
|
|
1049
|
+
jarRequestParams: parsed,
|
|
1050
|
+
callbacks: options.callbacks
|
|
1051
|
+
});
|
|
1052
|
+
const jwt = decodeJwt({ jwt: parsedJar.authorizationRequestJwt });
|
|
1053
|
+
parsedAuthorizationRequest = zAuthorizationRequest.safeParse(jwt.payload);
|
|
1054
|
+
if (!parsedAuthorizationRequest.success) throw new Oauth2ServerErrorResponseError({
|
|
1055
|
+
error: Oauth2ErrorCodes.InvalidRequest,
|
|
1056
|
+
error_description: `Invalid authorization request. Could not parse jar request payload.\n${(0, __openid4vc_utils.formatZodError)(parsedAuthorizationRequest.error)}`
|
|
1057
|
+
});
|
|
1058
|
+
authorizationRequestJwt = parsedJar.authorizationRequestJwt;
|
|
1059
|
+
} else {
|
|
1060
|
+
parsedAuthorizationRequest = zAuthorizationRequest.safeParse(options.authorizationRequest);
|
|
1061
|
+
if (!parsedAuthorizationRequest.success) throw new Oauth2ServerErrorResponseError({
|
|
1062
|
+
error: Oauth2ErrorCodes.InvalidRequest,
|
|
1063
|
+
error_description: `Error occurred during validation of pushed authorization request.\n${(0, __openid4vc_utils.formatZodError)(parsedAuthorizationRequest.error)}`
|
|
1064
|
+
});
|
|
1065
|
+
}
|
|
906
1066
|
const authorizationRequest = parsedAuthorizationRequest.data;
|
|
907
1067
|
const { clientAttestation, dpop } = parseAuthorizationRequest({
|
|
908
1068
|
authorizationRequest,
|
|
@@ -910,6 +1070,7 @@ function parsePushedAuthorizationRequest(options) {
|
|
|
910
1070
|
});
|
|
911
1071
|
return {
|
|
912
1072
|
authorizationRequest,
|
|
1073
|
+
authorizationRequestJwt,
|
|
913
1074
|
dpop,
|
|
914
1075
|
clientAttestation
|
|
915
1076
|
};
|
|
@@ -1060,10 +1221,6 @@ function clientAuthenticationClientAttestationJwt(options) {
|
|
|
1060
1221
|
};
|
|
1061
1222
|
}
|
|
1062
1223
|
|
|
1063
|
-
//#endregion
|
|
1064
|
-
//#region src/common/jwt/z-jwe.ts
|
|
1065
|
-
const zCompactJwe = zod.z.string().regex(/^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]*\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$/, { message: "Not a valid compact jwe" });
|
|
1066
|
-
|
|
1067
1224
|
//#endregion
|
|
1068
1225
|
//#region src/error/Oauth2ClientErrorResponseError.ts
|
|
1069
1226
|
var Oauth2ClientErrorResponseError = class extends Oauth2Error {
|
|
@@ -1197,6 +1354,57 @@ async function verifyIdTokenJwt(options) {
|
|
|
1197
1354
|
};
|
|
1198
1355
|
}
|
|
1199
1356
|
|
|
1357
|
+
//#endregion
|
|
1358
|
+
//#region src/jar/create-jar-authorization-request.ts
|
|
1359
|
+
/**
|
|
1360
|
+
* Creates a JAR (JWT Authorization Request) request object.
|
|
1361
|
+
*
|
|
1362
|
+
* @param options - The input parameters
|
|
1363
|
+
* @param options.authorizationRequestPayload - The authorization request parameters
|
|
1364
|
+
* @param options.jwtSigner - The JWT signer
|
|
1365
|
+
* @param options.jweEncryptor - The JWE encryptor (optional) if provided, the request object will be encrypted
|
|
1366
|
+
* @param options.requestUri - The request URI (optional) if provided, the request object needs to be fetched from the URI
|
|
1367
|
+
* @param options.callbacks - The callback context
|
|
1368
|
+
* @returns the requestParams, signerJwk, encryptionJwk, and requestObjectJwt
|
|
1369
|
+
*/
|
|
1370
|
+
async function createJarAuthorizationRequest(options) {
|
|
1371
|
+
const { jwtSigner, jweEncryptor, authorizationRequestPayload, requestUri, callbacks } = options;
|
|
1372
|
+
let authorizationRequestJwt;
|
|
1373
|
+
let encryptionJwk;
|
|
1374
|
+
const now = options.now ?? /* @__PURE__ */ new Date();
|
|
1375
|
+
const { jwt, signerJwk } = await callbacks.signJwt(jwtSigner, {
|
|
1376
|
+
header: {
|
|
1377
|
+
...jwtHeaderFromJwtSigner(jwtSigner),
|
|
1378
|
+
typ: "oauth-authz-req+jwt"
|
|
1379
|
+
},
|
|
1380
|
+
payload: {
|
|
1381
|
+
iat: (0, __openid4vc_utils.dateToSeconds)(now),
|
|
1382
|
+
exp: (0, __openid4vc_utils.dateToSeconds)((0, __openid4vc_utils.addSecondsToDate)(now, options.expiresInSeconds)),
|
|
1383
|
+
...options.additionalJwtPayload,
|
|
1384
|
+
...authorizationRequestPayload
|
|
1385
|
+
}
|
|
1386
|
+
});
|
|
1387
|
+
authorizationRequestJwt = jwt;
|
|
1388
|
+
if (jweEncryptor) {
|
|
1389
|
+
const encryptionResult = await callbacks.encryptJwe(jweEncryptor, authorizationRequestJwt);
|
|
1390
|
+
authorizationRequestJwt = encryptionResult.jwe;
|
|
1391
|
+
encryptionJwk = encryptionResult.encryptionJwk;
|
|
1392
|
+
}
|
|
1393
|
+
const client_id = authorizationRequestPayload.client_id;
|
|
1394
|
+
return {
|
|
1395
|
+
jarAuthorizationRequest: requestUri ? {
|
|
1396
|
+
client_id,
|
|
1397
|
+
request_uri: requestUri
|
|
1398
|
+
} : {
|
|
1399
|
+
client_id,
|
|
1400
|
+
request: authorizationRequestJwt
|
|
1401
|
+
},
|
|
1402
|
+
signerJwk,
|
|
1403
|
+
encryptionJwk,
|
|
1404
|
+
authorizationRequestJwt
|
|
1405
|
+
};
|
|
1406
|
+
}
|
|
1407
|
+
|
|
1200
1408
|
//#endregion
|
|
1201
1409
|
//#region src/metadata/fetch-well-known-metadata.ts
|
|
1202
1410
|
/**
|
|
@@ -1800,10 +2008,18 @@ function createPushedAuthorizationErrorResponse(options) {
|
|
|
1800
2008
|
//#endregion
|
|
1801
2009
|
//#region src/authorization-request/verify-pushed-authorization-request.ts
|
|
1802
2010
|
async function verifyPushedAuthorizationRequest(options) {
|
|
2011
|
+
let jar;
|
|
2012
|
+
if (options.authorizationRequestJwt) jar = await verifyJarRequest({
|
|
2013
|
+
authorizationRequestJwt: options.authorizationRequestJwt.jwt,
|
|
2014
|
+
jarRequestParams: options.authorizationRequest,
|
|
2015
|
+
callbacks: options.callbacks,
|
|
2016
|
+
jwtSigner: options.authorizationRequestJwt.signer
|
|
2017
|
+
});
|
|
1803
2018
|
const { clientAttestation, dpop } = await verifyAuthorizationRequest(options);
|
|
1804
2019
|
return {
|
|
1805
2020
|
dpop,
|
|
1806
|
-
clientAttestation
|
|
2021
|
+
clientAttestation,
|
|
2022
|
+
jar
|
|
1807
2023
|
};
|
|
1808
2024
|
}
|
|
1809
2025
|
|
|
@@ -1882,9 +2098,14 @@ var Oauth2AuthorizationServer = class {
|
|
|
1882
2098
|
/**
|
|
1883
2099
|
* Parse a pushed authorization request
|
|
1884
2100
|
*/
|
|
1885
|
-
parsePushedAuthorizationRequest(options) {
|
|
1886
|
-
return parsePushedAuthorizationRequest(options);
|
|
2101
|
+
async parsePushedAuthorizationRequest(options) {
|
|
2102
|
+
return await parsePushedAuthorizationRequest(options);
|
|
1887
2103
|
}
|
|
2104
|
+
/**
|
|
2105
|
+
* Verify pushed authorization request.
|
|
2106
|
+
*
|
|
2107
|
+
* Make sure to provide the `authorizationRequestJwt` if this was returned in the `parsePushedAuthorizationRequest`
|
|
2108
|
+
*/
|
|
1888
2109
|
verifyPushedAuthorizationRequest(options) {
|
|
1889
2110
|
return verifyPushedAuthorizationRequest({
|
|
1890
2111
|
...options,
|
|
@@ -2644,6 +2865,7 @@ exports.clientAuthenticationClientSecretPost = clientAuthenticationClientSecretP
|
|
|
2644
2865
|
exports.clientAuthenticationDynamic = clientAuthenticationDynamic;
|
|
2645
2866
|
exports.clientAuthenticationNone = clientAuthenticationNone;
|
|
2646
2867
|
exports.createClientAttestationJwt = createClientAttestationJwt;
|
|
2868
|
+
exports.createJarAuthorizationRequest = createJarAuthorizationRequest;
|
|
2647
2869
|
exports.decodeJwt = decodeJwt;
|
|
2648
2870
|
exports.decodeJwtHeader = decodeJwtHeader;
|
|
2649
2871
|
exports.fetchAuthorizationServerMetadata = fetchAuthorizationServerMetadata;
|
|
@@ -2657,6 +2879,7 @@ Object.defineProperty(exports, 'getGlobalConfig', {
|
|
|
2657
2879
|
}
|
|
2658
2880
|
});
|
|
2659
2881
|
exports.isJwkInSet = isJwkInSet;
|
|
2882
|
+
exports.jwtAuthorizationRequestJwtHeaderTyp = jwtAuthorizationRequestJwtHeaderTyp;
|
|
2660
2883
|
exports.jwtHeaderFromJwtSigner = jwtHeaderFromJwtSigner;
|
|
2661
2884
|
exports.jwtSignerFromJwt = jwtSignerFromJwt;
|
|
2662
2885
|
exports.parseAuthorizationResponseRedirectUrl = parseAuthorizationResponseRedirectUrl;
|
|
@@ -2671,6 +2894,8 @@ Object.defineProperty(exports, 'setGlobalConfig', {
|
|
|
2671
2894
|
return __openid4vc_utils.setGlobalConfig;
|
|
2672
2895
|
}
|
|
2673
2896
|
});
|
|
2897
|
+
exports.signedAuthorizationRequestJwtHeaderTyp = signedAuthorizationRequestJwtHeaderTyp;
|
|
2898
|
+
exports.validateJarRequestParams = validateJarRequestParams;
|
|
2674
2899
|
exports.verifyClientAttestationJwt = verifyClientAttestationJwt;
|
|
2675
2900
|
exports.verifyIdTokenJwt = verifyIdTokenJwt;
|
|
2676
2901
|
exports.verifyJwt = verifyJwt;
|
|
@@ -2685,6 +2910,8 @@ exports.zCompactJwe = zCompactJwe;
|
|
|
2685
2910
|
exports.zCompactJwt = zCompactJwt;
|
|
2686
2911
|
exports.zIdTokenJwtHeader = zIdTokenJwtHeader;
|
|
2687
2912
|
exports.zIdTokenJwtPayload = zIdTokenJwtPayload;
|
|
2913
|
+
exports.zJarAuthorizationRequest = zJarAuthorizationRequest;
|
|
2914
|
+
exports.zJarRequestObjectPayload = zJarRequestObjectPayload;
|
|
2688
2915
|
exports.zJwk = zJwk;
|
|
2689
2916
|
exports.zJwkSet = zJwkSet;
|
|
2690
2917
|
exports.zJwtHeader = zJwtHeader;
|