diff --git a/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/agent/server/jobs/IssueBackgroundJobs.scala b/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/agent/server/jobs/IssueBackgroundJobs.scala index d10e356e99..fee94e7a43 100644 --- a/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/agent/server/jobs/IssueBackgroundJobs.scala +++ b/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/agent/server/jobs/IssueBackgroundJobs.scala @@ -228,7 +228,7 @@ object IssueBackgroundJobs extends BackgroundJobsHelper { walletAccessContext <- ZIO .fromOption(offer.to) .flatMap(buildWalletAccessContextLayer) - .orElseFail(ZIO.die(new IllegalArgumentException("OfferCredential must have a recipient"))) + .mapError(e => CredentialServiceError.CredentialOfferMissingField(id.value, "recipient")) result <- for { credentialService <- ZIO.service[CredentialService] _ <- credentialService @@ -274,7 +274,7 @@ object IssueBackgroundJobs extends BackgroundJobsHelper { walletAccessContext <- ZIO .fromOption(offer.to) .flatMap(buildWalletAccessContextLayer) - .orElseFail(ZIO.die(new IllegalArgumentException("OfferCredential must have a recipient"))) + .mapError(e => CredentialServiceError.CredentialOfferMissingField(id.value, "recipient")) result <- for { credentialService <- ZIO.service[CredentialService] _ <- credentialService @@ -320,7 +320,8 @@ object IssueBackgroundJobs extends BackgroundJobsHelper { walletAccessContext <- ZIO .fromOption(offer.to) .flatMap(buildWalletAccessContextLayer) - .orElseFail(ZIO.die(new IllegalArgumentException("OfferCredential must have a recipient"))) + .mapError(e => CredentialServiceError.CredentialOfferMissingField(id.value, "recipient")) + result <- for { credentialService <- ZIO.service[CredentialService] _ <- credentialService 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 462f39be08..0bf8f7fb61 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 @@ -675,9 +675,10 @@ object PresentBackgroundJobs extends BackgroundJobsHelper { Unit ] = { val proverPresentationPendingToGeneratedFlow = for { - walletAccessContext <- buildWalletAccessContextLayer( - requestPresentation.to.getOrElse(throw new RuntimeException("to is None is not possible")) - ) + walletAccessContext <- ZIO + .fromOption(requestPresentation.to) + .flatMap(buildWalletAccessContextLayer) + .mapError(_ => PresentationError.RequestPresentationMissingField(id.value, "recipient")) _ <- for { presentationService <- ZIO.service[PresentationService] prover <- createPrismDIDIssuerFromPresentationCredentials(id, credentialsToUse.getOrElse(Nil)) @@ -696,24 +697,7 @@ object PresentBackgroundJobs extends BackgroundJobsHelper { presentationPayload.toW3CPresentationPayload, prover ) - presentation <- ZIO.succeed( - Presentation( - body = Presentation.Body( - goal_code = requestPresentation.body.goal_code, - comment = requestPresentation.body.comment - ), - attachments = Seq( - AttachmentDescriptor - .buildBase64Attachment( - payload = signedJwtPresentation.value.getBytes(), - mediaType = Some(PresentCredentialFormat.JWT.name) - ) - ), - thid = requestPresentation.thid.orElse(Some(requestPresentation.id)), - from = requestPresentation.to.getOrElse(throw new RuntimeException("to is None is not possible")), - to = requestPresentation.from.getOrElse(throw new RuntimeException("from is None is not possible")) - ) - ) + presentation <- createPresentation(id, requestPresentation, signedJwtPresentation) } yield presentation _ <- presentationService .markPresentationGenerated(id, presentation) @@ -724,6 +708,36 @@ object PresentBackgroundJobs extends BackgroundJobsHelper { proverPresentationPendingToGeneratedFlow } + private def createPresentation( + id: DidCommID, + requestPresentation: RequestPresentation, + signedJwtPresentation: JWT + ): ZIO[Any, PresentationError, Presentation] = { + for { + from <- ZIO + .fromOption(requestPresentation.to) + .mapError(_ => PresentationError.RequestPresentationMissingField(id.value, "recipient")) + to <- ZIO + .fromOption(requestPresentation.from) + .mapError(_ => PresentationError.RequestPresentationMissingField(id.value, "sender")) + } yield Presentation( + body = Presentation.Body( + goal_code = requestPresentation.body.goal_code, + comment = requestPresentation.body.comment + ), + attachments = Seq( + AttachmentDescriptor + .buildBase64Attachment( + payload = signedJwtPresentation.value.getBytes(), + mediaType = Some(PresentCredentialFormat.JWT.name) + ) + ), + thid = requestPresentation.thid.orElse(Some(requestPresentation.id)), + from = from, + to = to + ) + } + private def handleSDJWT( id: DidCommID, credentialsToUse: Option[List[String]], @@ -733,9 +747,10 @@ object PresentBackgroundJobs extends BackgroundJobsHelper { ERROR, Unit ] = for { - walletAccessContext <- buildWalletAccessContextLayer( - requestPresentation.to.getOrElse(throw new RuntimeException("to is None is not possible")) - ) + walletAccessContext <- ZIO + .fromOption(requestPresentation.to) + .flatMap(buildWalletAccessContextLayer) + .mapError(_ => PresentationError.RequestPresentationMissingField(id.value, "recipient")) result <- for { presentationService <- ZIO.service[PresentationService] @@ -765,9 +780,10 @@ object PresentBackgroundJobs extends BackgroundJobsHelper { maybeCredentialsToUseJson match { case Some(credentialsToUseJson) => val proverPresentationPendingToGeneratedFlow = for { - walletAccessContext <- buildWalletAccessContextLayer( - requestPresentation.to.getOrElse(throw new RuntimeException("to is None is not possible")) - ) + walletAccessContext <- ZIO + .fromOption(requestPresentation.to) + .flatMap(buildWalletAccessContextLayer) + .mapError(_ => PresentationError.RequestPresentationMissingField(id.value, "recipient")) result <- for { presentationService <- ZIO.service[PresentationService] anoncredCredentialProofs <- diff --git a/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/presentproof/controller/PresentProofController.scala b/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/presentproof/controller/PresentProofController.scala index fe4f5edd44..773dcce2fb 100644 --- a/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/presentproof/controller/PresentProofController.scala +++ b/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/presentproof/controller/PresentProofController.scala @@ -32,7 +32,7 @@ trait PresentProofController { ): ZIO[WalletAccessContext, ErrorResponse, PresentationStatus] def createOOBRequestPresentationInvitation( - request: OOBRequestPresentationInput + request: RequestPresentationInput )(implicit rc: RequestContext ): ZIO[WalletAccessContext, ErrorResponse, PresentationStatus] 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 c95f176c46..11adbd36f6 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 @@ -34,19 +34,23 @@ class PresentProofControllerImpl( override def requestPresentation(request: RequestPresentationInput)(implicit rc: RequestContext ): ZIO[WalletAccessContext, ErrorResponse, PresentationStatus] = { - val result: ZIO[WalletAccessContext, ConnectionServiceError | PresentationError, PresentationStatus] = for { - didIdPair <- getPairwiseDIDs(request.connectionId).provideSomeLayer(ZLayer.succeed(connectionService)) - record <- createRequestPresentation( - verifierDID = didIdPair.myDID, - proverDID = Some(didIdPair.theirDid), - connectionId = Some(request.connectionId.toString), - request = request - ) - } yield PresentationStatus.fromDomain(record) + val result: ZIO[WalletAccessContext, ConnectionServiceError | PresentationError, PresentationStatus] = + for { + connectionId <- ZIO + .fromOption(request.connectionId) + .mapError(_ => PresentationError.MissingConnectionIdForPresentationRequest) + didIdPair <- getPairwiseDIDs(connectionId).provideSomeLayer(ZLayer.succeed(connectionService)) + record <- createRequestPresentation( + verifierDID = didIdPair.myDID, + proverDID = Some(didIdPair.theirDid), + request = request, + expirationDuration = None + ) + } yield PresentationStatus.fromDomain(record) result } - override def createOOBRequestPresentationInvitation(request: OOBRequestPresentationInput)(implicit + override def createOOBRequestPresentationInvitation(request: RequestPresentationInput)(implicit rc: RequestContext ): ZIO[WalletAccessContext, ErrorResponse, PresentationStatus] = { val result: ZIO[WalletAccessContext, ConnectionServiceError | PresentationError, PresentationStatus] = for { @@ -54,8 +58,8 @@ class PresentProofControllerImpl( record <- createRequestPresentation( verifierDID = peerDid.did, proverDID = None, - connectionId = None, - request = request + request = request, + expirationDuration = Some(appConfig.pollux.presentationInvitationExpiry) ) } yield PresentationStatus.fromDomain(record) result @@ -64,39 +68,22 @@ class PresentProofControllerImpl( private def createRequestPresentation( verifierDID: DidId, proverDID: Option[DidId], - connectionId: Option[String], - request: RequestPresentationInput | OOBRequestPresentationInput + request: RequestPresentationInput, + expirationDuration: Option[Duration] ): ZIO[WalletAccessContext, PresentationError, PresentationRecord] = { - request match { - case req: RequestPresentationInput => - createPresentationRecord( - verifierDID, - proverDID, - connectionId, - req.credentialFormat, - req.proofs, - req.options.map(o => Options(o.challenge, o.domain)), - req.claims, - req.anoncredPresentationRequest, - None, - None, - None - ) - case req: OOBRequestPresentationInput => - createPresentationRecord( - verifierDID, - proverDID, - connectionId, - req.credentialFormat, - req.proofs, - req.options.map(o => Options(o.challenge, o.domain)), - req.claims, - req.anoncredPresentationRequest, - req.goalCode, - req.goal, - Some(appConfig.pollux.presentationInvitationExpiry) - ) - } + createPresentationRecord( + verifierDID, + proverDID, + request.connectionId.map(_.toString), + request.credentialFormat, + request.proofs, + request.options.map(o => Options(o.challenge, o.domain)), + request.claims, + request.anoncredPresentationRequest, + request.goalCode, + request.goal, + expirationDuration + ) } private def createPresentationRecord( diff --git a/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/presentproof/controller/PresentProofEndpoints.scala b/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/presentproof/controller/PresentProofEndpoints.scala index e24318ee5d..80e83db26c 100644 --- a/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/presentproof/controller/PresentProofEndpoints.scala +++ b/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/presentproof/controller/PresentProofEndpoints.scala @@ -120,7 +120,7 @@ object PresentProofEndpoints { val createOOBRequestPresentationInvitation: Endpoint[ (ApiKeyCredentials, JwtCredentials), - (RequestContext, OOBRequestPresentationInput), + (RequestContext, RequestPresentationInput), ErrorResponse, PresentationStatus, Any @@ -143,7 +143,7 @@ object PresentProofEndpoints { .securityIn(jwtAuthHeader) .in("present-proof" / "presentations" / "invitation") .in(extractFromRequest[RequestContext](RequestContext.apply)) - .in(jsonBody[OOBRequestPresentationInput].description("The present proof creation request.")) + .in(jsonBody[RequestPresentationInput].description("The present proof creation request.")) .out( statusCode(StatusCode.Created).description( "The proof presentation request invitation was created successfully and that can be delivered as out-of-band to a peer Agent.." diff --git a/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/presentproof/controller/PresentProofServerEndpoints.scala b/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/presentproof/controller/PresentProofServerEndpoints.scala index e7f30f9864..33036df13f 100644 --- a/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/presentproof/controller/PresentProofServerEndpoints.scala +++ b/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/presentproof/controller/PresentProofServerEndpoints.scala @@ -6,7 +6,6 @@ import org.hyperledger.identus.api.http.RequestContext import org.hyperledger.identus.iam.authentication.{Authenticator, Authorizer, DefaultAuthenticator, SecurityLogic} import org.hyperledger.identus.presentproof.controller.http.{ AcceptRequestPresentationInvitation, - OOBRequestPresentationInput, RequestPresentationAction, RequestPresentationInput } @@ -82,7 +81,7 @@ class PresentProofServerEndpoints( createOOBRequestPresentationInvitation .zServerSecurityLogic(SecurityLogic.authorizeWalletAccessWith(_)(authenticator, authorizer)) .serverLogic { wac => - { case (ctx: RequestContext, action: OOBRequestPresentationInput) => + { case (ctx: RequestContext, action: RequestPresentationInput) => presentProofController .createOOBRequestPresentationInvitation(action)(ctx) .provideSomeLayer(ZLayer.succeed(wac)) diff --git a/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/presentproof/controller/http/OOBRequestPresentationInput.scala b/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/presentproof/controller/http/OOBRequestPresentationInput.scala deleted file mode 100644 index eb2d57251b..0000000000 --- a/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/presentproof/controller/http/OOBRequestPresentationInput.scala +++ /dev/null @@ -1,160 +0,0 @@ -package org.hyperledger.identus.presentproof.controller.http - -import org.hyperledger.identus.api.http.Annotation -import org.hyperledger.identus.pollux.core.service.serdes.{ - AnoncredNonRevokedIntervalV1, - AnoncredPresentationRequestV1, - AnoncredRequestedAttributeV1, - AnoncredRequestedPredicateV1 -} -import sttp.tapir.{Schema, Validator} -import sttp.tapir.json.zio.* -import sttp.tapir.Schema.annotations.{description, encodedExample} -import zio.json.{DeriveJsonDecoder, DeriveJsonEncoder, JsonDecoder, JsonEncoder} -import OOBRequestPresentationInput.annotations - -//TODO Should I just use RequestPresentationInput and add the optional fields will that cause any confusion -final case class OOBRequestPresentationInput( - @description(annotations.goalcode.description) - @encodedExample(annotations.goalcode.example) - goalCode: Option[String] = None, - @description(annotations.goal.description) - @encodedExample(annotations.goal.example) - goal: Option[String] = None, - @description(annotations.options.description) - @encodedExample(annotations.options.example) - options: Option[Options] = None, - @description(annotations.proofs.description) - @encodedExample(annotations.proofs.example) - proofs: Seq[ProofRequestAux], - @description(annotations.anoncredPresentationRequest.description) - @encodedExample(annotations.anoncredPresentationRequest.example) - anoncredPresentationRequest: Option[AnoncredPresentationRequestV1], - @description(annotations.claims.description) - @encodedExample(annotations.claims.example) - claims: Option[zio.json.ast.Json.Obj], - @description(annotations.credentialFormat.description) - @encodedExample(annotations.credentialFormat.example) - credentialFormat: Option[String], -) - -object OOBRequestPresentationInput { - object annotations { - object goalcode - extends Annotation[String]( - description = - "A self-attested code the receiver may want to display to the user or use in automatically deciding what to do with the out-of-band message.", - example = "present-vp" - ) - - object goal - extends Annotation[String]( - description = - "A self-attested string that the receiver may want to display to the user about the context-specific goal of the out-of-band message.", - example = "Request proof of vaccine" - ) - - object options - extends Annotation[Option[Options]]( - description = "The options to use when creating the proof presentation request (e.g., domain, challenge).", - example = None - ) - object proofs - extends Annotation[Seq[ProofRequestAux]]( - description = - "The type of proofs requested in the context of this proof presentation request (e.g., VC schema, trusted issuers, etc.)", - example = Seq.empty - ) - - object anoncredPresentationRequest - extends Annotation[Option[AnoncredPresentationRequestV1]]( - description = "Anoncred Presentation Request", - example = Some( - AnoncredPresentationRequestV1( - requested_attributes = Map( - "attribute1" -> AnoncredRequestedAttributeV1( - "Attribute 1", - List( - Map( - "cred_def_id" -> "credential_definition_id_of_attribute1" - ) - ), - Some( - AnoncredNonRevokedIntervalV1( - Some(1635734400), - Some(1735734400) - ) - ) - ) - ), - requested_predicates = Map( - "predicate1" -> - AnoncredRequestedPredicateV1( - "Predicate 1", - ">=", - 18, - List( - Map( - "schema_id" -> "schema_id_of_predicate1" - ) - ), - Some( - AnoncredNonRevokedIntervalV1( - Some(1635734400), - None - ) - ) - ) - ), - name = "Example Presentation Request", - nonce = "1234567890", - version = "1.0", - non_revoked = None - ) - ) - ) - object claims - extends Annotation[Option[zio.json.ast.Json.Obj]]( - description = """ - |The set of claims to be disclosed from the issued credential. - |The JSON object should comply with the schema applicable for this offer (i.e. 'schemaId' or 'credentialDefinitionId'). - |""".stripMargin, - example = Some( - zio.json.ast.Json.Obj( - "firstname" -> zio.json.ast.Json.Str("Alice"), - "lastname" -> zio.json.ast.Json.Str("Wonderland"), - ) - ) - ) - object credentialFormat - extends Annotation[Option[String]]( - description = "The credential format (default to 'JWT')", - example = Some("JWT"), - validator = Validator.enumeration( - List( - Some("JWT"), - Some("SDJWT"), - Some("AnonCreds") - ) - ) - ) - } - - given encoder: JsonEncoder[OOBRequestPresentationInput] = - DeriveJsonEncoder.gen[OOBRequestPresentationInput] - - given decoder: JsonDecoder[OOBRequestPresentationInput] = - DeriveJsonDecoder.gen[OOBRequestPresentationInput] - - import AnoncredPresentationRequestV1.given - - given Schema[AnoncredPresentationRequestV1] = Schema.derived - - given Schema[AnoncredRequestedAttributeV1] = Schema.derived - - given Schema[AnoncredRequestedPredicateV1] = Schema.derived - - given Schema[AnoncredNonRevokedIntervalV1] = Schema.derived - - given schema: Schema[OOBRequestPresentationInput] = Schema.derived -} diff --git a/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/presentproof/controller/http/RequestPresentationInput.scala b/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/presentproof/controller/http/RequestPresentationInput.scala index a931c8fc8a..acf486f33d 100644 --- a/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/presentproof/controller/http/RequestPresentationInput.scala +++ b/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/presentproof/controller/http/RequestPresentationInput.scala @@ -11,9 +11,15 @@ import zio.json.{DeriveJsonDecoder, DeriveJsonEncoder, JsonDecoder, JsonEncoder} import java.util.UUID final case class RequestPresentationInput( + @description(annotations.goalcode.description) + @encodedExample(annotations.goalcode.example) + goalCode: Option[String] = None, + @description(annotations.goal.description) + @encodedExample(annotations.goal.example) + goal: Option[String] = None, @description(annotations.connectionId.description) @encodedExample(annotations.connectionId.example) - connectionId: UUID, + connectionId: Option[UUID] = None, @description(annotations.options.description) @encodedExample(annotations.options.example) options: Option[Options] = None, @@ -34,10 +40,35 @@ final case class RequestPresentationInput( object RequestPresentationInput { object annotations { object connectionId - extends Annotation[UUID]( - description = "The unique identifier of an established connection between the verifier and the prover.", - example = UUID.fromString("bc528dc8-69f1-4c5a-a508-5f8019047900") + extends Annotation[Option[UUID]]( + description = """ + |The unique identifier of a DIDComm connection that already exists between the this verifier agent and the prover cloud or edeg agent. + |It should be the identifier of a connection that exists in the verifier agent's database. + |This connection will be used to execute the present proof protocol. + |Note: connectionId is only required when the presentation request is from existing connection. + |connectionId is not required when the presentation request is from invitation for connectionless issuance. + |""".stripMargin, + example = Some(UUID.fromString("d9569cec-c81e-4779-aa86-0d5994d82676")) + ) + + object goalcode + extends Annotation[Option[String]]( + description = """ + | A self-attested code the receiver may want to display to the user or use in automatically deciding what to do with the out-of-band message. + | goalcode is optional and can be provided when the presentation request is from invitation for connectionless verification. + |""".stripMargin, + example = Some("present-vp") ) + + object goal + extends Annotation[Option[String]]( + description = """ + | A self-attested string that the receiver may want to display to the user about the context-specific goal of the out-of-band message. + | goal is optional and can be provided when the presentation request is from invitation for connectionless verification. + |""".stripMargin, + example = Some("Request proof of vaccine") + ) + object options extends Annotation[Option[Options]]( description = "The options to use when creating the proof presentation request (e.g., domain, challenge).", diff --git a/connect/core/src/main/scala/org/hyperledger/identus/connect/core/model/ConnectionRecord.scala b/connect/core/src/main/scala/org/hyperledger/identus/connect/core/model/ConnectionRecord.scala index 026e651312..64d6a287cf 100644 --- a/connect/core/src/main/scala/org/hyperledger/identus/connect/core/model/ConnectionRecord.scala +++ b/connect/core/src/main/scala/org/hyperledger/identus/connect/core/model/ConnectionRecord.scala @@ -3,7 +3,8 @@ package org.hyperledger.identus.connect.core.model import org.hyperledger.identus.connect.core.model.ConnectionRecord.{ProtocolState, Role} import org.hyperledger.identus.mercury.protocol.connection.{ConnectionRequest, ConnectionResponse} import org.hyperledger.identus.mercury.protocol.invitation.v2.Invitation -import org.hyperledger.identus.shared.models.{Failure, WalletId} +import org.hyperledger.identus.shared.models.Failure +import org.hyperledger.identus.shared.models.WalletId import java.time.temporal.ChronoUnit import java.time.Instant diff --git a/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/model/error/CredentialServiceError.scala b/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/model/error/CredentialServiceError.scala index f0e2bc2447..2c5950dfbc 100644 --- a/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/model/error/CredentialServiceError.scala +++ b/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/model/error/CredentialServiceError.scala @@ -43,6 +43,11 @@ object CredentialServiceError { StatusCode.InternalServerError, s"Credential Offer decoding error: $cause" ) + final case class CredentialOfferMissingField(recordId: String, missingField: String) + extends CredentialServiceError( + StatusCode.BadRequest, + s"Credential Offer missing $missingField field: $recordId" + ) final case class InvalidCredentialOffer(cause: String) extends CredentialServiceError( 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 bcf096c449..c71b88ede1 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 @@ -44,6 +44,12 @@ object PresentationError { s"Request Presentation with multi attachments: $presentationId" ) + final case class RequestPresentationMissingField(presentationId: String, field: String) + extends PresentationError( + StatusCode.BadRequest, + s"Request Presentation missing $field field: $presentationId" + ) + final case class IssuedCredentialNotFoundError(cause: String) extends PresentationError( StatusCode.InternalServerError, @@ -115,6 +121,11 @@ object PresentationError { StatusCode.InternalServerError, error ) + object MissingConnectionIdForPresentationRequest + extends PresentationError( + StatusCode.BadRequest, + s"Presentation Request missing connectionId" + ) final case class MissingAnoncredPresentationRequest(error: String) extends PresentationError(