mirror of
https://github.com/livebook-dev/livebook.git
synced 2025-10-09 21:16:26 +08:00
Pass allowed URI schemes to Markdown outputs and update naming
This commit is contained in:
parent
0990ab4cb2
commit
12f2322d08
9 changed files with 42 additions and 28 deletions
|
@ -229,10 +229,10 @@ The following environment variables configure Livebook:
|
|||
iframe. Set it to "true" to enable it. If you do enable it, then the application
|
||||
must run with HTTPS.
|
||||
|
||||
* LIVEBOOK_ALLOW_URI_SCHEMES - sets addtional extra hyperlink protocols to
|
||||
the Markdown content. Livebook sanitizes links in Markdown, allowing only a few
|
||||
standard protocols by default (such as http and https). Set a comma-separated list of
|
||||
protocols to configure additional protocols.
|
||||
* LIVEBOOK_ALLOW_URI_SCHEMES - sets additional allowed hyperlink schemes to the
|
||||
Markdown content. Livebook sanitizes links in Markdown, allowing only a few
|
||||
standard schemes by default (such as http and https). Set it to a comma-separated
|
||||
list of schemes.
|
||||
|
||||
<!-- Environment variables -->
|
||||
|
||||
|
|
|
@ -125,7 +125,10 @@ const Cell = {
|
|||
"data-smart-cell-js-view-ref",
|
||||
null
|
||||
),
|
||||
protocols: getAttributeOrThrow(this.el, "data-protocols"),
|
||||
allowedUriSchemes: getAttributeOrThrow(
|
||||
this.el,
|
||||
"data-allowed-uri-schemes"
|
||||
),
|
||||
};
|
||||
},
|
||||
|
||||
|
@ -217,7 +220,7 @@ const Cell = {
|
|||
const markdown = new Markdown(markdownContainer, source, {
|
||||
baseUrl: this.props.sessionPath,
|
||||
emptyText: "Empty markdown cell",
|
||||
extraProtocol: this.props.protocols.replace(/\s+/g, "").split(","),
|
||||
allowedUriSchemes: this.props.allowedUriSchemes.split(","),
|
||||
});
|
||||
|
||||
liveEditor.onChange((newSource) => {
|
||||
|
|
|
@ -15,6 +15,7 @@ const MarkdownRenderer = {
|
|||
|
||||
const markdown = new Markdown(this.el, "", {
|
||||
baseUrl: this.props.sessionPath,
|
||||
allowedUriSchemes: this.props.allowedUriSchemes.split(","),
|
||||
});
|
||||
|
||||
this.handleEvent(
|
||||
|
@ -29,6 +30,10 @@ const MarkdownRenderer = {
|
|||
return {
|
||||
id: getAttributeOrThrow(this.el, "data-id"),
|
||||
sessionPath: getAttributeOrThrow(this.el, "data-session-path"),
|
||||
allowedUriSchemes: getAttributeOrThrow(
|
||||
this.el,
|
||||
"data-allowed-uri-schemes"
|
||||
),
|
||||
};
|
||||
},
|
||||
};
|
||||
|
|
|
@ -28,13 +28,13 @@ class Markdown {
|
|||
constructor(
|
||||
container,
|
||||
content,
|
||||
{ baseUrl = null, emptyText = "", extraProtocol = [] } = {}
|
||||
{ baseUrl = null, emptyText = "", allowedUriSchemes = [] } = {}
|
||||
) {
|
||||
this.container = container;
|
||||
this.content = content;
|
||||
this.baseUrl = baseUrl;
|
||||
this.emptyText = emptyText;
|
||||
this.extraProtocol = extraProtocol;
|
||||
this.allowedUriSchemes = allowedUriSchemes;
|
||||
|
||||
this._render();
|
||||
}
|
||||
|
@ -67,7 +67,7 @@ class Markdown {
|
|||
.use(remarkRehype, { allowDangerousHtml: true })
|
||||
.use(rehypeRaw)
|
||||
.use(rehypeExpandUrls, { baseUrl: this.baseUrl })
|
||||
.use(rehypeSanitize, sanitizeSchema(this.extraProtocol))
|
||||
.use(rehypeSanitize, sanitizeSchema(this.allowedUriSchemes))
|
||||
.use(rehypeKatex)
|
||||
.use(rehypeMermaid)
|
||||
.use(rehypeExternalLinks, { baseUrl: this.baseUrl })
|
||||
|
@ -103,7 +103,7 @@ export default Markdown;
|
|||
|
||||
// Plugins
|
||||
|
||||
function sanitizeSchema(extraProtocol) {
|
||||
function sanitizeSchema(allowedUriSchemes) {
|
||||
// Allow class and style attributes on tags for syntax highlighting,
|
||||
// remarkMath tags, or user-written styles
|
||||
|
||||
|
@ -115,7 +115,7 @@ function sanitizeSchema(extraProtocol) {
|
|||
},
|
||||
protocols: {
|
||||
...defaultSchema.protocols,
|
||||
href: [...defaultSchema.protocols.href, ...extraProtocol],
|
||||
href: [...defaultSchema.protocols.href, ...allowedUriSchemes],
|
||||
},
|
||||
};
|
||||
}
|
||||
|
|
|
@ -195,9 +195,9 @@ defmodule Livebook.Config do
|
|||
end
|
||||
|
||||
@doc """
|
||||
Return list of added uri schemes.
|
||||
Return list of additional allowed hyperlink schemes.
|
||||
"""
|
||||
@spec allowed_uri_schemes() :: []
|
||||
@spec allowed_uri_schemes() :: list(String.t())
|
||||
def allowed_uri_schemes() do
|
||||
Application.fetch_env!(:livebook, :allowed_uri_schemes)
|
||||
end
|
||||
|
@ -407,6 +407,15 @@ defmodule Livebook.Config do
|
|||
end
|
||||
end
|
||||
|
||||
@doc """
|
||||
Parses and validates allowed URI schemes from env.
|
||||
"""
|
||||
def allowed_uri_schemes!(env) do
|
||||
if schemes = System.get_env(env) do
|
||||
String.split(schemes, ",", trim: true)
|
||||
end
|
||||
end
|
||||
|
||||
@doc """
|
||||
Returns the current version of running Livebook.
|
||||
"""
|
||||
|
@ -438,13 +447,4 @@ defmodule Livebook.Config do
|
|||
IO.puts("\nERROR!!! [Livebook] " <> message)
|
||||
System.halt(1)
|
||||
end
|
||||
|
||||
@doc """
|
||||
Parses and validates allowed URI schemes from env.
|
||||
"""
|
||||
def allowed_uri_schemes!(env) do
|
||||
if schemes = System.get_env(env) do
|
||||
String.split(schemes, ",", trim: true)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,6 +1,11 @@
|
|||
defmodule LivebookWeb.Output.MarkdownComponent do
|
||||
use LivebookWeb, :live_component
|
||||
|
||||
@impl true
|
||||
def mount(socket) do
|
||||
{:ok, assign(socket, allowed_uri_schemes: Livebook.Config.allowed_uri_schemes())}
|
||||
end
|
||||
|
||||
@impl true
|
||||
def update(assigns, socket) do
|
||||
socket = assign(socket, assigns)
|
||||
|
@ -20,6 +25,7 @@ defmodule LivebookWeb.Output.MarkdownComponent do
|
|||
phx-hook="MarkdownRenderer"
|
||||
data-id={@id}
|
||||
data-session-path={Routes.session_path(@socket, :page, @session_id)}
|
||||
data-allowed-uri-schemes={Enum.join(@allowed_uri_schemes, ",")}
|
||||
>
|
||||
</div>
|
||||
"""
|
||||
|
|
|
@ -5,7 +5,7 @@ defmodule LivebookWeb.SessionLive do
|
|||
import LivebookWeb.SessionHelpers
|
||||
import Livebook.Utils, only: [format_bytes: 1]
|
||||
|
||||
alias Livebook.{Config, Sessions, Session, Delta, Notebook, Runtime, LiveMarkdown, Secrets}
|
||||
alias Livebook.{Sessions, Session, Delta, Notebook, Runtime, LiveMarkdown, Secrets}
|
||||
alias Livebook.Notebook.{Cell, ContentLoader}
|
||||
alias Livebook.JSInterop
|
||||
alias Livebook.Hubs
|
||||
|
@ -64,7 +64,7 @@ defmodule LivebookWeb.SessionLive do
|
|||
saved_secrets: get_saved_secrets(),
|
||||
select_secret_ref: nil,
|
||||
select_secret_options: nil,
|
||||
protocols: Config.allowed_uri_schemes() |> Enum.join(",")
|
||||
allowed_uri_schemes: Livebook.Config.allowed_uri_schemes()
|
||||
)
|
||||
|> assign_private(data: data)
|
||||
|> prune_outputs()
|
||||
|
@ -271,9 +271,9 @@ defmodule LivebookWeb.SessionLive do
|
|||
session_id={@session.id}
|
||||
session_pid={@session.pid}
|
||||
client_id={@client_id}
|
||||
protocols={@protocols}
|
||||
runtime={@data_view.runtime}
|
||||
installing?={@data_view.installing?}
|
||||
allowed_uri_schemes={@allowed_uri_schemes}
|
||||
cell_view={@data_view.setup_cell_view}
|
||||
/>
|
||||
</div>
|
||||
|
@ -291,12 +291,12 @@ defmodule LivebookWeb.SessionLive do
|
|||
id={section_view.id}
|
||||
index={index}
|
||||
session_id={@session.id}
|
||||
protocols={@protocols}
|
||||
session_pid={@session.pid}
|
||||
client_id={@client_id}
|
||||
runtime={@data_view.runtime}
|
||||
smart_cell_definitions={@data_view.smart_cell_definitions}
|
||||
installing?={@data_view.installing?}
|
||||
allowed_uri_schemes={@allowed_uri_schemes}
|
||||
section_view={section_view}
|
||||
/>
|
||||
<% end %>
|
||||
|
|
|
@ -10,7 +10,6 @@ defmodule LivebookWeb.SessionLive.CellComponent do
|
|||
id={"cell-#{@cell_view.id}"}
|
||||
phx-hook="Cell"
|
||||
data-cell-id={@cell_view.id}
|
||||
data-protocols={@protocols}
|
||||
data-focusable-id={@cell_view.id}
|
||||
data-type={@cell_view.type}
|
||||
data-session-path={Routes.session_path(@socket, :page, @session_id)}
|
||||
|
@ -18,6 +17,7 @@ defmodule LivebookWeb.SessionLive.CellComponent do
|
|||
data-eval-validity={get_in(@cell_view, [:eval, :validity])}
|
||||
data-js-empty={empty?(@cell_view.source_view)}
|
||||
data-smart-cell-js-view-ref={smart_cell_js_view_ref(@cell_view)}
|
||||
data-allowed-uri-schemes={Enum.join(@allowed_uri_schemes, ",")}
|
||||
>
|
||||
<%= render_cell(assigns) %>
|
||||
</div>
|
||||
|
|
|
@ -142,9 +142,9 @@ defmodule LivebookWeb.SessionLive.SectionComponent do
|
|||
session_id={@session_id}
|
||||
session_pid={@session_pid}
|
||||
client_id={@client_id}
|
||||
protocols={@protocols}
|
||||
runtime={@runtime}
|
||||
installing?={@installing?}
|
||||
allowed_uri_schemes={@allowed_uri_schemes}
|
||||
cell_view={cell_view}
|
||||
/>
|
||||
<.live_component
|
||||
|
|
Loading…
Add table
Reference in a new issue