diff --git a/lib/live_svelte.ex b/lib/live_svelte.ex index c54d117..cd84895 100644 --- a/lib/live_svelte.ex +++ b/lib/live_svelte.ex @@ -45,6 +45,18 @@ defmodule LiveSvelte do doc: "Class to apply to the Svelte component", examples: ["my-class", "my-class another-class"] + attr :csp_nonce, :string, + default: nil, + doc: "A Content-Security-Policy nonce for the generated
{raw(@ssr_render["head"])} - {raw(@ssr_render["html"])} diff --git a/package.json b/package.json index 5207fab..f272340 100644 --- a/package.json +++ b/package.json @@ -16,8 +16,8 @@ }, "exports": { ".": { - "import": "./assets/js/live_svelte/index.ts", - "types": "./assets/js/live_svelte/types.d.ts" + "types": "./assets/js/live_svelte/types.d.ts", + "import": "./assets/js/live_svelte/index.ts" }, "./vitePlugin": "./assets/js/live_svelte/vite_plugin.js" }, diff --git a/test/csp_nonce_test.exs b/test/csp_nonce_test.exs new file mode 100644 index 0000000..6360564 --- /dev/null +++ b/test/csp_nonce_test.exs @@ -0,0 +1,60 @@ +defmodule LiveSvelte.CspNonceTest do + use ExUnit.Case, async: true + + defp render_html(opts) do + %{ + __changed__: nil, + socket: nil, + name: "TestComponent", + id: "test-csp", + key: nil, + props: %{}, + ssr: false, + class: nil, + loading: [], + inner_block: [], + csp_nonce: opts[:csp_nonce], + csp_script_nonce: opts[:csp_script_nonce], + csp_style_nonce: opts[:csp_style_nonce] + } + |> LiveSvelte.svelte() + |> Phoenix.HTML.Safe.to_iodata() + |> IO.iodata_to_binary() + end + + setup do + %{nonce: System.unique_integer([:positive])} + end + + test "no nonce attributes when none specified" do + refute render_html(%{}) =~ "nonce=" + end + + test "csp_nonce applies to both script and style", %{nonce: nonce} do + html = render_html(%{csp_nonce: nonce}) + + assert html =~ ~r/