diff --git a/pollux/vc-jwt/src/main/scala/org/hyperledger/identus/pollux/vc/jwt/VerifiableCredentialPayload.scala b/pollux/vc-jwt/src/main/scala/org/hyperledger/identus/pollux/vc/jwt/VerifiableCredentialPayload.scala index f152211274..da442b7397 100644 --- a/pollux/vc-jwt/src/main/scala/org/hyperledger/identus/pollux/vc/jwt/VerifiableCredentialPayload.scala +++ b/pollux/vc-jwt/src/main/scala/org/hyperledger/identus/pollux/vc/jwt/VerifiableCredentialPayload.scala @@ -53,7 +53,10 @@ case class CredentialSchema( `type`: String ) -case class CredentialIssuer(id: String) +case class CredentialIssuer( + id: String, + `type`: String +) sealed trait CredentialPayload { def maybeSub: Option[String] @@ -216,7 +219,8 @@ object CredentialPayload { (credentialIssuer: CredentialIssuer) => Json .obj( - ("id", credentialIssuer.id.asJson) + ("id", credentialIssuer.id.asJson), + ("type", credentialIssuer.`type`.asJson) ) implicit val credentialStatusPurposeEncoder: Encoder[StatusPurpose] = (a: StatusPurpose) => a.toString.asJson @@ -334,8 +338,9 @@ object CredentialPayload { (c: HCursor) => for { id <- c.downField("id").as[String] + `type` <- c.downField("type").as[String] } yield { - CredentialIssuer(id = id) + CredentialIssuer(id = id, `type` = `type`) } implicit val credentialStatusPurposeDecoder: Decoder[StatusPurpose] = (c: HCursor) => diff --git a/pollux/vc-jwt/src/test/scala/org/hyperledger/identus/pollux/vc/jwt/JWTVerificationTest.scala b/pollux/vc-jwt/src/test/scala/org/hyperledger/identus/pollux/vc/jwt/JWTVerificationTest.scala index 6bac6f5675..7572353859 100644 --- a/pollux/vc-jwt/src/test/scala/org/hyperledger/identus/pollux/vc/jwt/JWTVerificationTest.scala +++ b/pollux/vc-jwt/src/test/scala/org/hyperledger/identus/pollux/vc/jwt/JWTVerificationTest.scala @@ -62,7 +62,7 @@ object JWTVerificationTest extends ZIOSpecDefault { |} |""".stripMargin - private def createJwtCredential(issuer: IssuerWithKey): JWT = { + private def createJwtCredential(issuer: IssuerWithKey, issuerAsObject: Boolean = false): JWT = { val validFrom = Instant.parse("2010-01-05T00:00:00Z") // ISSUANCE DATE val jwtCredentialNbf = Instant.parse("2010-01-01T00:00:00Z") // ISSUANCE DATE val validUntil = Instant.parse("2010-01-09T00:00:00Z") // EXPIRATION DATE @@ -81,7 +81,10 @@ object JWTVerificationTest extends ZIOSpecDefault { maybeTermsOfUse = None, maybeValidFrom = Some(validFrom), maybeValidUntil = Some(validUntil), - maybeIssuer = Some(Left(issuer.issuer.did.toString)) + maybeIssuer = Some( + if (issuerAsObject) Right(CredentialIssuer(issuer.issuer.did.toString, "Profile")) + else Left(issuer.issuer.did.toString) + ) ), nbf = jwtCredentialNbf, // ISSUANCE DATE aud = Set.empty, @@ -199,6 +202,21 @@ object JWTVerificationTest extends ZIOSpecDefault { ) } yield assertTrue(validation.fold(_ => false, _ => true)) }, + test("validate issuer happy path") { + val issuer = createUser("did:prism:issuer") + val jwtCredential = createJwtCredential(issuer, false) + val jwtCredentialWithObjectIssuer = createJwtCredential(issuer, true) + for { + jwt <- JwtCredential + .decodeJwt(jwtCredential) + jwtWithObjectIssuer <- JwtCredential + .decodeJwt(jwtCredentialWithObjectIssuer) + jwtWithObjectIssuerIssuer = jwtWithObjectIssuer.vc.maybeIssuer.get.toOption.get.id + jwtIssuer = jwt.vc.maybeIssuer.get.left.toOption.get + } yield assertTrue( + jwtWithObjectIssuerIssuer.equals(jwtIssuer) + ) + }, test("validate dates should fail given after valid until") { val issuer = createUser("did:prism:issuer") val jwtCredential = createJwtCredential(issuer)