diff --git a/build.sbt b/build.sbt
index 2dfdcaa3..16a75996 100644
--- a/build.sbt
+++ b/build.sbt
@@ -23,7 +23,7 @@ lazy val V = new {
val zio = "2.0.18"
val zioJson = "0.6.2"
// val zioMunitTest = "0.1.1"
- val zioHttp = "3.0.0-RC2"
+ val zioHttp = "3.0.0-RC3"
val zioConfig = "4.0.0-RC16"
val zioLogging = "2.1.14"
val zioSl4j = "2.1.14"
diff --git a/http-utils/jvm/src/main/scala/io/iohk/atala/mediator/comm/MessageDispatcherJVM.scala b/http-utils/jvm/src/main/scala/io/iohk/atala/mediator/comm/MessageDispatcherJVM.scala
index 81623bfd..2704c260 100644
--- a/http-utils/jvm/src/main/scala/io/iohk/atala/mediator/comm/MessageDispatcherJVM.scala
+++ b/http-utils/jvm/src/main/scala/io/iohk/atala/mediator/comm/MessageDispatcherJVM.scala
@@ -33,14 +33,12 @@ class MessageDispatcherJVM(client: Client) extends MessageDispatcher {
.pipe(e => Header.ContentType(ZMediaType.application.any.copy(subType = "didcomm-encrypted+json")))
val xForwardedHostHeader = xForwardedHost.map(x => Header.Custom(customName = MyHeaders.xForwardedHost, x))
- // xForwardedHost.map(x => Header.(MyHeaders.xForwardedHost, x))
for {
res <- Client
.request(
- url = destination,
- method = Method.POST,
- headers = Headers(Seq(Some(contentTypeHeader), xForwardedHostHeader).flatten),
- content = Body.fromCharSequence(msg.toJson),
+ Request
+ .post(destination, Body.fromCharSequence(msg.toJson))
+ .setHeaders(Headers(Seq(Some(contentTypeHeader), xForwardedHostHeader).flatten))
)
.tapError(ex => ZIO.logWarning(s"Fail when calling '$destination': ${ex.toString}"))
.mapError(ex => DispatcherError(ex))
@@ -51,5 +49,7 @@ class MessageDispatcherJVM(client: Client) extends MessageDispatcher {
case true => ZIO.logWarning(data)
case false => ZIO.logInfo(data)
} yield (data)
- }.provideEnvironment(ZEnvironment(client))
+ }
+ .provideSomeLayer(Scope.default)
+ .provideEnvironment(ZEnvironment(client))
}
diff --git a/http-utils/jvm/src/main/scala/io/iohk/atala/mediator/utils/HttpHelpers.scala b/http-utils/jvm/src/main/scala/io/iohk/atala/mediator/utils/HttpHelpers.scala
index 48577fa1..1038b029 100644
--- a/http-utils/jvm/src/main/scala/io/iohk/atala/mediator/utils/HttpHelpers.scala
+++ b/http-utils/jvm/src/main/scala/io/iohk/atala/mediator/utils/HttpHelpers.scala
@@ -1,3 +1,4 @@
+/*
package io.iohk.atala.mediator.utils
import zio.*
@@ -50,3 +51,4 @@ object MiddlewareUtils {
}
}
+ */
diff --git a/mediator/src/main/scala/io/iohk/atala/mediator/app/IndexHtml.scala b/mediator/src/main/scala/io/iohk/atala/mediator/app/IndexHtml.scala
index f5923e5e..0af47f53 100644
--- a/mediator/src/main/scala/io/iohk/atala/mediator/app/IndexHtml.scala
+++ b/mediator/src/main/scala/io/iohk/atala/mediator/app/IndexHtml.scala
@@ -1,31 +1,38 @@
package io.iohk.atala.mediator.app
-import zio.http.Response
+import zio.http._
import fmgp.did.DID
object IndexHtml {
- // TODO use the html.Html.fromDomElement()
- def html(identity: DID) = Response.html(s"""
- |
- |
- | IOHK Mediator
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |""".stripMargin)
+ def html(identity: DID) =
+ Response(
+ status = Status.Ok,
+ headers = Headers(Header.ContentType(MediaType.text.html).untyped),
+ body = Body.fromString(
+ s"""
+ |
+ |
+ |
+ | IOHK Mediator
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |""".stripMargin
+ ),
+ )
}
diff --git a/mediator/src/main/scala/io/iohk/atala/mediator/app/MediatorAgent.scala b/mediator/src/main/scala/io/iohk/atala/mediator/app/MediatorAgent.scala
index a79dd525..6da8785d 100644
--- a/mediator/src/main/scala/io/iohk/atala/mediator/app/MediatorAgent.scala
+++ b/mediator/src/main/scala/io/iohk/atala/mediator/app/MediatorAgent.scala
@@ -14,7 +14,6 @@ import io.iohk.atala.mediator.db.*
import io.iohk.atala.mediator.protocols.*
import io.iohk.atala.mediator.utils.*
import io.netty.handler.codec.http.HttpHeaderNames
-import reactivemongo.api.bson.Macros.{*, given}
import reactivemongo.api.bson.{*, given}
import zio.*
import zio.http.*
@@ -23,7 +22,6 @@ import zio.json.*
import scala.concurrent.ExecutionContext.Implicits.global
import scala.util.Try
import scala.io.Source
-import zio.http.internal.middlewares.Cors.CorsConfig
import zio.http.Header.AccessControlAllowOrigin
import zio.http.Header.AccessControlAllowMethods
@@ -223,18 +221,20 @@ object MediatorAgent {
def make(id: DID, keyStore: KeyStore): ZIO[Any, Nothing, MediatorAgent] = ZIO.succeed(MediatorAgent(id, keyStore))
def didCommApp = {
- Http.collectZIO[Request] {
- case req @ Method.GET -> Root / "headers" =>
+ Routes(
+ Method.GET / "headers" -> handler { (req: Request) =>
val data = req.headers.toSeq.map(e => (e.headerName, e.renderedValue))
ZIO.succeed(Response.text("HEADERS:\n" + data.mkString("\n") + "\nRemoteAddress:" + req.remoteAddress)).debug
- case req @ Method.GET -> Root / "health" => ZIO.succeed(Response.ok)
- case Method.GET -> Root / "version" => ZIO.succeed(Response.text(MediatorBuildInfo.version))
- case Method.GET -> Root / "did" =>
+ },
+ Method.GET / "health" -> handler { (req: Request) => ZIO.succeed(Response.ok) },
+ Method.GET / "version" -> handler { (req: Request) => ZIO.succeed(Response.text(MediatorBuildInfo.version)) },
+ Method.GET / "did" -> handler { (req: Request) =>
for {
agent <- ZIO.service[MediatorAgent]
ret <- ZIO.succeed(Response.text(agent.id.string))
} yield (ret)
- case Method.GET -> Root / "invitation" =>
+ },
+ Method.GET / "invitation" -> handler { (req: Request) =>
for {
agent <- ZIO.service[MediatorAgent]
annotationMap <- ZIO.logAnnotations.map(_.map(e => LogAnnotation(e._1, e._2)).toSeq)
@@ -247,7 +247,8 @@ object MediatorAgent {
_ <- ZIO.log("New mediate invitation MsgID: " + invitation.id.value)
ret <- ZIO.succeed(Response.json(invitation.toPlaintextMessage.toJson))
} yield (ret)
- case Method.GET -> Root / "invitationOOB" =>
+ },
+ Method.GET / "invitationOOB" -> handler { (req: Request) =>
for {
agent <- ZIO.service[MediatorAgent]
annotationMap <- ZIO.logAnnotations.map(_.map(e => LogAnnotation(e._1, e._2)).toSeq)
@@ -263,98 +264,78 @@ object MediatorAgent {
OutOfBandPlaintext.from(invitation.toPlaintextMessage).makeURI("")
)
)
-
} yield (ret)
- case req @ Method.POST -> Root
- if req.headers
- // .header(Header.ContentType) // TODO BUG? this does not work
- .get("content-type")
- .exists { h =>
- // TODO after fix BUG
- // h.mediaType.mainType == "application" &&
- // (h.mediaType.subType == "didcomm-signed+json" || h.mediaType.subType == "didcomm-encrypted+json")
- // TODO after update lib
- // h.mediaType.mainType == ZMediaTypes.mainType &&
- // (h.mediaType.subType == MediaTypes.SIGNED.subType || h.mediaType.subType == MediaTypes.ENCRYPTED.subType)
- h == MediaTypes.SIGNED.typ || h == MediaTypes.ENCRYPTED.typ
- } =>
- for {
- agent <- ZIO.service[MediatorAgent]
- data <- req.body.asString
- ret <- agent
- .receiveMessage(data)
- .map {
- case None => Response.ok
- case Some(value: SignedMessage) => Response.json(value.toJson)
- case Some(value: EncryptedMessage) => Response.json(value.toJson)
- }
- .catchAll {
- case MediatorDidError(error) =>
- ZIO.logError(s"Error MediatorDidError: $error") *>
- ZIO.succeed(Response.status(Status.BadRequest))
- case MediatorThrowable(error) =>
- ZIO.logError(s"Error MediatorThrowable: $error") *>
- ZIO.succeed(Response.status(Status.BadRequest))
- case StorageCollection(error) =>
- ZIO.logError(s"Error StorageCollection: $error") *>
- ZIO.succeed(Response.status(Status.BadRequest))
- case StorageThrowable(error) =>
- ZIO.logError(s"Error StorageThrowable: $error") *>
- ZIO.succeed(Response.status(Status.BadRequest))
- case DuplicateMessage(error) =>
- ZIO.logError(s"Error DuplicateKeyError: $error") *>
- ZIO.succeed(Response.status(Status.BadRequest))
- case MissingProtocolError(piuri) =>
- ZIO.logError(s"MissingProtocolError ('$piuri')") *>
- ZIO.succeed(Response.status(Status.BadRequest)) // TODO
- }
- } yield ret
- // TODO [return_route extension](https://github.com/decentralized-identity/didcomm-messaging/blob/main/extensions/return_route/main.md)
- case req @ Method.POST -> Root =>
- ZIO
- .logError(s"Request Headers: ${req.headers.mkString(",")}")
- .as(
- Response
- .text(s"The content-type must be ${MediaTypes.SIGNED.typ} or ${MediaTypes.ENCRYPTED.typ}")
- .copy(status = Status.BadRequest)
- )
- case req @ Method.GET -> Root => { // html.Html.fromDomElement()
+ },
+ Method.POST / trailing -> handler { (req: Request) =>
+ {
+ if (
+ req.headers
+ .get("content-type")
+ .exists { h => h == MediaTypes.SIGNED.typ || h == MediaTypes.ENCRYPTED.typ }
+ ) {
+ for {
+ agent <- ZIO.service[MediatorAgent]
+ data <- req.body.asString
+ .catchAll(ex => ZIO.fail(Response.badRequest("Unable to read the body of the request")))
+ ret <- agent
+ .receiveMessage(data)
+ .map {
+ case None => Response.ok
+ case Some(value: SignedMessage) => Response.json(value.toJson)
+ case Some(value: EncryptedMessage) => Response.json(value.toJson)
+ }
+ .catchAll {
+ case MediatorDidError(error) =>
+ ZIO.logError(s"Error MediatorDidError: $error") *>
+ ZIO.succeed(Response.status(Status.BadRequest))
+ case MediatorThrowable(error) =>
+ ZIO.logError(s"Error MediatorThrowable: $error") *>
+ ZIO.succeed(Response.status(Status.BadRequest))
+ case StorageCollection(error) =>
+ ZIO.logError(s"Error StorageCollection: $error") *>
+ ZIO.succeed(Response.status(Status.BadRequest))
+ case StorageThrowable(error) =>
+ ZIO.logError(s"Error StorageThrowable: $error") *>
+ ZIO.succeed(Response.status(Status.BadRequest))
+ case DuplicateMessage(error) =>
+ ZIO.logError(s"Error DuplicateKeyError: $error") *>
+ ZIO.succeed(Response.status(Status.BadRequest))
+ case MissingProtocolError(piuri) =>
+ ZIO.logError(s"MissingProtocolError ('$piuri')") *>
+ ZIO.succeed(Response.status(Status.BadRequest)) // TODO
+ }
+ } yield ret
+ } else
+ ZIO
+ .logError(s"Request Headers: ${req.headers.mkString(",")}")
+ .as(
+ Response
+ .text(s"The content-type must be ${MediaTypes.SIGNED.typ} or ${MediaTypes.ENCRYPTED.typ}")
+ .copy(status = Status.BadRequest)
+ )
+ }
+ },
+ Method.GET / trailing -> handler { (req: Request) =>
for {
agent <- ZIO.service[MediatorAgent]
_ <- ZIO.log("index.html")
ret <- ZIO.succeed(IndexHtml.html(agent.id))
} yield ret
- }
- }: Http[
- Operations & Resolver & MessageDispatcher & MediatorAgent & MessageItemRepo & UserAccountRepo & OutboxMessageRepo,
- Throwable,
- Request,
- Response
- ]
- } ++ Http
- .fromResource(s"public/webapp-fastopt-bundle.js.gz")
- .map(_.setHeaders(Headers(Header.ContentType(MediaType.application.javascript), Header.ContentEncoding.GZip)))
- .when {
- case Method.GET -> Root / "public" / "webapp-fastopt-bundle.js" => true
- case _ => false
- }
- @@ HttpAppMiddleware.cors(
- CorsConfig(
- allowedOrigin = {
- // case origin @ Origin.Value(_, host, _) if host == "dev" => Some(AccessControlAllowOrigin.Specific(origin))
- case _ => Some(AccessControlAllowOrigin.All)
- },
- allowedMethods = AccessControlAllowMethods(Method.GET, Method.POST, Method.OPTIONS),
- )
+ },
+ Method.GET / "public" / string("path") -> handler { (path: String, req: Request) =>
+ // RoutesMiddleware
+ // TODO https://zio.dev/reference/stream/zpipeline/#:~:text=ZPipeline.gzip%20%E2%80%94%20The%20gzip%20pipeline%20compresses%20a%20stream%20of%20bytes%20as%20using%20gzip%20method%3A
+ val fullPath = s"public/$path"
+ val classLoader = Thread.currentThread().getContextClassLoader()
+ val headerContentType = fullPath match
+ case s if s.endsWith(".html") => Header.ContentType(MediaType.text.html)
+ case s if s.endsWith(".js") => Header.ContentType(MediaType.text.javascript)
+ case s if s.endsWith(".css") => Header.ContentType(MediaType.text.css)
+ case s if s.endsWith(".svg") => Header.ContentType(MediaType.image.`svg+xml`)
+ case s => Header.ContentType(MediaType.text.plain)
+ Handler.fromResource(fullPath).map(_.addHeader(headerContentType))
+ }.flatten
)
- // @@
- // HttpAppMiddleware.updateHeaders(headers =>
- // Headers(
- // headers.map(h =>
- // if (h.key == HttpHeaderNames.ACCESS_CONTROL_ALLOW_ORIGIN) {
- // Header(HttpHeaderNames.ACCESS_CONTROL_ALLOW_ORIGIN, "*")
- // } else h
- // )
- // )
- // )
+ }.sandbox.toHttpApp
+
}
diff --git a/mediator/src/main/scala/io/iohk/atala/mediator/app/MediatorStandalone.scala b/mediator/src/main/scala/io/iohk/atala/mediator/app/MediatorStandalone.scala
index 5b1b49ec..e7d36fa4 100644
--- a/mediator/src/main/scala/io/iohk/atala/mediator/app/MediatorStandalone.scala
+++ b/mediator/src/main/scala/io/iohk/atala/mediator/app/MediatorStandalone.scala
@@ -16,8 +16,6 @@ import zio.config.*
import zio.config.magnolia.*
import zio.config.typesafe.*
import zio.http.*
-import zio.http.Http.{Empty, Static}
-import zio.http.ZClient.ClientLive
import zio.json.*
import zio.logging.LogFormat.*
import zio.logging.backend.SLF4J
@@ -57,17 +55,6 @@ object MediatorStandalone extends ZIOAppDefault {
override val bootstrap: ZLayer[ZIOAppArgs, Any, Any] =
Runtime.removeDefaultLoggers >>> SLF4J.slf4j(mediatorColorFormat)
- // val app: HttpApp[ // type HttpApp[-R, +Err] = Http[R, Err, Request, Response]
- // Hub[String] & Operations & MessageDispatcher & MediatorAgent & Resolver & MessageItemRepo & UserAccountRepo &
- // OutboxMessageRepo,
- // Throwable
- // ]
- val app: Http[
- Operations & Resolver & UserAccountRepo & OutboxMessageRepo & MessageDispatcher & MediatorAgent & MessageItemRepo,
- (HttpAppMiddleware[Nothing, Any, Nothing, Any] | HttpAppMiddleware[Nothing, Any, Nothing, Any])#OutErr[Throwable],
- Request,
- Response
- ] = MediatorAgent.didCommApp
override val run = for {
_ <- Console.printLine( // https://patorjk.com/software/taag/#p=display&f=ANSI%20Shadow&t=Mediator
"""███╗ ███╗███████╗██████╗ ██╗ █████╗ ████████╗ ██████╗ ██████╗
@@ -103,18 +90,7 @@ object MediatorStandalone extends ZIOAppDefault {
client = Scope.default >>> Client.default
inboundHub <- Hub.bounded[String](5)
myServer <- Server
- .serve(
- (app @@ (MiddlewareUtils.annotateHeaders ++ MiddlewareUtils.serverTime))
- .tapUnhandledZIO(ZIO.logError("Unhandled Endpoint"))
- .tapErrorCauseZIO(cause => ZIO.logErrorCause(cause)) // THIS is to log all the erros
- .mapError(err =>
- Response(
- status = Status.BadRequest,
- headers = Headers.empty,
- body = Body.fromString(err.toString()), // Body.fromString(err.getMessage()),
- )
- )
- )
+ .serve(MediatorAgent.didCommApp @@ (Middleware.cors))
.provideSomeLayer(DidPeerResolver.layerDidPeerResolver)
.provideSomeLayer(mediatorConfig.agentLayer) // .provideSomeLayer(AgentByHost.layer)
.provideSomeLayer(
diff --git a/webapp/src/main/scala/io/iohk/atala/mediator/AppUtils.scala b/webapp/src/main/scala/io/iohk/atala/mediator/AppUtils.scala
index aebe5586..9a0c044b 100644
--- a/webapp/src/main/scala/io/iohk/atala/mediator/AppUtils.scala
+++ b/webapp/src/main/scala/io/iohk/atala/mediator/AppUtils.scala
@@ -96,7 +96,8 @@ object AppUtils {
href := "https://atalaprism.io",
target := "_blank",
img(
- src := "https://atalaprism.io/images/atala-prism-logo-suite.svg",
+ // src := "https://atalaprism.io/images/atala-prism-logo-suite.svg",
+ src := "public/atala-prism-logo-suite.svg", // Note: this is not the best server for CDN
className := "logo vanilla",
alt := "Prism Mediator"
),