Skip to content

Commit c54d002

Browse files
committed
feat(primer-service): Add a naïve CORS policy.
Notes: * This policy was created using the following references: https://stackoverflow.com/questions/63876281/cors-problem-while-making-a-fetch-call-from-ui-app-to-servant-server https://stackoverflow.com/questions/41399055/haskell-yesod-cors-problems-with-browsers-options-requests-when-doing-post-req/56256513#56256513 larskuhtz/wai-cors#29 (comment) We've also added `PUT` to the list of CORS methods recommended in the last reference, as our API uses it. * This policy does not specify any origins, which means its origins are equivalent to "*". Therefore, this policy will not work with credentialed requests. This is fine for now. * This policy does not specify an `Access-Control-Max-Age` (via wai-cors's `corsMaxAge` field), and therefore responses to browser preflight requests will only be cached for 5 seconds. This is helpful for testing, but is obviously not ideal for production use, so this will need to be addressed if we decide to use CORS in production.
1 parent 49ab499 commit c54d002

File tree

2 files changed

+23
-1
lines changed

2 files changed

+23
-1
lines changed

primer-service/primer-service.cabal

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ library
5353
, uuid ^>=1.3
5454
, wai ^>=3.2
5555
, wai-app-static ^>=3.1
56+
, wai-cors ^>=0.2.7
5657
, warp ^>=3.3
5758

5859
executable primer-service

primer-service/src/Primer/Server.hs

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
{-# LANGUAGE GADTs #-}
2+
{-# LANGUAGE ImportQualifiedPost #-}
23
{-# LANGUAGE OverloadedLabels #-}
34

45
-- | An HTTP service for the Primer API.
@@ -24,6 +25,15 @@ import Network.Wai.Handler.Warp (
2425
setPort,
2526
)
2627
import Network.Wai.Handler.Warp qualified as Warp (runSettings)
28+
import Network.Wai.Middleware.Cors (
29+
CorsResourcePolicy(..),
30+
cors,
31+
corsMethods,
32+
corsRequestHeaders,
33+
simpleCorsResourcePolicy,
34+
simpleHeaders,
35+
simpleMethods,
36+
)
2737
import Optics ((%), (.~), (?~))
2838
import Primer.API (
2939
Env (..),
@@ -410,10 +420,21 @@ primerServer = openAPIServer :<|> legacyServer
410420
server :: Env -> Server API
411421
server e = pure openAPIInfo :<|> hoistPrimer e
412422

423+
-- | CORS settings for the Primer API. Note that this policy will not
424+
-- work with credentialed requests because the origin is implicitly
425+
-- "*". See:
426+
-- https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#credentialed_requests_and_wildcards
427+
apiCors :: CorsResourcePolicy
428+
apiCors =
429+
simpleCorsResourcePolicy
430+
{ corsMethods = simpleMethods <> ["PUT", "OPTIONS"]
431+
, corsRequestHeaders = simpleHeaders <> ["Content-Type", "Authorization"]
432+
}
433+
413434
serve :: Sessions -> TBQueue Database.Op -> Version -> Int -> IO ()
414435
serve ss q v port = do
415436
putText $ "Listening on port " <> show port
416-
Warp.runSettings warpSettings $ noCache $ Servant.serve api $ server $ Env ss q v
437+
Warp.runSettings warpSettings $ noCache $ cors (const $ Just apiCors) $ Servant.serve api $ server $ Env ss q v
417438
where
418439
-- By default Warp will try to bind on either IPv4 or IPv6, whichever is
419440
-- available.

0 commit comments

Comments
 (0)