diff --git a/config/prod.exs b/config/prod.exs index deec65e..46ce690 100644 --- a/config/prod.exs +++ b/config/prod.exs @@ -8,7 +8,6 @@ config :mailgun_logger, MailgunLoggerWeb.Endpoint, code_reloader: false, version: Application.spec(:mailgun_logger, :vsn) - config :logger, level: String.to_existing_atom(System.get_env("ML_LOG_LEVEL", "info")) || :info, compile_time_purge_matching: [[application: :remote_ip]] diff --git a/config/test.exs b/config/test.exs index 09d1fdc..7718fd3 100644 --- a/config/test.exs +++ b/config/test.exs @@ -7,8 +7,7 @@ config :mailgun_logger, MailgunLoggerWeb.Endpoint, server: false # Quantum cron schedule -config :mailgun_logger, MailgunLogger.Scheduler, - jobs: [] +config :mailgun_logger, MailgunLogger.Scheduler, jobs: [] config :logger, level: :warning config :mailgun_logger, MailgunLogger.Repo, pool: Ecto.Adapters.SQL.Sandbox diff --git a/lib/mailgun_logger/roles/roles.ex b/lib/mailgun_logger/roles/roles.ex index 8a873bb..ce24c0a 100644 --- a/lib/mailgun_logger/roles/roles.ex +++ b/lib/mailgun_logger/roles/roles.ex @@ -7,13 +7,13 @@ defmodule MailgunLogger.Roles do @superuser_role "superuser" @admin_role "admin" + @member_role "member" ######################################################### @default_actions ~w() - - @admin_actions ~w(do_stuff) ++ @default_actions - + @member_actions ~w(view_events) ++ @default_actions + @admin_actions ~w(do_stuff manage_roles) ++ @member_actions @superuser_actions ~w() ++ @admin_actions ######################################################### @@ -55,6 +55,11 @@ defmodule MailgunLogger.Roles do Enum.any?(roles, &can?(&1.name, action)) end + for action <- @member_actions do + action = String.to_atom(action) + def can?(@member_role, unquote(action)), do: true + end + for action <- @admin_actions do action = String.to_atom(action) def can?(@admin_role, unquote(action)), do: true @@ -69,12 +74,14 @@ defmodule MailgunLogger.Roles do def is?(%User{roles: roles}, :superuser), do: is(roles, "superuser") def is?(%User{roles: roles}, :admin), do: is(roles, "admin") + def is?(%User{roles: roles}, :member), do: is(roles, "member") def is?(_, _), do: raise("Roles.is/2 requires roles to be preloaded") defp is(roles, role) when is_binary(role), do: Enum.map(roles, & &1.name) |> Enum.member?(role) def abilities(%User{roles: []}), do: [] def abilities(%User{roles: roles}), do: hd(roles) |> abilities() + def abilities(%Role{name: "member"}), do: @member_actions def abilities(%Role{name: "admin"}), do: @admin_actions def abilities(%Role{name: "superuser"}), do: @superuser_actions diff --git a/lib/mailgun_logger/seeder.ex b/lib/mailgun_logger/seeder.ex index 6fe0588..d2d25f4 100644 --- a/lib/mailgun_logger/seeder.ex +++ b/lib/mailgun_logger/seeder.ex @@ -6,7 +6,7 @@ defmodule MailgunLogger.Seeder do # alias MailgunLogger.UserRole - @roles [%Role{name: "superuser"}, %Role{name: "admin"}] + @roles [%Role{name: "superuser"}, %Role{name: "admin"}, %Role{name: "member"}] def run do Enum.each(@roles, &insert_if_new(&1)) diff --git a/lib/mailgun_logger/users/users.ex b/lib/mailgun_logger/users/users.ex index ae6902e..91b94dc 100644 --- a/lib/mailgun_logger/users/users.ex +++ b/lib/mailgun_logger/users/users.ex @@ -4,7 +4,6 @@ defmodule MailgunLogger.Users do alias MailgunLogger.Repo alias MailgunLogger.User - @type ecto_user() :: {:ok, User.t()} | {:error, Ecto.Changeset.t()} @type maybe_user() :: User.t() | nil @@ -151,6 +150,14 @@ defmodule MailgunLogger.Users do |> Repo.insert() end + @spec create_user_with_roles(map, [MailgunLogger.Role.t()]) :: ecto_user() + def create_user_with_roles(params, roles) do + %User{} + |> User.changeset(params) + |> Ecto.Changeset.put_assoc(:roles, roles) + |> Repo.insert() + end + @spec update_user(User.t(), map) :: ecto_user() def update_user(user, params) do user @@ -158,6 +165,14 @@ defmodule MailgunLogger.Users do |> Repo.update() end + @spec update_user_with_roles(User.t(), map, [MailgunLogger.Role.t()]) :: ecto_user() + def update_user_with_roles(user, params, roles) do + user + |> User.update_changeset(params) + |> Ecto.Changeset.put_assoc(:roles, roles) + |> Repo.update() + end + @spec delete_user(User.t()) :: ecto_user() def delete_user(%User{} = user) do Repo.delete(user) diff --git a/lib/mailgun_logger_web/components/core_components.ex b/lib/mailgun_logger_web/components/core_components.ex index 938c0b1..5d8d0f0 100644 --- a/lib/mailgun_logger_web/components/core_components.ex +++ b/lib/mailgun_logger_web/components/core_components.ex @@ -79,7 +79,7 @@ defmodule MailgunLoggerWeb.CoreComponents do
- <%= render_slot(@inner_block) %> + {render_slot(@inner_block)}
@@ -122,9 +122,9 @@ defmodule MailgunLoggerWeb.CoreComponents do

