@credo-ts/openid4vc 0.6.1-pr-2091-20241119140918 → 0.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/OpenId4VcApi.d.mts +24 -0
- package/build/OpenId4VcApi.d.mts.map +1 -0
- package/build/OpenId4VcApi.mjs +35 -0
- package/build/OpenId4VcApi.mjs.map +1 -0
- package/build/OpenId4VcModule.d.mts +30 -0
- package/build/OpenId4VcModule.d.mts.map +1 -0
- package/build/OpenId4VcModule.mjs +42 -0
- package/build/OpenId4VcModule.mjs.map +1 -0
- package/build/OpenId4VcModuleConfig.d.mts +44 -0
- package/build/OpenId4VcModuleConfig.d.mts.map +1 -0
- package/build/OpenId4VcModuleConfig.mjs +24 -0
- package/build/OpenId4VcModuleConfig.mjs.map +1 -0
- package/build/_virtual/_@oxc-project_runtime@0.99.0/helpers/decorate.mjs +10 -0
- package/build/_virtual/_@oxc-project_runtime@0.99.0/helpers/decorateMetadata.mjs +7 -0
- package/build/_virtual/_@oxc-project_runtime@0.99.0/helpers/decorateParam.mjs +9 -0
- package/build/index.d.mts +42 -0
- package/build/index.mjs +37 -0
- package/build/openid4vc-holder/OpenId4VcHolderApi.d.mts +238 -0
- package/build/openid4vc-holder/OpenId4VcHolderApi.d.mts.map +1 -0
- package/build/openid4vc-holder/OpenId4VcHolderApi.mjs +174 -0
- package/build/openid4vc-holder/OpenId4VcHolderApi.mjs.map +1 -0
- package/build/openid4vc-holder/OpenId4VcHolderModule.d.mts +17 -0
- package/build/openid4vc-holder/OpenId4VcHolderModule.d.mts.map +1 -0
- package/build/openid4vc-holder/OpenId4VcHolderModule.mjs +23 -0
- package/build/openid4vc-holder/OpenId4VcHolderModule.mjs.map +1 -0
- package/build/openid4vc-holder/OpenId4VciHolderService.d.mts +69 -0
- package/build/openid4vc-holder/OpenId4VciHolderService.d.mts.map +1 -0
- package/build/openid4vc-holder/OpenId4VciHolderService.mjs +751 -0
- package/build/openid4vc-holder/OpenId4VciHolderService.mjs.map +1 -0
- package/build/openid4vc-holder/OpenId4VciHolderServiceOptions.d.mts +398 -0
- package/build/openid4vc-holder/OpenId4VciHolderServiceOptions.d.mts.map +1 -0
- package/build/openid4vc-holder/OpenId4VciHolderServiceOptions.mjs +16 -0
- package/build/openid4vc-holder/OpenId4VciHolderServiceOptions.mjs.map +1 -0
- package/build/openid4vc-holder/OpenId4vpHolderService.d.mts +130 -0
- package/build/openid4vc-holder/OpenId4vpHolderService.d.mts.map +1 -0
- package/build/openid4vc-holder/OpenId4vpHolderService.mjs +278 -0
- package/build/openid4vc-holder/OpenId4vpHolderService.mjs.map +1 -0
- package/build/openid4vc-holder/OpenId4vpHolderServiceOptions.d.mts +112 -0
- package/build/openid4vc-holder/OpenId4vpHolderServiceOptions.d.mts.map +1 -0
- package/build/openid4vc-holder/index.d.mts +6 -0
- package/build/openid4vc-holder/index.mjs +5 -0
- package/build/openid4vc-issuer/OpenId4VcIssuanceSessionState.d.mts +16 -0
- package/build/openid4vc-issuer/OpenId4VcIssuanceSessionState.d.mts.map +1 -0
- package/build/openid4vc-issuer/OpenId4VcIssuanceSessionState.mjs +18 -0
- package/build/openid4vc-issuer/OpenId4VcIssuanceSessionState.mjs.map +1 -0
- package/build/openid4vc-issuer/OpenId4VcIssuerApi.d.mts +137 -0
- package/build/openid4vc-issuer/OpenId4VcIssuerApi.d.mts.map +1 -0
- package/build/openid4vc-issuer/OpenId4VcIssuerApi.mjs +108 -0
- package/build/openid4vc-issuer/OpenId4VcIssuerApi.mjs.map +1 -0
- package/build/openid4vc-issuer/OpenId4VcIssuerEvents.d.mts +19 -0
- package/build/openid4vc-issuer/OpenId4VcIssuerEvents.d.mts.map +1 -0
- package/build/openid4vc-issuer/OpenId4VcIssuerEvents.mjs +9 -0
- package/build/openid4vc-issuer/OpenId4VcIssuerEvents.mjs.map +1 -0
- package/build/openid4vc-issuer/OpenId4VcIssuerModule.d.mts +27 -0
- package/build/openid4vc-issuer/OpenId4VcIssuerModule.d.mts.map +1 -0
- package/build/openid4vc-issuer/OpenId4VcIssuerModule.mjs +150 -0
- package/build/openid4vc-issuer/OpenId4VcIssuerModule.mjs.map +1 -0
- package/build/openid4vc-issuer/OpenId4VcIssuerModuleConfig.d.mts +279 -0
- package/build/openid4vc-issuer/OpenId4VcIssuerModuleConfig.d.mts.map +1 -0
- package/build/openid4vc-issuer/OpenId4VcIssuerModuleConfig.mjs +179 -0
- package/build/openid4vc-issuer/OpenId4VcIssuerModuleConfig.mjs.map +1 -0
- package/build/openid4vc-issuer/OpenId4VcIssuerService.d.mts +182 -0
- package/build/openid4vc-issuer/OpenId4VcIssuerService.d.mts.map +1 -0
- package/build/openid4vc-issuer/OpenId4VcIssuerService.mjs +881 -0
- package/build/openid4vc-issuer/OpenId4VcIssuerService.mjs.map +1 -0
- package/build/openid4vc-issuer/OpenId4VcIssuerServiceOptions.d.mts +340 -0
- package/build/openid4vc-issuer/OpenId4VcIssuerServiceOptions.d.mts.map +1 -0
- package/build/openid4vc-issuer/OpenId4VcIssuerServiceOptions.mjs +1 -0
- package/build/openid4vc-issuer/index.d.mts +11 -0
- package/build/openid4vc-issuer/index.mjs +11 -0
- package/build/openid4vc-issuer/repository/OpenId4VcIssuanceSessionRecord.d.mts +300 -0
- package/build/openid4vc-issuer/repository/OpenId4VcIssuanceSessionRecord.d.mts.map +1 -0
- package/build/openid4vc-issuer/repository/OpenId4VcIssuanceSessionRecord.mjs +102 -0
- package/build/openid4vc-issuer/repository/OpenId4VcIssuanceSessionRecord.mjs.map +1 -0
- package/build/openid4vc-issuer/repository/OpenId4VcIssuanceSessionRepository.d.mts +10 -0
- package/build/openid4vc-issuer/repository/OpenId4VcIssuanceSessionRepository.d.mts.map +1 -0
- package/build/openid4vc-issuer/repository/OpenId4VcIssuanceSessionRepository.mjs +22 -0
- package/build/openid4vc-issuer/repository/OpenId4VcIssuanceSessionRepository.mjs.map +1 -0
- package/build/openid4vc-issuer/repository/OpenId4VcIssuerRecord.d.mts +84 -0
- package/build/openid4vc-issuer/repository/OpenId4VcIssuerRecord.d.mts.map +1 -0
- package/build/openid4vc-issuer/repository/OpenId4VcIssuerRecord.mjs +89 -0
- package/build/openid4vc-issuer/repository/OpenId4VcIssuerRecord.mjs.map +1 -0
- package/build/openid4vc-issuer/repository/OpenId4VcIssuerRepository.d.mts +12 -0
- package/build/openid4vc-issuer/repository/OpenId4VcIssuerRepository.d.mts.map +1 -0
- package/build/openid4vc-issuer/repository/OpenId4VcIssuerRepository.mjs +28 -0
- package/build/openid4vc-issuer/repository/OpenId4VcIssuerRepository.mjs.map +1 -0
- package/build/openid4vc-issuer/repository/index.d.mts +4 -0
- package/build/openid4vc-issuer/repository/index.mjs +4 -0
- package/build/openid4vc-issuer/router/accessTokenEndpoint.mjs +199 -0
- package/build/openid4vc-issuer/router/accessTokenEndpoint.mjs.map +1 -0
- package/build/openid4vc-issuer/router/authorizationChallengeEndpoint.mjs +241 -0
- package/build/openid4vc-issuer/router/authorizationChallengeEndpoint.mjs.map +1 -0
- package/build/openid4vc-issuer/router/authorizationEndpoint.mjs +51 -0
- package/build/openid4vc-issuer/router/authorizationEndpoint.mjs.map +1 -0
- package/build/openid4vc-issuer/router/authorizationServerMetadataEndpoint.mjs +25 -0
- package/build/openid4vc-issuer/router/authorizationServerMetadataEndpoint.mjs.map +1 -0
- package/build/openid4vc-issuer/router/credentialEndpoint.mjs +142 -0
- package/build/openid4vc-issuer/router/credentialEndpoint.mjs.map +1 -0
- package/build/openid4vc-issuer/router/credentialOfferEndpoint.mjs +38 -0
- package/build/openid4vc-issuer/router/credentialOfferEndpoint.mjs.map +1 -0
- package/build/openid4vc-issuer/router/deferredCredentialEndpoint.mjs +84 -0
- package/build/openid4vc-issuer/router/deferredCredentialEndpoint.mjs.map +1 -0
- package/build/openid4vc-issuer/router/index.mjs +12 -0
- package/build/openid4vc-issuer/router/issuerMetadataEndpoint.mjs +43 -0
- package/build/openid4vc-issuer/router/issuerMetadataEndpoint.mjs.map +1 -0
- package/build/openid4vc-issuer/router/jwksEndpoint.mjs +18 -0
- package/build/openid4vc-issuer/router/jwksEndpoint.mjs.map +1 -0
- package/build/openid4vc-issuer/router/nonceEndpoint.mjs +29 -0
- package/build/openid4vc-issuer/router/nonceEndpoint.mjs.map +1 -0
- package/build/openid4vc-issuer/router/pushedAuthorizationRequestEndpoint.mjs +164 -0
- package/build/openid4vc-issuer/router/pushedAuthorizationRequestEndpoint.mjs.map +1 -0
- package/build/openid4vc-issuer/router/redirectEndpoint.mjs +124 -0
- package/build/openid4vc-issuer/router/redirectEndpoint.mjs.map +1 -0
- package/build/openid4vc-issuer/util/txCode.mjs +18 -0
- package/build/openid4vc-issuer/util/txCode.mjs.map +1 -0
- package/build/openid4vc-verifier/OpenId4VcVerificationSessionState.d.mts +10 -0
- package/build/openid4vc-verifier/OpenId4VcVerificationSessionState.d.mts.map +1 -0
- package/build/openid4vc-verifier/OpenId4VcVerificationSessionState.mjs +12 -0
- package/build/openid4vc-verifier/OpenId4VcVerificationSessionState.mjs.map +1 -0
- package/build/openid4vc-verifier/OpenId4VcVerifierApi.d.mts +60 -0
- package/build/openid4vc-verifier/OpenId4VcVerifierApi.d.mts.map +1 -0
- package/build/openid4vc-verifier/OpenId4VcVerifierApi.mjs +83 -0
- package/build/openid4vc-verifier/OpenId4VcVerifierApi.mjs.map +1 -0
- package/build/openid4vc-verifier/OpenId4VcVerifierEvents.d.mts +19 -0
- package/build/openid4vc-verifier/OpenId4VcVerifierEvents.d.mts.map +1 -0
- package/build/openid4vc-verifier/OpenId4VcVerifierEvents.mjs +9 -0
- package/build/openid4vc-verifier/OpenId4VcVerifierEvents.mjs.map +1 -0
- package/build/openid4vc-verifier/OpenId4VcVerifierModule.d.mts +25 -0
- package/build/openid4vc-verifier/OpenId4VcVerifierModule.d.mts.map +1 -0
- package/build/openid4vc-verifier/OpenId4VcVerifierModule.mjs +91 -0
- package/build/openid4vc-verifier/OpenId4VcVerifierModule.mjs.map +1 -0
- package/build/openid4vc-verifier/OpenId4VcVerifierModuleConfig.d.mts +55 -0
- package/build/openid4vc-verifier/OpenId4VcVerifierModuleConfig.d.mts.map +1 -0
- package/build/openid4vc-verifier/OpenId4VcVerifierModuleConfig.mjs +36 -0
- package/build/openid4vc-verifier/OpenId4VcVerifierModuleConfig.mjs.map +1 -0
- package/build/openid4vc-verifier/OpenId4VpVerifierService.d.mts +60 -0
- package/build/openid4vc-verifier/OpenId4VpVerifierService.d.mts.map +1 -0
- package/build/openid4vc-verifier/OpenId4VpVerifierService.mjs +714 -0
- package/build/openid4vc-verifier/OpenId4VpVerifierService.mjs.map +1 -0
- package/build/openid4vc-verifier/OpenId4VpVerifierServiceOptions.d.mts +194 -0
- package/build/openid4vc-verifier/OpenId4VpVerifierServiceOptions.d.mts.map +1 -0
- package/build/openid4vc-verifier/index.d.mts +12 -0
- package/build/openid4vc-verifier/index.mjs +11 -0
- package/build/openid4vc-verifier/repository/OpenId4VcVerificationSessionRecord.d.mts +129 -0
- package/build/openid4vc-verifier/repository/OpenId4VcVerificationSessionRecord.d.mts.map +1 -0
- package/build/openid4vc-verifier/repository/OpenId4VcVerificationSessionRecord.mjs +64 -0
- package/build/openid4vc-verifier/repository/OpenId4VcVerificationSessionRecord.mjs.map +1 -0
- package/build/openid4vc-verifier/repository/OpenId4VcVerificationSessionRepository.d.mts +10 -0
- package/build/openid4vc-verifier/repository/OpenId4VcVerificationSessionRepository.d.mts.map +1 -0
- package/build/openid4vc-verifier/repository/OpenId4VcVerificationSessionRepository.mjs +22 -0
- package/build/openid4vc-verifier/repository/OpenId4VcVerificationSessionRepository.mjs.map +1 -0
- package/build/openid4vc-verifier/repository/OpenId4VcVerifierRecord.d.mts +33 -0
- package/build/openid4vc-verifier/repository/OpenId4VcVerifierRecord.d.mts.map +1 -0
- package/build/openid4vc-verifier/repository/OpenId4VcVerifierRecord.mjs +32 -0
- package/build/openid4vc-verifier/repository/OpenId4VcVerifierRecord.mjs.map +1 -0
- package/build/openid4vc-verifier/repository/OpenId4VcVerifierRepository.d.mts +12 -0
- package/build/openid4vc-verifier/repository/OpenId4VcVerifierRepository.d.mts.map +1 -0
- package/build/openid4vc-verifier/repository/OpenId4VcVerifierRepository.mjs +28 -0
- package/build/openid4vc-verifier/repository/OpenId4VcVerifierRepository.mjs.map +1 -0
- package/build/openid4vc-verifier/repository/index.d.mts +4 -0
- package/build/openid4vc-verifier/repository/index.mjs +4 -0
- package/build/openid4vc-verifier/router/authorizationEndpoint.mjs +117 -0
- package/build/openid4vc-verifier/router/authorizationEndpoint.mjs.map +1 -0
- package/build/openid4vc-verifier/router/authorizationRequestEndpoint.mjs +39 -0
- package/build/openid4vc-verifier/router/authorizationRequestEndpoint.mjs.map +1 -0
- package/build/openid4vc-verifier/router/index.mjs +1 -0
- package/build/shared/callbacks.d.mts +47 -0
- package/build/shared/callbacks.d.mts.map +1 -0
- package/build/shared/callbacks.mjs +279 -0
- package/build/shared/callbacks.mjs.map +1 -0
- package/build/shared/index.d.mts +7 -0
- package/build/shared/index.mjs +4 -0
- package/build/shared/issuerMetadataUtils.d.mts +22 -0
- package/build/shared/issuerMetadataUtils.d.mts.map +1 -0
- package/build/shared/issuerMetadataUtils.mjs +30 -0
- package/build/shared/issuerMetadataUtils.mjs.map +1 -0
- package/build/shared/models/CredentialHolderBinding.d.mts +71 -0
- package/build/shared/models/CredentialHolderBinding.d.mts.map +1 -0
- package/build/shared/models/CredentialHolderBinding.mjs +1 -0
- package/build/shared/models/OpenId4VcJwtIssuer.d.mts +46 -0
- package/build/shared/models/OpenId4VcJwtIssuer.d.mts.map +1 -0
- package/build/shared/models/OpenId4VcJwtIssuer.mjs +1 -0
- package/build/shared/models/OpenId4VciAuthorizationServerConfig.d.mts +71 -0
- package/build/shared/models/OpenId4VciAuthorizationServerConfig.d.mts.map +1 -0
- package/build/shared/models/OpenId4VciCredentialFormatProfile.d.mts +12 -0
- package/build/shared/models/OpenId4VciCredentialFormatProfile.d.mts.map +1 -0
- package/build/shared/models/OpenId4VciCredentialFormatProfile.mjs +14 -0
- package/build/shared/models/OpenId4VciCredentialFormatProfile.mjs.map +1 -0
- package/build/shared/models/index.d.mts +30 -0
- package/build/shared/models/index.d.mts.map +1 -0
- package/build/shared/models/index.mjs +6 -0
- package/build/shared/router/context.mjs +52 -0
- package/build/shared/router/context.mjs.map +1 -0
- package/build/shared/router/express.browser.d.mts +5 -0
- package/build/shared/router/express.browser.d.mts.map +1 -0
- package/build/shared/router/express.browser.mjs +8 -0
- package/build/shared/router/express.browser.mjs.map +1 -0
- package/build/shared/router/express.mjs +10 -0
- package/build/shared/router/express.mjs.map +1 -0
- package/build/shared/router/express.native.d.mts +5 -0
- package/build/shared/router/express.native.d.mts.map +1 -0
- package/build/shared/router/express.native.mjs +8 -0
- package/build/shared/router/express.native.mjs.map +1 -0
- package/build/shared/router/index.mjs +3 -0
- package/build/shared/router/tenants.mjs +36 -0
- package/build/shared/router/tenants.mjs.map +1 -0
- package/build/shared/transactionData.mjs +19 -0
- package/build/shared/transactionData.mjs.map +1 -0
- package/build/shared/utils.mjs +90 -0
- package/build/shared/utils.mjs.map +1 -0
- package/package.json +30 -23
- package/build/index.d.ts +0 -4
- package/build/index.js +0 -21
- package/build/index.js.map +0 -1
- package/build/openid4vc-holder/OpenId4VcHolderApi.d.ts +0 -124
- package/build/openid4vc-holder/OpenId4VcHolderApi.js +0 -155
- package/build/openid4vc-holder/OpenId4VcHolderApi.js.map +0 -1
- package/build/openid4vc-holder/OpenId4VcHolderModule.d.ts +0 -13
- package/build/openid4vc-holder/OpenId4VcHolderModule.js +0 -35
- package/build/openid4vc-holder/OpenId4VcHolderModule.js.map +0 -1
- package/build/openid4vc-holder/OpenId4VciHolderService.d.ts +0 -72
- package/build/openid4vc-holder/OpenId4VciHolderService.js +0 -569
- package/build/openid4vc-holder/OpenId4VciHolderService.js.map +0 -1
- package/build/openid4vc-holder/OpenId4VciHolderServiceOptions.d.ts +0 -238
- package/build/openid4vc-holder/OpenId4VciHolderServiceOptions.js +0 -14
- package/build/openid4vc-holder/OpenId4VciHolderServiceOptions.js.map +0 -1
- package/build/openid4vc-holder/OpenId4vcSiopHolderService.d.ts +0 -32
- package/build/openid4vc-holder/OpenId4vcSiopHolderService.js +0 -302
- package/build/openid4vc-holder/OpenId4vcSiopHolderService.js.map +0 -1
- package/build/openid4vc-holder/OpenId4vcSiopHolderServiceOptions.d.ts +0 -38
- package/build/openid4vc-holder/OpenId4vcSiopHolderServiceOptions.js +0 -3
- package/build/openid4vc-holder/OpenId4vcSiopHolderServiceOptions.js.map +0 -1
- package/build/openid4vc-holder/index.d.ts +0 -6
- package/build/openid4vc-holder/index.js +0 -23
- package/build/openid4vc-holder/index.js.map +0 -1
- package/build/openid4vc-issuer/OpenId4VcIssuanceSessionState.d.ts +0 -12
- package/build/openid4vc-issuer/OpenId4VcIssuanceSessionState.js +0 -19
- package/build/openid4vc-issuer/OpenId4VcIssuanceSessionState.js.map +0 -1
- package/build/openid4vc-issuer/OpenId4VcIssuerApi.d.ts +0 -101
- package/build/openid4vc-issuer/OpenId4VcIssuerApi.js +0 -110
- package/build/openid4vc-issuer/OpenId4VcIssuerApi.js.map +0 -1
- package/build/openid4vc-issuer/OpenId4VcIssuerEvents.d.ts +0 -13
- package/build/openid4vc-issuer/OpenId4VcIssuerEvents.js +0 -8
- package/build/openid4vc-issuer/OpenId4VcIssuerEvents.js.map +0 -1
- package/build/openid4vc-issuer/OpenId4VcIssuerModule.d.ts +0 -21
- package/build/openid4vc-issuer/OpenId4VcIssuerModule.js +0 -121
- package/build/openid4vc-issuer/OpenId4VcIssuerModule.js.map +0 -1
- package/build/openid4vc-issuer/OpenId4VcIssuerModuleConfig.d.ts +0 -190
- package/build/openid4vc-issuer/OpenId4VcIssuerModuleConfig.js +0 -141
- package/build/openid4vc-issuer/OpenId4VcIssuerModuleConfig.js.map +0 -1
- package/build/openid4vc-issuer/OpenId4VcIssuerService.d.ts +0 -116
- package/build/openid4vc-issuer/OpenId4VcIssuerService.js +0 -698
- package/build/openid4vc-issuer/OpenId4VcIssuerService.js.map +0 -1
- package/build/openid4vc-issuer/OpenId4VcIssuerServiceOptions.d.ts +0 -229
- package/build/openid4vc-issuer/OpenId4VcIssuerServiceOptions.js +0 -3
- package/build/openid4vc-issuer/OpenId4VcIssuerServiceOptions.js.map +0 -1
- package/build/openid4vc-issuer/index.d.ts +0 -8
- package/build/openid4vc-issuer/index.js +0 -27
- package/build/openid4vc-issuer/index.js.map +0 -1
- package/build/openid4vc-issuer/repository/OpenId4VcIssuanceSessionRecord.d.ts +0 -160
- package/build/openid4vc-issuer/repository/OpenId4VcIssuanceSessionRecord.js +0 -88
- package/build/openid4vc-issuer/repository/OpenId4VcIssuanceSessionRecord.js.map +0 -1
- package/build/openid4vc-issuer/repository/OpenId4VcIssuanceSessionRepository.d.ts +0 -5
- package/build/openid4vc-issuer/repository/OpenId4VcIssuanceSessionRepository.js +0 -29
- package/build/openid4vc-issuer/repository/OpenId4VcIssuanceSessionRepository.js.map +0 -1
- package/build/openid4vc-issuer/repository/OpenId4VcIssuerRecord.d.ts +0 -56
- package/build/openid4vc-issuer/repository/OpenId4VcIssuerRecord.js +0 -83
- package/build/openid4vc-issuer/repository/OpenId4VcIssuerRecord.js.map +0 -1
- package/build/openid4vc-issuer/repository/OpenId4VcIssuerRepository.d.ts +0 -8
- package/build/openid4vc-issuer/repository/OpenId4VcIssuerRepository.js +0 -35
- package/build/openid4vc-issuer/repository/OpenId4VcIssuerRepository.js.map +0 -1
- package/build/openid4vc-issuer/repository/index.d.ts +0 -4
- package/build/openid4vc-issuer/repository/index.js +0 -21
- package/build/openid4vc-issuer/repository/index.js.map +0 -1
- package/build/openid4vc-issuer/router/accessTokenEndpoint.d.ts +0 -5
- package/build/openid4vc-issuer/router/accessTokenEndpoint.js +0 -164
- package/build/openid4vc-issuer/router/accessTokenEndpoint.js.map +0 -1
- package/build/openid4vc-issuer/router/authorizationChallengeEndpoint.d.ts +0 -3
- package/build/openid4vc-issuer/router/authorizationChallengeEndpoint.js +0 -213
- package/build/openid4vc-issuer/router/authorizationChallengeEndpoint.js.map +0 -1
- package/build/openid4vc-issuer/router/authorizationServerMetadataEndpoint.d.ts +0 -6
- package/build/openid4vc-issuer/router/authorizationServerMetadataEndpoint.js +0 -25
- package/build/openid4vc-issuer/router/authorizationServerMetadataEndpoint.js.map +0 -1
- package/build/openid4vc-issuer/router/credentialEndpoint.d.ts +0 -3
- package/build/openid4vc-issuer/router/credentialEndpoint.js +0 -176
- package/build/openid4vc-issuer/router/credentialEndpoint.js.map +0 -1
- package/build/openid4vc-issuer/router/credentialOfferEndpoint.d.ts +0 -3
- package/build/openid4vc-issuer/router/credentialOfferEndpoint.js +0 -45
- package/build/openid4vc-issuer/router/credentialOfferEndpoint.js.map +0 -1
- package/build/openid4vc-issuer/router/index.d.ts +0 -9
- package/build/openid4vc-issuer/router/index.js +0 -20
- package/build/openid4vc-issuer/router/index.js.map +0 -1
- package/build/openid4vc-issuer/router/issuerMetadataEndpoint.d.ts +0 -2
- package/build/openid4vc-issuer/router/issuerMetadataEndpoint.js +0 -26
- package/build/openid4vc-issuer/router/issuerMetadataEndpoint.js.map +0 -1
- package/build/openid4vc-issuer/router/jwksEndpoint.d.ts +0 -3
- package/build/openid4vc-issuer/router/jwksEndpoint.js +0 -20
- package/build/openid4vc-issuer/router/jwksEndpoint.js.map +0 -1
- package/build/openid4vc-issuer/router/nonceEndpoint.d.ts +0 -3
- package/build/openid4vc-issuer/router/nonceEndpoint.js +0 -26
- package/build/openid4vc-issuer/router/nonceEndpoint.js.map +0 -1
- package/build/openid4vc-issuer/router/requestContext.d.ts +0 -5
- package/build/openid4vc-issuer/router/requestContext.js +0 -3
- package/build/openid4vc-issuer/router/requestContext.js.map +0 -1
- package/build/openid4vc-issuer/util/txCode.d.ts +0 -3
- package/build/openid4vc-issuer/util/txCode.js +0 -18
- package/build/openid4vc-issuer/util/txCode.js.map +0 -1
- package/build/openid4vc-verifier/OpenId4VcSiopVerifierService.d.ts +0 -55
- package/build/openid4vc-verifier/OpenId4VcSiopVerifierService.js +0 -498
- package/build/openid4vc-verifier/OpenId4VcSiopVerifierService.js.map +0 -1
- package/build/openid4vc-verifier/OpenId4VcSiopVerifierServiceOptions.d.ts +0 -77
- package/build/openid4vc-verifier/OpenId4VcSiopVerifierServiceOptions.js +0 -3
- package/build/openid4vc-verifier/OpenId4VcSiopVerifierServiceOptions.js.map +0 -1
- package/build/openid4vc-verifier/OpenId4VcVerificationSessionState.d.ts +0 -6
- package/build/openid4vc-verifier/OpenId4VcVerificationSessionState.js +0 -11
- package/build/openid4vc-verifier/OpenId4VcVerificationSessionState.js.map +0 -1
- package/build/openid4vc-verifier/OpenId4VcVerifierApi.d.ts +0 -61
- package/build/openid4vc-verifier/OpenId4VcVerifierApi.js +0 -108
- package/build/openid4vc-verifier/OpenId4VcVerifierApi.js.map +0 -1
- package/build/openid4vc-verifier/OpenId4VcVerifierEvents.d.ts +0 -13
- package/build/openid4vc-verifier/OpenId4VcVerifierEvents.js +0 -8
- package/build/openid4vc-verifier/OpenId4VcVerifierEvents.js.map +0 -1
- package/build/openid4vc-verifier/OpenId4VcVerifierModule.d.ts +0 -21
- package/build/openid4vc-verifier/OpenId4VcVerifierModule.js +0 -109
- package/build/openid4vc-verifier/OpenId4VcVerifierModule.js.map +0 -1
- package/build/openid4vc-verifier/OpenId4VcVerifierModuleConfig.d.ts +0 -31
- package/build/openid4vc-verifier/OpenId4VcVerifierModuleConfig.js +0 -28
- package/build/openid4vc-verifier/OpenId4VcVerifierModuleConfig.js.map +0 -1
- package/build/openid4vc-verifier/index.d.ts +0 -8
- package/build/openid4vc-verifier/index.js +0 -25
- package/build/openid4vc-verifier/index.js.map +0 -1
- package/build/openid4vc-verifier/repository/OpenId4VcRelyingPartyEventEmitter.d.ts +0 -49
- package/build/openid4vc-verifier/repository/OpenId4VcRelyingPartyEventEmitter.js +0 -234
- package/build/openid4vc-verifier/repository/OpenId4VcRelyingPartyEventEmitter.js.map +0 -1
- package/build/openid4vc-verifier/repository/OpenId4VcRelyingPartySessionManager.d.ts +0 -19
- package/build/openid4vc-verifier/repository/OpenId4VcRelyingPartySessionManager.js +0 -146
- package/build/openid4vc-verifier/repository/OpenId4VcRelyingPartySessionManager.js.map +0 -1
- package/build/openid4vc-verifier/repository/OpenId4VcVerificationSessionRecord.d.ts +0 -71
- package/build/openid4vc-verifier/repository/OpenId4VcVerificationSessionRecord.js +0 -46
- package/build/openid4vc-verifier/repository/OpenId4VcVerificationSessionRecord.js.map +0 -1
- package/build/openid4vc-verifier/repository/OpenId4VcVerificationSessionRepository.d.ts +0 -5
- package/build/openid4vc-verifier/repository/OpenId4VcVerificationSessionRepository.js +0 -29
- package/build/openid4vc-verifier/repository/OpenId4VcVerificationSessionRepository.js.map +0 -1
- package/build/openid4vc-verifier/repository/OpenId4VcVerifierRecord.d.ts +0 -29
- package/build/openid4vc-verifier/repository/OpenId4VcVerifierRecord.js +0 -29
- package/build/openid4vc-verifier/repository/OpenId4VcVerifierRecord.js.map +0 -1
- package/build/openid4vc-verifier/repository/OpenId4VcVerifierRepository.d.ts +0 -8
- package/build/openid4vc-verifier/repository/OpenId4VcVerifierRepository.js +0 -35
- package/build/openid4vc-verifier/repository/OpenId4VcVerifierRepository.js.map +0 -1
- package/build/openid4vc-verifier/repository/index.d.ts +0 -4
- package/build/openid4vc-verifier/repository/index.js +0 -21
- package/build/openid4vc-verifier/repository/index.js.map +0 -1
- package/build/openid4vc-verifier/router/authorizationEndpoint.d.ts +0 -11
- package/build/openid4vc-verifier/router/authorizationEndpoint.js +0 -102
- package/build/openid4vc-verifier/router/authorizationEndpoint.js.map +0 -1
- package/build/openid4vc-verifier/router/authorizationRequestEndpoint.d.ts +0 -11
- package/build/openid4vc-verifier/router/authorizationRequestEndpoint.js +0 -63
- package/build/openid4vc-verifier/router/authorizationRequestEndpoint.js.map +0 -1
- package/build/openid4vc-verifier/router/index.d.ts +0 -2
- package/build/openid4vc-verifier/router/index.js +0 -6
- package/build/openid4vc-verifier/router/index.js.map +0 -1
- package/build/openid4vc-verifier/router/requestContext.d.ts +0 -5
- package/build/openid4vc-verifier/router/requestContext.js +0 -3
- package/build/openid4vc-verifier/router/requestContext.js.map +0 -1
- package/build/shared/callbacks.d.ts +0 -18
- package/build/shared/callbacks.js +0 -81
- package/build/shared/callbacks.js.map +0 -1
- package/build/shared/index.d.ts +0 -2
- package/build/shared/index.js +0 -19
- package/build/shared/index.js.map +0 -1
- package/build/shared/issuerMetadataUtils.d.ts +0 -158
- package/build/shared/issuerMetadataUtils.js +0 -38
- package/build/shared/issuerMetadataUtils.js.map +0 -1
- package/build/shared/models/CredentialHolderBinding.d.ts +0 -13
- package/build/shared/models/CredentialHolderBinding.js +0 -3
- package/build/shared/models/CredentialHolderBinding.js.map +0 -1
- package/build/shared/models/OpenId4VcJwtIssuer.d.ts +0 -28
- package/build/shared/models/OpenId4VcJwtIssuer.js +0 -3
- package/build/shared/models/OpenId4VcJwtIssuer.js.map +0 -1
- package/build/shared/models/OpenId4VciAuthorizationServerConfig.d.ts +0 -10
- package/build/shared/models/OpenId4VciAuthorizationServerConfig.js +0 -3
- package/build/shared/models/OpenId4VciAuthorizationServerConfig.js.map +0 -1
- package/build/shared/models/OpenId4VciCredentialFormatProfile.d.ts +0 -7
- package/build/shared/models/OpenId4VciCredentialFormatProfile.js +0 -12
- package/build/shared/models/OpenId4VciCredentialFormatProfile.js.map +0 -1
- package/build/shared/models/index.d.ts +0 -24
- package/build/shared/models/index.js +0 -25
- package/build/shared/models/index.js.map +0 -1
- package/build/shared/router/context.d.ts +0 -17
- package/build/shared/router/context.js +0 -76
- package/build/shared/router/context.js.map +0 -1
- package/build/shared/router/express.d.ts +0 -2
- package/build/shared/router/express.js +0 -15
- package/build/shared/router/express.js.map +0 -1
- package/build/shared/router/express.native.d.ts +0 -1
- package/build/shared/router/express.native.js +0 -7
- package/build/shared/router/express.native.js.map +0 -1
- package/build/shared/router/index.d.ts +0 -3
- package/build/shared/router/index.js +0 -20
- package/build/shared/router/index.js.map +0 -1
- package/build/shared/router/tenants.d.ts +0 -13
- package/build/shared/router/tenants.js +0 -49
- package/build/shared/router/tenants.js.map +0 -1
- package/build/shared/transform.d.ts +0 -5
- package/build/shared/transform.js +0 -73
- package/build/shared/transform.js.map +0 -1
- package/build/shared/utils.d.ts +0 -22
- package/build/shared/utils.js +0 -154
- package/build/shared/utils.js.map +0 -1
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { getRequestContext, sendErrorResponse, sendJsonResponse, sendNotFoundResponse, sendUnknownServerErrorResponse } from "../../shared/router/context.mjs";
|
|
2
|
+
import "../../shared/router/index.mjs";
|
|
3
|
+
import { OpenId4VcIssuanceSessionState } from "../OpenId4VcIssuanceSessionState.mjs";
|
|
4
|
+
import { OpenId4VcIssuanceSessionRepository } from "../repository/OpenId4VcIssuanceSessionRepository.mjs";
|
|
5
|
+
import "../repository/index.mjs";
|
|
6
|
+
import { OpenId4VcIssuerService } from "../OpenId4VcIssuerService.mjs";
|
|
7
|
+
import { joinUriParts, utils } from "@credo-ts/core";
|
|
8
|
+
|
|
9
|
+
//#region src/openid4vc-issuer/router/credentialOfferEndpoint.ts
|
|
10
|
+
function configureCredentialOfferEndpoint(router, config) {
|
|
11
|
+
router.get(joinUriParts(config.credentialOfferEndpointPath, [":credentialOfferId"]), async (request, response, next) => {
|
|
12
|
+
const { agentContext, issuer } = getRequestContext(request);
|
|
13
|
+
if (!request.params.credentialOfferId || typeof request.params.credentialOfferId !== "string") return sendErrorResponse(response, next, agentContext.config.logger, 400, "invalid_request", "Invalid credential offer url");
|
|
14
|
+
try {
|
|
15
|
+
const issuerService = agentContext.dependencyManager.resolve(OpenId4VcIssuerService);
|
|
16
|
+
const issuerMetadata = await issuerService.getIssuerMetadata(agentContext, issuer);
|
|
17
|
+
const openId4VcIssuanceSessionRepository = agentContext.dependencyManager.resolve(OpenId4VcIssuanceSessionRepository);
|
|
18
|
+
const fullCredentialOfferUri = joinUriParts(issuerMetadata.credentialIssuer.credential_issuer, [config.credentialOfferEndpointPath, request.params.credentialOfferId]);
|
|
19
|
+
const openId4VcIssuanceSession = await openId4VcIssuanceSessionRepository.findSingleByQuery(agentContext, {
|
|
20
|
+
issuerId: issuer.issuerId,
|
|
21
|
+
credentialOfferUri: fullCredentialOfferUri,
|
|
22
|
+
$or: [{ credentialOfferId: request.params.credentialOfferId }, { credentialOfferUri: fullCredentialOfferUri }]
|
|
23
|
+
});
|
|
24
|
+
if (!openId4VcIssuanceSession) return sendNotFoundResponse(response, next, agentContext.config.logger, "Credential offer not found");
|
|
25
|
+
if (openId4VcIssuanceSession.state !== OpenId4VcIssuanceSessionState.OfferCreated && openId4VcIssuanceSession.state !== OpenId4VcIssuanceSessionState.OfferUriRetrieved) return sendNotFoundResponse(response, next, agentContext.config.logger, "Invalid state for credential offer");
|
|
26
|
+
const expiresAt = openId4VcIssuanceSession.expiresAt ?? utils.addSecondsToDate(openId4VcIssuanceSession.createdAt, config.statefulCredentialOfferExpirationInSeconds);
|
|
27
|
+
if (Date.now() > expiresAt.getTime()) return sendNotFoundResponse(response, next, agentContext.config.logger, "Session expired");
|
|
28
|
+
if (openId4VcIssuanceSession.state !== OpenId4VcIssuanceSessionState.OfferUriRetrieved) await issuerService.updateState(agentContext, openId4VcIssuanceSession, OpenId4VcIssuanceSessionState.OfferUriRetrieved);
|
|
29
|
+
return sendJsonResponse(response, next, openId4VcIssuanceSession.credentialOfferPayload);
|
|
30
|
+
} catch (error) {
|
|
31
|
+
return sendUnknownServerErrorResponse(response, next, agentContext.config.logger, error);
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
//#endregion
|
|
37
|
+
export { configureCredentialOfferEndpoint };
|
|
38
|
+
//# sourceMappingURL=credentialOfferEndpoint.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"credentialOfferEndpoint.mjs","names":[],"sources":["../../../src/openid4vc-issuer/router/credentialOfferEndpoint.ts"],"sourcesContent":["import { joinUriParts, utils } from '@credo-ts/core'\nimport type { Response, Router } from 'express'\nimport {\n getRequestContext,\n sendErrorResponse,\n sendJsonResponse,\n sendNotFoundResponse,\n sendUnknownServerErrorResponse,\n} from '../../shared/router'\nimport { OpenId4VcIssuanceSessionState } from '../OpenId4VcIssuanceSessionState'\nimport type { OpenId4VcIssuerModuleConfig } from '../OpenId4VcIssuerModuleConfig'\nimport { OpenId4VcIssuerService } from '../OpenId4VcIssuerService'\nimport { OpenId4VcIssuanceSessionRepository } from '../repository'\nimport type { OpenId4VcIssuanceRequest } from './requestContext'\n\nexport function configureCredentialOfferEndpoint(router: Router, config: OpenId4VcIssuerModuleConfig) {\n router.get(\n joinUriParts(config.credentialOfferEndpointPath, [':credentialOfferId']),\n async (request: OpenId4VcIssuanceRequest, response: Response, next) => {\n const { agentContext, issuer } = getRequestContext(request)\n\n if (!request.params.credentialOfferId || typeof request.params.credentialOfferId !== 'string') {\n return sendErrorResponse(\n response,\n next,\n agentContext.config.logger,\n 400,\n 'invalid_request',\n 'Invalid credential offer url'\n )\n }\n\n try {\n const issuerService = agentContext.dependencyManager.resolve(OpenId4VcIssuerService)\n const issuerMetadata = await issuerService.getIssuerMetadata(agentContext, issuer)\n const openId4VcIssuanceSessionRepository = agentContext.dependencyManager.resolve(\n OpenId4VcIssuanceSessionRepository\n )\n\n const fullCredentialOfferUri = joinUriParts(issuerMetadata.credentialIssuer.credential_issuer, [\n config.credentialOfferEndpointPath,\n request.params.credentialOfferId,\n ])\n\n const openId4VcIssuanceSession = await openId4VcIssuanceSessionRepository.findSingleByQuery(agentContext, {\n issuerId: issuer.issuerId,\n credentialOfferUri: fullCredentialOfferUri,\n $or: [\n {\n credentialOfferId: request.params.credentialOfferId,\n },\n // NOTE: this can soon be removed, credential offer id is cleaner,\n // but only introduced since 0.6\n {\n credentialOfferUri: fullCredentialOfferUri,\n },\n ],\n })\n if (!openId4VcIssuanceSession) {\n return sendNotFoundResponse(response, next, agentContext.config.logger, 'Credential offer not found')\n }\n\n if (\n openId4VcIssuanceSession.state !== OpenId4VcIssuanceSessionState.OfferCreated &&\n openId4VcIssuanceSession.state !== OpenId4VcIssuanceSessionState.OfferUriRetrieved\n ) {\n return sendNotFoundResponse(response, next, agentContext.config.logger, 'Invalid state for credential offer')\n }\n\n const expiresAt =\n openId4VcIssuanceSession.expiresAt ??\n utils.addSecondsToDate(openId4VcIssuanceSession.createdAt, config.statefulCredentialOfferExpirationInSeconds)\n\n if (Date.now() > expiresAt.getTime()) {\n return sendNotFoundResponse(response, next, agentContext.config.logger, 'Session expired')\n }\n\n // It's okay to retrieve the offer multiple times. So we only update the state if it's not already retrieved\n if (openId4VcIssuanceSession.state !== OpenId4VcIssuanceSessionState.OfferUriRetrieved) {\n await issuerService.updateState(\n agentContext,\n openId4VcIssuanceSession,\n OpenId4VcIssuanceSessionState.OfferUriRetrieved\n )\n }\n\n return sendJsonResponse(response, next, openId4VcIssuanceSession.credentialOfferPayload)\n } catch (error) {\n return sendUnknownServerErrorResponse(response, next, agentContext.config.logger, error)\n }\n }\n )\n}\n"],"mappings":";;;;;;;;;AAeA,SAAgB,iCAAiC,QAAgB,QAAqC;AACpG,QAAO,IACL,aAAa,OAAO,6BAA6B,CAAC,qBAAqB,CAAC,EACxE,OAAO,SAAmC,UAAoB,SAAS;EACrE,MAAM,EAAE,cAAc,WAAW,kBAAkB,QAAQ;AAE3D,MAAI,CAAC,QAAQ,OAAO,qBAAqB,OAAO,QAAQ,OAAO,sBAAsB,SACnF,QAAO,kBACL,UACA,MACA,aAAa,OAAO,QACpB,KACA,mBACA,+BACD;AAGH,MAAI;GACF,MAAM,gBAAgB,aAAa,kBAAkB,QAAQ,uBAAuB;GACpF,MAAM,iBAAiB,MAAM,cAAc,kBAAkB,cAAc,OAAO;GAClF,MAAM,qCAAqC,aAAa,kBAAkB,QACxE,mCACD;GAED,MAAM,yBAAyB,aAAa,eAAe,iBAAiB,mBAAmB,CAC7F,OAAO,6BACP,QAAQ,OAAO,kBAChB,CAAC;GAEF,MAAM,2BAA2B,MAAM,mCAAmC,kBAAkB,cAAc;IACxG,UAAU,OAAO;IACjB,oBAAoB;IACpB,KAAK,CACH,EACE,mBAAmB,QAAQ,OAAO,mBACnC,EAGD,EACE,oBAAoB,wBACrB,CACF;IACF,CAAC;AACF,OAAI,CAAC,yBACH,QAAO,qBAAqB,UAAU,MAAM,aAAa,OAAO,QAAQ,6BAA6B;AAGvG,OACE,yBAAyB,UAAU,8BAA8B,gBACjE,yBAAyB,UAAU,8BAA8B,kBAEjE,QAAO,qBAAqB,UAAU,MAAM,aAAa,OAAO,QAAQ,qCAAqC;GAG/G,MAAM,YACJ,yBAAyB,aACzB,MAAM,iBAAiB,yBAAyB,WAAW,OAAO,2CAA2C;AAE/G,OAAI,KAAK,KAAK,GAAG,UAAU,SAAS,CAClC,QAAO,qBAAqB,UAAU,MAAM,aAAa,OAAO,QAAQ,kBAAkB;AAI5F,OAAI,yBAAyB,UAAU,8BAA8B,kBACnE,OAAM,cAAc,YAClB,cACA,0BACA,8BAA8B,kBAC/B;AAGH,UAAO,iBAAiB,UAAU,MAAM,yBAAyB,uBAAuB;WACjF,OAAO;AACd,UAAO,+BAA+B,UAAU,MAAM,aAAa,OAAO,QAAQ,MAAM;;GAG7F"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { getRequestContext, sendJsonResponse, sendOauth2ErrorResponse, sendUnauthorizedError, sendUnknownServerErrorResponse } from "../../shared/router/context.mjs";
|
|
2
|
+
import "../../shared/router/index.mjs";
|
|
3
|
+
import { OpenId4VcIssuanceSessionState } from "../OpenId4VcIssuanceSessionState.mjs";
|
|
4
|
+
import { OpenId4VcIssuanceSessionRepository } from "../repository/OpenId4VcIssuanceSessionRepository.mjs";
|
|
5
|
+
import "../repository/index.mjs";
|
|
6
|
+
import { OpenId4VcIssuerService } from "../OpenId4VcIssuerService.mjs";
|
|
7
|
+
import { joinUriParts, utils } from "@credo-ts/core";
|
|
8
|
+
import { Oauth2ErrorCodes, Oauth2ResourceUnauthorizedError, Oauth2ServerErrorResponseError } from "@openid4vc/oauth2";
|
|
9
|
+
|
|
10
|
+
//#region src/openid4vc-issuer/router/deferredCredentialEndpoint.ts
|
|
11
|
+
function configureDeferredCredentialEndpoint(router, config) {
|
|
12
|
+
router.post(config.deferredCredentialEndpointPath, async (request, response, next) => {
|
|
13
|
+
const { agentContext, issuer } = getRequestContext(request);
|
|
14
|
+
const openId4VcIssuerService = agentContext.dependencyManager.resolve(OpenId4VcIssuerService);
|
|
15
|
+
const issuerMetadata = await openId4VcIssuerService.getIssuerMetadata(agentContext, issuer, true);
|
|
16
|
+
const vcIssuer = openId4VcIssuerService.getIssuer(agentContext);
|
|
17
|
+
const resourceServer = openId4VcIssuerService.getResourceServer(agentContext, issuer);
|
|
18
|
+
const fullRequestUrl = joinUriParts(issuerMetadata.credentialIssuer.credential_issuer, [config.deferredCredentialEndpointPath]);
|
|
19
|
+
const resourceRequestResult = await resourceServer.verifyResourceRequest({
|
|
20
|
+
authorizationServers: issuerMetadata.authorizationServers,
|
|
21
|
+
resourceServer: issuerMetadata.credentialIssuer.credential_issuer,
|
|
22
|
+
request: {
|
|
23
|
+
headers: new Headers(request.headers),
|
|
24
|
+
method: request.method,
|
|
25
|
+
url: fullRequestUrl
|
|
26
|
+
}
|
|
27
|
+
}).catch((error) => {
|
|
28
|
+
sendUnauthorizedError(response, next, agentContext.config.logger, error);
|
|
29
|
+
});
|
|
30
|
+
if (!resourceRequestResult) return;
|
|
31
|
+
const { tokenPayload, accessToken, scheme, authorizationServer } = resourceRequestResult;
|
|
32
|
+
const deferredCredentialRequest = request.body;
|
|
33
|
+
const issuanceSessionRepository = agentContext.dependencyManager.resolve(OpenId4VcIssuanceSessionRepository);
|
|
34
|
+
const parsedCredentialRequest = vcIssuer.parseDeferredCredentialRequest({ deferredCredentialRequest });
|
|
35
|
+
const preAuthorizedCode = typeof tokenPayload["pre-authorized_code"] === "string" ? tokenPayload["pre-authorized_code"] : void 0;
|
|
36
|
+
const issuerState = typeof tokenPayload.issuer_state === "string" ? tokenPayload.issuer_state : void 0;
|
|
37
|
+
if (!tokenPayload.sub) return sendOauth2ErrorResponse(response, next, agentContext.config.logger, new Oauth2ServerErrorResponseError({ error: Oauth2ErrorCodes.ServerError }, { internalMessage: `Received token without 'sub' claim. Subject is required for binding issuance session` }));
|
|
38
|
+
if (!issuerState && !preAuthorizedCode) return sendOauth2ErrorResponse(response, next, agentContext.config.logger, new Oauth2ServerErrorResponseError({ error: Oauth2ErrorCodes.InvalidRequest }, { internalMessage: `Received deferred credential request without 'pre-authorized_code' or 'issuer_state' claim. At least one of these claims is required to identify the issuance session` }));
|
|
39
|
+
const issuanceSession = await issuanceSessionRepository.findSingleByQuery(agentContext, {
|
|
40
|
+
preAuthorizedCode,
|
|
41
|
+
issuerState
|
|
42
|
+
});
|
|
43
|
+
if (!issuanceSession || !issuanceSession.transactions?.find((tx) => tx.transactionId === parsedCredentialRequest.deferredCredentialRequest.transaction_id)) {
|
|
44
|
+
agentContext.config.logger.warn(`No issuance session found for incoming deferred credential request for issuer ${issuer.issuerId} but access token data has ${issuerState ? "issuer_state" : "pre-authorized_code"}. Returning error response`, { tokenPayload });
|
|
45
|
+
return sendOauth2ErrorResponse(response, next, agentContext.config.logger, new Oauth2ServerErrorResponseError({ error: Oauth2ErrorCodes.InvalidTransactionId }, { internalMessage: `No issuance session found for incoming credential request for issuer ${issuer.issuerId}, access token data and transaction id` }));
|
|
46
|
+
}
|
|
47
|
+
if (issuanceSession.dpop?.required && !resourceRequestResult.dpop) return sendUnauthorizedError(response, next, agentContext.config.logger, new Oauth2ResourceUnauthorizedError("Missing required DPoP proof", {
|
|
48
|
+
scheme,
|
|
49
|
+
error: Oauth2ErrorCodes.InvalidDpopProof
|
|
50
|
+
}));
|
|
51
|
+
if (issuanceSession.authorization?.subject && issuanceSession.authorization.subject !== tokenPayload.sub) return sendOauth2ErrorResponse(response, next, agentContext.config.logger, new Oauth2ServerErrorResponseError({ error: Oauth2ErrorCodes.CredentialRequestDenied }, { internalMessage: `Issuance session authorization subject does not match with the token payload subject for issuance session '${issuanceSession.id}'. Returning error response` }));
|
|
52
|
+
const expiresAt = issuanceSession.expiresAt ?? utils.addSecondsToDate(issuanceSession.createdAt, config.statefulCredentialOfferExpirationInSeconds);
|
|
53
|
+
if (Date.now() > expiresAt.getTime()) {
|
|
54
|
+
issuanceSession.errorMessage = "Credential offer has expired";
|
|
55
|
+
await openId4VcIssuerService.updateState(agentContext, issuanceSession, OpenId4VcIssuanceSessionState.Error);
|
|
56
|
+
return sendOauth2ErrorResponse(response, next, agentContext.config.logger, new Oauth2ServerErrorResponseError({
|
|
57
|
+
error: Oauth2ErrorCodes.CredentialRequestDenied,
|
|
58
|
+
error_description: "Session expired"
|
|
59
|
+
}));
|
|
60
|
+
}
|
|
61
|
+
try {
|
|
62
|
+
const { deferredCredentialResponse } = await openId4VcIssuerService.createDeferredCredentialResponse(agentContext, {
|
|
63
|
+
issuanceSession,
|
|
64
|
+
deferredCredentialRequest: parsedCredentialRequest.deferredCredentialRequest,
|
|
65
|
+
authorization: {
|
|
66
|
+
authorizationServer,
|
|
67
|
+
accessToken: {
|
|
68
|
+
payload: tokenPayload,
|
|
69
|
+
value: accessToken
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
return sendJsonResponse(response, next, deferredCredentialResponse, void 0, deferredCredentialResponse.interval ? 202 : 200);
|
|
74
|
+
} catch (error) {
|
|
75
|
+
if (error instanceof Oauth2ServerErrorResponseError) return sendOauth2ErrorResponse(response, next, agentContext.config.logger, error);
|
|
76
|
+
if (error instanceof Oauth2ResourceUnauthorizedError) return sendUnauthorizedError(response, next, agentContext.config.logger, error);
|
|
77
|
+
return sendUnknownServerErrorResponse(response, next, agentContext.config.logger, error);
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
//#endregion
|
|
83
|
+
export { configureDeferredCredentialEndpoint };
|
|
84
|
+
//# sourceMappingURL=deferredCredentialEndpoint.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deferredCredentialEndpoint.mjs","names":[],"sources":["../../../src/openid4vc-issuer/router/deferredCredentialEndpoint.ts"],"sourcesContent":["import { joinUriParts, utils } from '@credo-ts/core'\nimport type { HttpMethod } from '@openid4vc/oauth2'\nimport { Oauth2ErrorCodes, Oauth2ResourceUnauthorizedError, Oauth2ServerErrorResponseError } from '@openid4vc/oauth2'\nimport type { Response, Router } from 'express'\nimport {\n getRequestContext,\n sendJsonResponse,\n sendOauth2ErrorResponse,\n sendUnauthorizedError,\n sendUnknownServerErrorResponse,\n} from '../../shared/router'\nimport { OpenId4VcIssuanceSessionState } from '../OpenId4VcIssuanceSessionState'\nimport type { OpenId4VcIssuerModuleConfig } from '../OpenId4VcIssuerModuleConfig'\nimport { OpenId4VcIssuerService } from '../OpenId4VcIssuerService'\nimport { OpenId4VcIssuanceSessionRepository } from '../repository'\nimport type { OpenId4VcIssuanceRequest } from './requestContext'\n\nexport function configureDeferredCredentialEndpoint(router: Router, config: OpenId4VcIssuerModuleConfig) {\n router.post(\n config.deferredCredentialEndpointPath,\n async (request: OpenId4VcIssuanceRequest, response: Response, next) => {\n const { agentContext, issuer } = getRequestContext(request)\n const openId4VcIssuerService = agentContext.dependencyManager.resolve(OpenId4VcIssuerService)\n const issuerMetadata = await openId4VcIssuerService.getIssuerMetadata(agentContext, issuer, true)\n const vcIssuer = openId4VcIssuerService.getIssuer(agentContext)\n const resourceServer = openId4VcIssuerService.getResourceServer(agentContext, issuer)\n\n const fullRequestUrl = joinUriParts(issuerMetadata.credentialIssuer.credential_issuer, [\n config.deferredCredentialEndpointPath,\n ])\n\n const resourceRequestResult = await resourceServer\n .verifyResourceRequest({\n authorizationServers: issuerMetadata.authorizationServers,\n resourceServer: issuerMetadata.credentialIssuer.credential_issuer,\n request: {\n headers: new Headers(request.headers as Record<string, string>),\n method: request.method as HttpMethod,\n url: fullRequestUrl,\n },\n })\n .catch((error) => {\n sendUnauthorizedError(response, next, agentContext.config.logger, error)\n })\n\n if (!resourceRequestResult) return\n const { tokenPayload, accessToken, scheme, authorizationServer } = resourceRequestResult\n\n const deferredCredentialRequest = request.body\n const issuanceSessionRepository = agentContext.dependencyManager.resolve(OpenId4VcIssuanceSessionRepository)\n\n const parsedCredentialRequest = vcIssuer.parseDeferredCredentialRequest({\n deferredCredentialRequest,\n })\n\n const preAuthorizedCode =\n typeof tokenPayload['pre-authorized_code'] === 'string' ? tokenPayload['pre-authorized_code'] : undefined\n const issuerState = typeof tokenPayload.issuer_state === 'string' ? tokenPayload.issuer_state : undefined\n\n const subject = tokenPayload.sub\n if (!subject) {\n return sendOauth2ErrorResponse(\n response,\n next,\n agentContext.config.logger,\n new Oauth2ServerErrorResponseError(\n {\n error: Oauth2ErrorCodes.ServerError,\n },\n {\n internalMessage: `Received token without 'sub' claim. Subject is required for binding issuance session`,\n }\n )\n )\n }\n\n if (!issuerState && !preAuthorizedCode) {\n return sendOauth2ErrorResponse(\n response,\n next,\n agentContext.config.logger,\n new Oauth2ServerErrorResponseError(\n {\n error: Oauth2ErrorCodes.InvalidRequest,\n },\n {\n internalMessage: `Received deferred credential request without 'pre-authorized_code' or 'issuer_state' claim. At least one of these claims is required to identify the issuance session`,\n }\n )\n )\n }\n\n const issuanceSession = await issuanceSessionRepository.findSingleByQuery(agentContext, {\n preAuthorizedCode,\n issuerState,\n })\n\n if (\n !issuanceSession ||\n !issuanceSession.transactions?.find(\n (tx) => tx.transactionId === parsedCredentialRequest.deferredCredentialRequest.transaction_id\n )\n ) {\n agentContext.config.logger.warn(\n `No issuance session found for incoming deferred credential request for issuer ${\n issuer.issuerId\n } but access token data has ${\n issuerState ? 'issuer_state' : 'pre-authorized_code'\n }. Returning error response`,\n {\n tokenPayload,\n }\n )\n\n return sendOauth2ErrorResponse(\n response,\n next,\n agentContext.config.logger,\n new Oauth2ServerErrorResponseError(\n {\n error: Oauth2ErrorCodes.InvalidTransactionId,\n },\n {\n internalMessage: `No issuance session found for incoming credential request for issuer ${issuer.issuerId}, access token data and transaction id`,\n }\n )\n )\n }\n\n // Use issuance session dpop config\n if (issuanceSession.dpop?.required && !resourceRequestResult.dpop) {\n return sendUnauthorizedError(\n response,\n next,\n agentContext.config.logger,\n new Oauth2ResourceUnauthorizedError('Missing required DPoP proof', {\n scheme,\n error: Oauth2ErrorCodes.InvalidDpopProof,\n })\n )\n }\n\n // Verify the issuance session subject\n if (issuanceSession.authorization?.subject && issuanceSession.authorization.subject !== tokenPayload.sub) {\n return sendOauth2ErrorResponse(\n response,\n next,\n agentContext.config.logger,\n new Oauth2ServerErrorResponseError(\n {\n error: Oauth2ErrorCodes.CredentialRequestDenied,\n },\n {\n internalMessage: `Issuance session authorization subject does not match with the token payload subject for issuance session '${issuanceSession.id}'. Returning error response`,\n }\n )\n )\n }\n\n const expiresAt =\n issuanceSession.expiresAt ??\n utils.addSecondsToDate(issuanceSession.createdAt, config.statefulCredentialOfferExpirationInSeconds)\n\n if (Date.now() > expiresAt.getTime()) {\n issuanceSession.errorMessage = 'Credential offer has expired'\n await openId4VcIssuerService.updateState(agentContext, issuanceSession, OpenId4VcIssuanceSessionState.Error)\n return sendOauth2ErrorResponse(\n response,\n next,\n agentContext.config.logger,\n new Oauth2ServerErrorResponseError({\n // What is the best error here?\n error: Oauth2ErrorCodes.CredentialRequestDenied,\n error_description: 'Session expired',\n })\n )\n }\n\n try {\n const { deferredCredentialResponse } = await openId4VcIssuerService.createDeferredCredentialResponse(\n agentContext,\n {\n issuanceSession,\n deferredCredentialRequest: parsedCredentialRequest.deferredCredentialRequest,\n authorization: {\n authorizationServer,\n accessToken: {\n payload: tokenPayload,\n value: accessToken,\n },\n },\n }\n )\n\n return sendJsonResponse(\n response,\n next,\n deferredCredentialResponse,\n undefined,\n deferredCredentialResponse.interval ? 202 : 200\n )\n } catch (error) {\n if (error instanceof Oauth2ServerErrorResponseError) {\n return sendOauth2ErrorResponse(response, next, agentContext.config.logger, error)\n }\n if (error instanceof Oauth2ResourceUnauthorizedError) {\n return sendUnauthorizedError(response, next, agentContext.config.logger, error)\n }\n\n return sendUnknownServerErrorResponse(response, next, agentContext.config.logger, error)\n }\n }\n )\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { configureAccessTokenEndpoint } from "./accessTokenEndpoint.mjs";
|
|
2
|
+
import { configurePushedAuthorizationRequestEndpoint } from "./pushedAuthorizationRequestEndpoint.mjs";
|
|
3
|
+
import { configureAuthorizationChallengeEndpoint } from "./authorizationChallengeEndpoint.mjs";
|
|
4
|
+
import { configureAuthorizationEndpoint } from "./authorizationEndpoint.mjs";
|
|
5
|
+
import { configureOAuthAuthorizationServerMetadataEndpoint } from "./authorizationServerMetadataEndpoint.mjs";
|
|
6
|
+
import { configureCredentialEndpoint } from "./credentialEndpoint.mjs";
|
|
7
|
+
import { configureCredentialOfferEndpoint } from "./credentialOfferEndpoint.mjs";
|
|
8
|
+
import { configureDeferredCredentialEndpoint } from "./deferredCredentialEndpoint.mjs";
|
|
9
|
+
import { configureIssuerMetadataEndpoint } from "./issuerMetadataEndpoint.mjs";
|
|
10
|
+
import { configureJwksEndpoint } from "./jwksEndpoint.mjs";
|
|
11
|
+
import { configureNonceEndpoint } from "./nonceEndpoint.mjs";
|
|
12
|
+
import { configureRedirectEndpoint } from "./redirectEndpoint.mjs";
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { getRequestContext, sendJsonResponse, sendUnknownServerErrorResponse } from "../../shared/router/context.mjs";
|
|
2
|
+
import "../../shared/router/index.mjs";
|
|
3
|
+
import { OpenId4VcIssuerService } from "../OpenId4VcIssuerService.mjs";
|
|
4
|
+
import { getAuthorizationServerMetadataFromList } from "@openid4vc/oauth2";
|
|
5
|
+
|
|
6
|
+
//#region src/openid4vc-issuer/router/issuerMetadataEndpoint.ts
|
|
7
|
+
function configureIssuerMetadataEndpoint(router, path) {
|
|
8
|
+
router.get(path, async (request, response, next) => {
|
|
9
|
+
const { agentContext, issuer } = getRequestContext(request);
|
|
10
|
+
try {
|
|
11
|
+
const openId4VcIssuerService = agentContext.dependencyManager.resolve(OpenId4VcIssuerService);
|
|
12
|
+
const issuerMetadata = await openId4VcIssuerService.getIssuerMetadata(agentContext, issuer);
|
|
13
|
+
const vcIssuer = openId4VcIssuerService.getIssuer(agentContext);
|
|
14
|
+
const issuerAuthorizationServer = getAuthorizationServerMetadataFromList(issuerMetadata.authorizationServers, issuerMetadata.credentialIssuer.credential_issuer);
|
|
15
|
+
const mediaTypeToUse = (request.headers.accept ? parseAcceptHeader(request.headers.accept) : []).find(({ mediaType }) => mediaType === "application/json" || issuerMetadata.signedMetadataJwt && mediaType === "application/jwt")?.mediaType ?? "application/json";
|
|
16
|
+
const transformedMetadata = {
|
|
17
|
+
...vcIssuer.getCredentialIssuerMetadataDraft11(issuerMetadata.credentialIssuer),
|
|
18
|
+
token_endpoint: issuerAuthorizationServer.token_endpoint,
|
|
19
|
+
dpop_signing_alg_values_supported: issuerAuthorizationServer.dpop_signing_alg_values_supported
|
|
20
|
+
};
|
|
21
|
+
if (issuerMetadata.signedMetadataJwt && mediaTypeToUse === "application/jwt") response.type("application/jwt").status(200).send(issuerMetadata.signedMetadataJwt);
|
|
22
|
+
else return sendJsonResponse(response, next, transformedMetadata);
|
|
23
|
+
} catch (e) {
|
|
24
|
+
return sendUnknownServerErrorResponse(response, next, agentContext.config.logger, e);
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
function parseAcceptHeader(header) {
|
|
29
|
+
return header.split(",").map((type) => {
|
|
30
|
+
const [mediaType, ...params] = type.trim().split(";");
|
|
31
|
+
let quality = 1;
|
|
32
|
+
const qParam = params.find((p) => p.trim().startsWith("q="));
|
|
33
|
+
if (qParam) quality = parseFloat(qParam.split("=")[1]) || 1;
|
|
34
|
+
return {
|
|
35
|
+
mediaType: mediaType.trim(),
|
|
36
|
+
quality
|
|
37
|
+
};
|
|
38
|
+
}).sort((a, b) => b.quality - a.quality);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
//#endregion
|
|
42
|
+
export { configureIssuerMetadataEndpoint };
|
|
43
|
+
//# sourceMappingURL=issuerMetadataEndpoint.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"issuerMetadataEndpoint.mjs","names":[],"sources":["../../../src/openid4vc-issuer/router/issuerMetadataEndpoint.ts"],"sourcesContent":["import { getAuthorizationServerMetadataFromList } from '@openid4vc/oauth2'\nimport type { Response, Router } from 'express'\nimport type { OpenId4VciCredentialIssuerMetadata } from '../../shared'\nimport { getRequestContext, sendJsonResponse, sendUnknownServerErrorResponse } from '../../shared/router'\nimport { OpenId4VcIssuerService } from '../OpenId4VcIssuerService'\nimport type { OpenId4VcIssuanceRequest } from './requestContext'\n\nexport function configureIssuerMetadataEndpoint(router: Router, path: string) {\n router.get(path, async (request: OpenId4VcIssuanceRequest, response: Response, next) => {\n const { agentContext, issuer } = getRequestContext(request)\n try {\n const openId4VcIssuerService = agentContext.dependencyManager.resolve(OpenId4VcIssuerService)\n const issuerMetadata = await openId4VcIssuerService.getIssuerMetadata(agentContext, issuer)\n const vcIssuer = openId4VcIssuerService.getIssuer(agentContext)\n const issuerAuthorizationServer = getAuthorizationServerMetadataFromList(\n issuerMetadata.authorizationServers,\n issuerMetadata.credentialIssuer.credential_issuer\n )\n\n // NOTE: for now we default to unsigned if the wallet doesn't explicitly indicate it supports signed\n const acceptedMediaTypes = request.headers.accept ? parseAcceptHeader(request.headers.accept) : []\n\n const mediaTypeToUse =\n acceptedMediaTypes.find(\n ({ mediaType }) =>\n mediaType === 'application/json' || (issuerMetadata.signedMetadataJwt && mediaType === 'application/jwt')\n )?.mediaType ?? 'application/json'\n\n const transformedMetadata = {\n // Get the draft 11 metadata (it also contains draft 14)\n ...vcIssuer.getCredentialIssuerMetadataDraft11(issuerMetadata.credentialIssuer),\n\n // TODO: these values should be removed, as they need to be hosted in the oauth-authorization-server\n // metadata. For backwards compatibility we will keep them in now.\n token_endpoint: issuerAuthorizationServer.token_endpoint,\n dpop_signing_alg_values_supported: issuerAuthorizationServer.dpop_signing_alg_values_supported,\n } satisfies OpenId4VciCredentialIssuerMetadata\n\n if (issuerMetadata.signedMetadataJwt && mediaTypeToUse === 'application/jwt') {\n response.type('application/jwt').status(200).send(issuerMetadata.signedMetadataJwt)\n } else {\n return sendJsonResponse(response, next, transformedMetadata)\n }\n } catch (e) {\n return sendUnknownServerErrorResponse(response, next, agentContext.config.logger, e)\n }\n })\n}\n\nfunction parseAcceptHeader(header: string) {\n return header\n .split(',')\n .map((type) => {\n const [mediaType, ...params] = type.trim().split(';')\n let quality = 1\n\n // Extract quality value if present\n const qParam = params.find((p) => p.trim().startsWith('q='))\n if (qParam) {\n quality = parseFloat(qParam.split('=')[1]) || 1.0\n }\n\n return {\n mediaType: mediaType.trim(),\n quality: quality,\n }\n })\n .sort((a, b) => b.quality - a.quality) // Sort by preference\n}\n"],"mappings":";;;;;;AAOA,SAAgB,gCAAgC,QAAgB,MAAc;AAC5E,QAAO,IAAI,MAAM,OAAO,SAAmC,UAAoB,SAAS;EACtF,MAAM,EAAE,cAAc,WAAW,kBAAkB,QAAQ;AAC3D,MAAI;GACF,MAAM,yBAAyB,aAAa,kBAAkB,QAAQ,uBAAuB;GAC7F,MAAM,iBAAiB,MAAM,uBAAuB,kBAAkB,cAAc,OAAO;GAC3F,MAAM,WAAW,uBAAuB,UAAU,aAAa;GAC/D,MAAM,4BAA4B,uCAChC,eAAe,sBACf,eAAe,iBAAiB,kBACjC;GAKD,MAAM,kBAFqB,QAAQ,QAAQ,SAAS,kBAAkB,QAAQ,QAAQ,OAAO,GAAG,EAAE,EAG7E,MAChB,EAAE,gBACD,cAAc,sBAAuB,eAAe,qBAAqB,cAAc,kBAC1F,EAAE,aAAa;GAElB,MAAM,sBAAsB;IAE1B,GAAG,SAAS,mCAAmC,eAAe,iBAAiB;IAI/E,gBAAgB,0BAA0B;IAC1C,mCAAmC,0BAA0B;IAC9D;AAED,OAAI,eAAe,qBAAqB,mBAAmB,kBACzD,UAAS,KAAK,kBAAkB,CAAC,OAAO,IAAI,CAAC,KAAK,eAAe,kBAAkB;OAEnF,QAAO,iBAAiB,UAAU,MAAM,oBAAoB;WAEvD,GAAG;AACV,UAAO,+BAA+B,UAAU,MAAM,aAAa,OAAO,QAAQ,EAAE;;GAEtF;;AAGJ,SAAS,kBAAkB,QAAgB;AACzC,QAAO,OACJ,MAAM,IAAI,CACV,KAAK,SAAS;EACb,MAAM,CAAC,WAAW,GAAG,UAAU,KAAK,MAAM,CAAC,MAAM,IAAI;EACrD,IAAI,UAAU;EAGd,MAAM,SAAS,OAAO,MAAM,MAAM,EAAE,MAAM,CAAC,WAAW,KAAK,CAAC;AAC5D,MAAI,OACF,WAAU,WAAW,OAAO,MAAM,IAAI,CAAC,GAAG,IAAI;AAGhD,SAAO;GACL,WAAW,UAAU,MAAM;GAClB;GACV;GACD,CACD,MAAM,GAAG,MAAM,EAAE,UAAU,EAAE,QAAQ"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { getRequestContext, sendJsonResponse, sendUnknownServerErrorResponse } from "../../shared/router/context.mjs";
|
|
2
|
+
import "../../shared/router/index.mjs";
|
|
3
|
+
|
|
4
|
+
//#region src/openid4vc-issuer/router/jwksEndpoint.ts
|
|
5
|
+
function configureJwksEndpoint(router, config) {
|
|
6
|
+
router.get(config.jwksEndpointPath, async (_request, response, next) => {
|
|
7
|
+
const { agentContext, issuer } = getRequestContext(_request);
|
|
8
|
+
try {
|
|
9
|
+
return sendJsonResponse(response, next, { keys: [issuer.resolvedAccessTokenPublicJwk.toJson({ includeKid: false })] }, "application/jwk-set+json");
|
|
10
|
+
} catch (e) {
|
|
11
|
+
return sendUnknownServerErrorResponse(response, next, agentContext.config.logger, e);
|
|
12
|
+
}
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
//#endregion
|
|
17
|
+
export { configureJwksEndpoint };
|
|
18
|
+
//# sourceMappingURL=jwksEndpoint.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jwksEndpoint.mjs","names":[],"sources":["../../../src/openid4vc-issuer/router/jwksEndpoint.ts"],"sourcesContent":["import type { Jwk, JwkSet } from '@openid4vc/oauth2'\nimport type { Response, Router } from 'express'\nimport { getRequestContext, sendJsonResponse, sendUnknownServerErrorResponse } from '../../shared/router'\nimport type { OpenId4VcIssuerModuleConfig } from '../OpenId4VcIssuerModuleConfig'\nimport type { OpenId4VcIssuanceRequest } from './requestContext'\n\nexport function configureJwksEndpoint(router: Router, config: OpenId4VcIssuerModuleConfig) {\n router.get(config.jwksEndpointPath, async (_request: OpenId4VcIssuanceRequest, response: Response, next) => {\n const { agentContext, issuer } = getRequestContext(_request)\n try {\n const jwks = {\n // Not needed to include kid in public facing JWKs\n keys: [issuer.resolvedAccessTokenPublicJwk.toJson({ includeKid: false }) as Jwk],\n } satisfies JwkSet\n\n return sendJsonResponse(response, next, jwks, 'application/jwk-set+json')\n } catch (e) {\n return sendUnknownServerErrorResponse(response, next, agentContext.config.logger, e)\n }\n })\n}\n"],"mappings":";;;;AAMA,SAAgB,sBAAsB,QAAgB,QAAqC;AACzF,QAAO,IAAI,OAAO,kBAAkB,OAAO,UAAoC,UAAoB,SAAS;EAC1G,MAAM,EAAE,cAAc,WAAW,kBAAkB,SAAS;AAC5D,MAAI;AAMF,UAAO,iBAAiB,UAAU,MALrB,EAEX,MAAM,CAAC,OAAO,6BAA6B,OAAO,EAAE,YAAY,OAAO,CAAC,CAAQ,EACjF,EAE6C,2BAA2B;WAClE,GAAG;AACV,UAAO,+BAA+B,UAAU,MAAM,aAAa,OAAO,QAAQ,EAAE;;GAEtF"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { getRequestContext, sendJsonResponse, sendUnknownServerErrorResponse } from "../../shared/router/context.mjs";
|
|
2
|
+
import "../../shared/router/index.mjs";
|
|
3
|
+
import { OpenId4VcIssuerService } from "../OpenId4VcIssuerService.mjs";
|
|
4
|
+
|
|
5
|
+
//#region src/openid4vc-issuer/router/nonceEndpoint.ts
|
|
6
|
+
function configureNonceEndpoint(router, config) {
|
|
7
|
+
router.post(config.nonceEndpointPath, async (request, response, next) => {
|
|
8
|
+
response.set({
|
|
9
|
+
"Cache-Control": "no-store",
|
|
10
|
+
Pragma: "no-cache"
|
|
11
|
+
});
|
|
12
|
+
const { agentContext, issuer } = getRequestContext(request);
|
|
13
|
+
try {
|
|
14
|
+
const openId4VcIssuerService = agentContext.dependencyManager.resolve(OpenId4VcIssuerService);
|
|
15
|
+
const vcIssuer = openId4VcIssuerService.getIssuer(agentContext);
|
|
16
|
+
const { cNonce, cNonceExpiresInSeconds } = await openId4VcIssuerService.createNonce(agentContext, issuer);
|
|
17
|
+
return sendJsonResponse(response, next, vcIssuer.createNonceResponse({
|
|
18
|
+
cNonce,
|
|
19
|
+
cNonceExpiresIn: cNonceExpiresInSeconds
|
|
20
|
+
}));
|
|
21
|
+
} catch (error) {
|
|
22
|
+
return sendUnknownServerErrorResponse(response, next, agentContext.config.logger, error);
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
//#endregion
|
|
28
|
+
export { configureNonceEndpoint };
|
|
29
|
+
//# sourceMappingURL=nonceEndpoint.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nonceEndpoint.mjs","names":[],"sources":["../../../src/openid4vc-issuer/router/nonceEndpoint.ts"],"sourcesContent":["import type { NextFunction, Response, Router } from 'express'\nimport { getRequestContext, sendJsonResponse, sendUnknownServerErrorResponse } from '../../shared/router'\nimport type { OpenId4VcIssuerModuleConfig } from '../OpenId4VcIssuerModuleConfig'\nimport { OpenId4VcIssuerService } from '../OpenId4VcIssuerService'\nimport type { OpenId4VcIssuanceRequest } from './requestContext'\n\nexport function configureNonceEndpoint(router: Router, config: OpenId4VcIssuerModuleConfig) {\n router.post(\n config.nonceEndpointPath,\n async (request: OpenId4VcIssuanceRequest, response: Response, next: NextFunction) => {\n response.set({ 'Cache-Control': 'no-store', Pragma: 'no-cache' })\n const requestContext = getRequestContext(request)\n const { agentContext, issuer } = requestContext\n\n try {\n const openId4VcIssuerService = agentContext.dependencyManager.resolve(OpenId4VcIssuerService)\n const vcIssuer = openId4VcIssuerService.getIssuer(agentContext)\n\n const { cNonce, cNonceExpiresInSeconds } = await openId4VcIssuerService.createNonce(agentContext, issuer)\n\n const nonceResponse = vcIssuer.createNonceResponse({\n cNonce,\n cNonceExpiresIn: cNonceExpiresInSeconds,\n })\n\n return sendJsonResponse(response, next, nonceResponse)\n } catch (error) {\n return sendUnknownServerErrorResponse(response, next, agentContext.config.logger, error)\n }\n }\n )\n}\n"],"mappings":";;;;;AAMA,SAAgB,uBAAuB,QAAgB,QAAqC;AAC1F,QAAO,KACL,OAAO,mBACP,OAAO,SAAmC,UAAoB,SAAuB;AACnF,WAAS,IAAI;GAAE,iBAAiB;GAAY,QAAQ;GAAY,CAAC;EAEjE,MAAM,EAAE,cAAc,WADC,kBAAkB,QAAQ;AAGjD,MAAI;GACF,MAAM,yBAAyB,aAAa,kBAAkB,QAAQ,uBAAuB;GAC7F,MAAM,WAAW,uBAAuB,UAAU,aAAa;GAE/D,MAAM,EAAE,QAAQ,2BAA2B,MAAM,uBAAuB,YAAY,cAAc,OAAO;AAOzG,UAAO,iBAAiB,UAAU,MALZ,SAAS,oBAAoB;IACjD;IACA,iBAAiB;IAClB,CAAC,CAEoD;WAC/C,OAAO;AACd,UAAO,+BAA+B,UAAU,MAAM,aAAa,OAAO,QAAQ,MAAM;;GAG7F"}
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import { OpenId4VcIssuerModuleConfig } from "../OpenId4VcIssuerModuleConfig.mjs";
|
|
2
|
+
import { getRequestContext, sendJsonResponse, sendOauth2ErrorResponse, sendUnknownServerErrorResponse } from "../../shared/router/context.mjs";
|
|
3
|
+
import "../../shared/router/index.mjs";
|
|
4
|
+
import { getAllowedAndRequestedScopeValues, getCredentialConfigurationsSupportedForScopes, getOfferedCredentials, getScopesFromCredentialConfigurationsSupported } from "../../shared/issuerMetadataUtils.mjs";
|
|
5
|
+
import "../../shared/index.mjs";
|
|
6
|
+
import { OpenId4VcIssuanceSessionState } from "../OpenId4VcIssuanceSessionState.mjs";
|
|
7
|
+
import "../repository/index.mjs";
|
|
8
|
+
import { OpenId4VcIssuerService } from "../OpenId4VcIssuerService.mjs";
|
|
9
|
+
import { AgentContext, joinUriParts, utils } from "@credo-ts/core";
|
|
10
|
+
import { Oauth2ErrorCodes, Oauth2ServerErrorResponseError, pushedAuthorizationRequestUriPrefix } from "@openid4vc/oauth2";
|
|
11
|
+
import { addSecondsToDate } from "@openid4vc/utils";
|
|
12
|
+
|
|
13
|
+
//#region src/openid4vc-issuer/router/pushedAuthorizationRequestEndpoint.ts
|
|
14
|
+
async function handlePushedAuthorizationRequest(agentContext, options) {
|
|
15
|
+
const openId4VcIssuerService = agentContext.dependencyManager.resolve(OpenId4VcIssuerService);
|
|
16
|
+
const config = agentContext.dependencyManager.resolve(OpenId4VcIssuerModuleConfig);
|
|
17
|
+
const { issuanceSession, parsedAuthorizationRequest, issuer, request } = options;
|
|
18
|
+
const issuerMetadata = await openId4VcIssuerService.getIssuerMetadata(agentContext, issuer);
|
|
19
|
+
if (!parsedAuthorizationRequest.authorizationRequest.scope) throw new Oauth2ServerErrorResponseError({
|
|
20
|
+
error: Oauth2ErrorCodes.InvalidScope,
|
|
21
|
+
error_description: `Missing required 'scope' parameter`
|
|
22
|
+
});
|
|
23
|
+
if (!parsedAuthorizationRequest.authorizationRequest.redirect_uri) throw new Oauth2ServerErrorResponseError({
|
|
24
|
+
error: Oauth2ErrorCodes.InvalidScope,
|
|
25
|
+
error_description: `Missing required 'redirect_uri' parameter.`
|
|
26
|
+
});
|
|
27
|
+
const allowedStates = [OpenId4VcIssuanceSessionState.OfferCreated, OpenId4VcIssuanceSessionState.OfferUriRetrieved];
|
|
28
|
+
if (!allowedStates.includes(issuanceSession.state)) throw new Oauth2ServerErrorResponseError({
|
|
29
|
+
error: Oauth2ErrorCodes.InvalidRequest,
|
|
30
|
+
error_description: `Invalid 'issuer_state' parameter`
|
|
31
|
+
}, { internalMessage: `Issuance session '${issuanceSession.id}' has state '${issuanceSession.state}' but expected one of ${allowedStates.join(", ")}` });
|
|
32
|
+
if (!issuanceSession.chainedIdentity?.externalAuthorizationServerUrl) throw new Oauth2ServerErrorResponseError({
|
|
33
|
+
error: Oauth2ErrorCodes.InvalidRequest,
|
|
34
|
+
error_description: `Unexpected redirect call for session.`
|
|
35
|
+
}, { internalMessage: `Issuance session '${issuanceSession.id}' is not configured to use chained identity for authorization.` });
|
|
36
|
+
const authorizationServer = openId4VcIssuerService.getOauth2AuthorizationServer(agentContext, { issuanceSessionId: issuanceSession.id });
|
|
37
|
+
const { clientAttestation, dpop } = await authorizationServer.verifyPushedAuthorizationRequest({
|
|
38
|
+
authorizationRequest: parsedAuthorizationRequest.authorizationRequest,
|
|
39
|
+
authorizationServerMetadata: issuerMetadata.authorizationServers[0],
|
|
40
|
+
request,
|
|
41
|
+
clientAttestation: {
|
|
42
|
+
...parsedAuthorizationRequest.clientAttestation,
|
|
43
|
+
required: issuanceSession.walletAttestation?.required ?? config.walletAttestationsRequired
|
|
44
|
+
},
|
|
45
|
+
dpop: {
|
|
46
|
+
...parsedAuthorizationRequest.dpop,
|
|
47
|
+
required: issuanceSession.dpop?.required ?? config.dpopRequired
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
if (dpop) issuanceSession.dpop = {
|
|
51
|
+
required: true,
|
|
52
|
+
dpopJkt: dpop.jwkThumbprint
|
|
53
|
+
};
|
|
54
|
+
if (clientAttestation) issuanceSession.walletAttestation = { required: true };
|
|
55
|
+
const offeredCredentialConfigurations = getOfferedCredentials(issuanceSession.credentialOfferPayload.credential_configuration_ids, issuerMetadata.credentialIssuer.credential_configurations_supported);
|
|
56
|
+
const requestedScopes = getAllowedAndRequestedScopeValues({
|
|
57
|
+
allowedScopes: getScopesFromCredentialConfigurationsSupported(offeredCredentialConfigurations),
|
|
58
|
+
requestedScope: parsedAuthorizationRequest.authorizationRequest.scope
|
|
59
|
+
});
|
|
60
|
+
const requestedCredentialConfigurations = getCredentialConfigurationsSupportedForScopes(offeredCredentialConfigurations, requestedScopes);
|
|
61
|
+
if (requestedScopes.length === 0 || Object.keys(requestedCredentialConfigurations).length === 0) throw new Oauth2ServerErrorResponseError({
|
|
62
|
+
error: Oauth2ErrorCodes.InvalidScope,
|
|
63
|
+
error_description: `No requested 'scope' values match with offered credential configurations.`
|
|
64
|
+
});
|
|
65
|
+
issuanceSession.authorization = {
|
|
66
|
+
...issuanceSession.authorization,
|
|
67
|
+
scopes: requestedScopes
|
|
68
|
+
};
|
|
69
|
+
issuanceSession.clientId = clientAttestation?.clientAttestation.payload.sub ?? parsedAuthorizationRequest.authorizationRequest.client_id;
|
|
70
|
+
const oauth2Client = openId4VcIssuerService.getOauth2Client(agentContext, issuer);
|
|
71
|
+
const authorizationServerUrl = issuanceSession.chainedIdentity.externalAuthorizationServerUrl;
|
|
72
|
+
const authorizationServerConfig = issuer.chainedAuthorizationServerConfigs?.find((config$1) => config$1.issuer === authorizationServerUrl);
|
|
73
|
+
if (!authorizationServerConfig) throw new Oauth2ServerErrorResponseError({ error: Oauth2ErrorCodes.ServerError }, { internalMessage: `Issuer '${issuer.issuerId}' does not have a chained authorization server config for issuer '${authorizationServerUrl}'` });
|
|
74
|
+
const authorizationServerMetadata = await oauth2Client.fetchAuthorizationServerMetadata(authorizationServerConfig.issuer);
|
|
75
|
+
if (!authorizationServerMetadata) throw new Oauth2ServerErrorResponseError({
|
|
76
|
+
error: Oauth2ErrorCodes.ServerError,
|
|
77
|
+
error_description: `Unable to retrieve authorization server metadata from external identity provider.`
|
|
78
|
+
}, { internalMessage: `Unable to retrieve authorization server metadata from '${authorizationServerConfig.issuer}'` });
|
|
79
|
+
const redirectUri = joinUriParts(config.baseUrl, [issuer.issuerId, "redirect"]);
|
|
80
|
+
const chainedIdentityState = utils.uuid();
|
|
81
|
+
const scopes = requestedScopes.flatMap((scope) => {
|
|
82
|
+
if (scope in authorizationServerConfig.scopesMapping) return authorizationServerConfig.scopesMapping[scope];
|
|
83
|
+
throw new Oauth2ServerErrorResponseError({ error: Oauth2ErrorCodes.ServerError }, { internalMessage: `Issuer '${issuer.issuerId}' does not have a scope mapping for scope '${scope}' for external authorization server '${authorizationServerConfig.issuer}'` });
|
|
84
|
+
});
|
|
85
|
+
const { authorizationRequestUrl, pkce } = await oauth2Client.initiateAuthorization({
|
|
86
|
+
authorizationServerMetadata,
|
|
87
|
+
clientId: authorizationServerConfig.clientAuthentication.clientId,
|
|
88
|
+
redirectUri,
|
|
89
|
+
state: chainedIdentityState,
|
|
90
|
+
scope: scopes.join(" ")
|
|
91
|
+
});
|
|
92
|
+
issuanceSession.chainedIdentity = {
|
|
93
|
+
...issuanceSession.chainedIdentity,
|
|
94
|
+
requestUriReferenceValue: utils.uuid(),
|
|
95
|
+
externalAuthorizationRequestUrl: authorizationRequestUrl,
|
|
96
|
+
requestUriExpiresAt: addSecondsToDate(/* @__PURE__ */ new Date(), config.requestUriExpiresInSeconds),
|
|
97
|
+
pkceCodeVerifier: pkce?.codeVerifier,
|
|
98
|
+
externalState: chainedIdentityState,
|
|
99
|
+
state: parsedAuthorizationRequest.authorizationRequest.state,
|
|
100
|
+
redirectUri: parsedAuthorizationRequest.authorizationRequest.redirect_uri,
|
|
101
|
+
externalAuthorizationServerMetadata: authorizationServerMetadata
|
|
102
|
+
};
|
|
103
|
+
const { pushedAuthorizationResponse } = authorizationServer.createPushedAuthorizationResponse({
|
|
104
|
+
expiresInSeconds: config.requestUriExpiresInSeconds,
|
|
105
|
+
requestUri: pushedAuthorizationRequestUriPrefix + issuanceSession.chainedIdentity.requestUriReferenceValue
|
|
106
|
+
});
|
|
107
|
+
await openId4VcIssuerService.updateState(agentContext, issuanceSession, OpenId4VcIssuanceSessionState.AuthorizationInitiated);
|
|
108
|
+
return { pushedAuthorizationResponse };
|
|
109
|
+
}
|
|
110
|
+
function configurePushedAuthorizationRequestEndpoint(router, config) {
|
|
111
|
+
router.post(config.pushedAuthorizationRequestEndpoint, async (request, response, next) => {
|
|
112
|
+
const { agentContext, issuer } = getRequestContext(request);
|
|
113
|
+
try {
|
|
114
|
+
const config$1 = agentContext.dependencyManager.resolve(OpenId4VcIssuerModuleConfig);
|
|
115
|
+
const openId4VcIssuerService = agentContext.dependencyManager.resolve(OpenId4VcIssuerService);
|
|
116
|
+
const issuerMetadata = await openId4VcIssuerService.getIssuerMetadata(agentContext, issuer);
|
|
117
|
+
const authorizationServer = openId4VcIssuerService.getOauth2AuthorizationServer(agentContext);
|
|
118
|
+
const fullRequestUrl = joinUriParts(issuerMetadata.credentialIssuer.credential_issuer, [config$1.pushedAuthorizationRequestEndpoint]);
|
|
119
|
+
const requestLike = {
|
|
120
|
+
headers: new Headers(request.headers),
|
|
121
|
+
method: request.method,
|
|
122
|
+
url: fullRequestUrl
|
|
123
|
+
};
|
|
124
|
+
const parseResult = await authorizationServer.parsePushedAuthorizationRequest({
|
|
125
|
+
authorizationRequest: request.body,
|
|
126
|
+
request: requestLike
|
|
127
|
+
});
|
|
128
|
+
if (parseResult.authorizationRequestJwt) throw new Oauth2ServerErrorResponseError({
|
|
129
|
+
error: Oauth2ErrorCodes.InvalidRequest,
|
|
130
|
+
error_description: `Using JWT-secured authorization request is not supported.`
|
|
131
|
+
});
|
|
132
|
+
if (!parseResult.authorizationRequest.issuer_state) throw new Oauth2ServerErrorResponseError({
|
|
133
|
+
error: Oauth2ErrorCodes.InvalidRequest,
|
|
134
|
+
error_description: `Missing required 'issuer_state' parameter. Only requests initiated by a credential offer are supported for pushed authorization requests.`
|
|
135
|
+
});
|
|
136
|
+
if (!parseResult.authorizationRequest.scope) throw new Oauth2ServerErrorResponseError({
|
|
137
|
+
error: Oauth2ErrorCodes.InvalidScope,
|
|
138
|
+
error_description: `Missing required 'scope' parameter`
|
|
139
|
+
});
|
|
140
|
+
const issuanceSession = await openId4VcIssuerService.findSingleIssuanceSessionByQuery(agentContext, {
|
|
141
|
+
issuerId: issuer.issuerId,
|
|
142
|
+
issuerState: parseResult.authorizationRequest.issuer_state
|
|
143
|
+
});
|
|
144
|
+
if (!issuanceSession) throw new Oauth2ServerErrorResponseError({
|
|
145
|
+
error: Oauth2ErrorCodes.InvalidRequest,
|
|
146
|
+
error_description: `Invalid 'issuer_state' parameter`
|
|
147
|
+
}, { internalMessage: `Issuance session not found for 'issuer_state' parameter '${parseResult.authorizationRequest.issuer_state}'` });
|
|
148
|
+
const { pushedAuthorizationResponse } = await handlePushedAuthorizationRequest(agentContext, {
|
|
149
|
+
issuanceSession,
|
|
150
|
+
issuer,
|
|
151
|
+
parsedAuthorizationRequest: parseResult,
|
|
152
|
+
request: requestLike
|
|
153
|
+
});
|
|
154
|
+
return sendJsonResponse(response, next, pushedAuthorizationResponse);
|
|
155
|
+
} catch (error) {
|
|
156
|
+
if (error instanceof Oauth2ServerErrorResponseError) return sendOauth2ErrorResponse(response, next, agentContext.config.logger, error);
|
|
157
|
+
return sendUnknownServerErrorResponse(response, next, agentContext.config.logger, error);
|
|
158
|
+
}
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
//#endregion
|
|
163
|
+
export { configurePushedAuthorizationRequestEndpoint, handlePushedAuthorizationRequest };
|
|
164
|
+
//# sourceMappingURL=pushedAuthorizationRequestEndpoint.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pushedAuthorizationRequestEndpoint.mjs","names":["config"],"sources":["../../../src/openid4vc-issuer/router/pushedAuthorizationRequestEndpoint.ts"],"sourcesContent":["import { AgentContext, joinUriParts, utils } from '@credo-ts/core'\nimport type { HttpMethod, ParsePushedAuthorizationRequestResult, RequestLike } from '@openid4vc/oauth2'\nimport {\n Oauth2ErrorCodes,\n Oauth2ServerErrorResponseError,\n pushedAuthorizationRequestUriPrefix,\n} from '@openid4vc/oauth2'\nimport { addSecondsToDate } from '@openid4vc/utils'\nimport type { NextFunction, Response, Router } from 'express'\nimport type { OpenId4VciCredentialConfigurationsSupportedWithFormats } from '../../shared'\nimport {\n getAllowedAndRequestedScopeValues,\n getCredentialConfigurationsSupportedForScopes,\n getOfferedCredentials,\n getScopesFromCredentialConfigurationsSupported,\n} from '../../shared'\nimport {\n getRequestContext,\n sendJsonResponse,\n sendOauth2ErrorResponse,\n sendUnknownServerErrorResponse,\n} from '../../shared/router'\nimport { OpenId4VcIssuanceSessionState } from '../OpenId4VcIssuanceSessionState'\nimport { OpenId4VcIssuerModuleConfig } from '../OpenId4VcIssuerModuleConfig'\nimport { OpenId4VcIssuerService } from '../OpenId4VcIssuerService'\nimport { OpenId4VcIssuanceSessionRecord, OpenId4VcIssuerRecord } from '../repository'\nimport type { OpenId4VcIssuanceRequest } from './requestContext'\n\nexport async function handlePushedAuthorizationRequest(\n agentContext: AgentContext,\n options: {\n issuer: OpenId4VcIssuerRecord\n issuanceSession: OpenId4VcIssuanceSessionRecord\n parsedAuthorizationRequest: ParsePushedAuthorizationRequestResult\n request: RequestLike\n }\n) {\n const openId4VcIssuerService = agentContext.dependencyManager.resolve(OpenId4VcIssuerService)\n const config = agentContext.dependencyManager.resolve(OpenId4VcIssuerModuleConfig)\n\n const { issuanceSession, parsedAuthorizationRequest, issuer, request } = options\n const issuerMetadata = await openId4VcIssuerService.getIssuerMetadata(agentContext, issuer)\n\n if (!parsedAuthorizationRequest.authorizationRequest.scope) {\n throw new Oauth2ServerErrorResponseError({\n error: Oauth2ErrorCodes.InvalidScope,\n error_description: `Missing required 'scope' parameter`,\n })\n }\n\n if (!parsedAuthorizationRequest.authorizationRequest.redirect_uri) {\n throw new Oauth2ServerErrorResponseError({\n error: Oauth2ErrorCodes.InvalidScope,\n error_description: `Missing required 'redirect_uri' parameter.`,\n })\n }\n\n const allowedStates = [OpenId4VcIssuanceSessionState.OfferCreated, OpenId4VcIssuanceSessionState.OfferUriRetrieved]\n if (!allowedStates.includes(issuanceSession.state)) {\n throw new Oauth2ServerErrorResponseError(\n {\n error: Oauth2ErrorCodes.InvalidRequest,\n error_description: `Invalid 'issuer_state' parameter`,\n },\n {\n internalMessage: `Issuance session '${issuanceSession.id}' has state '${\n issuanceSession.state\n }' but expected one of ${allowedStates.join(', ')}`,\n }\n )\n }\n\n if (!issuanceSession.chainedIdentity?.externalAuthorizationServerUrl) {\n throw new Oauth2ServerErrorResponseError(\n {\n error: Oauth2ErrorCodes.InvalidRequest,\n error_description: `Unexpected redirect call for session.`,\n },\n {\n internalMessage: `Issuance session '${issuanceSession.id}' is not configured to use chained identity for authorization.`,\n }\n )\n }\n\n const authorizationServer = openId4VcIssuerService.getOauth2AuthorizationServer(agentContext, {\n issuanceSessionId: issuanceSession.id,\n })\n\n const { clientAttestation, dpop } = await authorizationServer.verifyPushedAuthorizationRequest({\n authorizationRequest: parsedAuthorizationRequest.authorizationRequest,\n // First authorization server is the internal authorization server\n authorizationServerMetadata: issuerMetadata.authorizationServers[0],\n request,\n clientAttestation: {\n ...parsedAuthorizationRequest.clientAttestation,\n // First session config, fall back to global config\n required: issuanceSession.walletAttestation?.required ?? config.walletAttestationsRequired,\n },\n dpop: {\n ...parsedAuthorizationRequest.dpop,\n // First session config, fall back to global config\n required: issuanceSession.dpop?.required ?? config.dpopRequired,\n },\n })\n\n if (dpop) {\n // Bind dpop jwk thumbprint to session\n issuanceSession.dpop = {\n // If dpop is provided at the start, it's required from now on.\n required: true,\n dpopJkt: dpop.jwkThumbprint,\n }\n }\n\n if (clientAttestation) {\n issuanceSession.walletAttestation = {\n // If client attestation is provided at the start, it's required from now on.\n required: true,\n }\n }\n\n const offeredCredentialConfigurations = getOfferedCredentials(\n issuanceSession.credentialOfferPayload.credential_configuration_ids,\n issuerMetadata.credentialIssuer.credential_configurations_supported\n )\n const allowedScopes = getScopesFromCredentialConfigurationsSupported(offeredCredentialConfigurations)\n const requestedScopes = getAllowedAndRequestedScopeValues({\n allowedScopes,\n requestedScope: parsedAuthorizationRequest.authorizationRequest.scope,\n })\n const requestedCredentialConfigurations = getCredentialConfigurationsSupportedForScopes(\n offeredCredentialConfigurations,\n requestedScopes\n ) as OpenId4VciCredentialConfigurationsSupportedWithFormats\n if (requestedScopes.length === 0 || Object.keys(requestedCredentialConfigurations).length === 0) {\n throw new Oauth2ServerErrorResponseError({\n error: Oauth2ErrorCodes.InvalidScope,\n error_description: `No requested 'scope' values match with offered credential configurations.`,\n })\n }\n\n issuanceSession.authorization = {\n ...issuanceSession.authorization,\n scopes: requestedScopes,\n }\n\n // If client attestation is used we have verified this client_id matches with the sub\n // of the wallet attestation\n issuanceSession.clientId =\n clientAttestation?.clientAttestation.payload.sub ?? parsedAuthorizationRequest.authorizationRequest.client_id\n\n const oauth2Client = openId4VcIssuerService.getOauth2Client(agentContext, issuer)\n const authorizationServerUrl = issuanceSession.chainedIdentity.externalAuthorizationServerUrl\n\n const authorizationServerConfig = issuer.chainedAuthorizationServerConfigs?.find(\n (config) => config.issuer === authorizationServerUrl\n )\n if (!authorizationServerConfig) {\n throw new Oauth2ServerErrorResponseError(\n {\n error: Oauth2ErrorCodes.ServerError,\n },\n {\n internalMessage: `Issuer '${issuer.issuerId}' does not have a chained authorization server config for issuer '${authorizationServerUrl}'`,\n }\n )\n }\n\n const authorizationServerMetadata = await oauth2Client.fetchAuthorizationServerMetadata(\n authorizationServerConfig.issuer\n )\n if (!authorizationServerMetadata) {\n throw new Oauth2ServerErrorResponseError(\n {\n error: Oauth2ErrorCodes.ServerError,\n error_description: `Unable to retrieve authorization server metadata from external identity provider.`,\n },\n {\n internalMessage: `Unable to retrieve authorization server metadata from '${authorizationServerConfig.issuer}'`,\n }\n )\n }\n\n const redirectUri = joinUriParts(config.baseUrl, [issuer.issuerId, 'redirect'])\n const chainedIdentityState = utils.uuid()\n\n const scopes = requestedScopes.flatMap((scope) => {\n if (scope in authorizationServerConfig.scopesMapping) {\n return authorizationServerConfig.scopesMapping[scope]\n }\n\n throw new Oauth2ServerErrorResponseError(\n {\n error: Oauth2ErrorCodes.ServerError,\n },\n {\n internalMessage: `Issuer '${issuer.issuerId}' does not have a scope mapping for scope '${scope}' for external authorization server '${authorizationServerConfig.issuer}'`,\n }\n )\n })\n\n // TODO: add support for DPoP\n const { authorizationRequestUrl, pkce } = await oauth2Client.initiateAuthorization({\n authorizationServerMetadata,\n clientId: authorizationServerConfig.clientAuthentication.clientId,\n redirectUri,\n state: chainedIdentityState,\n scope: scopes.join(' '),\n })\n\n issuanceSession.chainedIdentity = {\n ...issuanceSession.chainedIdentity,\n requestUriReferenceValue: utils.uuid(),\n externalAuthorizationRequestUrl: authorizationRequestUrl,\n requestUriExpiresAt: addSecondsToDate(new Date(), config.requestUriExpiresInSeconds),\n pkceCodeVerifier: pkce?.codeVerifier,\n externalState: chainedIdentityState,\n state: parsedAuthorizationRequest.authorizationRequest.state,\n redirectUri: parsedAuthorizationRequest.authorizationRequest.redirect_uri,\n externalAuthorizationServerMetadata: authorizationServerMetadata,\n }\n\n const { pushedAuthorizationResponse } = authorizationServer.createPushedAuthorizationResponse({\n expiresInSeconds: config.requestUriExpiresInSeconds,\n requestUri: pushedAuthorizationRequestUriPrefix + issuanceSession.chainedIdentity.requestUriReferenceValue,\n })\n\n await openId4VcIssuerService.updateState(\n agentContext,\n issuanceSession,\n OpenId4VcIssuanceSessionState.AuthorizationInitiated\n )\n\n return { pushedAuthorizationResponse }\n}\n\nexport function configurePushedAuthorizationRequestEndpoint(router: Router, config: OpenId4VcIssuerModuleConfig) {\n router.post(\n config.pushedAuthorizationRequestEndpoint,\n async (request: OpenId4VcIssuanceRequest, response: Response, next: NextFunction) => {\n const requestContext = getRequestContext(request)\n const { agentContext, issuer } = requestContext\n\n try {\n const config = agentContext.dependencyManager.resolve(OpenId4VcIssuerModuleConfig)\n const openId4VcIssuerService = agentContext.dependencyManager.resolve(OpenId4VcIssuerService)\n const issuerMetadata = await openId4VcIssuerService.getIssuerMetadata(agentContext, issuer)\n const authorizationServer = openId4VcIssuerService.getOauth2AuthorizationServer(agentContext)\n const fullRequestUrl = joinUriParts(issuerMetadata.credentialIssuer.credential_issuer, [\n config.pushedAuthorizationRequestEndpoint,\n ])\n\n const requestLike = {\n headers: new Headers(request.headers as Record<string, string>),\n method: request.method as HttpMethod,\n url: fullRequestUrl,\n } as const\n\n const parseResult = await authorizationServer.parsePushedAuthorizationRequest({\n authorizationRequest: request.body,\n request: requestLike,\n })\n\n if (parseResult.authorizationRequestJwt) {\n throw new Oauth2ServerErrorResponseError({\n error: Oauth2ErrorCodes.InvalidRequest,\n error_description: `Using JWT-secured authorization request is not supported.`,\n })\n }\n\n // TODO: we could allow dynamic issuance sessions here. Maybe based on a callback?\n // Not sure how to decide which credentials are allowed to be requested dynamically\n if (!parseResult.authorizationRequest.issuer_state) {\n throw new Oauth2ServerErrorResponseError({\n error: Oauth2ErrorCodes.InvalidRequest,\n error_description: `Missing required 'issuer_state' parameter. Only requests initiated by a credential offer are supported for pushed authorization requests.`,\n })\n }\n\n if (!parseResult.authorizationRequest.scope) {\n throw new Oauth2ServerErrorResponseError({\n error: Oauth2ErrorCodes.InvalidScope,\n error_description: `Missing required 'scope' parameter`,\n })\n }\n\n const issuanceSession = await openId4VcIssuerService.findSingleIssuanceSessionByQuery(agentContext, {\n issuerId: issuer.issuerId,\n issuerState: parseResult.authorizationRequest.issuer_state,\n })\n\n if (!issuanceSession) {\n throw new Oauth2ServerErrorResponseError(\n {\n error: Oauth2ErrorCodes.InvalidRequest,\n error_description: `Invalid 'issuer_state' parameter`,\n },\n {\n internalMessage: `Issuance session not found for 'issuer_state' parameter '${parseResult.authorizationRequest.issuer_state}'`,\n }\n )\n }\n\n const { pushedAuthorizationResponse } = await handlePushedAuthorizationRequest(agentContext, {\n issuanceSession,\n issuer,\n parsedAuthorizationRequest: parseResult,\n request: requestLike,\n })\n\n return sendJsonResponse(response, next, pushedAuthorizationResponse)\n } catch (error) {\n if (error instanceof Oauth2ServerErrorResponseError) {\n return sendOauth2ErrorResponse(response, next, agentContext.config.logger, error)\n }\n return sendUnknownServerErrorResponse(response, next, agentContext.config.logger, error)\n }\n }\n )\n}\n"],"mappings":"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"}
|