{"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"}