Okay…
router.ex
...
# put host and configuration data into session for retrieval from liveview
defp sessionify_configuration(conn, _opts) do
import Plug.Conn
case MyApp.Sites.Domain.get_by_name(conn.host) do
{:ok, domain} ->
configuration =
domain.site_id
|> MyApp.Sites.Site.get_by_id!()
|> MyApp.Sites.load!(:configuration)
|> Map.get(:configuration)
conn
|> put_session(:configuration, configuration)
|> put_session(:current_host, conn.host)
|> put_session(:current_path, conn.request_path)
{:error, error} ->
IO.inspect(error)
raise "No Domain found with the name " <> conn.host
conn
end
end
pipeline :do_config do
plug :sessionify_configuration
end
scope "/", MyAppWeb do
pipe_through [:browser, :do_config]
# login not required
ash_authentication_live_session :authenticated_optional,
on_mount: [
{MyAppWeb.LiveUserAuth, :live_user_optional},
{MyAppWeb.AssignConfiguration, :assign_configuration}
] do
live "/", PublicLive.Index, :index
end
...
assign_configuration.ex
def on_mount(:assign_configuration, _params, session, socket) do
socket =
socket
|> Phoenix.Component.assign(:configuration, Map.get(session, "configuration"))
|> Phoenix.Component.assign(:current_host, Map.get(session, "current_host"))
|> Phoenix.Component.assign(:current_path, Map.get(session, "current_path"))
{:cont, socket}
end
index.ex
def mount(_params, _session, socket) do
socket =
socket
|> assign(:page_title, "public")
|> assign(:testificate, "testificatey")
layout = {MyAppWeb.Layouts, socket.assigns.configuration.theme}
{:ok, socket, layout: layout}
end
This is the flow I have right now that’s working! I was able to remove extraneous hooks and consolidate some functionality into the on_mount
. And it looks like Phoenix actually is letting me pass the layout template as a string, too, although it does complain that this is deprecated. So no String.to_atom
for now (and if I do have to do that later I think I can just whitelist it based on existing themes).
So the only thing I have to append to every liveview is
layout = {MyAppWeb.Layouts, socket.assigns.configuration.theme}
{:ok, socket, layout: layout}
Not too bad.
And to be clear I meant like they could potentially manipulate the session based on the hostname. If you are whitelisting hostnames then it’s no problem.
This area is all public stuff you can view by simply going to that site, so that should be fine as I understand it. Unless there’s anything drastic I’m missing.