From 3f95d7a54fd20d4dd6b023360cbe0b6cc4442780 Mon Sep 17 00:00:00 2001 From: Fabio Pinheiro Date: Mon, 4 Sep 2023 12:05:17 +0100 Subject: [PATCH] fix: Annotate Headers & Update zio-http to version 3.0.0-RC2 (#106) * fix: Annotate Headers & Update zio-http to version 3.0.0-RC2 * fix: cleanup code - remove websocket logic * fix: get Header.ContentType not working Signed-off-by: Fabio Pinheiro --- build.sbt | 2 +- .../mediator/comm/MessageDispatcherJVM.scala | 16 +- .../mediator/utils/DIDSocketManager.scala | 97 --------- .../atala/mediator/utils/HttpHelpers.scala | 75 ++++--- .../iohk/atala/mediator/utils/MyChannel.scala | 6 - .../atala/mediator/app/MediatorAgent.scala | 198 +++++------------- .../mediator/app/MediatorStandalone.scala | 28 +-- 7 files changed, 119 insertions(+), 303 deletions(-) delete mode 100644 http-utils/jvm/src/main/scala/io/iohk/atala/mediator/utils/DIDSocketManager.scala delete mode 100644 http-utils/jvm/src/main/scala/io/iohk/atala/mediator/utils/MyChannel.scala diff --git a/build.sbt b/build.sbt index 350d351e..77fa6b88 100644 --- a/build.sbt +++ b/build.sbt @@ -23,7 +23,7 @@ lazy val V = new { val zio = "2.0.15" val zioJson = "0.4.2" // val zioMunitTest = "0.1.1" - val zioHttp = "0.0.5" + val zioHttp = "3.0.0-RC2" 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 ed84db7c..81623bfd 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 @@ -6,10 +6,11 @@ import fmgp.did.comm.* import io.iohk.atala.mediator.comm.* import io.iohk.atala.mediator.utils.MyHeaders import zio.* -import zio.http.* -import zio.http.model.* +import zio.http.{MediaType => ZMediaType, *} import zio.json.* +import scala.util.chaining._ + object MessageDispatcherJVM { val layer: ZLayer[Client, Throwable, MessageDispatcher] = ZLayer.fromZIO( @@ -26,14 +27,19 @@ class MessageDispatcherJVM(client: Client) extends MessageDispatcher { destination: String, xForwardedHost: Option[String], ): ZIO[Any, DispatcherError, String] = { - val contentTypeHeader = Headers.contentType(msg.`protected`.obj.typ.getOrElse(MediaTypes.ENCRYPTED).typ) - val xForwardedHostHeader = Headers(xForwardedHost.map(x => Header(MyHeaders.xForwardedHost, x))) + val contentTypeHeader = msg.`protected`.obj.typ + .getOrElse(MediaTypes.ENCRYPTED) + // .pipe(e => Header.ContentType(ZMediaType(e.mainType, e.subType))) FIXME + .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 = contentTypeHeader ++ xForwardedHostHeader, + headers = Headers(Seq(Some(contentTypeHeader), xForwardedHostHeader).flatten), content = Body.fromCharSequence(msg.toJson), ) .tapError(ex => ZIO.logWarning(s"Fail when calling '$destination': ${ex.toString}")) diff --git a/http-utils/jvm/src/main/scala/io/iohk/atala/mediator/utils/DIDSocketManager.scala b/http-utils/jvm/src/main/scala/io/iohk/atala/mediator/utils/DIDSocketManager.scala deleted file mode 100644 index c909b82b..00000000 --- a/http-utils/jvm/src/main/scala/io/iohk/atala/mediator/utils/DIDSocketManager.scala +++ /dev/null @@ -1,97 +0,0 @@ -package io.iohk.atala.mediator.utils - -import fmgp.crypto.error.* -import fmgp.did.* -import fmgp.did.comm.* -import zio.* -import zio.http.socket.* -import zio.http.{Channel, ChannelEvent} -import zio.json.* -import zio.stream.* - -case class DIDSocketManager( - sockets: Map[SocketID, MyChannel] = Map.empty, - ids: Map[FROMTO, Seq[SocketID]] = Map.empty, - kids: Map[VerificationMethodReferenced, Seq[SocketID]] = Map.empty, - tapBy: Seq[SocketID] = Seq.empty, -) { - - def link(from: VerificationMethodReferenced, socketID: SocketID): DIDSocketManager = - if (!sockets.keySet.contains(socketID)) this // if sockets is close - else - kids.get(from) match - case Some(seq) if seq.contains(socketID) => this - case Some(seq) => this.copy(kids = kids + (from -> (seq :+ socketID))).link(from.fromto, socketID) - case None => this.copy(kids = kids + (from -> Seq(socketID))).link(from.fromto, socketID) - - def link(from: FROMTO, socketID: SocketID): DIDSocketManager = - if (!sockets.keySet.contains(socketID)) this // if sockets is close - else - ids.get(from) match - case Some(seq) if seq.contains(socketID) => this - case Some(seq) => this.copy(ids = ids + (from -> (seq :+ socketID))) - case None => this.copy(ids = ids + (from -> Seq(socketID))) - - def tap(socketID: SocketID) = this.copy(tapBy = tapBy :+ socketID) - - def tapSockets = sockets.filter(e => tapBy.contains(e._1)).map(_._2) - - def registerSocket(myChannel: MyChannel) = this.copy(sockets = sockets + (myChannel.id -> myChannel)) - - def unregisterSocket(socketID: SocketID) = this.copy( - sockets = sockets.view.filterKeys(_ != socketID).toMap, - ids = ids.map { case (did, socketsID) => (did, socketsID.filter(_ != socketID)) }.filterNot(_._2.isEmpty), - kids = kids.map { case (kid, socketsID) => (kid, socketsID.filter(_ != socketID)) }.filterNot(_._2.isEmpty), - tapBy = tapBy.filter(_ != socketID) - ) - -} - -object DIDSocketManager { - def inBoundSize = 5 - def outBoundSize = 3 - - private given JsonEncoder[Hub[String]] = JsonEncoder.string.contramap((e: Hub[String]) => "HUB") - private given JsonEncoder[MyChannel] = DeriveJsonEncoder.gen[MyChannel] - given encoder: JsonEncoder[DIDSocketManager] = DeriveJsonEncoder.gen[DIDSocketManager] - - def make = Ref.make(DIDSocketManager()) - - def tapSocket(didSubject: DIDSubject, channel: Channel[WebSocketFrame]) = - for { - socketManager <- ZIO.service[Ref[DIDSocketManager]] - hub <- Hub.bounded[String](outBoundSize) - myChannel = MyChannel(channel.id, hub) - _ <- socketManager.update { _.registerSocket(myChannel).tap(socketID = channel.id) } - sink = ZSink.foreach((value: String) => channel.writeAndFlush(WebSocketFrame.text(value))) - _ <- ZIO.log(s"Tapping into channel") - _ <- ZStream.fromHub(myChannel.socketOutHub).run(sink) // TODO .fork does not work!!! - _ <- ZIO.log(s"Tap channel concluded") - } yield () - - def registerSocket(channel: Channel[WebSocketFrame]) = - for { - socketManager <- ZIO.service[Ref[DIDSocketManager]] - hub <- Hub.bounded[String](outBoundSize) - myChannel = MyChannel(channel.id, hub) - _ <- socketManager.update { _.registerSocket(myChannel) } - sink = ZSink.foreach((value: String) => channel.writeAndFlush(WebSocketFrame.text(value))) - _ <- ZIO.log(s"Registering channel") - _ <- ZStream.fromHub(myChannel.socketOutHub).run(sink) // TODO .fork does not work!!! - _ <- ZIO.log(s"Channel concluded") - } yield () - - def newMessage(channel: Channel[WebSocketFrame], data: String) = - for { - socketManager <- ZIO.service[Ref[DIDSocketManager]] - id = channel.id - } yield (id, data) - - def unregisterSocket(channel: Channel[WebSocketFrame]) = - for { - socketManager <- ZIO.service[Ref[DIDSocketManager]] - _ <- socketManager.update { case sm: DIDSocketManager => sm.unregisterSocket(channel.id) } - _ <- ZIO.log(s"Channel unregisterSocket") - } yield () - -} 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 b688e29d..48577fa1 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 @@ -2,40 +2,51 @@ package io.iohk.atala.mediator.utils import zio.* import zio.http.* +import java.util.concurrent.TimeUnit -extension [R, Err](app: HttpApp[R, Err]) - def annotateLogs: HttpApp[R, Err] = - app @@ new HttpAppMiddleware.Simple[Any, Nothing] { self1 => - override def apply[R, Err]( - http: Http[R, Err, Request, Response], - )(implicit trace: Trace): Http[R, Err, Request, Response] = - http.mapZIO { request => - val headers = request.headers.toSeq.map(e => (e.key.toString.toLowerCase, e.value)).toMap - inline def composeAnnotate( - inline headerName: String, - inline logName: String, - inline run: ZIO[R, Err, Response] - ) = headers.get(headerName) match - case Some(value) => ZIO.logAnnotate(logName, value.toString) { run } - case None => run - - composeAnnotate( - "fly-client-ip", - "client-ip", - composeAnnotate( - "X-Request-ID", - "fly-request-id", - composeAnnotate( - "user-agent", - "user-agent", - composeAnnotate( - "host", - "host", - ZIO.succeed(request) - ) - ) - ) +object MiddlewareUtils { + + final def serverTime: RequestHandlerMiddleware[Nothing, Any, Nothing, Any] = HttpAppMiddleware.patchZIO(_ => + for { + currentMilliseconds <- Clock.currentTime(TimeUnit.MILLISECONDS) + withHeader = Response.Patch.addHeader("X-Time", currentMilliseconds.toString) + } yield withHeader, + ) + + final def annotateHeaders: RequestHandlerMiddleware[Nothing, Any, Nothing, Any] = + new RequestHandlerMiddleware.Simple[Any, Nothing] { + override def apply[R1 <: Any, Err1 >: Nothing]( + handler: Handler[R1, Err1, Request, Response], + )(implicit trace: Trace): Handler[R1, Err1, Request, Response] = + Handler.fromFunctionZIO { (request: Request) => + + def annotations = request.headers.toSet.flatMap(h => + h.headerName.toLowerCase() match { + case "fly-client-ip" => Some(LogAnnotation("client-ip", h.renderedValue)) + case "fly-request-id" => Some(LogAnnotation("fly-request-id", h.renderedValue)) + case "x-request-id" => Some(LogAnnotation("x-request-id", h.renderedValue)) + case "user-agent" => Some(LogAnnotation("user-agent", h.renderedValue)) + case "host" => Some(LogAnnotation("host", h.renderedValue)) + case _ => None + } ) + val requestHandler = handler + .runZIO(request) + .sandbox + .exit + .timed + .tap { + case (duration, Exit.Success(response)) => + ZIO.log(s"${response.status.code} ${request.method} ${request.url.encode} ${duration.toMillis}ms") + case (duration, Exit.Failure(cause)) => + ZIO.log(s"Failed ${request.method} ${request.url.encode} ${duration.toMillis}ms: " + cause.prettyPrint) + } + .flatMap(_._2) + .unsandbox + + ZIO.logAnnotate(annotations)(requestHandler) } } + +} diff --git a/http-utils/jvm/src/main/scala/io/iohk/atala/mediator/utils/MyChannel.scala b/http-utils/jvm/src/main/scala/io/iohk/atala/mediator/utils/MyChannel.scala deleted file mode 100644 index be873a8a..00000000 --- a/http-utils/jvm/src/main/scala/io/iohk/atala/mediator/utils/MyChannel.scala +++ /dev/null @@ -1,6 +0,0 @@ -package io.iohk.atala.mediator.utils - -import zio.* - -type SocketID = String -case class MyChannel(id: SocketID, socketOutHub: Hub[String]) 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 e8dc9891..48489471 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 @@ -18,24 +18,21 @@ import reactivemongo.api.bson.Macros.{*, given} import reactivemongo.api.bson.{*, given} import zio.* import zio.http.* -import zio.http.model.* -import zio.http.socket.* 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 case class MediatorAgent( override val id: DID, override val keyStore: KeyStore, // Should we make it lazy with ZIO - didSocketManager: Ref[DIDSocketManager], ) extends Agent { override def keys: Seq[PrivateKey] = keyStore.keys.toSeq - // val resolverLayer: ULayer[DynamicResolver] = - // DynamicResolver.resolverLayer(didSocketManager) - type Services = Resolver & Agent & Operations & MessageDispatcher & UserAccountRepo & MessageItemRepo & OutboxMessageRepo val protocolHandlerLayer: URLayer[UserAccountRepo & MessageItemRepo & OutboxMessageRepo, ProtocolExecuter[ @@ -87,10 +84,7 @@ case class MediatorAgent( } yield (plaintextMessage) } - def receiveMessage( - data: String, - mSocketID: Option[SocketID], - ): ZIO[ + def receiveMessage(data: String): ZIO[ Operations & Resolver & MessageDispatcher & MediatorAgent & MessageItemRepo & UserAccountRepo & OutboxMessageRepo, MediatorError | StorageError, Option[SignedMessage | EncryptedMessage] @@ -105,13 +99,10 @@ case class MediatorAgent( "Message's recipients KIDs: " + message.recipientsKid.mkString(",") + "; DID: " + "Message's recipients DIDs: " + message.recipientsSubject.mkString(",") ) *> ZIO.succeed(message) - maybeSyncReplyMsg <- receiveMessage(msg, mSocketID) + maybeSyncReplyMsg <- receiveMessage(msg) } yield (maybeSyncReplyMsg) - def receiveMessage( - msg: EncryptedMessage, - mSocketID: Option[SocketID] - ): ZIO[ + def receiveMessage(msg: EncryptedMessage): ZIO[ Operations & Resolver & MessageDispatcher & MediatorAgent & MessageItemRepo & UserAccountRepo & OutboxMessageRepo, MediatorError | StorageError, Option[SignedMessage | EncryptedMessage] @@ -173,18 +164,6 @@ case class MediatorAgent( ) ) } - _ <- didSocketManager.get.flatMap { m => // TODO HACK REMOVE !!!!!!!!!!!!!!!!!!!!!!!! - ZIO.foreach(m.tapSockets)(_.socketOutHub.publish(TapMessage(msg, plaintextMessage).toJson)) - } - _ <- mSocketID match - case None => ZIO.unit - case Some(socketID) => - plaintextMessage.from match - case None => ZIO.unit - case Some(from) => - didSocketManager.update { - _.link(from.asFROMTO, socketID) - } // TODO Store context of the decrypt unwarping // TODO SreceiveMessagetore context with MsgID and PIURI ret <- { @@ -203,99 +182,21 @@ case class MediatorAgent( } .provideSomeLayer( /*resolverLayer ++ indentityLayer ++*/ protocolHandlerLayer) - def createSocketApp( - annotationMap: Seq[LogAnnotation] - ): ZIO[ - MediatorAgent & Resolver & Operations & MessageDispatcher & MessageItemRepo & UserAccountRepo & OutboxMessageRepo, - Nothing, - zio.http.Response - ] = { - val SOCKET_ID = "SocketID" - val appAux = SocketApp { - case ChannelEvent(ch, ChannelEvent.UserEventTriggered(ChannelEvent.UserEvent.HandshakeComplete)) => - ZIO.logAnnotate(LogAnnotation(SOCKET_ID, ch.id), annotationMap: _*) { - DIDSocketManager.registerSocket(ch) - } - case ChannelEvent(ch, ChannelEvent.ChannelRead(WebSocketFrame.Text(text))) => - ZIO.logAnnotate(LogAnnotation(SOCKET_ID, ch.id), annotationMap: _*) { - DIDSocketManager - .newMessage(ch, text) - .flatMap { case (socketID, encryptedMessage) => receiveMessage(encryptedMessage, Some(socketID)) } - .mapError { - case ex: MediatorError => MediatorException(ex) - case ex: StorageError => StorageException(ex) - } - } - case ChannelEvent(ch, ChannelEvent.ChannelUnregistered) => - ZIO.logAnnotate(LogAnnotation(SOCKET_ID, ch.id), annotationMap: _*) { - DIDSocketManager.unregisterSocket(ch) - } - case channelEvent => - ZIO.logAnnotate(LogAnnotation(SOCKET_ID, channelEvent.channel.id), annotationMap: _*) { - ZIO.logError(s"Unknown event type: ${channelEvent.event}") - } - } - appAux.toResponse.provideSomeEnvironment { (env) => env.add(env.get[MediatorAgent].didSocketManager) } - } - - def websocketListenerApp( - annotationMap: Seq[LogAnnotation] - ): ZIO[MediatorAgent & Operations & MessageDispatcher, Nothing, zio.http.Response] = { - val SOCKET_ID = "SocketID" - SocketApp { - case ChannelEvent(ch, ChannelEvent.UserEventTriggered(ChannelEvent.UserEvent.HandshakeComplete)) => - ZIO.logAnnotate(LogAnnotation(SOCKET_ID, ch.id), annotationMap: _*) { - // ch.writeAndFlush(WebSocketFrame.text("Greetings!")) *> - // ch.writeAndFlush(WebSocketFrame.text(s"Tap into ${id.did}")) *> - DIDSocketManager.tapSocket(id, ch) - } - case ChannelEvent(ch, ChannelEvent.ChannelRead(WebSocketFrame.Text(text))) => - ZIO.logAnnotate(LogAnnotation(SOCKET_ID, ch.id), annotationMap: _*) { - ZIO.logWarning(s"Ignored Message from '${ch.id}'") - } - case ChannelEvent(ch, ChannelEvent.ChannelUnregistered) => - ZIO.logAnnotate(LogAnnotation(SOCKET_ID, ch.id), annotationMap: _*) { - DIDSocketManager.unregisterSocket(ch) - } - case channelEvent => - ZIO.logAnnotate(LogAnnotation(SOCKET_ID, channelEvent.channel.id), annotationMap: _*) { - ZIO.logError(s"Unknown event type: ${channelEvent.event}") - } - }.toResponse - .provideSomeEnvironment { (env) => env.add(env.get[MediatorAgent].didSocketManager) } - } } object MediatorAgent { - def make(id: DID, keyStore: KeyStore): ZIO[Any, Nothing, MediatorAgent] = for { - sm <- DIDSocketManager.make - } yield MediatorAgent(id, keyStore, sm) + def make(id: DID, keyStore: KeyStore): ZIO[Any, Nothing, MediatorAgent] = ZIO.succeed(MediatorAgent(id, keyStore)) def didCommApp = { Http.collectZIO[Request] { - case req @ Method.GET -> !! / "headers" => - val data = req.headersAsList.toSeq.map(e => (e.key.toString(), e.value.toString())) + case req @ Method.GET -> Root / "headers" => + println(req.headers.size) + 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 -> !! / "health" => ZIO.succeed(Response.ok) + case req @ Method.GET -> Root / "health" => ZIO.succeed(Response.ok) - case req @ Method.GET -> !! if req.headersAsList.exists { h => - h.key.toString.toLowerCase == "content-type" && - (h.value.toString.startsWith(MediaTypes.SIGNED.typ) || - h.value.toString.startsWith(MediaTypes.ENCRYPTED.typ)) - } => - for { - agent <- ZIO.service[MediatorAgent] - annotationMap <- ZIO.logAnnotations.map(_.map(e => LogAnnotation(e._1, e._2)).toSeq) - ret <- agent.createSocketApp(annotationMap) - } yield (ret) - case Method.GET -> !! / "tap" => // TODO only on dev mode - for { - agent <- ZIO.service[MediatorAgent] - annotationMap <- ZIO.logAnnotations.map(_.map(e => LogAnnotation(e._1, e._2)).toSeq) - ret <- agent.websocketListenerApp(annotationMap) - } yield (ret) - case Method.GET -> !! / "invitation" => + case Method.GET -> Root / "invitation" => for { agent <- ZIO.service[MediatorAgent] annotationMap <- ZIO.logAnnotations.map(_.map(e => LogAnnotation(e._1, e._2)).toSeq) @@ -309,7 +210,7 @@ object MediatorAgent { ret <- ZIO.succeed(Response.json(invitation.toPlaintextMessage.toJson)) } yield (ret) - case Method.GET -> !! / "invitationOOB" => + case Method.GET -> Root / "invitationOOB" => for { agent <- ZIO.service[MediatorAgent] annotationMap <- ZIO.logAnnotations.map(_.map(e => LogAnnotation(e._1, e._2)).toSeq) @@ -327,16 +228,24 @@ object MediatorAgent { ) } yield (ret) - case req @ Method.POST -> !! if req.headersAsList.exists { h => - h.key.toString.toLowerCase == "content-type" && - (h.value.toString.startsWith(MediaTypes.SIGNED.typ) || - h.value.toString.startsWith(MediaTypes.ENCRYPTED.typ)) - } => + 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, None) + .receiveMessage(data) .map { case None => Response.ok case Some(value: SignedMessage) => Response.json(value.toJson) @@ -361,15 +270,15 @@ object MediatorAgent { } } yield ret // TODO [return_route extension](https://github.com/decentralized-identity/didcomm-messaging/blob/main/extensions/return_route/main.md) - case req @ Method.POST -> !! => + 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}") - .setStatus(Status.BadRequest) + .copy(status = Status.BadRequest) ) - case req @ Method.GET -> !! => { // html.Html.fromDomElement() + case req @ Method.GET -> Root => { // html.Html.fromDomElement() for { agent <- ZIO.service[MediatorAgent] _ <- ZIO.log("index.html") @@ -384,35 +293,28 @@ object MediatorAgent { ] } ++ Http .fromResource(s"public/webapp-fastopt-bundle.js.gz") - .map(e => - e.setHeaders( - Headers( - e.headers.filter(_.key != "content-encoding") ++ Seq( - Header("content-type", "application/javascript"), - Header("content-encoding", "gzip"), - ) - ) - ) - ) + .map(_.setHeaders(Headers(Header.ContentType(MediaType.application.javascript), Header.ContentEncoding.GZip))) .when { - case Method.GET -> !! / "public" / "webapp-fastopt-bundle.js" => true - case _ => false + case Method.GET -> Root / "public" / "webapp-fastopt-bundle.js" => true + case _ => false } - @@ - HttpAppMiddleware.cors( - zio.http.middleware.Cors.CorsConfig( - allowedOrigins = _ => true, - allowedMethods = Some(Set(Method.GET, Method.POST, Method.OPTIONS)), - ) - ) - @@ - HttpAppMiddleware.updateHeaders(headers => - Headers( - headers.map(h => - if (h.key == HttpHeaderNames.ACCESS_CONTROL_ALLOW_ORIGIN) { - Header(HttpHeaderNames.ACCESS_CONTROL_ALLOW_ORIGIN, "*") - } else h - ) + @@ 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), ) ) + // @@ + // HttpAppMiddleware.updateHeaders(headers => + // Headers( + // headers.map(h => + // if (h.key == HttpHeaderNames.ACCESS_CONTROL_ALLOW_ORIGIN) { + // Header(HttpHeaderNames.ACCESS_CONTROL_ALLOW_ORIGIN, "*") + // } else h + // ) + // ) + // ) } 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 71b75ece..eb9bef4b 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 @@ -18,8 +18,6 @@ import zio.config.typesafe.* import zio.http.* import zio.http.Http.{Empty, Static} import zio.http.ZClient.ClientLive -import zio.http.model.* -import zio.http.socket.* import zio.json.* import zio.logging.LogFormat.* import zio.logging.backend.SLF4J @@ -59,13 +57,19 @@ 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: 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 ++ Http - .collectZIO[Request] { case Method.GET -> !! / "hello" => + .collectZIO[Request] { case Method.GET -> Root / "hello" => ZIO.succeed(Response.text("Hello World! DID Comm Mediator APP")).debug } override val run = for { @@ -94,22 +98,18 @@ object MediatorStandalone extends ZIOAppDefault { .nested("mediator") .load(Config.int("port")) _ <- ZIO.log(s"Starting server on port: $port") - server = { - val config = ServerConfig(address = new java.net.InetSocketAddress(port)) - ServerConfig.live(config)(using Trace.empty) >>> Server.live - } client = Scope.default >>> Client.default inboundHub <- Hub.bounded[String](5) myServer <- Server .serve( - app.annotateLogs + (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.getMessage()), + body = Body.fromString(err.toString()), // Body.fromString(err.getMessage()), ) ) ) @@ -123,7 +123,7 @@ object MediatorStandalone extends ZIOAppDefault { .provideSomeLayer(Operations.layerDefault) .provideSomeLayer(client >>> MessageDispatcherJVM.layer) .provideSomeEnvironment { (env: ZEnvironment[Server]) => env.add(myHub) } - .provide(server) + .provide(Server.defaultWithPort(port)) .debug .fork _ <- ZIO.log(s"Mediator Started")