defmodule LivebookWeb.AppAuthLive do use LivebookWeb, :live_view @impl true def mount(%{"slug" => slug} = params, _session, socket) when not socket.assigns.app_authenticated? do {:ok, assign(socket, slug: slug, authenticated_path: authenticated_path(params), password: "", errors: [] )} end def mount(params, _session, socket) do {:ok, push_navigate(socket, to: authenticated_path(params))} end defp authenticated_path(%{"slug" => slug, "id" => id}), do: ~p"/apps/#{slug}/sessions/#{id}" defp authenticated_path(%{"slug" => slug}), do: ~p"/apps/#{slug}" @impl true def render(assigns) do ~H"""
livebook
This app is password-protected
Type the app password to access it or log in to Livebook.
<.text_field type="password" name="password" value={@password} placeholder="Password" autofocus /> <%= translate_error(error) %>
<.button type="submit"> Authenticate
""" end @impl true def handle_event("authenticate", %{"password" => password}, socket) do socket = if LivebookWeb.AppAuthHook.valid_password?(password, socket.assigns.app_settings) do token = LivebookWeb.AppAuthHook.get_auth_token(socket.assigns.app_settings) push_event(socket, "persist_app_auth", %{"slug" => socket.assigns.slug, "token" => token}) else assign(socket, password: password, errors: [{"app password is invalid", []}]) end {:noreply, socket} end def handle_event("app_auth_persisted", %{}, socket) do {:noreply, push_navigate(socket, to: socket.assigns.authenticated_path)} end end