<.icon :if={@kind == :info} name="hero-information-circle-mini" class="h-4 w-4" /> <.icon :if={@kind == :error} name="hero-exclamation-circle-mini" class="h-4 w-4" /> - <%= @title %> + {@title}

-

<%= msg %>

+

{msg}

@@ -186,9 +186,9 @@ defmodule MailgunLoggerWeb.CoreComponents do ~H""" <.form :let={f} for={@for} as={@as} {@rest}>
- <%= render_slot(@inner_block, f) %> + {render_slot(@inner_block, f)}
- <%= render_slot(action, f) %> + {render_slot(action, f)}
@@ -220,7 +220,7 @@ defmodule MailgunLoggerWeb.CoreComponents do ]} {@rest} > - <%= render_slot(@inner_block) %> + {render_slot(@inner_block)} """ end @@ -291,9 +291,9 @@ defmodule MailgunLoggerWeb.CoreComponents do checked={@checked} {@rest} /> - <%= @label %> + {@label} - <.error :for={msg <- @errors}><%= msg %> + <.error :for={msg <- @errors}>{msg} """ end @@ -301,7 +301,7 @@ defmodule MailgunLoggerWeb.CoreComponents do def input(%{type: "select"} = assigns) do ~H"""
- <.label for={@id}><%= @label %> + <.label for={@id}>{@label} - <.error :for={msg <- @errors}><%= msg %> + <.error :for={msg <- @errors}>{msg}
""" end @@ -320,14 +320,14 @@ defmodule MailgunLoggerWeb.CoreComponents do def input(%{type: "textarea"} = assigns) do ~H"""
- <.label for={@id}><%= @label %> + <.label for={@id}>{@label} - <.error :for={msg <- @errors}><%= msg %> + <.error :for={msg <- @errors}>{msg}
""" end @@ -336,7 +336,7 @@ defmodule MailgunLoggerWeb.CoreComponents do def input(assigns) do ~H"""
- <.label for={@id}><%= @label %> + <.label for={@id}>{@label} - <.error :for={msg <- @errors}><%= msg %> + <.error :for={msg <- @errors}>{msg}
""" end @@ -360,7 +360,7 @@ defmodule MailgunLoggerWeb.CoreComponents do def label(assigns) do ~H""" """ end @@ -373,7 +373,7 @@ defmodule MailgunLoggerWeb.CoreComponents do def error(assigns) do ~H"""

- <%= render_slot(@inner_block) %> + {render_slot(@inner_block)}

