diff --git a/app/server-routes/src/main/scala/org/bitcoins/server/routes/CORSHandler.scala b/app/server-routes/src/main/scala/org/bitcoins/server/routes/CORSHandler.scala new file mode 100644 index 0000000000..0cde6f62f1 --- /dev/null +++ b/app/server-routes/src/main/scala/org/bitcoins/server/routes/CORSHandler.scala @@ -0,0 +1,45 @@ +package org.bitcoins.server.routes + +import akka.http.scaladsl.model.{HttpResponse, StatusCodes} +import akka.http.scaladsl.model.headers._ +import akka.http.scaladsl.model.HttpMethods._ +import akka.http.scaladsl.server.Directive0 +import akka.http.scaladsl.server.Directives._ +import akka.http.scaladsl.server.Route + +/** Add CORS handling for accessing backend over localhost from modern browsers + * @see dzone.com/articles/handling-cors-in-akka-http + */ +trait CORSHandler { + + private val corsResponseHeaders = List( + `Access-Control-Allow-Origin`.*, + `Access-Control-Allow-Credentials`(true), + `Access-Control-Allow-Headers`("Authorization", + "Content-Type", + "X-Requested-With") + ) + + //this directive adds access control headers to normal responses + private def addAccessControlHeaders: Directive0 = { + respondWithHeaders(corsResponseHeaders) + } + + //this handles preflight OPTIONS requests. + private def preflightRequestHandler: Route = options { + complete( + HttpResponse(StatusCodes.OK).withHeaders( + `Access-Control-Allow-Methods`(OPTIONS, POST, PUT, GET, DELETE))) + } + + // Wrap the Route with this method to enable adding of CORS headers + def corsHandler(r: Route): Route = addAccessControlHeaders { + preflightRequestHandler ~ r + } + + // Helper method to add CORS headers to HttpResponse + // preventing duplication of CORS headers across code + def addCORSHeaders(response: HttpResponse): HttpResponse = + response.withHeaders(corsResponseHeaders) + +} diff --git a/app/server-routes/src/main/scala/org/bitcoins/server/routes/Server.scala b/app/server-routes/src/main/scala/org/bitcoins/server/routes/Server.scala index c737014340..1ea8976d89 100644 --- a/app/server-routes/src/main/scala/org/bitcoins/server/routes/Server.scala +++ b/app/server-routes/src/main/scala/org/bitcoins/server/routes/Server.scala @@ -18,7 +18,8 @@ case class Server( handlers: Seq[ServerRoute], rpcbindOpt: Option[String], rpcport: Int)(implicit system: ActorSystem) - extends HttpLogger { + extends HttpLogger + with CORSHandler { import system.dispatcher @@ -54,7 +55,7 @@ case class Server( handleRejections(rejectionHandler) { handleExceptions(exceptionHandler) { - route + corsHandler(route) } } }