diff --git a/lib/livebook/live_markdown/export.ex b/lib/livebook/live_markdown/export.ex
index 3e1a5140f..909e5c046 100644
--- a/lib/livebook/live_markdown/export.ex
+++ b/lib/livebook/live_markdown/export.ex
@@ -49,12 +49,14 @@ defmodule Livebook.LiveMarkdown.Export do
end
defp render_cell(%Cell.Input{} = cell) do
+ value = if cell.type == :password, do: "", else: cell.value
+
json =
Jason.encode!(%{
livebook_object: :cell_input,
type: cell.type,
name: cell.name,
- value: cell.value
+ value: value
})
""
diff --git a/lib/livebook/notebook/cell/input.ex b/lib/livebook/notebook/cell/input.ex
index c01c0fc95..b3d514b94 100644
--- a/lib/livebook/notebook/cell/input.ex
+++ b/lib/livebook/notebook/cell/input.ex
@@ -19,7 +19,7 @@ defmodule Livebook.Notebook.Cell.Input do
value: String.t()
}
- @type type :: :text | :url | :number
+ @type type :: :text | :url | :number | :password
@doc """
Returns an empty cell.
@@ -46,6 +46,8 @@ defmodule Livebook.Notebook.Cell.Input do
defp validate_value(_value, :text), do: :ok
+ defp validate_value(_value, :password), do: :ok
+
defp validate_value(value, :url) do
if Utils.valid_url?(value) do
:ok
diff --git a/lib/livebook_web/live/session_live/cell_component.ex b/lib/livebook_web/live/session_live/cell_component.ex
index 0ad184175..d004640fe 100644
--- a/lib/livebook_web/live/session_live/cell_component.ex
+++ b/lib/livebook_web/live/session_live/cell_component.ex
@@ -191,7 +191,7 @@ defmodule LivebookWeb.SessionLive.CellComponent do
<%= @cell_view.name %>
- "
data-element="input"
class="input <%= if(@cell_view.error, do: "input--error") %>"
name="value"
diff --git a/lib/livebook_web/live/session_live/input_cell_settings_component.ex b/lib/livebook_web/live/session_live/input_cell_settings_component.ex
index a90d02dc6..79905666d 100644
--- a/lib/livebook_web/live/session_live/input_cell_settings_component.ex
+++ b/lib/livebook_web/live/session_live/input_cell_settings_component.ex
@@ -29,7 +29,7 @@ defmodule LivebookWeb.SessionLive.InputCellSettingsComponent do
- <%= render_radios("type", [text: "Text", url: "URL", number: "Number"], @type) %>
+ <%= render_radios("type", [text: "Text", url: "URL", number: "Number", password: "Password"], @type) %>
<%= live_patch "Cancel", to: @return_to, class: "button button-outlined-gray" %>
diff --git a/test/livebook/live_markdown/export_test.exs b/test/livebook/live_markdown/export_test.exs
index 0e5a8c800..3878d1858 100644
--- a/test/livebook/live_markdown/export_test.exs
+++ b/test/livebook/live_markdown/export_test.exs
@@ -382,4 +382,39 @@ defmodule Livebook.LiveMarkdown.ExportTest do
assert expected_document == document
end
+
+ test "save password as empty string" do
+ notebook = %{
+ Notebook.new()
+ | name: "My Notebook",
+ metadata: %{},
+ sections: [
+ %{
+ Notebook.Section.new()
+ | name: "Section 1",
+ metadata: %{},
+ cells: [
+ %{
+ Notebook.Cell.new(:input)
+ | type: :password,
+ name: "pass",
+ value: "0123456789"
+ }
+ ]
+ }
+ ]
+ }
+
+ expected_document = """
+ # My Notebook
+
+ ## Section 1
+
+
+ """
+
+ document = Export.notebook_to_markdown(notebook)
+
+ assert expected_document == document
+ end
end