yada 2020-03-27

@emil0r has left the channel

we're running into a problem with websockets and Content-Security-Policy when deploying our yada app to a staging environment:

sse.cljs:52 Refused to connect to '' because it violates the following Content Security Policy directive: "default-src https: data: 'unsafe-inline' 'unsafe-eval'". Note that 'connect-src' was not explicitly set, so 'default-src' is used as a fallback.
We don't send this header in nginx. Is yada sending a default for this?

I do see a couple of issues around this: https://github.com/juxt/yada/issues/61

You can change the CSP per-resource.

@dominicm I now have this:

(resource
   system
   {:swagger/tags ["app"]
    :id :dre.resources/sse
    :content-security-policy "default-src https: wss: data: 'unsafe-inline' 'unsafe-eval'"
    :methods
    {:get
     {:consumes "application/json"
      :produces "application/json"
      :response
      (fn [ctx]
        (let [req (:request ctx)
              conn (http/websocket-connection req)
              user-id (auth/user-id (user-profile ctx))
              sse (:dre.app.sse/sse system)
              chan (sse/new-chan-for-user! sse user-id)
              _ (-> conn (d/chain
                          (fn [socket]
                            (s/connect chan socket)))
                    (d/catch (fn [e]
                               (error e))))]
          (sse/send-message-to-user sse user-id :sse/ack)
          nil))}}})
but we're still getting something else back in the browser 😕

something else than: :content-security-policy "default-src https: wss: data: 'unsafe-inline' 'unsafe-eval'"

I thought it went inside a map

we used to have it on the top level of our yada resources like months or years ago:

:produces formats
         :consumes formats
         :content-security-policy content-security-policy

Hmm. Yes.

hmm, adding :content-security-policy "default-src https: wss: data: 'unsafe-inline' 'unsafe-eval'" on ALL resources works, but not when I only add it to the resource which produces the websocket:

(defn new-websocket-resource
  [system]
  (resource
   system
   {:swagger/tags ["app"]
    :id :dre.resources/sse
    :content-security-policy "default-src https: wss: data: 'unsafe-inline' 'unsafe-eval'"
    :methods
    {:get
     {:consumes "application/json"
      :produces "application/json"
      :response
      (fn [ctx]
        (let [req (:request ctx)
              conn (http/websocket-connection req)
              user-id (auth/user-id (user-profile ctx))
              sse (:dre.app.sse/sse system)
              chan (sse/new-chan-for-user! sse user-id)
              _ (-> conn (d/chain
                          (fn [socket]
                            (s/connect chan socket)))
                    (d/catch (fn [e]
                               (error e))))]
          (sse/send-message-to-user sse user-id :sse/ack)
          {}))}}}))

so what's up with that?

No idea 😹

Don't you need to adjust the csp elsewhere anyway?

You need to set the csp for your html pages to allow websockets.

Not on the websocket resource

well, then it's fine I guess

I really don't care as long as this works

I'm not sure websockets supports headers, it isn't http

thanks for the help!