diff --git a/cloud-agent/service/server/src/main/resources/application.conf b/cloud-agent/service/server/src/main/resources/application.conf index be4f6a0328..fa68027d75 100644 --- a/cloud-agent/service/server/src/main/resources/application.conf +++ b/cloud-agent/service/server/src/main/resources/application.conf @@ -52,6 +52,8 @@ pollux { syncRevocationStatusesBgJobProcessingParallelism = ${?SYNC_REVOCATION_STATUSES_BG_JOB_PROCESSING_PARALLELISM} credential.sdJwt.expiry = 30 days credential.sdJwt.expiry = ${?CREDENTIAL_SD_JWT_EXPIRY} + presentationInvitationExpiry = 300 seconds + presentationInvitationExpiry = ${?PRESENTATION_INVITATION_EXPIRY} } connect { diff --git a/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/agent/server/config/AppConfig.scala b/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/agent/server/config/AppConfig.scala index 78fd4eb455..7955ae9641 100644 --- a/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/agent/server/config/AppConfig.scala +++ b/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/agent/server/config/AppConfig.scala @@ -78,6 +78,7 @@ final case class PolluxConfig( presentationBgJobProcessingParallelism: Int, syncRevocationStatusesBgJobRecurrenceDelay: Duration, syncRevocationStatusesBgJobProcessingParallelism: Int, + presentationInvitationExpiry: Duration, ) final case class ConnectConfig( database: DatabaseConfig, diff --git a/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/agent/server/jobs/PresentBackgroundJobs.scala b/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/agent/server/jobs/PresentBackgroundJobs.scala index a07ac1f04a..2d1104eec6 100644 --- a/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/agent/server/jobs/PresentBackgroundJobs.scala +++ b/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/agent/server/jobs/PresentBackgroundJobs.scala @@ -17,6 +17,7 @@ import org.hyperledger.identus.castor.core.model.error.DIDResolutionError as Cas import org.hyperledger.identus.castor.core.service.DIDService import org.hyperledger.identus.mercury.* import org.hyperledger.identus.mercury.model.* +import org.hyperledger.identus.mercury.protocol.invitation.v2.Invitation import org.hyperledger.identus.mercury.protocol.presentproof.* import org.hyperledger.identus.mercury.protocol.reportproblem.v2.{ProblemCode, ReportProblem} import org.hyperledger.identus.pollux.core.model.* @@ -436,7 +437,7 @@ object PresentBackgroundJobs extends BackgroundJobsHelper { _, PresentationReceived, credentialFormat, - _, + invitation, Some(requestPresentation), _, Some(presentation), @@ -450,7 +451,7 @@ object PresentBackgroundJobs extends BackgroundJobsHelper { _ ) => // Verifier ZIO.logDebug("PresentationRecord: PresentationReceived") *> ZIO.unit - Verifier.PresentationReceived.handle(id, requestPresentation, presentation, credentialFormat) + Verifier.PresentationReceived.handle(id, requestPresentation, presentation, credentialFormat, invitation) case PresentationRecord( id, @@ -893,7 +894,8 @@ object PresentBackgroundJobs extends BackgroundJobsHelper { id: DidCommID, requestPresentation: RequestPresentation, presentation: Presentation, - credentialFormat: CredentialFormat + credentialFormat: CredentialFormat, + invitation: Option[Invitation] ): ZIO[ AppConfig & JwtDidResolver & COMMON_RESOURCES & MESSAGING_RESOURCES, Failure, @@ -901,14 +903,34 @@ object PresentBackgroundJobs extends BackgroundJobsHelper { ] = { val result = credentialFormat match { - case CredentialFormat.JWT => handleJWT(id, requestPresentation, presentation) - case CredentialFormat.SDJWT => handleSDJWT(id, presentation) - case CredentialFormat.AnonCreds => handleAnoncred(id, requestPresentation, presentation) + case CredentialFormat.JWT => handleJWT(id, requestPresentation, presentation, invitation) + case CredentialFormat.SDJWT => handleSDJWT(id, presentation, invitation) + case CredentialFormat.AnonCreds => handleAnoncred(id, requestPresentation, presentation, invitation) } result @@ metric } - private def handleJWT(id: DidCommID, requestPresentation: RequestPresentation, presentation: Presentation): ZIO[ + private def checkInvitationExpiry( + id: DidCommID, + invitation: Option[Invitation] + ): ZIO[PresentationService & WalletAccessContext, PresentationError, Unit] = { + invitation.flatMap(_.expires_time) match { + case Some(expiryTime) if Instant.now().getEpochSecond > expiryTime => + for { + service <- ZIO.service[PresentationService] + _ <- service.markPresentationInvitationExpired(id) + _ <- ZIO.fail(PresentationError.InvitationExpired(s"Invitation has expired. Expiry time: $expiryTime")) + } yield () + case _ => ZIO.unit + } + } + + private def handleJWT( + id: DidCommID, + requestPresentation: RequestPresentation, + presentation: Presentation, + invitation: Option[Invitation] + ): ZIO[ AppConfig & JwtDidResolver & COMMON_RESOURCES & MESSAGING_RESOURCES, Failure, Unit @@ -916,6 +938,7 @@ object PresentBackgroundJobs extends BackgroundJobsHelper { val clock = java.time.Clock.system(ZoneId.systemDefault) for { walletAccessContext <- buildWalletAccessContextLayer(presentation.to) + _ <- checkInvitationExpiry(id, invitation).provideSomeLayer(ZLayer.succeed(walletAccessContext)) result <- for { didResolverService <- ZIO.service[JwtDidResolver] credentialsClaimsValidationResult <- presentation.attachments.head.data match { @@ -1022,13 +1045,14 @@ object PresentBackgroundJobs extends BackgroundJobsHelper { } yield result } - private def handleSDJWT(id: DidCommID, presentation: Presentation): ZIO[ + private def handleSDJWT(id: DidCommID, presentation: Presentation, invitation: Option[Invitation]): ZIO[ JwtDidResolver & COMMON_RESOURCES & MESSAGING_RESOURCES, Failure, Unit ] = { for { walletAccessContext <- buildWalletAccessContextLayer(presentation.to) + _ <- checkInvitationExpiry(id, invitation).provideSomeLayer(ZLayer.succeed(walletAccessContext)) result <- for { didResolverService <- ZIO.service[JwtDidResolver] credentialsClaimsValidationResult <- presentation.attachments.head.data match { @@ -1090,7 +1114,8 @@ object PresentBackgroundJobs extends BackgroundJobsHelper { private def handleAnoncred( id: DidCommID, requestPresentation: RequestPresentation, - presentation: Presentation + presentation: Presentation, + invitation: Option[Invitation] ): ZIO[ PresentationService & DIDNonSecretStorage & MESSAGING_RESOURCES, PresentationError | DIDSecretStorageError, @@ -1098,12 +1123,13 @@ object PresentBackgroundJobs extends BackgroundJobsHelper { ] = { for { walletAccessContext <- buildWalletAccessContextLayer(presentation.to) - presReceivedToProcessedAspect = CustomMetricsAspect.endRecordingTime( - s"${id}_present_proof_flow_verifier_presentation_received_to_verification_success_or_failure_ms_gauge", - "present_proof_flow_verifier_presentation_received_to_verification_success_or_failure_ms_gauge" - ) + _ <- checkInvitationExpiry(id, invitation).provideSomeLayer(ZLayer.succeed(walletAccessContext)) result <- for { service <- ZIO.service[PresentationService] + presReceivedToProcessedAspect = CustomMetricsAspect.endRecordingTime( + s"${id}_present_proof_flow_verifier_presentation_received_to_verification_success_or_failure_ms_gauge", + "present_proof_flow_verifier_presentation_received_to_verification_success_or_failure_ms_gauge" + ) _ <- (service .verifyAnoncredPresentation(presentation, requestPresentation, id) .provideSomeLayer(ZLayer.succeed(walletAccessContext)) @@ presReceivedToProcessedAspect) diff --git a/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/presentproof/controller/PresentProofControllerImpl.scala b/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/presentproof/controller/PresentProofControllerImpl.scala index 044ae2d40b..c95f176c46 100644 --- a/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/presentproof/controller/PresentProofControllerImpl.scala +++ b/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/presentproof/controller/PresentProofControllerImpl.scala @@ -79,6 +79,7 @@ class PresentProofControllerImpl( req.claims, req.anoncredPresentationRequest, None, + None, None ) case req: OOBRequestPresentationInput => @@ -92,7 +93,8 @@ class PresentProofControllerImpl( req.claims, req.anoncredPresentationRequest, req.goalCode, - req.goal + req.goal, + Some(appConfig.pollux.presentationInvitationExpiry) ) } } @@ -107,7 +109,8 @@ class PresentProofControllerImpl( claims: Option[zio.json.ast.Json.Obj], anoncredPresentationRequest: Option[AnoncredPresentationRequestV1], goalCode: Option[String], - goal: Option[String] + goal: Option[String], + expirationDuration: Option[Duration], ): ZIO[WalletAccessContext, PresentationError, PresentationRecord] = { val format = credentialFormat.map(CredentialFormat.valueOf).getOrElse(CredentialFormat.JWT) format match { @@ -126,7 +129,8 @@ class PresentProofControllerImpl( }, options = options, goalCode = goalCode, - goal = goal + goal = goal, + expirationDuration = expirationDuration, ) case CredentialFormat.SDJWT => claims match { @@ -146,7 +150,8 @@ class PresentProofControllerImpl( claimsToDisclose = claimsToDisclose, options = options, goalCode = goalCode, - goal = goal + goal = goal, + expirationDuration = expirationDuration, ) case None => ZIO.fail( @@ -165,7 +170,8 @@ class PresentProofControllerImpl( connectionId = connectionId, presentationRequest = presentationRequest, goalCode = goalCode, - goal = goal + goal = goal, + expirationDuration = expirationDuration, ) case None => ZIO.fail( diff --git a/mercury/protocol-invitation/src/main/scala/org/hyperledger/identus/mercury/protocol/invitation/v2/Invitation.scala b/mercury/protocol-invitation/src/main/scala/org/hyperledger/identus/mercury/protocol/invitation/v2/Invitation.scala index 3e044813a8..c774bd54e4 100644 --- a/mercury/protocol-invitation/src/main/scala/org/hyperledger/identus/mercury/protocol/invitation/v2/Invitation.scala +++ b/mercury/protocol-invitation/src/main/scala/org/hyperledger/identus/mercury/protocol/invitation/v2/Invitation.scala @@ -14,11 +14,12 @@ final case class Invitation( `type`: PIURI = Invitation.`type`, from: DidId, body: Invitation.Body, - attachments: Option[Seq[AttachmentDescriptor]] = None + attachments: Option[Seq[AttachmentDescriptor]] = None, + created_time: Option[Long] = None, + expires_time: Option[Long] = None, ) { assert(`type` == "https://didcomm.org/out-of-band/2.0/invitation") def toBase64: String = java.util.Base64.getUrlEncoder.encodeToString(this.asJson.deepDropNullValues.noSpaces.getBytes) - } object Invitation { diff --git a/mercury/protocol-present-proof/src/main/scala/org/hyperledger/identus/mercury/protocol/presentproof/PresentProofInvitation.scala b/mercury/protocol-present-proof/src/main/scala/org/hyperledger/identus/mercury/protocol/presentproof/PresentProofInvitation.scala index 905438b6d9..313ecc04ca 100644 --- a/mercury/protocol-present-proof/src/main/scala/org/hyperledger/identus/mercury/protocol/presentproof/PresentProofInvitation.scala +++ b/mercury/protocol-present-proof/src/main/scala/org/hyperledger/identus/mercury/protocol/presentproof/PresentProofInvitation.scala @@ -2,18 +2,26 @@ package org.hyperledger.identus.mercury.protocol.presentproof import org.hyperledger.identus.mercury.model.{AttachmentDescriptor, DidId} import org.hyperledger.identus.mercury.protocol.invitation.v2.Invitation +import zio.Duration + +import java.time.Instant + object PresentProofInvitation { def makeInvitation( from: DidId, goalCode: Option[String], goal: Option[String], invitationId: String, - requestPresentation: RequestPresentation + requestPresentation: RequestPresentation, + expirationDuration: Option[Duration] = None, ): Invitation = { val attachmentDescriptor = AttachmentDescriptor.buildJsonAttachment(payload = requestPresentation) + val now = Instant.now Invitation( id = invitationId, from = from, + created_time = Some(now.getEpochSecond), + expires_time = expirationDuration.map(now.plus(_).getEpochSecond), body = Invitation.Body( goal_code = goalCode, goal = goal, diff --git a/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/model/error/PresentationError.scala b/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/model/error/PresentationError.scala index 93acaf4ef4..3a47821c7e 100644 --- a/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/model/error/PresentationError.scala +++ b/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/model/error/PresentationError.scala @@ -217,6 +217,12 @@ object PresentationError { cause ) + final case class InvitationExpired(msg: String) + extends PresentationError( + StatusCode.BadRequest, + msg + ) + final case class InvitationAlreadyReceived(msg: String) extends PresentationError( StatusCode.BadRequest, diff --git a/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/service/PresentationService.scala b/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/service/PresentationService.scala index 5981338168..d3c3781cf2 100644 --- a/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/service/PresentationService.scala +++ b/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/service/PresentationService.scala @@ -28,6 +28,7 @@ trait PresentationService { options: Option[org.hyperledger.identus.pollux.core.model.presentation.Options], goalCode: Option[String], goal: Option[String], + expirationDuration: Option[Duration], ): ZIO[WalletAccessContext, PresentationError, PresentationRecord] def createSDJWTPresentationRecord( @@ -40,6 +41,7 @@ trait PresentationService { options: Option[org.hyperledger.identus.pollux.core.model.presentation.Options], goalCode: Option[String], goal: Option[String], + expirationDuration: Option[Duration], ): ZIO[WalletAccessContext, PresentationError, PresentationRecord] def createAnoncredPresentationRecord( @@ -50,6 +52,7 @@ trait PresentationService { presentationRequest: AnoncredPresentationRequestV1, goalCode: Option[String], goal: Option[String], + expirationDuration: Option[Duration], ): ZIO[WalletAccessContext, PresentationError, PresentationRecord] def getPresentationRecords( @@ -180,4 +183,8 @@ trait PresentationService { pairwiseProverDID: DidId, invitation: String ): ZIO[WalletAccessContext, PresentationError, RequestPresentation] + + def markPresentationInvitationExpired( + recordId: DidCommID + ): ZIO[WalletAccessContext, PresentationError, PresentationRecord] } diff --git a/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/service/PresentationServiceImpl.scala b/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/service/PresentationServiceImpl.scala index 9178b2f688..49789d2c1d 100644 --- a/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/service/PresentationServiceImpl.scala +++ b/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/service/PresentationServiceImpl.scala @@ -312,6 +312,7 @@ private class PresentationServiceImpl( options: Option[org.hyperledger.identus.pollux.core.model.presentation.Options], goalCode: Option[String] = None, goal: Option[String] = None, + expirationDuration: Option[Duration] = None, ): ZIO[WalletAccessContext, PresentationError, PresentationRecord] = { createPresentationRecord( pairwiseVerifierDID, @@ -322,7 +323,8 @@ private class PresentationServiceImpl( proofTypes, options.map(o => Seq(toJWTAttachment(o))).getOrElse(Seq.empty), goalCode, - goal + goal, + expirationDuration ) } @@ -336,6 +338,7 @@ private class PresentationServiceImpl( options: Option[org.hyperledger.identus.pollux.core.model.presentation.Options], goalCode: Option[String] = None, goal: Option[String] = None, + expirationDuration: Option[Duration] = None, ): ZIO[WalletAccessContext, PresentationError, PresentationRecord] = { createPresentationRecord( pairwiseVerifierDID, @@ -346,7 +349,8 @@ private class PresentationServiceImpl( proofTypes, attachments = Seq(toSDJWTAttachment(options, claimsToDisclose)), goalCode, - goal + goal, + expirationDuration ) } @@ -358,6 +362,7 @@ private class PresentationServiceImpl( presentationRequest: AnoncredPresentationRequestV1, goalCode: Option[String] = None, goal: Option[String] = None, + expirationDuration: Option[Duration] = None, ): ZIO[WalletAccessContext, PresentationError, PresentationRecord] = { createPresentationRecord( pairwiseVerifierDID, @@ -368,7 +373,8 @@ private class PresentationServiceImpl( Seq.empty, Seq(toAnoncredAttachment(presentationRequest)), goalCode, - goal + goal, + expirationDuration ) } @@ -382,6 +388,7 @@ private class PresentationServiceImpl( attachments: Seq[AttachmentDescriptor], goalCode: Option[String] = None, goal: Option[String] = None, + expirationDuration: Option[Duration] = None, ) = { for { request <- ZIO.succeed( @@ -400,7 +407,8 @@ private class PresentationServiceImpl( goalCode, goal, thid.value, - request + request, + expirationDuration ) ) )(_ => None) @@ -414,7 +422,7 @@ private class PresentationServiceImpl( connectionId = connectionId, schemaId = None, // TODO REMOVE from DB role = PresentationRecord.Role.Verifier, - subjectId = pairwiseProverDID.getOrElse(DidId("TODO REMOVE subject did")), + subjectId = pairwiseProverDID.getOrElse(DidId("TODO REMOVE")), // TODO REMOVE from DB protocolState = invitation.fold(PresentationRecord.ProtocolState.RequestPending)(_ => PresentationRecord.ProtocolState.InvitationGenerated ), @@ -1065,6 +1073,15 @@ private class PresentationServiceImpl( PresentationRecord.ProtocolState.RequestRejected ) + override def markPresentationInvitationExpired( + recordId: DidCommID + ): ZIO[WalletAccessContext, PresentationError, PresentationRecord] = + updatePresentationRecordProtocolState( + recordId, + PresentationRecord.ProtocolState.PresentationReceived, + PresentationRecord.ProtocolState.InvitationExpired + ) + override def markPresentationVerificationFailed( recordId: DidCommID ): ZIO[WalletAccessContext, PresentationError, PresentationRecord] = @@ -1230,6 +1247,13 @@ private class PresentationServiceImpl( invitation <- ZIO .fromEither(io.circe.parser.decode[Invitation](Base64Utils.decodeUrlToString(invitation))) .mapError(err => InvitationParsingError(err.getMessage)) + _ <- invitation.expires_time match { + case Some(expiryTime) => + ZIO + .fail(PresentationError.InvitationExpired(s"Invitation has expired. Expiry time: $expiryTime")) + .when(Instant.now().getEpochSecond > expiryTime) + case None => ZIO.unit + } _ <- presentationRepository .findPresentationRecordByThreadId(DidCommID(invitation.id)) .flatMap { diff --git a/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/service/PresentationServiceNotifier.scala b/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/service/PresentationServiceNotifier.scala index 955149f1df..d9afe48cd5 100644 --- a/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/service/PresentationServiceNotifier.scala +++ b/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/service/PresentationServiceNotifier.scala @@ -16,7 +16,7 @@ import org.hyperledger.identus.pollux.core.service.serdes.{AnoncredCredentialPro import org.hyperledger.identus.pollux.sdjwt.{HolderPrivateKey, PresentationCompact} import org.hyperledger.identus.pollux.vc.jwt.{Issuer, PresentationPayload, W3cCredentialPayload} import org.hyperledger.identus.shared.models.* -import zio.{IO, UIO, URLayer, ZIO, ZLayer} +import zio.{Duration, IO, UIO, URLayer, ZIO, ZLayer} import zio.json.* import java.time.Instant @@ -38,6 +38,7 @@ class PresentationServiceNotifier( options: Option[Options], goalCode: Option[String], goal: Option[String], + expirationTime: Option[Duration], ): ZIO[WalletAccessContext, PresentationError, PresentationRecord] = notifyOnSuccess( svc.createJwtPresentationRecord( @@ -48,7 +49,8 @@ class PresentationServiceNotifier( proofTypes, options, goalCode, - goal + goal, + expirationTime ) ) @@ -62,6 +64,7 @@ class PresentationServiceNotifier( options: Option[org.hyperledger.identus.pollux.core.model.presentation.Options], goalCode: Option[String], goal: Option[String], + expirationTime: Option[Duration], ): ZIO[WalletAccessContext, PresentationError, PresentationRecord] = notifyOnSuccess( svc.createSDJWTPresentationRecord( @@ -73,7 +76,8 @@ class PresentationServiceNotifier( claimsToDisclose, options, goalCode, - goal + goal, + expirationTime ) ) @@ -84,7 +88,8 @@ class PresentationServiceNotifier( connectionId: Option[String], presentationRequest: AnoncredPresentationRequestV1, goalCode: Option[String], - goal: Option[String] + goal: Option[String], + expirationTime: Option[Duration], ): ZIO[WalletAccessContext, PresentationError, PresentationRecord] = notifyOnSuccess( svc.createAnoncredPresentationRecord( @@ -94,7 +99,8 @@ class PresentationServiceNotifier( connectionId, presentationRequest, goalCode, - goal + goal, + expirationTime ) ) @@ -158,6 +164,11 @@ class PresentationServiceNotifier( ): ZIO[WalletAccessContext, PresentationError, PresentationRecord] = notifyOnSuccess(svc.markPresentationVerificationFailed(recordId)) + override def markPresentationInvitationExpired( + recordId: DidCommID + ): ZIO[WalletAccessContext, PresentationError, PresentationRecord] = + notifyOnSuccess(svc.markPresentationInvitationExpired(recordId)) + override def verifyAnoncredPresentation( presentation: Presentation, requestPresentation: RequestPresentation, diff --git a/pollux/core/src/test/scala/org/hyperledger/identus/pollux/core/service/MockPresentationService.scala b/pollux/core/src/test/scala/org/hyperledger/identus/pollux/core/service/MockPresentationService.scala index bcfb0d95d7..dce4713c8e 100644 --- a/pollux/core/src/test/scala/org/hyperledger/identus/pollux/core/service/MockPresentationService.scala +++ b/pollux/core/src/test/scala/org/hyperledger/identus/pollux/core/service/MockPresentationService.scala @@ -18,6 +18,7 @@ import org.hyperledger.identus.shared.models.* import zio.{mock, IO, UIO, URLayer, ZIO, ZLayer} import zio.json.* import zio.mock.{Mock, Proxy} +import zio.Duration import java.time.Instant import java.util.UUID @@ -34,7 +35,8 @@ object MockPresentationService extends Mock[PresentationService] { Seq[ProofType], Option[Options], Option[String], - Option[String] + Option[String], + Option[Duration] ), PresentationError, PresentationRecord @@ -50,7 +52,8 @@ object MockPresentationService extends Mock[PresentationService] { ast.Json.Obj, Option[Options], Option[String], - Option[String] + Option[String], + Option[Duration] ), PresentationError, PresentationRecord @@ -65,7 +68,8 @@ object MockPresentationService extends Mock[PresentationService] { Option[String], AnoncredPresentationRequestV1, Option[String], - Option[String] + Option[String], + Option[Duration] ), PresentationError, PresentationRecord @@ -77,6 +81,8 @@ object MockPresentationService extends Mock[PresentationService] { object MarkPresentationVerified extends Effect[DidCommID, PresentationError, PresentationRecord] + object MarkPresentationInvitationExpired extends Effect[DidCommID, PresentationError, PresentationRecord] + object MarkPresentationAccepted extends Effect[DidCommID, PresentationError, PresentationRecord] object MarkPresentationRejected extends Effect[DidCommID, PresentationError, PresentationRecord] @@ -125,11 +131,22 @@ object MockPresentationService extends Mock[PresentationService] { proofTypes: Seq[ProofType], options: Option[Options], goalCode: Option[String], - goal: Option[String] + goal: Option[String], + expirationTime: Option[Duration] ): IO[PresentationError, PresentationRecord] = proxy( CreateJwtPresentationRecord, - (pairwiseVerifierDID, pairwiseProverDID, thid, connectionId, proofTypes, options, goalCode, goal) + ( + pairwiseVerifierDID, + pairwiseProverDID, + thid, + connectionId, + proofTypes, + options, + goalCode, + goal, + expirationTime + ) ) override def createSDJWTPresentationRecord( @@ -141,7 +158,8 @@ object MockPresentationService extends Mock[PresentationService] { claimsToDisclose: ast.Json.Obj, options: Option[org.hyperledger.identus.pollux.core.model.presentation.Options], goalCode: Option[String], - goal: Option[String] + goal: Option[String], + expirationTime: Option[Duration] ): ZIO[WalletAccessContext, PresentationError, PresentationRecord] = proxy( CreateSDJWTPresentationRecord, @@ -154,7 +172,8 @@ object MockPresentationService extends Mock[PresentationService] { claimsToDisclose, options, goalCode, - goal + goal, + expirationTime ) ) @@ -165,11 +184,21 @@ object MockPresentationService extends Mock[PresentationService] { connectionId: Option[String], presentationRequest: AnoncredPresentationRequestV1, goalCode: Option[String], - goal: Option[String] + goal: Option[String], + expirationTime: Option[Duration] ): ZIO[WalletAccessContext, PresentationError, PresentationRecord] = { proxy( CreateAnoncredPresentationRecord, - (pairwiseVerifierDID, pairwiseProverDID, thid, connectionId, presentationRequest, goalCode, goal) + ( + pairwiseVerifierDID, + pairwiseProverDID, + thid, + connectionId, + presentationRequest, + goalCode, + goal, + expirationTime + ) ) } @@ -213,6 +242,9 @@ object MockPresentationService extends Mock[PresentationService] { override def markPresentationVerified(recordId: DidCommID): IO[PresentationError, PresentationRecord] = proxy(MarkPresentationVerified, recordId) + override def markPresentationInvitationExpired(recordId: DidCommID): IO[PresentationError, PresentationRecord] = + proxy(MarkPresentationInvitationExpired, recordId) + override def markPresentationRejected(recordId: DidCommID): IO[PresentationError, PresentationRecord] = proxy(MarkPresentationRejected, recordId) diff --git a/pollux/core/src/test/scala/org/hyperledger/identus/pollux/core/service/PresentationServiceNotifierSpec.scala b/pollux/core/src/test/scala/org/hyperledger/identus/pollux/core/service/PresentationServiceNotifierSpec.scala index 9eef4b8372..02fdfd5a07 100644 --- a/pollux/core/src/test/scala/org/hyperledger/identus/pollux/core/service/PresentationServiceNotifierSpec.scala +++ b/pollux/core/src/test/scala/org/hyperledger/identus/pollux/core/service/PresentationServiceNotifierSpec.scala @@ -116,6 +116,7 @@ object PresentationServiceNotifierSpec extends ZIOSpecDefault with PresentationS Seq.empty, None, None, + None, None ) _ <- svc.markRequestPresentationSent(record.id) diff --git a/pollux/core/src/test/scala/org/hyperledger/identus/pollux/core/service/PresentationServiceSpec.scala b/pollux/core/src/test/scala/org/hyperledger/identus/pollux/core/service/PresentationServiceSpec.scala index b135946e1d..7e494568a3 100644 --- a/pollux/core/src/test/scala/org/hyperledger/identus/pollux/core/service/PresentationServiceSpec.scala +++ b/pollux/core/src/test/scala/org/hyperledger/identus/pollux/core/service/PresentationServiceSpec.scala @@ -76,7 +76,8 @@ object PresentationServiceSpec extends ZIOSpecDefault with PresentationServiceSp proofTypes, options, None, - None + None, + None, ) } yield { assertTrue(record.thid == thid) && @@ -143,6 +144,7 @@ object PresentationServiceSpec extends ZIOSpecDefault with PresentationServiceSp Some(connectionId), anoncredPresentationRequestV1, None, + None, None ) } yield { diff --git a/pollux/core/src/test/scala/org/hyperledger/identus/pollux/core/service/PresentationServiceSpecHelper.scala b/pollux/core/src/test/scala/org/hyperledger/identus/pollux/core/service/PresentationServiceSpecHelper.scala index 701852d856..34877bd9dd 100644 --- a/pollux/core/src/test/scala/org/hyperledger/identus/pollux/core/service/PresentationServiceSpecHelper.scala +++ b/pollux/core/src/test/scala/org/hyperledger/identus/pollux/core/service/PresentationServiceSpecHelper.scala @@ -170,7 +170,8 @@ trait PresentationServiceSpecHelper { proofTypes = Seq(proofType), options = options, goalCode = None, - goal = None + goal = None, + expirationDuration = None ) } @@ -214,7 +215,8 @@ trait PresentationServiceSpecHelper { connectionId = Some("connectionId"), anoncredPresentationRequestV1, goalCode = None, - goal = None + goal = None, + expirationDuration = None ) } }