{"version":3,"sources":["../lib/index.ts","../lib/OID4VCIServer.ts","../lib/oid4vci-api-functions.ts","../lib/IssuerTokenEndpoint.ts","../lib/expressUtils.ts"],"sourcesContent":["export * from './OID4VCIServer'\nexport * from './oid4vci-api-functions'\nexport * from './expressUtils'\n\n// We re-export oidc-client types, as they were previously exported here\nexport type { ClientResponseType, ClientAuthMethod, ClientMetadata } from '@sphereon/oid4vci-common'\n","import {\n  AuthorizationRequest,\n  ClientMetadata,\n  CreateCredentialOfferURIResult,\n  CredentialConfigurationSupportedV1_0_15,\n  CredentialOfferMode,\n  OID4VCICredentialFormat,\n  QRCodeOpts,\n} from '@sphereon/oid4vci-common'\nimport {\n  CredentialSupportedBuilderV1_15,\n  ITokenEndpointOpts,\n  oidcAccessTokenVerifyCallback,\n  VcIssuer,\n  VcIssuerBuilder,\n} from '@sphereon/oid4vci-issuer'\nimport { ExpressSupport, HasEndpointOpts, ISingleEndpointOpts } from '@sphereon/ssi-express-support'\nimport express, { Express } from 'express'\n\nimport {\n  accessTokenEndpoint,\n  authorizationChallengeEndpoint,\n  createCredentialOfferEndpoint,\n  deleteCredentialOfferEndpoint,\n  getBasePath,\n  getCredentialEndpoint,\n  getCredentialOfferEndpoint,\n  getCredentialOfferReferenceEndpoint,\n  getIssueStatusEndpoint,\n  getMetadataEndpoints,\n  nonceEndpoint,\n  pushedAuthorizationEndpoint,\n} from './oid4vci-api-functions'\n\nfunction buildVCIFromEnvironment() {\n  const credentialsSupported: Record<string, CredentialConfigurationSupportedV1_0_15> = new CredentialSupportedBuilderV1_15()\n    .withCredentialSigningAlgValuesSupported(process.env.credential_signing_alg_values_supported as string)\n    .withCryptographicBindingMethod(process.env.cryptographic_binding_methods_supported as string)\n    .withFormat(process.env.credential_supported_format as unknown as OID4VCICredentialFormat)\n    .withCredentialName(process.env.credential_supported_name_1 as string)\n    .withCredentialDefinition({\n      type: [process.env.credential_supported_1_definition_type_1 as string, process.env.credential_supported_1_definition_type_2 as string],\n      // TODO: setup credentialSubject here from env\n      // credentialSubject\n    })\n    .withCredentialSupportedDisplay({\n      name: process.env.credential_display_name as string,\n      locale: process.env.credential_display_locale as string,\n      logo: {\n        url: process.env.credential_display_logo_url as string,\n        alt_text: process.env.credential_display_logo_alt_text as string,\n      },\n      background_color: process.env.credential_display_background_color as string,\n      text_color: process.env.credential_display_text_color as string,\n    })\n    .build()\n  const issuerBuilder = new VcIssuerBuilder()\n    .withTXCode({\n      length: process.env.user_pin_length as unknown as number,\n      input_mode: process.env.user_pin_input_mode as 'numeric' | 'text',\n    })\n    .withAuthorizationServers(process.env.authorization_server as string)\n    .withCredentialEndpoint(process.env.credential_endpoint as string)\n    .withNonceEndpoint(process.env.nonce_endpoint as string)\n    .withCredentialIssuer(process.env.credential_issuer as string)\n    .withIssuerDisplay({\n      name: process.env.issuer_name as string,\n      locale: process.env.issuer_locale as string,\n    })\n    .withCredentialConfigurationsSupported(credentialsSupported)\n    .withInMemoryCredentialOfferState()\n    .withInMemoryCNonceState()\n\n  if (process.env.authorization_server_client_id) {\n    if (!process.env.authorization_server_redirect_uri) {\n      throw Error('Authorization server redirect uri is required when client id is set')\n    }\n    issuerBuilder.withASClientMetadataParams({\n      client_id: process.env.authorization_server_client_id,\n      client_secret: process.env.authorization_server_client_secret,\n      redirect_uris: [process.env.authorization_server_redirect_uri],\n    })\n  }\n\n  return issuerBuilder.build()\n}\n\nexport type ICreateCredentialOfferURIResponse = Omit<CreateCredentialOfferURIResult, 'session'>\n\nexport interface IGetCredentialOfferEndpointOpts extends ISingleEndpointOpts {\n  baseUrl: string\n}\n\nexport interface IDeleteCredentialOfferEndpointOpts extends ISingleEndpointOpts {\n  baseUrl: string\n}\n\nexport interface ICreateCredentialOfferEndpointOpts extends ISingleEndpointOpts {\n  getOfferPath?: string\n  qrCodeOpts?: QRCodeOpts\n  baseUrl?: string\n  credentialOfferReferenceBasePath?: string\n  defaultCredentialOfferMode?: CredentialOfferMode\n}\n\nexport interface IGetIssueStatusEndpointOpts extends ISingleEndpointOpts {\n  baseUrl: string | URL\n}\n\nexport interface IGetIssuePayloadEndpointOpts extends ISingleEndpointOpts {\n  baseUrl: string | URL\n}\n\nexport interface IAuthorizationChallengeEndpointOpts extends ISingleEndpointOpts {\n  createAuthRequestUriEndpointPath?: string\n  verifyAuthResponseEndpointPath?: string\n  /**\n   * Callback used for creating the authorization request uri used for the RP.\n   * Added an optional state parameter so that when direct calls are used,\n   * one could set the state value of the RP session to match the state value of the VCI session.\n   */\n  createAuthRequestUriCallback: (state?: string) => Promise<string>\n  /**\n   * Callback used for verifying the status of the authorization response.\n   * This is checked by the issuer before issuing an authorization code.\n   */\n  verifyAuthResponseCallback: (correlationId: string) => Promise<boolean>\n}\n\nexport interface IOID4VCIEndpointOpts {\n  trustProxy?: boolean | Array<string>\n  tokenEndpointOpts?: ITokenEndpointOpts\n  notificationOpts?: ISingleEndpointOpts\n  createCredentialOfferOpts?: ICreateCredentialOfferEndpointOpts\n  deleteCredentialOfferOpts?: IDeleteCredentialOfferEndpointOpts\n  getCredentialOfferOpts?: IGetCredentialOfferEndpointOpts\n  getStatusOpts?: IGetIssueStatusEndpointOpts\n  getIssuePayloadOpts?: IGetIssuePayloadEndpointOpts\n  parOpts?: ISingleEndpointOpts\n  authorizationChallengeOpts?: IAuthorizationChallengeEndpointOpts\n  nonceOpts?: INonceEndpointOpts\n}\n\nexport interface INonceEndpointOpts extends ISingleEndpointOpts {\n  baseUrl: string | URL\n}\n\nexport enum WellKnownHostLocation {\n  AT_CONTEXT_PATH = 'AT_CONTEXT_PATH',\n  AT_ROOT_PATH = 'AT_ROOT_PATH',\n  AT_BOTH = 'AT_BOTH',\n}\n\nexport interface IOID4VCIServerOpts extends HasEndpointOpts {\n  asClientOpts?: ClientMetadata\n  endpointOpts?: IOID4VCIEndpointOpts\n  baseUrl?: string\n  wellKnownHostLocation?: WellKnownHostLocation\n}\n\nexport class OID4VCIServer {\n  private readonly _issuer: VcIssuer\n  private authRequestsData: Map<string, AuthorizationRequest> = new Map()\n  private readonly _app: Express\n  private readonly _baseUrl: URL\n  private readonly _expressSupport: ExpressSupport\n  // private readonly _server?: http.Server\n  private readonly _router: express.Router\n  private readonly _asClientOpts?: ClientMetadata\n  private readonly _wellknownHostLocation?: WellKnownHostLocation\n\n  constructor(\n    expressSupport: ExpressSupport,\n    opts: IOID4VCIServerOpts & {\n      issuer?: VcIssuer\n    } /*If not supplied as argument, it will be fully configured from environment variables*/,\n  ) {\n    this._baseUrl = new URL(opts?.baseUrl ?? process.env.BASE_URL ?? opts?.issuer?.issuerMetadata?.credential_issuer ?? 'http://localhost')\n    this._expressSupport = expressSupport\n    this._app = expressSupport.express\n    this._router = express.Router()\n    this._issuer = opts?.issuer ? opts.issuer : buildVCIFromEnvironment()\n    this._asClientOpts =\n      opts.asClientOpts || this._issuer.asClientOpts ? ({ ...opts.asClientOpts, ...this._issuer.asClientOpts } as ClientMetadata) : undefined\n    this._wellknownHostLocation =\n      opts?.wellKnownHostLocation ?? (process.env.WELLKNOWN_HOST_LOCATION as WellKnownHostLocation) ?? WellKnownHostLocation.AT_BOTH\n    pushedAuthorizationEndpoint(this.router, this.issuer, this.authRequestsData)\n\n    // Create root router for alternative .well-known endpoints if needed\n    const basePath = getBasePath(this.baseUrl)\n    let rootRouter: express.Router | undefined\n    if (\n      basePath &&\n      basePath !== '/' &&\n      (this.wellknownHostLocation == WellKnownHostLocation.AT_ROOT_PATH || this.wellknownHostLocation == WellKnownHostLocation.AT_BOTH)\n    ) {\n      rootRouter = express.Router()\n      this._app.use('/', rootRouter)\n    }\n\n    getMetadataEndpoints(this.router, this.issuer, {\n      rootRouter,\n      basePath,\n      wellKnownHostLocation: this.wellknownHostLocation,\n    })\n\n    let issuerPayloadPath: string | undefined\n    if (this.isGetIssuePayloadEndpointEnabled(opts?.endpointOpts?.getIssuePayloadOpts)) {\n      issuerPayloadPath = getCredentialOfferReferenceEndpoint(this.router, this.issuer, {\n        ...opts?.endpointOpts?.getIssuePayloadOpts,\n        baseUrl: this.baseUrl,\n      })\n    }\n\n    if (opts?.endpointOpts?.createCredentialOfferOpts?.enabled !== false || process.env.CREDENTIAL_OFFER_ENDPOINT_ENABLED === 'true') {\n      createCredentialOfferEndpoint(this.router, this.issuer, opts?.endpointOpts?.createCredentialOfferOpts, issuerPayloadPath)\n      deleteCredentialOfferEndpoint(this.router, this.issuer, opts?.endpointOpts?.deleteCredentialOfferOpts)\n    }\n    getCredentialOfferEndpoint(this.router, this.issuer, opts?.endpointOpts?.getCredentialOfferOpts)\n    getCredentialEndpoint(this.router, this.issuer, {\n      ...opts?.endpointOpts?.tokenEndpointOpts,\n      baseUrl: this.baseUrl,\n      accessTokenVerificationCallback:\n        opts.endpointOpts?.tokenEndpointOpts?.accessTokenVerificationCallback ??\n        (this._asClientOpts\n          ? oidcAccessTokenVerifyCallback({\n              clientMetadata: this._asClientOpts,\n              credentialIssuer: this._issuer.issuerMetadata.credential_issuer,\n              authorizationServer: this._issuer.issuerMetadata.authorization_servers![0],\n            })\n          : undefined),\n    })\n    this.assertAccessTokenHandling()\n    if (!this.isTokenEndpointDisabled(opts?.endpointOpts?.tokenEndpointOpts, opts?.asClientOpts)) {\n      accessTokenEndpoint(this.router, this.issuer, {\n        ...opts?.endpointOpts?.tokenEndpointOpts,\n        baseUrl: this.baseUrl,\n        authRequestsData: this.authRequestsData,\n      })\n    }\n    if (this.isStatusEndpointEnabled(opts?.endpointOpts?.getStatusOpts)) {\n      getIssueStatusEndpoint(this.router, this.issuer, { ...opts?.endpointOpts?.getStatusOpts, baseUrl: this.baseUrl })\n    }\n    if (this.isAuthorizationChallengeEndpointEnabled(opts?.endpointOpts?.authorizationChallengeOpts)) {\n      if (!opts?.endpointOpts?.authorizationChallengeOpts?.createAuthRequestUriCallback) {\n        throw Error(`Unable to enable authorization challenge endpoint. No createAuthRequestUriCallback present in authorization challenge options`)\n      } else if (!opts?.endpointOpts?.authorizationChallengeOpts?.verifyAuthResponseCallback) {\n        throw Error(`Unable to enable authorization challenge endpoint. No verifyAuthResponseCallback present in authorization challenge options`)\n      }\n      authorizationChallengeEndpoint(this.router, this.issuer, {\n        ...opts?.endpointOpts?.authorizationChallengeOpts,\n        baseUrl: this.baseUrl,\n      })\n    }\n\n    if (this.isNonceEndpointEnabled(opts?.endpointOpts?.nonceOpts)) {\n      nonceEndpoint(this.router, this.issuer, {\n        ...opts?.endpointOpts?.nonceOpts,\n        baseUrl: this.baseUrl,\n      })\n    }\n    this._app.use(basePath, this._router)\n  }\n\n  public get app(): Express {\n    return this._app\n  }\n\n  /*public get server(): http.Server | undefined {\n    return this._server\n  }*/\n\n  public get router(): express.Router {\n    return this._router\n  }\n\n  get issuer(): VcIssuer {\n    return this._issuer\n  }\n\n  public async stop() {\n    if (!this._expressSupport) {\n      throw Error('Cannot stop server is the REST API is only a router of an existing express app')\n    }\n    await this._expressSupport.stop()\n  }\n\n  private isTokenEndpointDisabled(tokenEndpointOpts?: ITokenEndpointOpts, asClientMetadata?: ClientMetadata) {\n    return tokenEndpointOpts?.tokenEndpointDisabled === true || process.env.TOKEN_ENDPOINT_DISABLED === 'true' || asClientMetadata\n  }\n\n  private isStatusEndpointEnabled(statusEndpointOpts?: IGetIssueStatusEndpointOpts) {\n    return statusEndpointOpts?.enabled !== false || process.env.STATUS_ENDPOINT_ENABLED !== 'false'\n  }\n\n  private isGetIssuePayloadEndpointEnabled(payloadEndpointOpts?: IGetIssuePayloadEndpointOpts) {\n    return payloadEndpointOpts?.enabled !== false || process.env.STATUS_ENDPOINT_ENABLED !== 'false'\n  }\n\n  private isAuthorizationChallengeEndpointEnabled(authorizationChallengeEndpointOpts?: IAuthorizationChallengeEndpointOpts) {\n    return authorizationChallengeEndpointOpts?.enabled === true || process.env.AUTHORIZATION_CHALLENGE_ENDPOINT_ENABLED === 'true'\n  }\n\n  private assertAccessTokenHandling(tokenEndpointOpts?: ITokenEndpointOpts) {\n    const authServer = this.issuer.issuerMetadata.authorization_servers\n    if (this.isTokenEndpointDisabled(tokenEndpointOpts, this.issuer.asClientOpts)) {\n      if (!authServer || authServer.length === 0) {\n        throw Error(\n          `No Authorization Server (AS) is defined in the issuer metadata and the token endpoint is disabled. An AS or token endpoints needs to be present`,\n        )\n      }\n      if (this.issuer.asClientOpts) {\n        console.log(`Token endpoint disabled because AS client metadata is set for ${authServer[0]}`)\n      } else {\n        console.log(`Token endpoint disabled by configuration`)\n      }\n    } else {\n      if (authServer && authServer.some((as) => as !== this.issuer.issuerMetadata.credential_issuer)) {\n        throw Error(\n          `An external Authorization Server (AS) was already enabled in the issuer metadata (${authServer}). Cannot both have an AS and enable the token endpoint at the same time `,\n        )\n      } else if (this._asClientOpts) {\n        throw Error(`OIDC Client metadata is set, but the token endpoint is not disabled. This is not supported.`)\n      }\n    }\n  }\n\n  private isNonceEndpointEnabled(nonceEndpointOpts?: INonceEndpointOpts) {\n    return nonceEndpointOpts?.enabled !== false || process.env.NONCE_ENDPOINT_ENABLED !== 'false'\n  }\n\n  get baseUrl(): URL {\n    return this._baseUrl\n  }\n\n  get wellknownHostLocation(): WellKnownHostLocation | undefined {\n    return this._wellknownHostLocation\n  }\n}\n","import { uuidv4 } from '@sphereon/oid4vc-common'\nimport {\n  ACCESS_TOKEN_ISSUER_REQUIRED_ERROR,\n  AccessTokenRequest,\n  adjustUrl,\n  AuthorizationChallengeCodeResponse,\n  AuthorizationChallengeError,\n  AuthorizationChallengeErrorResponse,\n  AuthorizationRequest,\n  CommonAuthorizationChallengeRequest,\n  CredentialIssuerMetadataOptsV1_0_15,\n  CredentialOfferMode,\n  CredentialOfferRESTRequestV1_0_15,\n  CredentialRequestV1_0_15,\n  determineGrantTypes,\n  EVENTS,\n  extractBearerToken,\n  generateRandomString,\n  getNumberOrUndefined,\n  Grant,\n  IssueStatusResponse,\n  JWT_SIGNER_CALLBACK_REQUIRED_ERROR,\n  NotificationRequest,\n  NotificationStatusEventNames,\n  TokenErrorResponse,\n  trimBoth,\n  trimEnd,\n  trimStart,\n  validateJWT,\n  WellKnownEndpoints,\n} from '@sphereon/oid4vci-common'\nimport { IssuerCorrelation, ITokenEndpointOpts, LOG, VcIssuer } from '@sphereon/oid4vci-issuer'\nimport { env, ISingleEndpointOpts, sendErrorResponse } from '@sphereon/ssi-express-support'\nimport { InitiatorType, SubSystem, System } from '@sphereon/ssi-types'\nimport { NextFunction, Request, Response, Router } from 'express'\n\nimport { handleTokenRequest, verifyTokenRequest } from './IssuerTokenEndpoint'\nimport {\n  IAuthorizationChallengeEndpointOpts,\n  ICreateCredentialOfferEndpointOpts,\n  ICreateCredentialOfferURIResponse,\n  IGetCredentialOfferEndpointOpts,\n  IGetIssueStatusEndpointOpts,\n  INonceEndpointOpts,\n  WellKnownHostLocation,\n} from './OID4VCIServer'\nimport { validateRequestBody } from './expressUtils'\n\nconst expiresIn = process.env.EXPIRES_IN ? parseInt(process.env.EXPIRES_IN) : 90\n\nexport function getIssueStatusEndpoint(router: Router, issuer: VcIssuer, opts: IGetIssueStatusEndpointOpts) {\n  const path = determinePath(opts.baseUrl, opts?.path ?? '/webapp/credential-offer-status', { stripBasePath: true })\n  LOG.log(`[OID4VCI] getIssueStatus endpoint enabled at ${path}`)\n  router.post(path, async (request: Request, response: Response) => {\n    try {\n      const { id } = request.body\n      const session = await issuer.getCredentialOfferSessionById(id)\n      if (!session || !session.credentialOffer) {\n        return sendErrorResponse(response, 404, {\n          error: 'invalid_request',\n          error_description: `Credential offer ${id} not found`,\n        })\n      }\n\n      const authStatusBody: IssueStatusResponse = {\n        createdAt: session.createdAt,\n        lastUpdatedAt: session.lastUpdatedAt,\n        expiresAt: session.expiresAt,\n        status: session.status,\n        statusLists: session.statusLists,\n        ...(session.error && { error: session.error }),\n        ...(session.clientId && { clientId: session.clientId }),\n      }\n      return response.json(authStatusBody)\n    } catch (e) {\n      return sendErrorResponse(\n        response,\n        500,\n        {\n          error: 'invalid_request',\n          error_description: (e as Error).message,\n        },\n        e,\n      )\n    }\n  })\n}\n\nexport function getCredentialOfferReferenceEndpoint(router: Router, issuer: VcIssuer, opts: IGetIssueStatusEndpointOpts): string {\n  const path = determinePath(opts.baseUrl, opts?.path ?? '/credential-offers/:id', { stripBasePath: true })\n  LOG.log(`[OID4VCI] getCredentialOfferReferenceEndpoint endpoint enabled at ${path}`)\n  router.get(path, async (request: Request, response: Response) => {\n    try {\n      const { id } = request.params\n      if (!id) {\n        return sendErrorResponse(response, 404, {\n          error: 'invalid_request',\n          error_description: `query parameter 'id' is missing`,\n        })\n      }\n\n      let session\n      try {\n        session = await issuer.getCredentialOfferSessionById(id as string)\n      } catch (e) {\n        /* will crash with 500 instead of 404 if we do not catch */\n      }\n\n      if (!session || !session.credentialOffer || session.status !== 'OFFER_CREATED') {\n        if (session?.status) {\n          LOG.warning(\n            `[OID4VCI] credential offer reference URI request with ${id}, but request was already received earlier. Session status: ${session.status}`,\n          )\n        }\n        return sendErrorResponse(response, 404, {\n          error: 'invalid_request',\n          error_description: `Credential offer ${id} not found`,\n        })\n      }\n\n      return response.json(session.credentialOffer.credential_offer)\n    } catch (e) {\n      return sendErrorResponse(\n        response,\n        500,\n        {\n          error: 'invalid_request',\n          error_description: (e as Error).message,\n        },\n        e,\n      )\n    }\n  })\n  return path\n}\n\nfunction isExternalAS(issuerMetadata: CredentialIssuerMetadataOptsV1_0_15) {\n  return issuerMetadata.authorization_servers?.some((as) => !as.includes(issuerMetadata.credential_issuer))\n}\n\nexport function authorizationChallengeEndpoint(\n  router: Router,\n  issuer: VcIssuer,\n  opts: IAuthorizationChallengeEndpointOpts & { baseUrl: string | URL },\n) {\n  const endpoint = issuer.authorizationServerMetadata.authorization_challenge_endpoint ?? issuer.issuerMetadata.authorization_challenge_endpoint\n  const baseUrl = getBaseUrl(opts.baseUrl)\n  if (!endpoint) {\n    LOG.info('authorization challenge endpoint disabled as no \"authorization_challenge_endpoint\" has been configured in issuer metadata')\n    return\n  }\n  const path = determinePath(baseUrl, endpoint, { stripBasePath: true })\n  LOG.log(`[OID4VCI] authorization challenge endpoint at ${path}`)\n  router.post(path, async (request: Request, response: Response) => {\n    const authorizationChallengeRequest = request.body as CommonAuthorizationChallengeRequest\n    const { client_id, issuer_state, auth_session, presentation_during_issuance_session } = authorizationChallengeRequest\n\n    try {\n      if (!client_id && !auth_session) {\n        const authorizationChallengeErrorResponse: AuthorizationChallengeErrorResponse = {\n          error: AuthorizationChallengeError.invalid_request,\n          error_description: 'No client id or auth session present',\n        } as AuthorizationChallengeErrorResponse\n        throw authorizationChallengeErrorResponse\n      }\n\n      if (!auth_session && issuer_state) {\n        const session = await issuer.credentialOfferSessions.get(issuer_state)\n        if (!session) {\n          const authorizationChallengeErrorResponse: AuthorizationChallengeErrorResponse = {\n            error: AuthorizationChallengeError.invalid_session,\n            error_description: 'Session is invalid',\n          }\n          throw authorizationChallengeErrorResponse\n        }\n\n        const authRequestURI = await opts.createAuthRequestUriCallback(issuer_state) // TODO generate some error\n        const authorizationChallengeErrorResponse: AuthorizationChallengeErrorResponse = {\n          error: AuthorizationChallengeError.insufficient_authorization,\n          auth_session: issuer_state,\n          presentation: authRequestURI,\n        }\n        throw authorizationChallengeErrorResponse\n      }\n\n      if (auth_session && presentation_during_issuance_session) {\n        const session = await issuer.credentialOfferSessions.get(auth_session)\n        if (!session) {\n          const authorizationChallengeErrorResponse: AuthorizationChallengeErrorResponse = {\n            error: AuthorizationChallengeError.invalid_session,\n            error_description: 'Session is invalid',\n          }\n          throw authorizationChallengeErrorResponse\n        }\n\n        const verifiedResponse = await opts.verifyAuthResponseCallback(presentation_during_issuance_session) // TODO generate some error\n        if (verifiedResponse) {\n          const authorizationCode = generateRandomString(16, 'base64url')\n          session.authorizationCode = authorizationCode\n          await issuer.credentialOfferSessions.set(auth_session, session)\n          const authorizationChallengeCodeResponse: AuthorizationChallengeCodeResponse = {\n            authorization_code: authorizationCode,\n          }\n          return response.json(authorizationChallengeCodeResponse)\n        }\n      }\n\n      const authorizationChallengeErrorResponse: AuthorizationChallengeErrorResponse = {\n        error: AuthorizationChallengeError.invalid_request,\n      }\n      throw authorizationChallengeErrorResponse\n    } catch (e) {\n      return sendErrorResponse(response, 400, e as Error, e)\n    }\n  })\n}\n\nexport function accessTokenEndpoint(\n  router: Router,\n  issuer: VcIssuer,\n  opts: ITokenEndpointOpts &\n    ISingleEndpointOpts & {\n      baseUrl: string | URL\n      authRequestsData?: Map<string, AuthorizationRequest>\n    },\n) {\n  const externalAS = isExternalAS(issuer.issuerMetadata) || issuer.asClientOpts\n  if (externalAS || (opts.accessTokenProvider && opts.accessTokenProvider !== 'internal')) {\n    LOG.log(\n      `[OID4VCI] External Authorization Server ${issuer.issuerMetadata.authorization_servers} is being used. Not enabling internal issuer token endpoint`,\n    )\n    return\n  } else if (opts?.enabled === false) {\n    LOG.log(`[OID4VCI] Internal issuer token endpoint is not enabled`)\n    return\n  }\n  const accessTokenIssuer =\n    opts?.accessTokenIssuer ??\n    process.env.ACCESS_TOKEN_ISSUER ??\n    issuer.issuerMetadata.authorization_servers?.[0] ??\n    issuer.issuerMetadata.credential_issuer\n\n  const preAuthorizedCodeExpirationDuration =\n    opts?.preAuthorizedCodeExpirationDuration ?? getNumberOrUndefined(process.env.PRE_AUTHORIZED_CODE_EXPIRATION_DURATION) ?? 300\n  const interval = opts?.interval ?? getNumberOrUndefined(process.env.INTERVAL) ?? 300\n  const tokenExpiresIn = opts?.tokenExpiresIn ?? 300\n\n  // todo: this means we cannot sign JWTs or issue access tokens when configured from env vars!\n  if (opts?.accessTokenSignerCallback === undefined) {\n    throw new Error(JWT_SIGNER_CALLBACK_REQUIRED_ERROR)\n  } else if (!accessTokenIssuer) {\n    throw new Error(ACCESS_TOKEN_ISSUER_REQUIRED_ERROR)\n  }\n\n  const baseUrl = getBaseUrl(opts.baseUrl)\n\n  // issuer is also AS\n  const path = determinePath(baseUrl, opts?.tokenPath ?? process.env.TOKEN_PATH ?? '/token', {\n    skipBaseUrlCheck: false,\n    stripBasePath: true,\n  })\n  // let's fix any baseUrl ending with a slash as path will always start with a slash, and we already removed it at the end of the base url\n\n  const url = new URL(`${baseUrl}${path}`)\n\n  LOG.log(`[OID4VCI] Token endpoint enabled at ${url.toString()}`)\n\n  // this.issuer.issuerMetadata.token_endpoint = url.toString()\n  router.post(\n    determinePath(baseUrl, url.pathname, { stripBasePath: true }),\n    verifyTokenRequest({\n      issuer,\n      preAuthorizedCodeExpirationDuration,\n      authRequestsData: opts.authRequestsData,\n    }),\n    handleTokenRequest({\n      issuer,\n      accessTokenSignerCallback: opts.accessTokenSignerCallback,\n      cNonceExpiresIn: issuer.cNonceExpiresIn,\n      interval,\n      tokenExpiresIn,\n      accessTokenIssuer,\n    }),\n  )\n}\n\nexport function getCredentialEndpoint(\n  router: Router,\n  issuer: VcIssuer,\n  opts: Pick<ITokenEndpointOpts, 'accessTokenVerificationCallback' | 'accessTokenSignerCallback' | 'tokenExpiresIn' | 'cNonceExpiresIn'> &\n    ISingleEndpointOpts & { baseUrl: string | URL },\n) {\n  const endpoint = issuer.issuerMetadata.credential_endpoint\n  const baseUrl = getBaseUrl(opts.baseUrl)\n  let path: string\n  if (!endpoint) {\n    path = `/credentials`\n    issuer.issuerMetadata.credential_endpoint = `${baseUrl}${path}`\n  } else {\n    path = determinePath(baseUrl, endpoint, { stripBasePath: true, skipBaseUrlCheck: false })\n  }\n  path = determinePath(baseUrl, path, { stripBasePath: true })\n  LOG.log(`[OID4VCI] getCredential endpoint enabled at ${path}`)\n  router.post(path, async (request: Request, response: Response) => {\n    try {\n      const credentialRequest = request.body as CredentialRequestV1_0_15\n      LOG.log(`credential request received`, credentialRequest)\n      const issuerCorrelation: IssuerCorrelation = {}\n      try {\n        const jwt = extractBearerToken(request.header('Authorization'))\n        const jwtVerifyResult = await validateJWT(jwt, {\n          accessTokenVerificationCallback: opts.accessTokenVerificationCallback ?? issuer.jwtVerifyCallback,\n        })\n        const tokenClaims = jwtVerifyResult.jwt.payload\n        if ('preAuthorizedCode' in tokenClaims && typeof tokenClaims.preAuthorizedCode === 'string') {\n          issuerCorrelation.preAuthorizedCode = tokenClaims.preAuthorizedCode\n        }\n        if ('issuer_state' in tokenClaims && typeof tokenClaims.issuer_state === 'string') {\n          issuerCorrelation.issuerState = tokenClaims.issuer_state\n        }\n\n        // Handle credential_identifier from authorization_details flow\n        if ('authorization_details' in tokenClaims && Array.isArray(tokenClaims.authorization_details)) {\n          issuerCorrelation.authorizationDetails = tokenClaims.authorization_details\n\n          if (credentialRequest.credential_identifier) {\n            const validIdentifiers = tokenClaims.authorization_details.flatMap((detail: any) => detail.credential_identifiers || [])\n\n            if (!validIdentifiers.includes(credentialRequest.credential_identifier)) {\n              return sendErrorResponse(response, 400, {\n                error: 'invalid_credential_request',\n                error_description: 'credential_identifier not found in authorization_details',\n              })\n            }\n          }\n        }\n      } catch (e) {\n        LOG.warning(e)\n        return sendErrorResponse(response, 400, {\n          error: 'invalid_token',\n        })\n      }\n\n      const credential = await issuer.issueCredential({\n        credentialRequest: credentialRequest,\n        issuerCorrelation,\n        tokenExpiresIn: opts.tokenExpiresIn,\n        cNonceExpiresIn: opts.cNonceExpiresIn,\n      })\n      return response.json(credential)\n    } catch (e) {\n      return sendErrorResponse(\n        response,\n        500,\n        {\n          error: 'invalid_request',\n          error_description: (e as Error).message,\n        },\n        e,\n      )\n    }\n  })\n}\n\nexport function notificationEndpoint(\n  router: Router,\n  issuer: VcIssuer,\n  opts: ISingleEndpointOpts & Pick<ITokenEndpointOpts, 'accessTokenVerificationCallback'> & { baseUrl: string | URL },\n) {\n  const endpoint = issuer.issuerMetadata.notification_endpoint\n  const baseUrl = getBaseUrl(opts.baseUrl)\n  if (!endpoint) {\n    LOG.warning('Notification endpoint disabled as no \"notification_endpoint\" has been configured in issuer metadata')\n    return\n  }\n  const path = determinePath(baseUrl, endpoint, { stripBasePath: true })\n  LOG.log(`[OID4VCI] notification endpoint enabled at ${path}`)\n  router.post(path, async (request: Request, response: Response) => {\n    try {\n      const notificationRequest = request.body as NotificationRequest\n      LOG.log(\n        `notification ${notificationRequest.event}/${notificationRequest.event_description} received for ${notificationRequest.notification_id}`,\n      )\n      const jwt = extractBearerToken(request.header('Authorization'))\n      EVENTS.emit(NotificationStatusEventNames.OID4VCI_NOTIFICATION_RECEIVED, {\n        eventName: NotificationStatusEventNames.OID4VCI_NOTIFICATION_RECEIVED,\n        id: uuidv4(),\n        data: notificationRequest,\n        initiator: jwt,\n        initiatorType: InitiatorType.EXTERNAL,\n        system: System.OID4VCI,\n        subsystem: SubSystem.API,\n      })\n      try {\n        const jwtResult = await validateJWT(jwt, { accessTokenVerificationCallback: opts.accessTokenVerificationCallback })\n        const accessToken = jwtResult.jwt.payload as AccessTokenRequest\n        const errorOrSession = await issuer.processNotification({\n          preAuthorizedCode: accessToken['pre-authorized_code'],\n          /*TODO: authorizationCode*/ notification: notificationRequest,\n        })\n        if (errorOrSession instanceof Error) {\n          EVENTS.emit(NotificationStatusEventNames.OID4VCI_NOTIFICATION_ERROR, {\n            eventName: NotificationStatusEventNames.OID4VCI_NOTIFICATION_ERROR,\n            id: uuidv4(),\n            data: notificationRequest,\n            initiator: jwtResult.jwt,\n            initiatorType: InitiatorType.EXTERNAL,\n            system: System.OID4VCI,\n            subsystem: SubSystem.API,\n          })\n          return sendErrorResponse(response, 400, errorOrSession.message)\n        } else {\n          EVENTS.emit(NotificationStatusEventNames.OID4VCI_NOTIFICATION_PROCESSED, {\n            eventName: NotificationStatusEventNames.OID4VCI_NOTIFICATION_PROCESSED,\n            id: uuidv4(),\n            data: notificationRequest,\n            initiator: jwtResult.jwt,\n            initiatorType: InitiatorType.EXTERNAL,\n            system: System.OID4VCI,\n            subsystem: SubSystem.API,\n          })\n        }\n      } catch (e) {\n        LOG.warning(e)\n        return sendErrorResponse(response, 400, {\n          error: 'invalid_token',\n        })\n      }\n      return response.status(204).send()\n    } catch (e) {\n      return sendErrorResponse(\n        response,\n        400,\n        {\n          error: 'invalid_notification_request',\n          error_description: (e as Error).message,\n        },\n        e,\n      )\n    }\n  })\n}\n\nexport function nonceEndpoint(router: Router, issuer: VcIssuer, opts: INonceEndpointOpts) {\n  const endpoint = issuer.issuerMetadata.nonce_endpoint\n  const baseUrl = getBaseUrl(opts.baseUrl)\n\n  if (!endpoint) {\n    LOG.warning('Nonce endpoint disabled as no \"nonce_endpoint\" has been configured in issuer metadata')\n    return\n  }\n\n  const path = determinePath(baseUrl, endpoint, { stripBasePath: true })\n  LOG.log(`[OID4VCI] nonce endpoint enabled at ${path}`)\n\n  router.post(path, async (request: Request, response: Response) => {\n    try {\n      const cNonce = uuidv4()\n      const cNonceExpiresIn = issuer.cNonceExpiresIn || 300\n\n      const createdAt = +Date.now()\n      const expiresAt = createdAt + Math.abs(cNonceExpiresIn) * 1000\n\n      // Create nonce state - only include session identifiers if available\n      const cNonceState: any = {\n        cNonce,\n        createdAt,\n        expiresAt,\n      }\n\n      await issuer.cNonces.set(cNonce, cNonceState)\n\n      return response.json({\n        c_nonce: cNonce,\n        c_nonce_expires_in: cNonceExpiresIn,\n      })\n    } catch (e) {\n      return sendErrorResponse(\n        response,\n        500,\n        {\n          error: 'server_error',\n          error_description: (e as Error).message,\n        },\n        e,\n      )\n    }\n  })\n}\n\nexport function getCredentialOfferEndpoint(router: Router, issuer: VcIssuer, opts?: IGetCredentialOfferEndpointOpts) {\n  const path = determinePath(opts?.baseUrl, opts?.path ?? '/webapp/credential-offers/:id', { stripBasePath: true })\n  LOG.log(`[OID4VCI] getCredentialOffer endpoint enabled at ${path}`)\n  router.get(path, async (request: Request, response: Response) => {\n    try {\n      const { id } = request.params\n      const session = await issuer.getCredentialOfferSessionById(id)\n      if (!session || !session.credentialOffer) {\n        return sendErrorResponse(response, 404, {\n          error: 'invalid_request',\n          error_description: `Credential offer ${id} not found`,\n        })\n      }\n      return response.json(session.credentialOffer.credential_offer)\n    } catch (e) {\n      return sendErrorResponse(\n        response,\n        500,\n        {\n          error: 'invalid_request',\n          error_description: (e as Error).message,\n        },\n        e,\n      )\n    }\n  })\n}\n\nexport function deleteCredentialOfferEndpoint(router: Router, issuer: VcIssuer, opts?: IGetCredentialOfferEndpointOpts) {\n  const path = determinePath(opts?.baseUrl, opts?.path ?? '/webapp/credential-offers/:id', { stripBasePath: true })\n  LOG.log(`[OID4VCI] deleteCredentialOffer endpoint enabled at ${path}`)\n  router.delete(path, async (request: Request, response: Response) => {\n    try {\n      const { id } = request.params\n      if (!id) {\n        return sendErrorResponse(response, 400, {\n          error: 'invalid_request',\n          error_description: 'id must be present',\n        })\n      }\n      await issuer.deleteCredentialOfferSessionById(id)\n      return response.sendStatus(204)\n    } catch (e) {\n      return sendErrorResponse(\n        response,\n        500,\n        {\n          error: 'invalid_request',\n          error_description: (e as Error).message,\n        },\n        e,\n      )\n    }\n  })\n}\n\nfunction buildCredentialOfferReferenceUri(request: Request<CredentialOfferRESTRequestV1_0_15>, offerReferencePath?: string) {\n  if (!offerReferencePath) {\n    return Promise.reject(Error('issuePayloadPath must bet set for offerMode REFERENCE!'))\n  }\n\n  const protocol = request.headers['x-forwarded-proto']?.toString() ?? request.protocol\n  let host = request.headers['x-forwarded-host']?.toString() ?? request.get('host')\n  const forwardedPort = request.headers['x-forwarded-port']?.toString()\n\n  if (forwardedPort && !(protocol === 'https' && forwardedPort === '443') && !(protocol === 'http' && forwardedPort === '80')) {\n    host += `:${forwardedPort}`\n  }\n\n  const forwardedPrefix = request.headers['x-forwarded-prefix']?.toString() ?? ''\n\n  return `${protocol}://${host}${forwardedPrefix}${request.baseUrl}${offerReferencePath}`\n}\n\nexport function createCredentialOfferEndpoint(\n  router: Router,\n  issuer: VcIssuer,\n  opts?: ICreateCredentialOfferEndpointOpts & { baseUrl?: string },\n  issuerPayloadPath?: string, // backwards compat, sigh\n) {\n  const path = determinePath(opts?.baseUrl, opts?.path ?? '/webapp/credential-offers', { stripBasePath: true })\n  const offerReferencePath =\n    opts?.credentialOfferReferenceBasePath ?? issuerPayloadPath ?? determinePath(opts?.baseUrl, '/credential-offers', { stripBasePath: true })\n\n  LOG.log(`[OID4VCI] createCredentialOffer endpoint enabled at ${path}`)\n  router.post(path, async (request: Request<CredentialOfferRESTRequestV1_0_15>, response: Response<ICreateCredentialOfferURIResponse>) => {\n    try {\n      // const specVersion = determineSpecVersionFromOffer(request.body.original_credential_offer)\n      // if (specVersion < OpenId4VCIVersion.VER_1_0_15) {\n      //   return sendErrorResponse(response, 400, {\n      //     error: TokenErrorResponse.invalid_client,\n      //     error_description: 'credential offer request should be of spec version 1.0.15 or above',\n      //   })\n      // }\n\n      const grantTypes = determineGrantTypes(request.body)\n      if (grantTypes.length === 0) {\n        return sendErrorResponse(response, 400, {\n          error: TokenErrorResponse.invalid_grant,\n          error_description: 'No grant type supplied',\n        })\n      }\n      const grants = request.body.grants as Grant\n      const credentialConfigIds = request.body.credential_configuration_ids as string[]\n      if (!credentialConfigIds || credentialConfigIds.length === 0) {\n        return sendErrorResponse(response, 400, {\n          error: TokenErrorResponse.invalid_request,\n          error_description: 'credential_configuration_ids missing credential_configuration_ids in credential offer payload',\n        })\n      }\n      const qrCodeOpts = request.body.qrCodeOpts ?? opts?.qrCodeOpts\n      const offerMode: CredentialOfferMode = request.body.offerMode ?? opts?.defaultCredentialOfferMode ?? 'VALUE' // default to existing mode when nothing specified\n\n      const client_id: string | undefined = request.body.client_id ?? request.body.original_credential_offer?.client_id\n      const result = await issuer.createCredentialOfferURI({\n        ...request.body,\n        offerMode,\n        client_id,\n        ...(request.body.correlationId && { correlationId: request.body.correlationId }),\n        ...(offerMode === 'REFERENCE' && { credentialOfferUri: buildCredentialOfferReferenceUri(request, offerReferencePath) }),\n        qrCodeOpts,\n        grants,\n      })\n      const resultResponse: ICreateCredentialOfferURIResponse = result\n      if ('session' in resultResponse) {\n        // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n        // @ts-ignore\n        delete resultResponse.session\n      }\n      return response.json(resultResponse)\n    } catch (e) {\n      return sendErrorResponse(\n        response,\n        500,\n        {\n          error: TokenErrorResponse.invalid_request,\n          error_description: (e as Error).message,\n        },\n        e,\n      )\n    }\n  })\n}\n\nexport function pushedAuthorizationEndpoint(\n  router: Router,\n  issuer: VcIssuer,\n  authRequestsData: Map<string, AuthorizationRequest>,\n  opts?: ISingleEndpointOpts,\n) {\n  const externalAS = isExternalAS(issuer.issuerMetadata) || issuer.asClientOpts\n  if (externalAS) {\n    LOG.log(\n      `[OID4VCI] External Authorization Server ${issuer.issuerMetadata.authorization_servers} is being used. Not enabling internal PAR endpoint`,\n    )\n    return\n  } else if (opts?.enabled === false) {\n    LOG.log(`[OID4VCI] Internal PAR endpoint is not enabled`)\n    return\n  }\n\n  const handleHttpStatus400 = async (req: Request, res: Response, next: NextFunction) => {\n    if (!req.body) {\n      return res.status(400).json({ error: 'invalid_request', error_description: 'Request body must be present' })\n    }\n    const required = ['client_id', 'code_challenge_method', 'code_challenge', 'redirect_uri']\n    const conditional = ['authorization_details', 'scope']\n    try {\n      validateRequestBody({ required, conditional, body: req.body })\n    } catch (e: unknown) {\n      return sendErrorResponse(res, 400, {\n        error: 'invalid_request',\n        error_description: (e as Error).message,\n      })\n    }\n    return next()\n  }\n\n  router.post('/par', handleHttpStatus400, (req: Request, res: Response) => {\n    // FIXME Fake client for testing, it needs to come from a registered client\n    const client = {\n      scope: ['openid', 'test'],\n      redirectUris: ['http://localhost:8080/*', 'https://www.test.com/*', 'https://test.nl', 'http://*/chart', 'http:*'],\n    }\n\n    // For security reasons the redirect_uri from the request needs to be matched against the ones present in the registered client\n    const matched = client.redirectUris.filter((s: string) => new RegExp(s.replace('*', '.*')).test(req.body.redirect_uri))\n    if (!matched.length) {\n      return sendErrorResponse(res, 400, {\n        error: 'invalid_request',\n        error_description: 'redirect_uri is not valid for the given client',\n      })\n    }\n\n    // The scopes from the request need to be matched against the ones present in the registered client\n    if (!req.body.scope.split(',').every((scope: string) => client.scope.includes(scope))) {\n      return sendErrorResponse(res, 400, {\n        error: 'invalid_scope',\n        error_description: 'scope is not valid for the given client',\n      })\n    }\n\n    // Add the authorization_details validation here:\n    if (req.body.authorization_details) {\n      const authDetails = Array.isArray(req.body.authorization_details) ? req.body.authorization_details : JSON.parse(req.body.authorization_details)\n\n      // Validate each authorization detail\n      for (const detail of authDetails) {\n        if (detail.type !== 'openid_credential') {\n          return sendErrorResponse(res, 400, {\n            error: 'invalid_authorization_details',\n            error_description: 'Only openid_credential type is supported',\n          })\n        }\n\n        // Validate credential_configuration_id exists in issuer metadata\n        if (detail.credential_configuration_id && !issuer.issuerMetadata.credential_configurations_supported[detail.credential_configuration_id]) {\n          return sendErrorResponse(res, 400, {\n            error: 'invalid_credential_request',\n            error_description: `Unsupported credential configuration: ${detail.credential_configuration_id}`,\n          })\n        }\n      }\n    }\n\n    // TODO: Both UUID and requestURI need to be configurable for the server\n    const uuid = uuidv4()\n    const requestUri = `urn:ietf:params:oauth:request_uri:${uuid}`\n\n    // Store authorization_details in the request for later retrieval\n    let requestData = req.body\n    if (req.body.authorization_details) {\n      const authDetails = Array.isArray(req.body.authorization_details) ? req.body.authorization_details : JSON.parse(req.body.authorization_details)\n\n      requestData = {\n        ...req.body,\n        authorization_details: authDetails, // Store parsed authorization details\n      }\n    }\n\n    authRequestsData.set(requestUri, requestData)\n\n    // Invalidates the request_uri removing it from the mapping after it is expired, needs to be refactored because\n    // some of the properties will be needed in subsequent steps if the authorization succeeds\n    // TODO in the /token endpoint the code_challenge must be matched against the hashed code_verifier\n    setTimeout(() => {\n      authRequestsData.delete(requestUri)\n    }, expiresIn * 1000)\n\n    return res.status(201).json({ request_uri: requestUri, expires_in: expiresIn })\n  })\n}\n\nexport function getMetadataEndpoints(\n  router: Router,\n  issuer: VcIssuer,\n  opts?: {\n    rootRouter?: Router\n    basePath?: string\n    wellKnownHostLocation?: WellKnownHostLocation\n  },\n) {\n  const credentialIssuerHandler = (request: Request, response: Response) => {\n    return response.json(issuer.issuerMetadata)\n  }\n\n  const authorizationServerHandler = (request: Request, response: Response) => {\n    return response.json(issuer.authorizationServerMetadata)\n  }\n\n  const location = opts?.wellKnownHostLocation ?? WellKnownHostLocation.AT_BOTH\n\n  // Register endpoints on context router if configured\n  if (location === WellKnownHostLocation.AT_CONTEXT_PATH || location === WellKnownHostLocation.AT_BOTH) {\n    router.get(WellKnownEndpoints.OPENID4VCI_ISSUER, credentialIssuerHandler)\n    router.get(WellKnownEndpoints.OAUTH_AS, authorizationServerHandler)\n  }\n\n  // Register endpoints on root router if configured\n  if (\n    opts?.rootRouter &&\n    opts?.basePath &&\n    opts.basePath !== '/' &&\n    (location === WellKnownHostLocation.AT_ROOT_PATH || location === WellKnownHostLocation.AT_BOTH)\n  ) {\n    opts.rootRouter.get(`/.well-known/openid-credential-issuer${opts.basePath}`, credentialIssuerHandler)\n    opts.rootRouter.get(`/.well-known/oauth-authorization-server${opts.basePath}`, authorizationServerHandler)\n  }\n}\n\nexport function determinePath(\n  baseUrl: URL | string | undefined,\n  endpoint: string,\n  opts?: { skipBaseUrlCheck?: boolean; prependUrl?: string; stripBasePath?: boolean },\n) {\n  const basePath = baseUrl ? getBasePath(baseUrl) : ''\n  let path = endpoint\n  if (opts?.prependUrl) {\n    path = adjustUrl(path, { prepend: opts.prependUrl })\n  }\n  if (opts?.skipBaseUrlCheck !== true) {\n    assertEndpointHasIssuerBaseUrl(baseUrl, endpoint)\n  }\n  if (endpoint.includes('://')) {\n    path = new URL(endpoint).pathname\n  }\n  path = `/${trimBoth(path, '/')}`\n  if (opts?.stripBasePath && path.startsWith(basePath)) {\n    path = trimStart(path, basePath)\n    path = `/${trimBoth(path, '/')}`\n  }\n  return path\n}\n\nfunction assertEndpointHasIssuerBaseUrl(baseUrl: URL | string | undefined, endpoint: string) {\n  if (!validateEndpointHasIssuerBaseUrl(baseUrl, endpoint)) {\n    throw Error(`endpoint '${endpoint}' does not have base url '${baseUrl ? getBaseUrl(baseUrl) : '<no baseurl supplied>'}'`)\n  }\n}\n\nfunction validateEndpointHasIssuerBaseUrl(baseUrl: URL | string | undefined, endpoint: string): boolean {\n  if (!endpoint) {\n    return false\n  } else if (!endpoint.includes('://')) {\n    return true //absolute or relative path, not containing a hostname\n  } else if (!baseUrl) {\n    return true\n  }\n  return endpoint.startsWith(getBaseUrl(baseUrl))\n}\n\nexport function getBaseUrl(url?: URL | string | undefined) {\n  let baseUrl = url\n  if (!baseUrl) {\n    const envUrl = env('BASE_URL', process?.env?.ENV_PREFIX)\n    if (envUrl && envUrl.length > 0) {\n      baseUrl = new URL(envUrl)\n    }\n  }\n  if (!baseUrl) {\n    throw Error(`No base URL provided`)\n  }\n  return trimEnd(baseUrl.toString(), '/')\n}\n\nexport function getBasePath(url?: URL | string) {\n  const basePath = new URL(getBaseUrl(url)).pathname\n  if (basePath === '' || basePath === '/') {\n    return ''\n  }\n  return `/${trimBoth(basePath, '/')}`\n}\n","import { DPoPVerifyJwtCallback, JWK, uuidv4, verifyDPoP } from '@sphereon/oid4vc-common'\nimport { AuthorizationRequest, GrantTypes, PRE_AUTHORIZED_CODE_REQUIRED_ERROR, TokenError, TokenErrorResponse } from '@sphereon/oid4vci-common'\nimport { assertValidAccessTokenRequest, createAccessTokenResponse, ITokenEndpointOpts, VcIssuer } from '@sphereon/oid4vci-issuer'\nimport { sendErrorResponse } from '@sphereon/ssi-express-support'\nimport { NextFunction, Request, Response } from 'express'\n\n/**\n *\n * @param tokenExpiresIn\n * @param accessTokenSignerCallback\n * @param accessTokenIssuer\n * @param cNonceExpiresIn\n * @param issuer\n * @param interval\n */\nexport const handleTokenRequest = ({\n  tokenExpiresIn, // expiration in seconds\n  accessTokenEndpoint,\n  accessTokenSignerCallback,\n  accessTokenIssuer,\n  cNonceExpiresIn, // expiration in seconds\n  issuer,\n  interval,\n  dpop,\n}: Required<Pick<ITokenEndpointOpts, 'accessTokenIssuer' | 'cNonceExpiresIn' | 'interval' | 'accessTokenSignerCallback' | 'tokenExpiresIn'>> & {\n  issuer: VcIssuer\n  dpop?: {\n    requireDPoP?: boolean\n    dPoPVerifyJwtCallback: DPoPVerifyJwtCallback\n  }\n  // The full URL of the access token endpoint\n  accessTokenEndpoint?: string\n}) => {\n  return async (request: Request, response: Response) => {\n    response.set({\n      'Cache-Control': 'no-store',\n      Pragma: 'no-cache',\n    })\n\n    if (request.body.grant_type !== GrantTypes.PRE_AUTHORIZED_CODE) {\n      // Yes this is redundant, only here to remind us that we need to implement the auth flow as well\n      return sendErrorResponse(response, 400, {\n        error: TokenErrorResponse.invalid_request,\n        error_description: PRE_AUTHORIZED_CODE_REQUIRED_ERROR,\n      })\n    }\n\n    if (request.headers.authorization && request.headers.authorization.startsWith('DPoP ') && !request.headers.DPoP) {\n      return sendErrorResponse(response, 400, {\n        error: TokenErrorResponse.invalid_request,\n        error_description: 'DPoP header is required',\n      })\n    }\n\n    let dPoPJwk: JWK | undefined\n    if (dpop?.requireDPoP && !request.headers.dpop) {\n      return sendErrorResponse(response, 400, {\n        error: TokenErrorResponse.invalid_request,\n        error_description: 'DPoP is required for requesting access tokens.',\n      })\n    }\n\n    if (request.headers.dpop) {\n      if (!dpop) {\n        console.error('Received unsupported DPoP header. The issuer is not configured to work with DPoP. Provide DPoP options for it to work.')\n\n        return sendErrorResponse(response, 400, {\n          error: TokenErrorResponse.invalid_request,\n          error_description: 'Received unsupported DPoP header.',\n        })\n      }\n\n      try {\n        const fullUrl = accessTokenEndpoint ?? request.protocol + '://' + request.get('host') + request.originalUrl\n        dPoPJwk = await verifyDPoP(\n          { method: request.method, headers: request.headers, fullUrl },\n          {\n            jwtVerifyCallback: dpop.dPoPVerifyJwtCallback,\n            expectAccessToken: false,\n            maxIatAgeInSeconds: undefined,\n          },\n        )\n      } catch (error) {\n        return sendErrorResponse(response, 400, {\n          error: TokenErrorResponse.invalid_dpop_proof,\n          error_description: error instanceof Error ? error.message : 'Unknown error',\n        })\n      }\n    }\n\n    try {\n      const responseBody = await createAccessTokenResponse(request.body, {\n        credentialOfferSessions: issuer.credentialOfferSessions,\n        accessTokenIssuer,\n        cNonces: issuer.cNonces,\n        cNonce: uuidv4(),\n        accessTokenSignerCallback,\n        cNonceExpiresIn,\n        interval,\n        tokenExpiresIn,\n        dPoPJwk,\n      })\n      return response.status(200).json(responseBody)\n    } catch (error) {\n      return sendErrorResponse(\n        response,\n        400,\n        {\n          error: TokenErrorResponse.invalid_request,\n        },\n        error,\n      )\n    }\n  }\n}\n\nexport const verifyTokenRequest = ({\n  preAuthorizedCodeExpirationDuration,\n  issuer,\n  authRequestsData,\n}: Required<Pick<ITokenEndpointOpts, 'preAuthorizedCodeExpirationDuration'>> & {\n  issuer: VcIssuer\n  authRequestsData?: Map<string, AuthorizationRequest>\n}) => {\n  return async (request: Request, response: Response, next: NextFunction) => {\n    try {\n      await assertValidAccessTokenRequest(request.body, {\n        expirationDuration: preAuthorizedCodeExpirationDuration,\n        credentialOfferSessions: issuer.credentialOfferSessions,\n        authRequestsData,\n      })\n    } catch (error) {\n      if (error instanceof TokenError) {\n        return sendErrorResponse(response, error.statusCode, {\n          error: error.responseError,\n          error_description: error.getDescription(),\n        })\n      } else {\n        return sendErrorResponse(response, 400, { error: TokenErrorResponse.invalid_request, error_description: (error as Error).message }, error)\n      }\n    }\n\n    return next()\n  }\n}\n","import { Request } from 'express'\n\nexport const validateRequestBody = ({\n  required,\n  conditional,\n  body,\n}: {\n  required?: string[]\n  conditional?: string[]\n  body: Pick<Request, 'body'>\n}): void => {\n  const keys = Object.keys(body)\n  let message\n  if (required && !required.every((k) => keys.includes(k))) {\n    message = `Request must contain ${required.toString()}`\n  }\n  if (conditional && !conditional.some((k) => keys.includes(k))) {\n    message = message ? `and request must contain ether ${conditional.toString()}` : `Request must contain ether ${conditional.toString()}`\n  }\n  if (message) {\n    throw new Error(message)\n  }\n}\n"],"mappings":"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","names":["import_oid4vci_issuer","import_oid4vc_common","import_oid4vci_common","import_oid4vci_issuer","import_ssi_express_support","handleTokenRequest","tokenExpiresIn","accessTokenEndpoint","accessTokenSignerCallback","accessTokenIssuer","cNonceExpiresIn","issuer","interval","dpop","request","response","set","Pragma","body","grant_type","GrantTypes","PRE_AUTHORIZED_CODE","sendErrorResponse","error","TokenErrorResponse","invalid_request","error_description","PRE_AUTHORIZED_CODE_REQUIRED_ERROR","headers","authorization","startsWith","DPoP","dPoPJwk","requireDPoP","console","fullUrl","protocol","get","originalUrl","verifyDPoP","method","jwtVerifyCallback","dPoPVerifyJwtCallback","expectAccessToken","maxIatAgeInSeconds","undefined","invalid_dpop_proof","Error","message","responseBody","createAccessTokenResponse","credentialOfferSessions","cNonces","cNonce","uuidv4","status","json","verifyTokenRequest","preAuthorizedCodeExpirationDuration","authRequestsData","next","assertValidAccessTokenRequest","expirationDuration","TokenError","statusCode","responseError","getDescription","validateRequestBody","required","conditional","body","keys","Object","message","every","k","includes","toString","some","Error","expiresIn","process","env","EXPIRES_IN","parseInt","getIssueStatusEndpoint","router","issuer","opts","path","determinePath","baseUrl","stripBasePath","LOG","log","post","request","response","id","body","session","getCredentialOfferSessionById","credentialOffer","sendErrorResponse","error","error_description","authStatusBody","createdAt","lastUpdatedAt","expiresAt","status","statusLists","clientId","json","e","message","getCredentialOfferReferenceEndpoint","get","params","warning","credential_offer","isExternalAS","issuerMetadata","authorization_servers","some","as","includes","credential_issuer","authorizationChallengeEndpoint","endpoint","authorizationServerMetadata","authorization_challenge_endpoint","getBaseUrl","info","authorizationChallengeRequest","client_id","issuer_state","auth_session","presentation_during_issuance_session","authorizationChallengeErrorResponse","AuthorizationChallengeError","invalid_request","credentialOfferSessions","invalid_session","authRequestURI","createAuthRequestUriCallback","insufficient_authorization","presentation","verifiedResponse","verifyAuthResponseCallback","authorizationCode","generateRandomString","set","authorizationChallengeCodeResponse","authorization_code","accessTokenEndpoint","externalAS","asClientOpts","accessTokenProvider","enabled","accessTokenIssuer","ACCESS_TOKEN_ISSUER","preAuthorizedCodeExpirationDuration","getNumberOrUndefined","PRE_AUTHORIZED_CODE_EXPIRATION_DURATION","interval","INTERVAL","tokenExpiresIn","accessTokenSignerCallback","undefined","Error","JWT_SIGNER_CALLBACK_REQUIRED_ERROR","ACCESS_TOKEN_ISSUER_REQUIRED_ERROR","tokenPath","TOKEN_PATH","skipBaseUrlCheck","url","URL","toString","pathname","verifyTokenRequest","authRequestsData","handleTokenRequest","cNonceExpiresIn","getCredentialEndpoint","credential_endpoint","credentialRequest","issuerCorrelation","jwt","extractBearerToken","header","jwtVerifyResult","validateJWT","accessTokenVerificationCallback","jwtVerifyCallback","tokenClaims","payload","preAuthorizedCode","issuerState","Array","isArray","authorization_details","authorizationDetails","credential_identifier","validIdentifiers","flatMap","detail","credential_identifiers","credential","issueCredential","notificationEndpoint","notification_endpoint","notificationRequest","event","event_description","notification_id","EVENTS","emit","NotificationStatusEventNames","OID4VCI_NOTIFICATION_RECEIVED","eventName","uuidv4","data","initiator","initiatorType","InitiatorType","EXTERNAL","system","System","OID4VCI","subsystem","SubSystem","API","jwtResult","accessToken","errorOrSession","processNotification","notification","OID4VCI_NOTIFICATION_ERROR","OID4VCI_NOTIFICATION_PROCESSED","send","nonceEndpoint","nonce_endpoint","cNonce","Date","now","Math","abs","cNonceState","cNonces","c_nonce","c_nonce_expires_in","getCredentialOfferEndpoint","deleteCredentialOfferEndpoint","delete","deleteCredentialOfferSessionById","sendStatus","buildCredentialOfferReferenceUri","offerReferencePath","Promise","reject","protocol","headers","host","forwardedPort","forwardedPrefix","createCredentialOfferEndpoint","issuerPayloadPath","credentialOfferReferenceBasePath","grantTypes","determineGrantTypes","length","TokenErrorResponse","invalid_grant","grants","credentialConfigIds","credential_configuration_ids","qrCodeOpts","offerMode","defaultCredentialOfferMode","original_credential_offer","result","createCredentialOfferURI","correlationId","credentialOfferUri","resultResponse","pushedAuthorizationEndpoint","handleHttpStatus400","req","res","next","required","conditional","validateRequestBody","client","scope","redirectUris","matched","filter","s","RegExp","replace","test","redirect_uri","split","every","authDetails","JSON","parse","type","credential_configuration_id","credential_configurations_supported","uuid","requestUri","requestData","setTimeout","request_uri","expires_in","getMetadataEndpoints","credentialIssuerHandler","authorizationServerHandler","location","wellKnownHostLocation","WellKnownHostLocation","AT_BOTH","AT_CONTEXT_PATH","WellKnownEndpoints","OPENID4VCI_ISSUER","OAUTH_AS","rootRouter","basePath","AT_ROOT_PATH","getBasePath","prependUrl","adjustUrl","prepend","assertEndpointHasIssuerBaseUrl","trimBoth","startsWith","trimStart","validateEndpointHasIssuerBaseUrl","envUrl","ENV_PREFIX","trimEnd","buildVCIFromEnvironment","credentialsSupported","CredentialSupportedBuilderV1_15","withCredentialSigningAlgValuesSupported","process","env","credential_signing_alg_values_supported","withCryptographicBindingMethod","cryptographic_binding_methods_supported","withFormat","credential_supported_format","withCredentialName","credential_supported_name_1","withCredentialDefinition","type","credential_supported_1_definition_type_1","credential_supported_1_definition_type_2","withCredentialSupportedDisplay","name","credential_display_name","locale","credential_display_locale","logo","url","credential_display_logo_url","alt_text","credential_display_logo_alt_text","background_color","credential_display_background_color","text_color","credential_display_text_color","build","issuerBuilder","VcIssuerBuilder","withTXCode","length","user_pin_length","input_mode","user_pin_input_mode","withAuthorizationServers","authorization_server","withCredentialEndpoint","credential_endpoint","withNonceEndpoint","nonce_endpoint","withCredentialIssuer","credential_issuer","withIssuerDisplay","issuer_name","issuer_locale","withCredentialConfigurationsSupported","withInMemoryCredentialOfferState","withInMemoryCNonceState","authorization_server_client_id","authorization_server_redirect_uri","Error","withASClientMetadataParams","client_id","client_secret","authorization_server_client_secret","redirect_uris","WellKnownHostLocation","OID4VCIServer","_issuer","authRequestsData","Map","_app","_baseUrl","_expressSupport","_router","_asClientOpts","_wellknownHostLocation","expressSupport","opts","URL","baseUrl","BASE_URL","issuer","issuerMetadata","express","Router","asClientOpts","undefined","wellKnownHostLocation","WELLKNOWN_HOST_LOCATION","pushedAuthorizationEndpoint","router","basePath","getBasePath","rootRouter","wellknownHostLocation","use","getMetadataEndpoints","issuerPayloadPath","isGetIssuePayloadEndpointEnabled","endpointOpts","getIssuePayloadOpts","getCredentialOfferReferenceEndpoint","createCredentialOfferOpts","enabled","CREDENTIAL_OFFER_ENDPOINT_ENABLED","createCredentialOfferEndpoint","deleteCredentialOfferEndpoint","deleteCredentialOfferOpts","getCredentialOfferEndpoint","getCredentialOfferOpts","getCredentialEndpoint","tokenEndpointOpts","accessTokenVerificationCallback","oidcAccessTokenVerifyCallback","clientMetadata","credentialIssuer","authorizationServer","authorization_servers","assertAccessTokenHandling","isTokenEndpointDisabled","accessTokenEndpoint","isStatusEndpointEnabled","getStatusOpts","getIssueStatusEndpoint","isAuthorizationChallengeEndpointEnabled","authorizationChallengeOpts","createAuthRequestUriCallback","verifyAuthResponseCallback","authorizationChallengeEndpoint","isNonceEndpointEnabled","nonceOpts","nonceEndpoint","app","stop","asClientMetadata","tokenEndpointDisabled","TOKEN_ENDPOINT_DISABLED","statusEndpointOpts","STATUS_ENDPOINT_ENABLED","payloadEndpointOpts","authorizationChallengeEndpointOpts","AUTHORIZATION_CHALLENGE_ENDPOINT_ENABLED","authServer","console","log","some","as","nonceEndpointOpts","NONCE_ENDPOINT_ENABLED"]}