""" end @@ -392,13 +392,13 @@ defmodule MailgunLoggerWeb.CoreComponents do

- <%= render_slot(@inner_block) %> + {render_slot(@inner_block)}

- <%= render_slot(@subtitle) %> + {render_slot(@subtitle)}

-
<%= render_slot(@actions) %>
+
{render_slot(@actions)}
""" end @@ -440,8 +440,8 @@ defmodule MailgunLoggerWeb.CoreComponents do - - + + - <%= render_slot(col, @row_item.(row)) %> + {render_slot(col, @row_item.(row))} @@ -469,7 +469,7 @@ defmodule MailgunLoggerWeb.CoreComponents do :for={action <- @action} class="relative ml-4 font-semibold leading-6 text-zinc-900 hover:text-zinc-700" > - <%= render_slot(action, @row_item.(row)) %> + {render_slot(action, @row_item.(row))} @@ -499,8 +499,8 @@ defmodule MailgunLoggerWeb.CoreComponents do
-
<%= item.title %>
-
<%= render_slot(item) %>
+
{item.title}
+
{render_slot(item)}
@@ -525,7 +525,7 @@ defmodule MailgunLoggerWeb.CoreComponents do class="text-sm font-semibold leading-6 text-zinc-900 hover:text-zinc-700" > <.icon name="hero-arrow-left-solid" class="h-3 w-3" /> - <%= render_slot(@inner_block) %> + {render_slot(@inner_block)} """ diff --git a/lib/mailgun_logger_web/controllers/setup_controller.ex b/lib/mailgun_logger_web/controllers/setup_controller.ex index 0c71a58..2c549e9 100644 --- a/lib/mailgun_logger_web/controllers/setup_controller.ex +++ b/lib/mailgun_logger_web/controllers/setup_controller.ex @@ -15,7 +15,7 @@ defmodule MailgunLoggerWeb.SetupController do end end - def create_root(conn, %{"user" => params}) do + def create_root(conn, %{"user" => params}) do # Only allow create_root if there are no users in the database yet, # otherwise it's possible for any unauthenticated request to this # endpoint to make an admin user. diff --git a/lib/mailgun_logger_web/controllers/user_controller.ex b/lib/mailgun_logger_web/controllers/user_controller.ex index 1128c69..fb32908 100644 --- a/lib/mailgun_logger_web/controllers/user_controller.ex +++ b/lib/mailgun_logger_web/controllers/user_controller.ex @@ -1,6 +1,7 @@ defmodule MailgunLoggerWeb.UserController do use MailgunLoggerWeb, :controller + alias MailgunLogger.Roles alias MailgunLogger.Users alias MailgunLogger.User @@ -10,43 +11,105 @@ defmodule MailgunLoggerWeb.UserController do end def new(conn, _) do + current_user = conn.assigns[:current_user] changeset = User.changeset(%User{}) - render(conn, :new, changeset: changeset) + + render(conn, :new, + changeset: changeset, + all_roles: Roles.list_roles(), + selected_role_ids: [], + show_roles?: Roles.can?(current_user, :manage_roles) + ) end def create(conn, %{"user" => params}) do - case Users.create_user(params) do - {:ok, _} -> redirect(conn, to: Routes.user_path(conn, :index)) - {:error, changeset} -> render(conn, :new, changeset: changeset) + current_user = conn.assigns[:current_user] + roles = resolve_roles(current_user, params, []) + + case Users.create_user_with_roles(params, roles) do + {:ok, _user} -> + conn + |> put_flash(:info, "User created successfully.") + |> redirect(to: Routes.user_path(conn, :index)) + + {:error, changeset} -> + render(conn, :new, + changeset: changeset, + all_roles: Roles.list_roles(), + selected_role_ids: Enum.map(roles, & &1.id), + show_roles?: Roles.can?(current_user, :manage_roles) + ) end end def edit(conn, %{"id" => id}) do + current_user = conn.assigns[:current_user] user = Users.get_user!(id) - changeset = User.changeset(user) - render(conn, :edit, changeset: changeset, user: user) + changeset = User.update_changeset(user) + + render(conn, :edit, + changeset: changeset, + user: user, + all_roles: Roles.list_roles(), + selected_role_ids: Enum.map(user.roles, & &1.id), + show_roles?: Roles.can?(current_user, :manage_roles) + ) end def update(conn, %{"id" => id, "user" => params}) do + current_user = conn.assigns[:current_user] user = Users.get_user!(id) + roles = resolve_roles(current_user, params, user.roles) - case Users.update_user(user, params) do - {:ok, _} -> - redirect(conn, to: Routes.user_path(conn, :index)) + if Roles.can?(current_user, :manage_roles) && current_user.id == user.id && + self_downgrade?(current_user, roles) do + conn + |> put_flash(:error, "You cannot remove your own role.") + |> render(:edit, + changeset: User.update_changeset(user, params), + user: user, + all_roles: Roles.list_roles(), + selected_role_ids: Enum.map(roles, & &1.id), + show_roles?: true + ) + else + case Users.update_user_with_roles(user, params, roles) do + {:ok, _updated} -> + conn + |> put_flash(:info, "User updated successfully.") + |> redirect(to: Routes.user_path(conn, :index)) - {:error, changeset} -> - render(conn, :edit, changeset: changeset, user: user) + {:error, changeset} -> + render(conn, :edit, + changeset: changeset, + user: user, + all_roles: Roles.list_roles(), + selected_role_ids: Enum.map(roles, & &1.id), + show_roles?: Roles.can?(current_user, :manage_roles) + ) + end end end def delete(conn, %{"id" => id}) do - {:ok, _} = - id - |> Users.get_user!() - |> Users.delete_user() + {:ok, _} = id |> Users.get_user!() |> Users.delete_user() conn |> put_flash(:info, "user deleted successfully.") |> redirect(to: Routes.user_path(conn, :index)) end + + defp resolve_roles(current_user, params, existing_roles) do + if Roles.can?(current_user, :manage_roles) do + params |> Map.get("role_ids", []) |> Enum.map(&String.to_integer/1) |> Roles.get_roles_by_id() + else + existing_roles + end + end + + defp self_downgrade?(%User{roles: current_roles}, new_roles) do + current_ids = MapSet.new(current_roles, & &1.id) + new_ids = MapSet.new(new_roles, & &1.id) + not MapSet.subset?(current_ids, new_ids) + end end diff --git a/lib/mailgun_logger_web/plugs/require_permission.ex b/lib/mailgun_logger_web/plugs/require_permission.ex new file mode 100644 index 0000000..7e87039 --- /dev/null +++ b/lib/mailgun_logger_web/plugs/require_permission.ex @@ -0,0 +1,26 @@ +defmodule MailgunLoggerWeb.Plugs.RequirePermission do + import Plug.Conn + import Phoenix.Controller + + alias MailgunLogger.Roles + alias MailgunLoggerWeb.Router.Helpers, as: Routes + + @moduledoc """ + Enforces that the authenticated user has the required permission. + This plug expects MailgunLoggerWeb.Plugs.Auth to have assigned :current_user. + """ + def init(permission), do: permission + + def call(conn, permission) do + user = conn.assigns[:current_user] + + if user && Roles.can?(user, permission) do + conn + else + conn + |> put_flash(:error, "You do not have permission to access this page.") + |> redirect(to: Routes.event_path(conn, :index)) + |> halt() + end + end +end diff --git a/lib/mailgun_logger_web/router.ex b/lib/mailgun_logger_web/router.ex index 7297982..6a72d05 100644 --- a/lib/mailgun_logger_web/router.ex +++ b/lib/mailgun_logger_web/router.ex @@ -23,6 +23,14 @@ defmodule MailgunLoggerWeb.Router do plug(MailgunLoggerWeb.Plugs.Auth) end + pipeline :require_events_access do + plug(MailgunLoggerWeb.Plugs.RequirePermission, :view_events) + end + + pipeline :require_admin_access do + plug(MailgunLoggerWeb.Plugs.RequirePermission, :do_stuff) + end + # Always except in prod if Application.compile_env(:mailgun_logger, :env) == :dev do forward("/sent_emails", Bamboo.SentEmailViewerPlug) @@ -73,18 +81,28 @@ defmodule MailgunLoggerWeb.Router do pipe_through([:browser, :auth]) get("/logout", AuthController, :logout) + get("/profile", ProfileController, :edit) + put("/profile", ProfileController, :update) + end + + scope "/", MailgunLoggerWeb do + pipe_through([:browser, :auth, :require_events_access]) + + get("/", PageController, :index) + get("/non-affiliation", PageController, :non_affiliation) resources("/events", EventController, only: [:index, :show]) get("/events/:id/stored_message", EventController, :stored_message) + end + + scope "/", MailgunLoggerWeb do + pipe_through([:browser, :auth, :require_admin_access]) + resources("/accounts", AccountController, except: [:show]) - get("/profile", ProfileController, :edit) - put("/profile", ProfileController, :update) resources("/users", UserController, except: [:show]) - get("/", PageController, :index) post("/trigger-run", PageController, :trigger_run) get("/stats", PageController, :stats) get("/graphs", PageController, :graphs) - get("/non-affiliation", PageController, :non_affiliation) end end diff --git a/lib/mailgun_logger_web/templates/account/edit.html.heex b/lib/mailgun_logger_web/templates/account/edit.html.heex index 18fabb4..2b807d6 100644 --- a/lib/mailgun_logger_web/templates/account/edit.html.heex +++ b/lib/mailgun_logger_web/templates/account/edit.html.heex @@ -1,4 +1,15 @@

Edit account

-<%= render "form.html", action: Routes.account_path(@conn, :update, @account), changeset: @changeset, flash: @flash %> +{render("form.html", + action: Routes.account_path(@conn, :update, @account), + changeset: @changeset, + flash: @flash +)}
-<.link href={Routes.account_path(@conn, :delete, @account)} method="delete" data-confirm="Are you sure?" class="btn btn-danger btn-sm">delete +<.link + href={Routes.account_path(@conn, :delete, @account)} + method="delete" + data-confirm="Are you sure?" + class="btn btn-danger btn-sm" +> + delete + diff --git a/lib/mailgun_logger_web/templates/account/form.html.heex b/lib/mailgun_logger_web/templates/account/form.html.heex index ba990bf..2c214dd 100644 --- a/lib/mailgun_logger_web/templates/account/form.html.heex +++ b/lib/mailgun_logger_web/templates/account/form.html.heex @@ -3,22 +3,32 @@

Oops, something went wrong! Please check the errors below.

-

These settings can be found on your Mailgun dashboard. An account covers a sending domain / API key combo. If you have multiple domains, add them on seperate accounts.

+

+ These settings can be found on your Mailgun dashboard. An account covers a sending domain / API key combo. If you have multiple domains, add them on seperate accounts. +

- <%= Phoenix.Flash.get(@flash, :info) %> + {Phoenix.Flash.get(@flash, :info)}
<.input field={f[:domain]} label="Sending domain" /> -
Find on Mailgun dashboard
+
+ + Find on Mailgun dashboard + +
<.input field={f[:api_key]} label="API key" /> -
Find on Mailgun dashboard
+
+ + Find on Mailgun dashboard + +
<.input field={f[:is_active]} type="checkbox" label="Is active" /> <.input field={f[:is_eu]} type="checkbox" label="Is EU" />
- <%= submit "submit", class: "btn btn-primary"%> + {submit("submit", class: "btn btn-primary")}
diff --git a/lib/mailgun_logger_web/templates/account/index.html.heex b/lib/mailgun_logger_web/templates/account/index.html.heex index 8ee45ba..2fb607f 100644 --- a/lib/mailgun_logger_web/templates/account/index.html.heex +++ b/lib/mailgun_logger_web/templates/account/index.html.heex @@ -12,16 +12,16 @@ <%= for account <- @accounts do %> - - - - - - - + + + + + + + <% end %>
<%= col[:label] %><%= gettext("Actions") %>{col[:label]}{gettext("Actions")}
<%= account.domain %><%= account.api_key %>EU -
active
-
inactive
-
<.link href={Routes.account_path(@conn, :edit, account)}>edit
{account.domain}{account.api_key}EU +
active
+
inactive
+
<.link href={Routes.account_path(@conn, :edit, account)}>edit
diff --git a/lib/mailgun_logger_web/templates/account/new.html.heex b/lib/mailgun_logger_web/templates/account/new.html.heex index 013d40f..2cbf46f 100644 --- a/lib/mailgun_logger_web/templates/account/new.html.heex +++ b/lib/mailgun_logger_web/templates/account/new.html.heex @@ -1,2 +1,2 @@

New account

-<%= render "form.html", action: ~p"/accounts", changeset: @changeset, flash: @flash %> +{render("form.html", action: ~p"/accounts", changeset: @changeset, flash: @flash)} diff --git a/lib/mailgun_logger_web/templates/auth/new.html.heex b/lib/mailgun_logger_web/templates/auth/new.html.heex index ed0af1d..f70f1cd 100644 --- a/lib/mailgun_logger_web/templates/auth/new.html.heex +++ b/lib/mailgun_logger_web/templates/auth/new.html.heex @@ -1,24 +1,26 @@
-

<%= gettext("Inloggen") %>

+

{gettext("Inloggen")}

<.form :let={f} for={@conn} action={Routes.auth_path(@conn, :create)} as={:user} novalidate> <.input field={f[:email]} type="email" label={gettext("Email")} required autofocus /> <.input field={f[:password]} type="password" label={gettext("Password")} required /> - <%= submit gettext("Inloggen"), class: "btn btn-primary" %> + {submit(gettext("Inloggen"), class: "btn btn-primary")} -
+
- <.link href={Routes.password_reset_path(@conn, :request_new)}><%= gettext("Forgot password?") %> + <.link href={Routes.password_reset_path(@conn, :request_new)}> + {gettext("Forgot password?")} +
diff --git a/lib/mailgun_logger_web/templates/event/index.html.heex b/lib/mailgun_logger_web/templates/event/index.html.heex index de31390..cd7c3b7 100644 --- a/lib/mailgun_logger_web/templates/event/index.html.heex +++ b/lib/mailgun_logger_web/templates/event/index.html.heex @@ -1,7 +1,7 @@ @@ -26,15 +26,21 @@ <%= for event <- @events do %>
- <%= event_name(event.event) %> - <%= event_type(event.log_level) %> - <%= send_recv(event.method) %> - <%= event.timestamp %> - <%= event.message_from %> - <%= event.recipient %> - <%= event.message_subject %> + {event_name(event.event)} + {event_type(event.log_level)} + {send_recv(event.method)} + {event.timestamp} + {event.message_from} + {event.recipient} + {event.message_subject} - msg + + msg + <.link href={Routes.event_path(@conn, :show, event.id)}>detail
@@ -42,7 +48,12 @@
- + <:previous attrs={[class: "pagination-btn"]}> ← Previous diff --git a/lib/mailgun_logger_web/templates/event/show.html.heex b/lib/mailgun_logger_web/templates/event/show.html.heex index c41d456..cd44c4a 100644 --- a/lib/mailgun_logger_web/templates/event/show.html.heex +++ b/lib/mailgun_logger_web/templates/event/show.html.heex @@ -1,38 +1,42 @@
Error detail
-
<%= error_msg(@event) %>
+
{error_msg(@event)}
Recipient
-
<%= @event.recipient %>
+
{@event.recipient}
Message subject
-
<%= @event.message_subject %>
+
{@event.message_subject}
Account
-
<%= @event.account.domain %>
+
{@event.account.domain}
Event
-
<%= event_name(@event.event) %>
+
{event_name(@event.event)}
Method
-
<%= @event.method %>
+
{@event.method}
Attachments
-
<%= list_attachments(@event.raw) %>
+
{list_attachments(@event.raw)}
Timestamp
-
<%= @event.timestamp %>
+
{@event.timestamp}
From
-
<%= @event.message_from %>
+
{@event.message_from}
Linked events
<%= if Application.get_env(:mailgun_logger, :store_messages) and @event.has_stored_message do %> -
Raw Stored Message data
-
view json file on S3
-
Actual sent email
-
view
+
Raw Stored Message data
+
view json file on S3
+
Actual sent email
+
view
<% end %>
Dev Stuff
-
<%= pretty_raw(@event.raw) %>
+
{pretty_raw(@event.raw)}
diff --git a/lib/mailgun_logger_web/templates/event/stored_message.html.heex b/lib/mailgun_logger_web/templates/event/stored_message.html.heex index 288c837..74aadcb 100644 --- a/lib/mailgun_logger_web/templates/event/stored_message.html.heex +++ b/lib/mailgun_logger_web/templates/event/stored_message.html.heex @@ -1 +1 @@ -<%= raw(@html) %> +{raw(@html)} diff --git a/lib/mailgun_logger_web/templates/layout/app.html.heex b/lib/mailgun_logger_web/templates/layout/app.html.heex index 6a78307..f1f92ac 100644 --- a/lib/mailgun_logger_web/templates/layout/app.html.heex +++ b/lib/mailgun_logger_web/templates/layout/app.html.heex @@ -1,14 +1,18 @@ - - - - - - Mailgun Logger v<%= Application.spec(:mailgun_logger, :vsn) %> - - + + + + + + Mailgun Logger v{Application.spec(:mailgun_logger, :vsn)} + + - + + diff --git a/lib/mailgun_logger_web/templates/layout/setup.html.heex b/lib/mailgun_logger_web/templates/layout/setup.html.heex index e3589dc..e71b108 100644 --- a/lib/mailgun_logger_web/templates/layout/setup.html.heex +++ b/lib/mailgun_logger_web/templates/layout/setup.html.heex @@ -1,18 +1,23 @@ - - - - - - Mailgun Logger v<%= Application.spec(:mailgun_logger, :vsn) %> - - + + + + + + Mailgun Logger v{Application.spec(:mailgun_logger, :vsn)} + + - <%= @inner_content %> - + {@inner_content} + diff --git a/lib/mailgun_logger_web/templates/page/graphs.html.heex b/lib/mailgun_logger_web/templates/page/graphs.html.heex index afdc91b..a650710 100644 --- a/lib/mailgun_logger_web/templates/page/graphs.html.heex +++ b/lib/mailgun_logger_web/templates/page/graphs.html.heex @@ -2,7 +2,13 @@

System

Sent in the last 24h
- +