From 4bbf9742c5667a8ef75d1d2b7b4ba1572d3abdb1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ra=C3=BAl=20R=20Pearson?=
Date: Thu, 19 Mar 2026 17:29:09 +0000
Subject: [PATCH] Add audit log (#214)
* Add audit log
* Update translation files
* Improve Audit queries
* Improve Audit.Log schema
* Make user auth audit logs async
* Relax Flop and Flop Phoenix dep specs
* Make Flop.validate!/2 call more robust
* Improve a11y and UI for audit log live view
* Improve audit_logs indexes
* Fix formatting
* Fix async_log_action and tests
* Add remote_ip
* Update translation files
---
.env.sample | 8 +
config/config.exs | 2 +
config/runtime.exs | 20 +-
lib/claper/audit.ex | 125 +++++
lib/claper/audit/log.ex | 45 ++
lib/claper_web/components/core_components.ex | 498 ++++++++++++++++++
lib/claper_web/components/icons.ex | 57 ++
lib/claper_web/controllers/user_auth.ex | 25 +-
lib/claper_web/endpoint.ex | 4 +
lib/claper_web/helpers/conn_utils.ex | 31 ++
.../live/admin_live/audit_log_live.ex | 74 +++
.../live/admin_live/audit_log_live.html.heex | 169 ++++++
lib/claper_web/router.ex | 3 +
.../templates/layout/admin.html.heex | 18 +-
mix.exs | 3 +
mix.lock | 4 +
priv/gettext/de/LC_MESSAGES/default.po | 107 +++-
priv/gettext/default.pot | 107 +++-
priv/gettext/en/LC_MESSAGES/default.po | 107 +++-
priv/gettext/es/LC_MESSAGES/default.po | 107 +++-
priv/gettext/fr/LC_MESSAGES/default.po | 107 +++-
priv/gettext/hu/LC_MESSAGES/default.po | 109 +++-
priv/gettext/it/LC_MESSAGES/default.po | 107 +++-
priv/gettext/lv/LC_MESSAGES/default.po | 109 +++-
priv/gettext/nl/LC_MESSAGES/default.po | 107 +++-
.../20260129165937_create_audit_logs.exs | 19 +
test/claper/audit_test.exs | 89 ++++
test/claper_web/helpers/conn_utils_test.exs | 29 +
test/support/conn_case.ex | 21 +-
test/support/data_case.ex | 20 +-
test/support/fixtures/audit_fixtures.ex | 23 +
31 files changed, 2148 insertions(+), 106 deletions(-)
create mode 100644 lib/claper/audit.ex
create mode 100644 lib/claper/audit/log.ex
create mode 100644 lib/claper_web/components/core_components.ex
create mode 100644 lib/claper_web/components/icons.ex
create mode 100644 lib/claper_web/helpers/conn_utils.ex
create mode 100644 lib/claper_web/live/admin_live/audit_log_live.ex
create mode 100644 lib/claper_web/live/admin_live/audit_log_live.html.heex
create mode 100644 priv/repo/migrations/20260129165937_create_audit_logs.exs
create mode 100644 test/claper/audit_test.exs
create mode 100644 test/claper_web/helpers/conn_utils_test.exs
create mode 100644 test/support/fixtures/audit_fixtures.ex
diff --git a/.env.sample b/.env.sample
index 0f1d8df..8cdd36d 100644
--- a/.env.sample
+++ b/.env.sample
@@ -75,6 +75,14 @@ MAIL_FROM_NAME=Claper
# GS_JPG_RESOLUTION=300x300
# LANGUAGES=en,fr,es,it,nl,de
+# == Reverse proxy / IP forwarding (set these if Claper runs behind a load balancer or reverse proxy)
+
+# Comma-separated list of trusted proxy IPs or CIDR ranges whose forwarding headers will be trusted
+# REMOTE_IP_PROXIES=10.0.0.0/8,172.16.0.0/12,192.168.0.0/16
+
+# Comma-separated list of headers to inspect for the real client IP (replaces the defaults: forwarded, x-forwarded-for, x-client-ip, x-real-ip)
+# REMOTE_IP_HEADERS=forwarded,x-forwarded-for,x-client-ip,x-real-ip
+
# === OIDC configuration ===
diff --git a/config/config.exs b/config/config.exs
index 51120c3..a5d9e30 100644
--- a/config/config.exs
+++ b/config/config.exs
@@ -75,6 +75,8 @@ config :porcelain, driver: Porcelain.Driver.Basic
config :claper, :storage_dir, System.get_env("PRESENTATION_STORAGE_DIR", "priv/static")
+config :flop, repo: Claper.Repo
+
# Import environment specific config. This must remain at the bottom
# of this file so it overrides the configuration defined above.
import_config "#{config_env()}.exs"
diff --git a/config/runtime.exs b/config/runtime.exs
index 843177b..1f66d4a 100644
--- a/config/runtime.exs
+++ b/config/runtime.exs
@@ -110,6 +110,22 @@ s3_public_url =
)
)
+remote_ip_proxies =
+ get_var_from_path_or_env(config_dir, "REMOTE_IP_PROXIES", "")
+ |> String.split(",")
+ |> Enum.map(&String.trim/1)
+ |> Enum.reject(&(&1 == ""))
+
+remote_ip_headers =
+ get_var_from_path_or_env(
+ config_dir,
+ "REMOTE_IP_HEADERS",
+ "forwarded,x-forwarded-for,x-client-ip,x-real-ip"
+ )
+ |> String.split(",")
+ |> Enum.map(&String.trim/1)
+ |> Enum.reject(&(&1 == ""))
+
same_site_cookie = get_var_from_path_or_env(config_dir, "SAME_SITE_COOKIE", "Lax")
secure_cookie =
@@ -192,7 +208,9 @@ config :claper,
email_confirmation: email_confirmation,
allow_unlink_external_provider: allow_unlink_external_provider,
logout_redirect_url: logout_redirect_url,
- languages: languages
+ languages: languages,
+ remote_ip_proxies: remote_ip_proxies,
+ remote_ip_headers: remote_ip_headers
config :claper, :presentations,
max_file_size: max_file_size,
diff --git a/lib/claper/audit.ex b/lib/claper/audit.ex
new file mode 100644
index 0000000..df97fd2
--- /dev/null
+++ b/lib/claper/audit.ex
@@ -0,0 +1,125 @@
+defmodule Claper.Audit do
+ @moduledoc """
+ The Audit context for tracking actions in the system.
+ """
+
+ import Ecto.Query, only: [from: 2]
+
+ alias Claper.{Accounts, Repo}
+ alias Claper.Audit.Log
+
+ @doc """
+ Logs an action.
+
+ ## Examples
+
+ iex> log_action(user, "user.login", %{ip_address: "127.0.0.1"})
+ {:ok, %Log{}}
+
+ iex> log_action(nil, "system.startup", %{})
+ {:ok, %Log{}}
+
+ """
+ def log_action(user, action, metadata \\ %{})
+
+ def log_action(%Accounts.User{} = user, action, metadata) do
+ create_log(%{
+ user_id: user.id,
+ action: action,
+ metadata: metadata
+ })
+ end
+
+ def log_action(nil, action, metadata) do
+ create_log(%{
+ action: action,
+ metadata: metadata
+ })
+ end
+
+ @doc """
+ Logs an action related to a specific resource.
+
+ ## Examples
+
+ iex> log_resource_action(user, "event.create", "event", 123, %{})
+ {:ok, %Log{}}
+
+ """
+ def log_resource_action(
+ %Accounts.User{} = user,
+ action,
+ resource_type,
+ resource_id,
+ metadata \\ %{}
+ ) do
+ create_log(%{
+ user_id: user.id,
+ action: action,
+ resource_type: resource_type,
+ resource_id: resource_id,
+ metadata: metadata
+ })
+ end
+
+ @doc """
+ Returns a paginated, optionally filtered and sorted, list of audit logs.
+ """
+ def list_logs(params \\ %{}) do
+ query = from l in Log, left_join: u in assoc(l, :user), as: :user, preload: [user: u]
+ Flop.validate_and_run!(query, params, for: Log, replace_invalid_params: true)
+ end
+
+ @doc """
+ Returns a list of distinct action types for filtering.
+ """
+ def list_action_types do
+ from(l in Log,
+ distinct: true,
+ select: l.action,
+ order_by: l.action
+ )
+ |> Repo.all()
+ end
+
+ @doc """
+ Gets a single log.
+
+ Raises `Ecto.NoResultsError` if the Log does not exist.
+
+ ## Examples
+
+ iex> get_log!(123)
+ %Log{}
+
+ iex> get_log!(456)
+ ** (Ecto.NoResultsError)
+
+ """
+ def get_log!(id) do
+ Repo.one!(
+ from l in Log, left_join: u in assoc(l, :user), where: l.id == ^id, preload: [user: u]
+ )
+ end
+
+ @doc """
+ Creates a log entry.
+
+ This is a simple wrapper over a low-level insert. You likely want to use
+ `log_action/3` and `log_resource_action/5` instead.
+
+ ## Examples
+
+ iex> create_log(%{action: "user.login"})
+ {:ok, %Log{}}
+
+ iex> create_log(%{action: nil})
+ {:error, %Ecto.Changeset{}}
+
+ """
+ def create_log(attrs \\ %{}) do
+ %Log{}
+ |> Log.changeset(attrs)
+ |> Repo.insert()
+ end
+end
diff --git a/lib/claper/audit/log.ex b/lib/claper/audit/log.ex
new file mode 100644
index 0000000..fef6720
--- /dev/null
+++ b/lib/claper/audit/log.ex
@@ -0,0 +1,45 @@
+defmodule Claper.Audit.Log do
+ use Ecto.Schema
+ import Ecto.Changeset
+
+ @derive {
+ Flop.Schema,
+ max_limit: 100,
+ filterable: [:action, :user_email],
+ sortable: [:inserted_at, :action],
+ default_order: %{
+ order_by: [:inserted_at],
+ order_directions: [:desc]
+ },
+ adapter_opts: [
+ join_fields: [
+ user_email: [
+ binding: :user,
+ field: :email,
+ path: [:user, :email]
+ ]
+ ]
+ ]
+ }
+
+ schema "audit_logs" do
+ field :action, :string
+ field :resource_type, :string
+ field :resource_id, :integer
+ field :metadata, :map, default: %{}
+
+ belongs_to :user, Claper.Accounts.User
+
+ timestamps(updated_at: false)
+ end
+
+ @doc false
+ def changeset(log, attrs) do
+ log
+ |> cast(attrs, [:action, :resource_type, :resource_id, :metadata, :user_id])
+ |> validate_required([:action])
+ |> validate_length(:action, max: 255)
+ |> validate_length(:resource_type, max: 255)
+ |> assoc_constraint(:user)
+ end
+end
diff --git a/lib/claper_web/components/core_components.ex b/lib/claper_web/components/core_components.ex
new file mode 100644
index 0000000..f3d98b8
--- /dev/null
+++ b/lib/claper_web/components/core_components.ex
@@ -0,0 +1,498 @@
+defmodule ClaperWeb.CoreComponents do
+ @moduledoc """
+ Provides core UI components.
+
+ At first glance, this module may seem daunting, but its goal is to provide
+ core building blocks for your application, such as tables, forms, and
+ inputs. The components consist mostly of markup and are well-documented
+ with doc strings and declarative assigns. You may customize and style
+ them in any way you want, based on your application growth and needs.
+
+ The foundation for styling is Tailwind CSS, a utility-first CSS framework,
+ augmented with daisyUI, a Tailwind CSS plugin that provides UI components
+ and themes. Here are useful references:
+
+ * [daisyUI](https://daisyui.com/docs/intro/) - a good place to get
+ started and see the available components.
+
+ * [Tailwind CSS](https://tailwindcss.com) - the foundational framework
+ we build on. You will use it for layout, sizing, flexbox, grid, and
+ spacing.
+
+ * [Heroicons](https://heroicons.com) - see `icon/1` for usage.
+
+ * [Phoenix.Component](https://hexdocs.pm/phoenix_live_view/Phoenix.Component.html) -
+ the component system used by Phoenix. Some components, such as `<.link>`
+ and `<.form>`, are defined there.
+
+ """
+ use Phoenix.Component
+ use Gettext, backend: ClaperWeb.Gettext
+
+ alias Phoenix.LiveView.JS
+
+ @doc """
+ Renders flash notices.
+
+ ## Examples
+
+ <.flash kind={:info} flash={@flash} />
+ <.flash kind={:info} phx-mounted={show("#flash")}>Welcome Back!
+ """
+ attr :id, :string, doc: "the optional id of flash container"
+ attr :flash, :map, default: %{}, doc: "the map of flash messages to display"
+ attr :title, :string, default: nil
+ attr :kind, :atom, values: [:info, :error], doc: "used for styling and flash lookup"
+ attr :rest, :global, doc: "the arbitrary HTML attributes to add to the flash container"
+
+ slot :inner_block, doc: "the optional inner block that renders the flash message"
+
+ def flash(assigns) do
+ assigns = assign_new(assigns, :id, fn -> "flash-#{assigns.kind}" end)
+
+ ~H"""
+ hide("##{@id}")}
+ role="alert"
+ class="toast toast-top toast-end z-50"
+ {@rest}
+ >
+
+ <.icon :if={@kind == :info} name="hero-information-circle" class="size-5 shrink-0" />
+ <.icon :if={@kind == :error} name="hero-exclamation-circle" class="size-5 shrink-0" />
+
+
+
+
+
+ """
+ end
+
+ @doc """
+ Renders a button with navigation support.
+
+ ## Examples
+
+ <.button>Send!
+ <.button phx-click="go" variant="primary">Send!
+ <.button navigate={~p"/"}>Home
+ """
+ attr :rest, :global, include: ~w(href navigate patch method download name value disabled)
+ attr :class, :any
+ attr :variant, :string, values: ~w(primary)
+ slot :inner_block, required: true
+
+ def button(%{rest: rest} = assigns) do
+ variants = %{"primary" => "btn-primary", nil => "btn-primary btn-soft"}
+
+ assigns =
+ assign_new(assigns, :class, fn ->
+ ["btn", Map.fetch!(variants, assigns[:variant])]
+ end)
+
+ if rest[:href] || rest[:navigate] || rest[:patch] do
+ ~H"""
+ <.link class={@class} {@rest}>
+ {render_slot(@inner_block)}
+
+ """
+ else
+ ~H"""
+
+ """
+ end
+ end
+
+ @doc """
+ Renders an input with label and error messages.
+
+ A `Phoenix.HTML.FormField` may be passed as argument,
+ which is used to retrieve the input name, id, and values.
+ Otherwise all attributes may be passed explicitly.
+
+ ## Types
+
+ This function accepts all HTML input types, considering that:
+
+ * You may also set `type="select"` to render a `
+ """,
+ table_attrs: [class: "table table-zebra w-full"],
+ symbol_asc: ~H"""
+
+ """,
+ symbol_desc: ~H"""
+
+ """
+ ]}
+ >
+ <:col :let={log} label={gettext("ID")} field={:id}>{log.id}
+ <:col :let={log} label={gettext("Action")} field={:action}>
+ {log.action}
+
+ <:col :let={log} label={gettext("User")} field={:user_email}>
+ {get_in(log.user.email) || "—"}
+
+ <:col :let={log} label={gettext("Timestamp")} field={:inserted_at}>
+ {format_timestamp(log.inserted_at)}
+
+ <:col
+ :let={log}
+ label={gettext("Metadata")}
+ field={:metadata}
+ tbody_td_attrs={[class: "max-w-xs truncate text-sm text-base-content/70"]}
+ >
+ {format_metadata(log.metadata)}
+
+ <:action :let={log} tbody_td_attrs={[class: "text-right"]}>
+ <.link
+ patch={~p"/admin/audit_logs/#{log}"}
+ class="btn btn-link btn-sm"
+ aria-label={gettext("View details for log #%{id}", id: log.id)}
+ >
+
+
+
+
+<% end %>
+
+<%= if @live_action == :show do %>
+
+
+
- {gettext("ID")}
+ -
+ {@log.id}
+
+
+
+
- {gettext("Action")}
+ -
+ {@log.action}
+
+
+
+
- {gettext("User")}
+
-
+ <%= if @log.user do %>
+
+ {@log.user.email}
+ <.link
+ navigate={~p"/admin/users/#{@log.user}"}
+ class="link link-primary *:inline"
+ aria-label={gettext("View profile for %{email}", email: @log.user.email)}
+ >
+
+
+
+ <% else %>
+ —
+ <% end %>
+
+
+
+
- {gettext("Timestamp")}
+ -
+ {format_timestamp(@log.inserted_at)}
+
+
+ <%= if @log.resource_type do %>
+
+
- {gettext("Resource Type")}
+ -
+ {@log.resource_type}
+
+
+ <% end %>
+ <%= if @log.resource_id do %>
+
+
- {gettext("Resource ID")}
+ -
+ {@log.resource_id}
+
+
+ <% end %>
+
+
- {gettext("Metadata")}
+
-
+ <%= if @log.metadata && map_size(@log.metadata) > 0 do %>
+
+ <%= for {key, value} <- @log.metadata do %>
+
+
- {key}:
+ - {value}
+
+ <% end %>
+
+ <% else %>
+ —
+ <% end %>
+
+
+
+<% end %>
diff --git a/lib/claper_web/router.ex b/lib/claper_web/router.ex
index 67c93ae..0c7c9a2 100644
--- a/lib/claper_web/router.ex
+++ b/lib/claper_web/router.ex
@@ -198,6 +198,9 @@ defmodule ClaperWeb.Router do
live "/oidc_providers/new", OidcProviderLive, :new
live "/oidc_providers/:id/edit", OidcProviderLive, :edit
live "/oidc_providers/:id", OidcProviderLive, :show
+
+ live "/audit_logs", AuditLogLive, :index
+ live "/audit_logs/:id", AuditLogLive, :show
end
end
end
diff --git a/lib/claper_web/templates/layout/admin.html.heex b/lib/claper_web/templates/layout/admin.html.heex
index 5385685..43c14ba 100644
--- a/lib/claper_web/templates/layout/admin.html.heex
+++ b/lib/claper_web/templates/layout/admin.html.heex
@@ -18,7 +18,7 @@
-
+
@@ -230,6 +230,22 @@
{gettext("Users")}
+
+ <.link
+ patch={~p"/admin/audit_logs"}
+ class={"#{if @conn.path_info == ["admin", "audit_logs"], do: "active", else: ""}"}
+ >
+
+ {gettext("Audit Logs")}
+
+
<%!--
<.link
patch={~p"/admin/oidc_providers"}
diff --git a/mix.exs b/mix.exs
index 48e0aa6..f57481b 100644
--- a/mix.exs
+++ b/mix.exs
@@ -115,6 +115,9 @@ defmodule Claper.MixProject do
{:oidcc, "~> 3.5"},
{:oban, "~> 2.19"},
{:hammer, "~> 7.0"},
+ {:flop, "~> 0.26"},
+ {:flop_phoenix, "~> 0.25"},
+ {:remote_ip, "~> 1.2"},
{:tailwind, "~> 0.3", runtime: Mix.env() == :dev}
]
end
diff --git a/mix.lock b/mix.lock
index 4595508..c83f327 100644
--- a/mix.lock
+++ b/mix.lock
@@ -2,6 +2,7 @@
"bcrypt_elixir": {:hex, :bcrypt_elixir, "3.3.2", "d50091e3c9492d73e17fc1e1619a9b09d6a5ef99160eb4d736926fd475a16ca3", [:make, :mix], [{:comeonin, "~> 5.3", [hex: :comeonin, repo: "hexpm", optional: false]}, {:elixir_make, "~> 0.6", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm", "471be5151874ae7931911057d1467d908955f93554f7a6cd1b7d804cac8cef53"},
"bunt": {:hex, :bunt, "1.0.0", "081c2c665f086849e6d57900292b3a161727ab40431219529f13c4ddcf3e7a44", [:mix], [], "hexpm", "dc5f86aa08a5f6fa6b8096f0735c4e76d54ae5c9fa2c143e5a1fc7c1cd9bb6b5"},
"castore": {:hex, :castore, "1.0.14", "4582dd7d630b48cf5e1ca8d3d42494db51e406b7ba704e81fbd401866366896a", [:mix], [], "hexpm", "7bc1b65249d31701393edaaac18ec8398d8974d52c647b7904d01b964137b9f4"},
+ "combine": {:hex, :combine, "0.10.0", "eff8224eeb56498a2af13011d142c5e7997a80c8f5b97c499f84c841032e429f", [:mix], [], "hexpm", "1b1dbc1790073076580d0d1d64e42eae2366583e7aecd455d1215b0d16f2451b"},
"comeonin": {:hex, :comeonin, "5.5.1", "5113e5f3800799787de08a6e0db307133850e635d34e9fab23c70b6501669510", [:mix], [], "hexpm", "65aac8f19938145377cee73973f192c5645873dcf550a8a6b18187d17c13ccdb"},
"cowboy": {:hex, :cowboy, "2.13.0", "09d770dd5f6a22cc60c071f432cd7cb87776164527f205c5a6b0f24ff6b38990", [:make, :rebar3], [{:cowlib, ">= 2.14.0 and < 3.0.0", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, ">= 1.8.0 and < 3.0.0", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm", "e724d3a70995025d654c1992c7b11dbfea95205c047d86ff9bf1cda92ddc5614"},
"cowboy_telemetry": {:hex, :cowboy_telemetry, "0.4.0", "f239f68b588efa7707abce16a84d0d2acf3a0f50571f8bb7f56a15865aae820c", [:rebar3], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "7d98bac1ee4565d31b62d59f8823dfd8356a169e7fcbb83831b8a5397404c9de"},
@@ -23,6 +24,8 @@
"file_system": {:hex, :file_system, "1.1.0", "08d232062284546c6c34426997dd7ef6ec9f8bbd090eb91780283c9016840e8f", [:mix], [], "hexpm", "bfcf81244f416871f2a2e15c1b515287faa5db9c6bcf290222206d120b3d43f6"},
"finch": {:hex, :finch, "0.19.0", "c644641491ea854fc5c1bbaef36bfc764e3f08e7185e1f084e35e0672241b76d", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mint, "~> 1.6.2 or ~> 1.7", [hex: :mint, repo: "hexpm", optional: false]}, {:nimble_options, "~> 0.4 or ~> 1.0", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:nimble_pool, "~> 1.1", [hex: :nimble_pool, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "fc5324ce209125d1e2fa0fcd2634601c52a787aff1cd33ee833664a5af4ea2b6"},
"floki": {:hex, :floki, "0.38.0", "62b642386fa3f2f90713f6e231da0fa3256e41ef1089f83b6ceac7a3fd3abf33", [:mix], [], "hexpm", "a5943ee91e93fb2d635b612caf5508e36d37548e84928463ef9dd986f0d1abd9"},
+ "flop": {:hex, :flop, "0.26.3", "9bc700b34f96a57e56aaa89b850926356311372556eacd5a1abe0fdd0ea40bf2", [:mix], [{:ecto, "~> 3.11", [hex: :ecto, repo: "hexpm", optional: false]}, {:nimble_options, "~> 1.0", [hex: :nimble_options, repo: "hexpm", optional: false]}], "hexpm", "cd77588229778ac55560c90dfbe15ab6486773f067d6e52db9fa703b8c9a9d2d"},
+ "flop_phoenix": {:hex, :flop_phoenix, "0.25.3", "a623649f6cd00ce3be1eac8dbd6d4fadf47a3212c7d2fc4701f6f2f90f347549", [:mix], [{:flop, ">= 0.23.0 and < 0.27.0", [hex: :flop, repo: "hexpm", optional: false]}, {:phoenix, ">= 1.6.0 and < 1.9.0", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 4.0", [hex: :phoenix_html, repo: "hexpm", optional: false]}, {:phoenix_live_view, "~> 1.0.6 or ~> 1.1.0", [hex: :phoenix_live_view, repo: "hexpm", optional: false]}], "hexpm", "912fae3c343dde43c5ea4f642275793d9dbef32989bf200013e12b85adb93b9c"},
"gen_smtp": {:hex, :gen_smtp, "1.3.0", "62c3d91f0dcf6ce9db71bcb6881d7ad0d1d834c7f38c13fa8e952f4104a8442e", [:rebar3], [{:ranch, ">= 1.8.0", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm", "0b73fbf069864ecbce02fe653b16d3f35fd889d0fdd4e14527675565c39d84e6"},
"gettext": {:hex, :gettext, "0.26.2", "5978aa7b21fada6deabf1f6341ddba50bc69c999e812211903b169799208f2a8", [:mix], [{:expo, "~> 0.5.1 or ~> 1.0", [hex: :expo, repo: "hexpm", optional: false]}], "hexpm", "aa978504bcf76511efdc22d580ba08e2279caab1066b76bb9aa81c4a1e0a32a5"},
"hammer": {:hex, :hammer, "7.2.0", "73113eca87f0fd20a6d3679c1182e8c4c1778266f61de4e9dc8c589dee156c30", [:mix], [], "hexpm", "c50fa865ddfe7b3d4f8a6941f56940679e02a9a1465b00668a95d140b101d828"},
@@ -60,6 +63,7 @@
"porcelain": {:hex, :porcelain, "2.0.3", "2d77b17d1f21fed875b8c5ecba72a01533db2013bd2e5e62c6d286c029150fdc", [:mix], [], "hexpm", "dc996ab8fadbc09912c787c7ab8673065e50ea1a6245177b0c24569013d23620"},
"postgrex": {:hex, :postgrex, "0.20.0", "363ed03ab4757f6bc47942eff7720640795eb557e1935951c1626f0d303a3aed", [:mix], [{:db_connection, "~> 2.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.5 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "d36ef8b36f323d29505314f704e21a1a038e2dc387c6409ee0cd24144e187c0f"},
"ranch": {:hex, :ranch, "2.2.0", "25528f82bc8d7c6152c57666ca99ec716510fe0925cb188172f41ce93117b1b0", [:make, :rebar3], [], "hexpm", "fa0b99a1780c80218a4197a59ea8d3bdae32fbff7e88527d7d8a4787eff4f8e7"},
+ "remote_ip": {:hex, :remote_ip, "1.2.0", "fb078e12a44414f4cef5a75963c33008fe169b806572ccd17257c208a7bc760f", [:mix], [{:combine, "~> 0.10", [hex: :combine, repo: "hexpm", optional: false]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "2ff91de19c48149ce19ed230a81d377186e4412552a597d6a5137373e5877cb7"},
"req": {:hex, :req, "0.5.14", "521b449fa0bf275e6d034c05f29bec21789a0d6cd6f7a1c326c7bee642bf6e07", [:mix], [{:brotli, "~> 0.3.1", [hex: :brotli, repo: "hexpm", optional: true]}, {:ezstd, "~> 1.0", [hex: :ezstd, repo: "hexpm", optional: true]}, {:finch, "~> 0.17", [hex: :finch, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:mime, "~> 2.0.6 or ~> 2.1", [hex: :mime, repo: "hexpm", optional: false]}, {:nimble_csv, "~> 1.0", [hex: :nimble_csv, repo: "hexpm", optional: true]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "b7b15692071d556c73432c7797aa7e96b51d1a2db76f746b976edef95c930021"},
"sweet_xml": {:hex, :sweet_xml, "0.7.5", "803a563113981aaac202a1dbd39771562d0ad31004ddbfc9b5090bdcd5605277", [:mix], [], "hexpm", "193b28a9b12891cae351d81a0cead165ffe67df1b73fe5866d10629f4faefb12"},
"swoosh": {:hex, :swoosh, "1.19.3", "02ad4455939f502386e4e1443d4de94c514995fd0e51b3cafffd6bd270ffe81c", [:mix], [{:bandit, ">= 1.0.0", [hex: :bandit, repo: "hexpm", optional: true]}, {:cowboy, "~> 1.1 or ~> 2.4", [hex: :cowboy, repo: "hexpm", optional: true]}, {:ex_aws, "~> 2.1", [hex: :ex_aws, repo: "hexpm", optional: true]}, {:finch, "~> 0.6", [hex: :finch, repo: "hexpm", optional: true]}, {:gen_smtp, "~> 0.13 or ~> 1.0", [hex: :gen_smtp, repo: "hexpm", optional: true]}, {:hackney, "~> 1.9", [hex: :hackney, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:mail, "~> 0.2", [hex: :mail, repo: "hexpm", optional: true]}, {:mime, "~> 1.1 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mua, "~> 0.2.3", [hex: :mua, repo: "hexpm", optional: true]}, {:multipart, "~> 0.4", [hex: :multipart, repo: "hexpm", optional: true]}, {:plug, "~> 1.9", [hex: :plug, repo: "hexpm", optional: true]}, {:plug_cowboy, ">= 1.0.0", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:req, "~> 0.5.10 or ~> 0.6 or ~> 1.0", [hex: :req, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.2 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "04a10f8496786b744b84130e3510eb53ca51e769c39511b65023bdf4136b732f"},
diff --git a/priv/gettext/de/LC_MESSAGES/default.po b/priv/gettext/de/LC_MESSAGES/default.po
index 98ae3a9..0007bfd 100644
--- a/priv/gettext/de/LC_MESSAGES/default.po
+++ b/priv/gettext/de/LC_MESSAGES/default.po
@@ -18,7 +18,7 @@ msgstr "Einstellungen"
#: lib/claper_web/live/admin_live/user_live.html.heex:74
#: lib/claper_web/live/admin_live/user_live.html.heex:254
#: lib/claper_web/live/admin_live/user_live/form_component.ex:18
-#: lib/claper_web/live/event_live/manage.ex:838
+#: lib/claper_web/live/event_live/manage.ex:844
#: lib/claper_web/live/form_live/form_component.html.heex:32
#: lib/claper_web/live/user_settings_live/show.html.heex:34
#: lib/claper_web/templates/user_registration/new.html.heex:29
@@ -476,9 +476,9 @@ msgstr "Interaktion hinzufügen"
msgid "Blocking this user will delete all his messages and he will not be able to join again, confirm ?"
msgstr "Wenn Sie diesen Benutzer sperren, werden alle seine Nachrichten gelöscht, und er kann nicht mehr beitreten. Bestätigen?"
-#: lib/claper_web/live/event_live/show.ex:51
-#: lib/claper_web/live/event_live/show.ex:206
-#: lib/claper_web/live/event_live/show.ex:221
+#: lib/claper_web/live/event_live/show.ex:64
+#: lib/claper_web/live/event_live/show.ex:219
+#: lib/claper_web/live/event_live/show.ex:234
#, elixir-autogen, elixir-format
msgid "You have been banned from this event"
msgstr "Sie wurden von dieser Veranstaltung ausgeschlossen"
@@ -705,7 +705,7 @@ msgstr "Formulareinsendungen der Teilnehmer werden hier angezeigt."
#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:74
#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:254
#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:24
-#: lib/claper_web/live/event_live/manage.ex:837
+#: lib/claper_web/live/event_live/manage.ex:843
#, elixir-autogen, elixir-format
msgid "Name"
msgstr "Name"
@@ -1068,6 +1068,7 @@ msgstr "Hier finden Sie alle Interaktionen Ihrer Teilnehmer. Sie können Nachric
msgid "Identify users by their unique avatars."
msgstr "Identifizieren Sie Benutzer anhand ihrer einzigartigen Avatare."
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:40
#: lib/claper_web/live/event_live/event_form_component.html.heex:5
#: lib/claper_web/live/event_live/index.html.heex:106
#: lib/claper_web/live/event_live/manage.html.heex:427
@@ -1194,7 +1195,7 @@ msgstr "Wählen Sie Ihre Präsentation aus (optional)"
msgid "This code will be used by your attendees to access the event. You have the option to create a custom code."
msgstr "Dieser Code wird von Ihren Teilnehmern verwendet, um auf die Veranstaltung zuzugreifen. Sie haben die Möglichkeit, einen benutzerdefinierten Code zu erstellen."
-#: lib/claper_web/live/event_live/show.ex:193
+#: lib/claper_web/live/event_live/show.ex:206
#, elixir-autogen, elixir-format
msgid "This event has been terminated"
msgstr "Diese Veranstaltung wurde beendet"
@@ -1216,7 +1217,7 @@ msgstr "Erstellen Sie Ihre nächste Präsentation mit"
#: lib/claper_web/live/event_live/manage.ex:23
#: lib/claper_web/live/event_live/presenter.ex:26
-#: lib/claper_web/live/event_live/show.ex:25
+#: lib/claper_web/live/event_live/show.ex:38
#, elixir-autogen, elixir-format
msgid "Event doesn't exist"
msgstr "Veranstaltung existiert nicht"
@@ -1272,7 +1273,7 @@ msgid "Event manager"
msgstr "Veranstaltungsmanager"
#: lib/claper_web/templates/layout/_user_menu.html.heex:19
-#: lib/claper_web/templates/layout/admin.html.heex:262
+#: lib/claper_web/templates/layout/admin.html.heex:278
#, elixir-autogen, elixir-format
msgid "Documentation"
msgstr "Dokumentation"
@@ -1475,6 +1476,7 @@ msgid "Please enter a valid link starting with http:// or https://"
msgstr "Bitte geben Sie einen gültigen Link ein, der mit http:// oder https:// beginnt"
#: lib/claper/embeds/embed.ex:98
+#: lib/claper/embeds/embed.ex:122
#, elixir-autogen, elixir-format
msgid "Please enter valid HTML content with an iframe tag"
msgstr "Bitte geben Sie gültigen HTML-Inhalt mit einem iframe-Tag ein"
@@ -1564,12 +1566,12 @@ msgstr "Beenden"
msgid "More options"
msgstr "Weitere Optionen"
-#: lib/claper_web/live/event_live/manage.ex:818
+#: lib/claper_web/live/event_live/manage.ex:824
#, elixir-autogen, elixir-format
msgid "No"
msgstr "Nein"
-#: lib/claper_web/live/event_live/manage.ex:818
+#: lib/claper_web/live/event_live/manage.ex:824
#, elixir-autogen, elixir-format
msgid "Yes"
msgstr "Ja"
@@ -1718,6 +1720,7 @@ msgstr "Neues Quiz"
msgid "Presentation"
msgstr "Präsentation"
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:34
#: lib/claper_web/live/event_live/manager_settings_component.ex:168
#, elixir-autogen, elixir-format
msgid "Previous"
@@ -1932,6 +1935,7 @@ msgstr "Ein eindeutiger Name zur Identifikation dieses OIDC-Anbieters"
msgid "Account is confirmed and active"
msgstr "Konto ist bestätigt und aktiv"
+#: lib/claper_web/components/core_components.ex:368
#: lib/claper_web/live/admin_live/event_live.html.heex:126
#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:108
#: lib/claper_web/live/admin_live/user_live.html.heex:111
@@ -2639,7 +2643,7 @@ msgstr "Anbieter"
msgid "Admin"
msgstr "Admin"
-#: lib/claper_web/templates/layout/admin.html.heex:285
+#: lib/claper_web/templates/layout/admin.html.heex:301
#, elixir-autogen, elixir-format
msgid "Back to app"
msgstr "Zurück zur App"
@@ -2679,3 +2683,84 @@ msgstr "Erforderlich"
#, elixir-autogen, elixir-format
msgid "(optional)"
msgstr "(optional)"
+
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:67
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:105
+#, elixir-autogen, elixir-format, fuzzy
+msgid "Action"
+msgstr "Aktion"
+
+#: lib/claper_web/live/admin_live/audit_log_live.ex:39
+#, elixir-autogen, elixir-format, fuzzy
+msgid "All actions"
+msgstr "Alle Aktionen"
+
+#: lib/claper_web/live/admin_live/audit_log_live.ex:50
+#, elixir-autogen, elixir-format
+msgid "Audit Log Details"
+msgstr "Details zum Überwachungsprotokoll"
+
+#: lib/claper_web/live/admin_live/audit_log_live.ex:24
+#: lib/claper_web/templates/layout/admin.html.heex:246
+#, elixir-autogen, elixir-format
+msgid "Audit Logs"
+msgstr "Überwachungsprotokolle"
+
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:66
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:99
+#, elixir-autogen, elixir-format
+msgid "ID"
+msgstr "ID"
+
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:78
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:152
+#, elixir-autogen, elixir-format
+msgid "Metadata"
+msgstr "Metadaten"
+
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:55
+#, elixir-autogen, elixir-format, fuzzy
+msgid "No results."
+msgstr "Keine Ergebnisse."
+
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:145
+#, elixir-autogen, elixir-format
+msgid "Resource ID"
+msgstr "Ressourcen-ID"
+
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:137
+#, elixir-autogen, elixir-format, fuzzy
+msgid "Resource Type"
+msgstr "Ressourcentyp"
+
+#: lib/claper_web/live/admin_live/audit_log_live.ex:33
+#, elixir-autogen, elixir-format
+msgid "Search by user email"
+msgstr "Suche nach Benutzer-E-Mail"
+
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:73
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:130
+#, elixir-autogen, elixir-format
+msgid "Timestamp"
+msgstr "Zeitstempel"
+
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:70
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:111
+#, elixir-autogen, elixir-format, fuzzy
+msgid "User"
+msgstr "Benutzer"
+
+#: lib/claper_web/components/core_components.ex:74
+#, elixir-autogen, elixir-format, fuzzy
+msgid "close"
+msgstr "schließen"
+
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:88
+#, elixir-autogen, elixir-format
+msgid "View details for log #%{id}"
+msgstr "Details für Protokoll Nr. %{id} anzeigen"
+
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:119
+#, elixir-autogen, elixir-format
+msgid "View profile for %{email}"
+msgstr "Profil für %{email} anzeigen"
diff --git a/priv/gettext/default.pot b/priv/gettext/default.pot
index 08e38f4..46d50f5 100644
--- a/priv/gettext/default.pot
+++ b/priv/gettext/default.pot
@@ -20,7 +20,7 @@ msgstr ""
#: lib/claper_web/live/admin_live/user_live.html.heex:74
#: lib/claper_web/live/admin_live/user_live.html.heex:254
#: lib/claper_web/live/admin_live/user_live/form_component.ex:18
-#: lib/claper_web/live/event_live/manage.ex:838
+#: lib/claper_web/live/event_live/manage.ex:844
#: lib/claper_web/live/form_live/form_component.html.heex:32
#: lib/claper_web/live/user_settings_live/show.html.heex:34
#: lib/claper_web/templates/user_registration/new.html.heex:29
@@ -478,9 +478,9 @@ msgstr ""
msgid "Blocking this user will delete all his messages and he will not be able to join again, confirm ?"
msgstr ""
-#: lib/claper_web/live/event_live/show.ex:51
-#: lib/claper_web/live/event_live/show.ex:206
-#: lib/claper_web/live/event_live/show.ex:221
+#: lib/claper_web/live/event_live/show.ex:64
+#: lib/claper_web/live/event_live/show.ex:219
+#: lib/claper_web/live/event_live/show.ex:234
#, elixir-autogen, elixir-format
msgid "You have been banned from this event"
msgstr ""
@@ -707,7 +707,7 @@ msgstr ""
#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:74
#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:254
#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:24
-#: lib/claper_web/live/event_live/manage.ex:837
+#: lib/claper_web/live/event_live/manage.ex:843
#, elixir-autogen, elixir-format
msgid "Name"
msgstr ""
@@ -1070,6 +1070,7 @@ msgstr ""
msgid "Identify users by their unique avatars."
msgstr ""
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:40
#: lib/claper_web/live/event_live/event_form_component.html.heex:5
#: lib/claper_web/live/event_live/index.html.heex:106
#: lib/claper_web/live/event_live/manage.html.heex:427
@@ -1196,7 +1197,7 @@ msgstr ""
msgid "This code will be used by your attendees to access the event. You have the option to create a custom code."
msgstr ""
-#: lib/claper_web/live/event_live/show.ex:193
+#: lib/claper_web/live/event_live/show.ex:206
#, elixir-autogen, elixir-format
msgid "This event has been terminated"
msgstr ""
@@ -1218,7 +1219,7 @@ msgstr ""
#: lib/claper_web/live/event_live/manage.ex:23
#: lib/claper_web/live/event_live/presenter.ex:26
-#: lib/claper_web/live/event_live/show.ex:25
+#: lib/claper_web/live/event_live/show.ex:38
#, elixir-autogen, elixir-format
msgid "Event doesn't exist"
msgstr ""
@@ -1274,7 +1275,7 @@ msgid "Event manager"
msgstr ""
#: lib/claper_web/templates/layout/_user_menu.html.heex:19
-#: lib/claper_web/templates/layout/admin.html.heex:262
+#: lib/claper_web/templates/layout/admin.html.heex:278
#, elixir-autogen, elixir-format
msgid "Documentation"
msgstr ""
@@ -1477,6 +1478,7 @@ msgid "Please enter a valid link starting with http:// or https://"
msgstr ""
#: lib/claper/embeds/embed.ex:98
+#: lib/claper/embeds/embed.ex:122
#, elixir-autogen, elixir-format
msgid "Please enter valid HTML content with an iframe tag"
msgstr ""
@@ -1566,12 +1568,12 @@ msgstr ""
msgid "More options"
msgstr ""
-#: lib/claper_web/live/event_live/manage.ex:818
+#: lib/claper_web/live/event_live/manage.ex:824
#, elixir-autogen, elixir-format
msgid "No"
msgstr ""
-#: lib/claper_web/live/event_live/manage.ex:818
+#: lib/claper_web/live/event_live/manage.ex:824
#, elixir-autogen, elixir-format
msgid "Yes"
msgstr ""
@@ -1720,6 +1722,7 @@ msgstr ""
msgid "Presentation"
msgstr ""
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:34
#: lib/claper_web/live/event_live/manager_settings_component.ex:168
#, elixir-autogen, elixir-format
msgid "Previous"
@@ -1934,6 +1937,7 @@ msgstr ""
msgid "Account is confirmed and active"
msgstr ""
+#: lib/claper_web/components/core_components.ex:368
#: lib/claper_web/live/admin_live/event_live.html.heex:126
#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:108
#: lib/claper_web/live/admin_live/user_live.html.heex:111
@@ -2641,7 +2645,7 @@ msgstr ""
msgid "Admin"
msgstr ""
-#: lib/claper_web/templates/layout/admin.html.heex:285
+#: lib/claper_web/templates/layout/admin.html.heex:301
#, elixir-autogen, elixir-format
msgid "Back to app"
msgstr ""
@@ -2681,3 +2685,84 @@ msgstr ""
#, elixir-autogen, elixir-format
msgid "(optional)"
msgstr ""
+
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:67
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:105
+#, elixir-autogen, elixir-format
+msgid "Action"
+msgstr ""
+
+#: lib/claper_web/live/admin_live/audit_log_live.ex:39
+#, elixir-autogen, elixir-format
+msgid "All actions"
+msgstr ""
+
+#: lib/claper_web/live/admin_live/audit_log_live.ex:50
+#, elixir-autogen, elixir-format
+msgid "Audit Log Details"
+msgstr ""
+
+#: lib/claper_web/live/admin_live/audit_log_live.ex:24
+#: lib/claper_web/templates/layout/admin.html.heex:246
+#, elixir-autogen, elixir-format
+msgid "Audit Logs"
+msgstr ""
+
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:66
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:99
+#, elixir-autogen, elixir-format
+msgid "ID"
+msgstr ""
+
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:78
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:152
+#, elixir-autogen, elixir-format
+msgid "Metadata"
+msgstr ""
+
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:55
+#, elixir-autogen, elixir-format
+msgid "No results."
+msgstr ""
+
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:145
+#, elixir-autogen, elixir-format
+msgid "Resource ID"
+msgstr ""
+
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:137
+#, elixir-autogen, elixir-format
+msgid "Resource Type"
+msgstr ""
+
+#: lib/claper_web/live/admin_live/audit_log_live.ex:33
+#, elixir-autogen, elixir-format
+msgid "Search by user email"
+msgstr ""
+
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:73
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:130
+#, elixir-autogen, elixir-format
+msgid "Timestamp"
+msgstr ""
+
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:70
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:111
+#, elixir-autogen, elixir-format
+msgid "User"
+msgstr ""
+
+#: lib/claper_web/components/core_components.ex:74
+#, elixir-autogen, elixir-format
+msgid "close"
+msgstr ""
+
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:88
+#, elixir-autogen, elixir-format
+msgid "View details for log #%{id}"
+msgstr ""
+
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:119
+#, elixir-autogen, elixir-format
+msgid "View profile for %{email}"
+msgstr ""
diff --git a/priv/gettext/en/LC_MESSAGES/default.po b/priv/gettext/en/LC_MESSAGES/default.po
index 49ce3b1..2e17be9 100644
--- a/priv/gettext/en/LC_MESSAGES/default.po
+++ b/priv/gettext/en/LC_MESSAGES/default.po
@@ -18,7 +18,7 @@ msgstr ""
#: lib/claper_web/live/admin_live/user_live.html.heex:74
#: lib/claper_web/live/admin_live/user_live.html.heex:254
#: lib/claper_web/live/admin_live/user_live/form_component.ex:18
-#: lib/claper_web/live/event_live/manage.ex:838
+#: lib/claper_web/live/event_live/manage.ex:844
#: lib/claper_web/live/form_live/form_component.html.heex:32
#: lib/claper_web/live/user_settings_live/show.html.heex:34
#: lib/claper_web/templates/user_registration/new.html.heex:29
@@ -476,9 +476,9 @@ msgstr ""
msgid "Blocking this user will delete all his messages and he will not be able to join again, confirm ?"
msgstr ""
-#: lib/claper_web/live/event_live/show.ex:51
-#: lib/claper_web/live/event_live/show.ex:206
-#: lib/claper_web/live/event_live/show.ex:221
+#: lib/claper_web/live/event_live/show.ex:64
+#: lib/claper_web/live/event_live/show.ex:219
+#: lib/claper_web/live/event_live/show.ex:234
#, elixir-autogen, elixir-format
msgid "You have been banned from this event"
msgstr ""
@@ -705,7 +705,7 @@ msgstr ""
#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:74
#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:254
#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:24
-#: lib/claper_web/live/event_live/manage.ex:837
+#: lib/claper_web/live/event_live/manage.ex:843
#, elixir-autogen, elixir-format
msgid "Name"
msgstr ""
@@ -1068,6 +1068,7 @@ msgstr ""
msgid "Identify users by their unique avatars."
msgstr ""
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:40
#: lib/claper_web/live/event_live/event_form_component.html.heex:5
#: lib/claper_web/live/event_live/index.html.heex:106
#: lib/claper_web/live/event_live/manage.html.heex:427
@@ -1194,7 +1195,7 @@ msgstr ""
msgid "This code will be used by your attendees to access the event. You have the option to create a custom code."
msgstr ""
-#: lib/claper_web/live/event_live/show.ex:193
+#: lib/claper_web/live/event_live/show.ex:206
#, elixir-autogen, elixir-format
msgid "This event has been terminated"
msgstr ""
@@ -1216,7 +1217,7 @@ msgstr ""
#: lib/claper_web/live/event_live/manage.ex:23
#: lib/claper_web/live/event_live/presenter.ex:26
-#: lib/claper_web/live/event_live/show.ex:25
+#: lib/claper_web/live/event_live/show.ex:38
#, elixir-autogen, elixir-format
msgid "Event doesn't exist"
msgstr ""
@@ -1272,7 +1273,7 @@ msgid "Event manager"
msgstr ""
#: lib/claper_web/templates/layout/_user_menu.html.heex:19
-#: lib/claper_web/templates/layout/admin.html.heex:262
+#: lib/claper_web/templates/layout/admin.html.heex:278
#, elixir-autogen, elixir-format
msgid "Documentation"
msgstr ""
@@ -1475,6 +1476,7 @@ msgid "Please enter a valid link starting with http:// or https://"
msgstr ""
#: lib/claper/embeds/embed.ex:98
+#: lib/claper/embeds/embed.ex:122
#, elixir-autogen, elixir-format
msgid "Please enter valid HTML content with an iframe tag"
msgstr ""
@@ -1564,12 +1566,12 @@ msgstr ""
msgid "More options"
msgstr ""
-#: lib/claper_web/live/event_live/manage.ex:818
+#: lib/claper_web/live/event_live/manage.ex:824
#, elixir-autogen, elixir-format
msgid "No"
msgstr ""
-#: lib/claper_web/live/event_live/manage.ex:818
+#: lib/claper_web/live/event_live/manage.ex:824
#, elixir-autogen, elixir-format
msgid "Yes"
msgstr ""
@@ -1718,6 +1720,7 @@ msgstr ""
msgid "Presentation"
msgstr ""
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:34
#: lib/claper_web/live/event_live/manager_settings_component.ex:168
#, elixir-autogen, elixir-format
msgid "Previous"
@@ -1932,6 +1935,7 @@ msgstr ""
msgid "Account is confirmed and active"
msgstr ""
+#: lib/claper_web/components/core_components.ex:368
#: lib/claper_web/live/admin_live/event_live.html.heex:126
#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:108
#: lib/claper_web/live/admin_live/user_live.html.heex:111
@@ -2639,7 +2643,7 @@ msgstr ""
msgid "Admin"
msgstr ""
-#: lib/claper_web/templates/layout/admin.html.heex:285
+#: lib/claper_web/templates/layout/admin.html.heex:301
#, elixir-autogen, elixir-format
msgid "Back to app"
msgstr ""
@@ -2679,3 +2683,84 @@ msgstr ""
#, elixir-autogen, elixir-format
msgid "(optional)"
msgstr ""
+
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:67
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:105
+#, elixir-autogen, elixir-format, fuzzy
+msgid "Action"
+msgstr ""
+
+#: lib/claper_web/live/admin_live/audit_log_live.ex:39
+#, elixir-autogen, elixir-format, fuzzy
+msgid "All actions"
+msgstr ""
+
+#: lib/claper_web/live/admin_live/audit_log_live.ex:50
+#, elixir-autogen, elixir-format
+msgid "Audit Log Details"
+msgstr ""
+
+#: lib/claper_web/live/admin_live/audit_log_live.ex:24
+#: lib/claper_web/templates/layout/admin.html.heex:246
+#, elixir-autogen, elixir-format
+msgid "Audit Logs"
+msgstr ""
+
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:66
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:99
+#, elixir-autogen, elixir-format
+msgid "ID"
+msgstr ""
+
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:78
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:152
+#, elixir-autogen, elixir-format
+msgid "Metadata"
+msgstr ""
+
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:55
+#, elixir-autogen, elixir-format, fuzzy
+msgid "No results."
+msgstr ""
+
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:145
+#, elixir-autogen, elixir-format
+msgid "Resource ID"
+msgstr ""
+
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:137
+#, elixir-autogen, elixir-format, fuzzy
+msgid "Resource Type"
+msgstr ""
+
+#: lib/claper_web/live/admin_live/audit_log_live.ex:33
+#, elixir-autogen, elixir-format
+msgid "Search by user email"
+msgstr ""
+
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:73
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:130
+#, elixir-autogen, elixir-format
+msgid "Timestamp"
+msgstr ""
+
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:70
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:111
+#, elixir-autogen, elixir-format, fuzzy
+msgid "User"
+msgstr ""
+
+#: lib/claper_web/components/core_components.ex:74
+#, elixir-autogen, elixir-format, fuzzy
+msgid "close"
+msgstr ""
+
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:88
+#, elixir-autogen, elixir-format
+msgid "View details for log #%{id}"
+msgstr ""
+
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:119
+#, elixir-autogen, elixir-format
+msgid "View profile for %{email}"
+msgstr ""
diff --git a/priv/gettext/es/LC_MESSAGES/default.po b/priv/gettext/es/LC_MESSAGES/default.po
index db4b4c7..1aa476c 100644
--- a/priv/gettext/es/LC_MESSAGES/default.po
+++ b/priv/gettext/es/LC_MESSAGES/default.po
@@ -18,7 +18,7 @@ msgstr "Configuración"
#: lib/claper_web/live/admin_live/user_live.html.heex:74
#: lib/claper_web/live/admin_live/user_live.html.heex:254
#: lib/claper_web/live/admin_live/user_live/form_component.ex:18
-#: lib/claper_web/live/event_live/manage.ex:838
+#: lib/claper_web/live/event_live/manage.ex:844
#: lib/claper_web/live/form_live/form_component.html.heex:32
#: lib/claper_web/live/user_settings_live/show.html.heex:34
#: lib/claper_web/templates/user_registration/new.html.heex:29
@@ -476,9 +476,9 @@ msgstr "Añadir interacción"
msgid "Blocking this user will delete all his messages and he will not be able to join again, confirm ?"
msgstr "Bloquear este usuario borrará todos sus mensajes y él no será capaz de unirse de nuevo, ¿estás seguro?"
-#: lib/claper_web/live/event_live/show.ex:51
-#: lib/claper_web/live/event_live/show.ex:206
-#: lib/claper_web/live/event_live/show.ex:221
+#: lib/claper_web/live/event_live/show.ex:64
+#: lib/claper_web/live/event_live/show.ex:219
+#: lib/claper_web/live/event_live/show.ex:234
#, elixir-autogen, elixir-format
msgid "You have been banned from this event"
msgstr "Has sido excluido/a de este evento"
@@ -705,7 +705,7 @@ msgstr "Los envíos de formulario de los asistentes aparecerán aquí."
#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:74
#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:254
#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:24
-#: lib/claper_web/live/event_live/manage.ex:837
+#: lib/claper_web/live/event_live/manage.ex:843
#, elixir-autogen, elixir-format
msgid "Name"
msgstr "Nombre"
@@ -1068,6 +1068,7 @@ msgstr "Aquí encontrarás todas las interacciones de tus asistentes. Puedes ges
msgid "Identify users by their unique avatars."
msgstr "Identificar usuarios por sus avatares únicos."
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:40
#: lib/claper_web/live/event_live/event_form_component.html.heex:5
#: lib/claper_web/live/event_live/index.html.heex:106
#: lib/claper_web/live/event_live/manage.html.heex:427
@@ -1194,7 +1195,7 @@ msgstr "Selecciona tu presentación (opcional)"
msgid "This code will be used by your attendees to access the event. You have the option to create a custom code."
msgstr "Este código será usado por tus asistentes para acceder al evento. Tienes la opción de crear un código personalizado."
-#: lib/claper_web/live/event_live/show.ex:193
+#: lib/claper_web/live/event_live/show.ex:206
#, elixir-autogen, elixir-format
msgid "This event has been terminated"
msgstr "Este evento ha sido terminado"
@@ -1216,7 +1217,7 @@ msgstr "Crea tu siguiente presentación con"
#: lib/claper_web/live/event_live/manage.ex:23
#: lib/claper_web/live/event_live/presenter.ex:26
-#: lib/claper_web/live/event_live/show.ex:25
+#: lib/claper_web/live/event_live/show.ex:38
#, elixir-autogen, elixir-format
msgid "Event doesn't exist"
msgstr "El evento no existe"
@@ -1272,7 +1273,7 @@ msgid "Event manager"
msgstr "Gestor de evento"
#: lib/claper_web/templates/layout/_user_menu.html.heex:19
-#: lib/claper_web/templates/layout/admin.html.heex:262
+#: lib/claper_web/templates/layout/admin.html.heex:278
#, elixir-autogen, elixir-format
msgid "Documentation"
msgstr "Documentación"
@@ -1475,6 +1476,7 @@ msgid "Please enter a valid link starting with http:// or https://"
msgstr "Por favor, introduce un enlace válido que comience con http:// o https://"
#: lib/claper/embeds/embed.ex:98
+#: lib/claper/embeds/embed.ex:122
#, elixir-autogen, elixir-format
msgid "Please enter valid HTML content with an iframe tag"
msgstr "Por favor, introduce contenido HTML válido con una etiqueta iframe"
@@ -1564,12 +1566,12 @@ msgstr "Finalizar"
msgid "More options"
msgstr "Más opciones"
-#: lib/claper_web/live/event_live/manage.ex:818
+#: lib/claper_web/live/event_live/manage.ex:824
#, elixir-autogen, elixir-format
msgid "No"
msgstr "No"
-#: lib/claper_web/live/event_live/manage.ex:818
+#: lib/claper_web/live/event_live/manage.ex:824
#, elixir-autogen, elixir-format
msgid "Yes"
msgstr "Sí"
@@ -1718,6 +1720,7 @@ msgstr "Nuevo cuestionario"
msgid "Presentation"
msgstr "Presentación"
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:34
#: lib/claper_web/live/event_live/manager_settings_component.ex:168
#, elixir-autogen, elixir-format
msgid "Previous"
@@ -1932,6 +1935,7 @@ msgstr "Un nombre único para identificar este proveedor OIDC"
msgid "Account is confirmed and active"
msgstr "La cuenta está confirmada y activa"
+#: lib/claper_web/components/core_components.ex:368
#: lib/claper_web/live/admin_live/event_live.html.heex:126
#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:108
#: lib/claper_web/live/admin_live/user_live.html.heex:111
@@ -2639,7 +2643,7 @@ msgstr "Proveedor"
msgid "Admin"
msgstr "Admin"
-#: lib/claper_web/templates/layout/admin.html.heex:285
+#: lib/claper_web/templates/layout/admin.html.heex:301
#, elixir-autogen, elixir-format
msgid "Back to app"
msgstr "Volver a la aplicación"
@@ -2679,3 +2683,84 @@ msgstr "Obligatorio"
#, elixir-autogen, elixir-format
msgid "(optional)"
msgstr "(opcional)"
+
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:67
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:105
+#, elixir-autogen, elixir-format, fuzzy
+msgid "Action"
+msgstr "Acciones"
+
+#: lib/claper_web/live/admin_live/audit_log_live.ex:39
+#, elixir-autogen, elixir-format, fuzzy
+msgid "All actions"
+msgstr "Todas las acciones"
+
+#: lib/claper_web/live/admin_live/audit_log_live.ex:50
+#, elixir-autogen, elixir-format
+msgid "Audit Log Details"
+msgstr "Detalles del registro de auditoría"
+
+#: lib/claper_web/live/admin_live/audit_log_live.ex:24
+#: lib/claper_web/templates/layout/admin.html.heex:246
+#, elixir-autogen, elixir-format
+msgid "Audit Logs"
+msgstr "Registros de auditoría"
+
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:66
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:99
+#, elixir-autogen, elixir-format
+msgid "ID"
+msgstr "ID"
+
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:78
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:152
+#, elixir-autogen, elixir-format
+msgid "Metadata"
+msgstr "Metadatos"
+
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:55
+#, elixir-autogen, elixir-format, fuzzy
+msgid "No results."
+msgstr "Sin resultados."
+
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:145
+#, elixir-autogen, elixir-format
+msgid "Resource ID"
+msgstr "ID del recurso"
+
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:137
+#, elixir-autogen, elixir-format, fuzzy
+msgid "Resource Type"
+msgstr "Tipo de recurso"
+
+#: lib/claper_web/live/admin_live/audit_log_live.ex:33
+#, elixir-autogen, elixir-format
+msgid "Search by user email"
+msgstr "Buscar por email de usuario"
+
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:73
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:130
+#, elixir-autogen, elixir-format
+msgid "Timestamp"
+msgstr "Fecha y hora"
+
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:70
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:111
+#, elixir-autogen, elixir-format, fuzzy
+msgid "User"
+msgstr "Usuario"
+
+#: lib/claper_web/components/core_components.ex:74
+#, elixir-autogen, elixir-format, fuzzy
+msgid "close"
+msgstr "cerrar"
+
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:88
+#, elixir-autogen, elixir-format
+msgid "View details for log #%{id}"
+msgstr "Ver detalles del registro nº %{id}"
+
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:119
+#, elixir-autogen, elixir-format
+msgid "View profile for %{email}"
+msgstr "Ver perfil de %{email}"
diff --git a/priv/gettext/fr/LC_MESSAGES/default.po b/priv/gettext/fr/LC_MESSAGES/default.po
index da8c14f..f6444c9 100644
--- a/priv/gettext/fr/LC_MESSAGES/default.po
+++ b/priv/gettext/fr/LC_MESSAGES/default.po
@@ -18,7 +18,7 @@ msgstr "Paramètres"
#: lib/claper_web/live/admin_live/user_live.html.heex:74
#: lib/claper_web/live/admin_live/user_live.html.heex:254
#: lib/claper_web/live/admin_live/user_live/form_component.ex:18
-#: lib/claper_web/live/event_live/manage.ex:838
+#: lib/claper_web/live/event_live/manage.ex:844
#: lib/claper_web/live/form_live/form_component.html.heex:32
#: lib/claper_web/live/user_settings_live/show.html.heex:34
#: lib/claper_web/templates/user_registration/new.html.heex:29
@@ -477,9 +477,9 @@ msgstr "Ajouter une interaction"
msgid "Blocking this user will delete all his messages and he will not be able to join again, confirm ?"
msgstr "Bloquer cet utilisateur supprimera tous ses messages et il ne pourra pas rejoindre à nouveau, confirmer ?"
-#: lib/claper_web/live/event_live/show.ex:51
-#: lib/claper_web/live/event_live/show.ex:206
-#: lib/claper_web/live/event_live/show.ex:221
+#: lib/claper_web/live/event_live/show.ex:64
+#: lib/claper_web/live/event_live/show.ex:219
+#: lib/claper_web/live/event_live/show.ex:234
#, elixir-autogen, elixir-format
msgid "You have been banned from this event"
msgstr "Vous avez été banni de cet événement"
@@ -709,7 +709,7 @@ msgstr "Les formulaires soumis par les participants apparaîtront ici."
#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:74
#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:254
#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:24
-#: lib/claper_web/live/event_live/manage.ex:837
+#: lib/claper_web/live/event_live/manage.ex:843
#, elixir-autogen, elixir-format
msgid "Name"
msgstr "Nom"
@@ -1072,6 +1072,7 @@ msgstr "Ici, vous trouverez toutes les interactions de vos participants. Vous po
msgid "Identify users by their unique avatars."
msgstr "Identifiez les utilisateurs par leurs avatars uniques."
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:40
#: lib/claper_web/live/event_live/event_form_component.html.heex:5
#: lib/claper_web/live/event_live/index.html.heex:106
#: lib/claper_web/live/event_live/manage.html.heex:427
@@ -1198,7 +1199,7 @@ msgstr "Sélectionnez votre présentation (facultatif)"
msgid "This code will be used by your attendees to access the event. You have the option to create a custom code."
msgstr "Ce code sera utilisé par vos participants pour accéder à l'événement. Vous avez la possibilité de créer un code personnalisé."
-#: lib/claper_web/live/event_live/show.ex:193
+#: lib/claper_web/live/event_live/show.ex:206
#, elixir-autogen, elixir-format
msgid "This event has been terminated"
msgstr "Cet événement viens d'être terminé"
@@ -1220,7 +1221,7 @@ msgstr "Créez votre prochaine présentation avec"
#: lib/claper_web/live/event_live/manage.ex:23
#: lib/claper_web/live/event_live/presenter.ex:26
-#: lib/claper_web/live/event_live/show.ex:25
+#: lib/claper_web/live/event_live/show.ex:38
#, elixir-autogen, elixir-format
msgid "Event doesn't exist"
msgstr "L'événement n'existe pas"
@@ -1276,7 +1277,7 @@ msgid "Event manager"
msgstr "Gestionnaire d'événement"
#: lib/claper_web/templates/layout/_user_menu.html.heex:19
-#: lib/claper_web/templates/layout/admin.html.heex:262
+#: lib/claper_web/templates/layout/admin.html.heex:278
#, elixir-autogen, elixir-format
msgid "Documentation"
msgstr "Documentation"
@@ -1479,6 +1480,7 @@ msgid "Please enter a valid link starting with http:// or https://"
msgstr "Veuillez entrer un lien valide commençant par http:// ou https://"
#: lib/claper/embeds/embed.ex:98
+#: lib/claper/embeds/embed.ex:122
#, elixir-autogen, elixir-format
msgid "Please enter valid HTML content with an iframe tag"
msgstr "Veuillez entrer un contenu HTML valide avec une balise iframe"
@@ -1568,12 +1570,12 @@ msgstr "Terminer"
msgid "More options"
msgstr "Plus d'options"
-#: lib/claper_web/live/event_live/manage.ex:818
+#: lib/claper_web/live/event_live/manage.ex:824
#, elixir-autogen, elixir-format
msgid "No"
msgstr "Non"
-#: lib/claper_web/live/event_live/manage.ex:818
+#: lib/claper_web/live/event_live/manage.ex:824
#, elixir-autogen, elixir-format
msgid "Yes"
msgstr "Oui"
@@ -1722,6 +1724,7 @@ msgstr "Nouveau quiz"
msgid "Presentation"
msgstr "Présentation"
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:34
#: lib/claper_web/live/event_live/manager_settings_component.ex:168
#, elixir-autogen, elixir-format
msgid "Previous"
@@ -1936,6 +1939,7 @@ msgstr "Un nom unique pour identifier ce fournisseur OIDC"
msgid "Account is confirmed and active"
msgstr "Le compte est confirmé et actif"
+#: lib/claper_web/components/core_components.ex:368
#: lib/claper_web/live/admin_live/event_live.html.heex:126
#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:108
#: lib/claper_web/live/admin_live/user_live.html.heex:111
@@ -2643,7 +2647,7 @@ msgstr "Détails du fournisseur"
msgid "Admin"
msgstr "Admin"
-#: lib/claper_web/templates/layout/admin.html.heex:285
+#: lib/claper_web/templates/layout/admin.html.heex:301
#, elixir-autogen, elixir-format
msgid "Back to app"
msgstr "Retour à l'app"
@@ -2683,3 +2687,84 @@ msgstr "Obligatoire"
#, elixir-autogen, elixir-format
msgid "(optional)"
msgstr "(facultatif)"
+
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:67
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:105
+#, elixir-autogen, elixir-format, fuzzy
+msgid "Action"
+msgstr "Action"
+
+#: lib/claper_web/live/admin_live/audit_log_live.ex:39
+#, elixir-autogen, elixir-format, fuzzy
+msgid "All actions"
+msgstr "Toutes les actions"
+
+#: lib/claper_web/live/admin_live/audit_log_live.ex:50
+#, elixir-autogen, elixir-format
+msgid "Audit Log Details"
+msgstr "Détails du journal d'audit"
+
+#: lib/claper_web/live/admin_live/audit_log_live.ex:24
+#: lib/claper_web/templates/layout/admin.html.heex:246
+#, elixir-autogen, elixir-format
+msgid "Audit Logs"
+msgstr "Journaux d'audit"
+
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:66
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:99
+#, elixir-autogen, elixir-format
+msgid "ID"
+msgstr "ID"
+
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:78
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:152
+#, elixir-autogen, elixir-format
+msgid "Metadata"
+msgstr "Métadonnées"
+
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:55
+#, elixir-autogen, elixir-format, fuzzy
+msgid "No results."
+msgstr "Aucun résultat."
+
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:145
+#, elixir-autogen, elixir-format
+msgid "Resource ID"
+msgstr "ID de ressource"
+
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:137
+#, elixir-autogen, elixir-format, fuzzy
+msgid "Resource Type"
+msgstr "Type de ressource"
+
+#: lib/claper_web/live/admin_live/audit_log_live.ex:33
+#, elixir-autogen, elixir-format
+msgid "Search by user email"
+msgstr "Recherche par e-mail de l'utilisateur"
+
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:73
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:130
+#, elixir-autogen, elixir-format
+msgid "Timestamp"
+msgstr "Horodatage"
+
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:70
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:111
+#, elixir-autogen, elixir-format, fuzzy
+msgid "User"
+msgstr "Utilisateur"
+
+#: lib/claper_web/components/core_components.ex:74
+#, elixir-autogen, elixir-format, fuzzy
+msgid "close"
+msgstr "fermer"
+
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:88
+#, elixir-autogen, elixir-format
+msgid "View details for log #%{id}"
+msgstr "Afficher les détails du journal nº %{id}"
+
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:119
+#, elixir-autogen, elixir-format
+msgid "View profile for %{email}"
+msgstr "Voir le profil pour %{email}"
diff --git a/priv/gettext/hu/LC_MESSAGES/default.po b/priv/gettext/hu/LC_MESSAGES/default.po
index 4eb1a2f..5c2a7f1 100644
--- a/priv/gettext/hu/LC_MESSAGES/default.po
+++ b/priv/gettext/hu/LC_MESSAGES/default.po
@@ -18,7 +18,7 @@ msgstr "Beállítások"
#: lib/claper_web/live/admin_live/user_live.html.heex:74
#: lib/claper_web/live/admin_live/user_live.html.heex:254
#: lib/claper_web/live/admin_live/user_live/form_component.ex:18
-#: lib/claper_web/live/event_live/manage.ex:838
+#: lib/claper_web/live/event_live/manage.ex:844
#: lib/claper_web/live/form_live/form_component.html.heex:32
#: lib/claper_web/live/user_settings_live/show.html.heex:34
#: lib/claper_web/templates/user_registration/new.html.heex:29
@@ -476,9 +476,9 @@ msgstr "Interakció hozzáadása"
msgid "Blocking this user will delete all his messages and he will not be able to join again, confirm ?"
msgstr "Ezen felhasználó blokkolásával az üzenetei törlődnek, és nem fog tudni újra csatlakozni. Biztos benne?"
-#: lib/claper_web/live/event_live/show.ex:51
-#: lib/claper_web/live/event_live/show.ex:206
-#: lib/claper_web/live/event_live/show.ex:221
+#: lib/claper_web/live/event_live/show.ex:64
+#: lib/claper_web/live/event_live/show.ex:219
+#: lib/claper_web/live/event_live/show.ex:234
#, elixir-autogen, elixir-format
msgid "You have been banned from this event"
msgstr "Ki van tiltva erről az eseményről"
@@ -705,7 +705,7 @@ msgstr "A résztvevők által beküldött űrlapok itt fognak megjelenni."
#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:74
#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:254
#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:24
-#: lib/claper_web/live/event_live/manage.ex:837
+#: lib/claper_web/live/event_live/manage.ex:843
#, elixir-autogen, elixir-format
msgid "Name"
msgstr "Név"
@@ -1068,6 +1068,7 @@ msgstr "Itt találhatóak majd a résztvevők interakciói. Lehetőség van az
msgid "Identify users by their unique avatars."
msgstr "Azonosítsa a felhasználókat egyedi profilképeik alapján."
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:40
#: lib/claper_web/live/event_live/event_form_component.html.heex:5
#: lib/claper_web/live/event_live/index.html.heex:106
#: lib/claper_web/live/event_live/manage.html.heex:427
@@ -1194,7 +1195,7 @@ msgstr "Válassza ki a prezentációt (opcionális)"
msgid "This code will be used by your attendees to access the event. You have the option to create a custom code."
msgstr "A résztvevők ezt a kódot fogják használni a csatlakozáshoz. Lehetőség van egyéni kódot is létrehozni."
-#: lib/claper_web/live/event_live/show.ex:193
+#: lib/claper_web/live/event_live/show.ex:206
#, elixir-autogen, elixir-format
msgid "This event has been terminated"
msgstr "Az esemény befejeződött"
@@ -1216,7 +1217,7 @@ msgstr "Hozza létre következő prezentációját ezzel:"
#: lib/claper_web/live/event_live/manage.ex:23
#: lib/claper_web/live/event_live/presenter.ex:26
-#: lib/claper_web/live/event_live/show.ex:25
+#: lib/claper_web/live/event_live/show.ex:38
#, elixir-autogen, elixir-format
msgid "Event doesn't exist"
msgstr "Az esemény nem található"
@@ -1272,7 +1273,7 @@ msgid "Event manager"
msgstr "Eseménykezelő"
#: lib/claper_web/templates/layout/_user_menu.html.heex:19
-#: lib/claper_web/templates/layout/admin.html.heex:262
+#: lib/claper_web/templates/layout/admin.html.heex:278
#, elixir-autogen, elixir-format
msgid "Documentation"
msgstr "Dokumentáció"
@@ -1475,6 +1476,7 @@ msgid "Please enter a valid link starting with http:// or https://"
msgstr "Adjon meg egy http:// vagy https:// előtaggal kezdődő érvényes linket"
#: lib/claper/embeds/embed.ex:98
+#: lib/claper/embeds/embed.ex:122
#, elixir-autogen, elixir-format
msgid "Please enter valid HTML content with an iframe tag"
msgstr "Adjon meg érvényes HTML tartalmat iframe taggel"
@@ -1564,12 +1566,12 @@ msgstr "Befejezés"
msgid "More options"
msgstr "További lehetőségek"
-#: lib/claper_web/live/event_live/manage.ex:818
+#: lib/claper_web/live/event_live/manage.ex:824
#, elixir-autogen, elixir-format
msgid "No"
msgstr "Nem"
-#: lib/claper_web/live/event_live/manage.ex:818
+#: lib/claper_web/live/event_live/manage.ex:824
#, elixir-autogen, elixir-format
msgid "Yes"
msgstr "Igen"
@@ -1718,6 +1720,7 @@ msgstr "Új kvíz"
msgid "Presentation"
msgstr "Prezentáció"
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:34
#: lib/claper_web/live/event_live/manager_settings_component.ex:168
#, elixir-autogen, elixir-format
msgid "Previous"
@@ -1932,6 +1935,7 @@ msgstr ""
msgid "Account is confirmed and active"
msgstr ""
+#: lib/claper_web/components/core_components.ex:368
#: lib/claper_web/live/admin_live/event_live.html.heex:126
#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:108
#: lib/claper_web/live/admin_live/user_live.html.heex:111
@@ -2639,10 +2643,10 @@ msgstr "Szolgáltató"
msgid "Admin"
msgstr ""
-#: lib/claper_web/templates/layout/admin.html.heex:285
+#: lib/claper_web/templates/layout/admin.html.heex:301
#, elixir-autogen, elixir-format
msgid "Back to app"
-msgstr ""
+msgstr "Vissza az alkalmazáshoz"
#: lib/claper_web/templates/user_notifier/change.html.heex:17
#, elixir-autogen, elixir-format, fuzzy
@@ -2679,3 +2683,84 @@ msgstr "Kötelező"
#, elixir-autogen, elixir-format
msgid "(optional)"
msgstr "(opcionális)"
+
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:67
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:105
+#, elixir-autogen, elixir-format, fuzzy
+msgid "Action"
+msgstr "Művelet"
+
+#: lib/claper_web/live/admin_live/audit_log_live.ex:39
+#, elixir-autogen, elixir-format, fuzzy
+msgid "All actions"
+msgstr "Összes művelet"
+
+#: lib/claper_web/live/admin_live/audit_log_live.ex:50
+#, elixir-autogen, elixir-format
+msgid "Audit Log Details"
+msgstr "Auditnapló részletei"
+
+#: lib/claper_web/live/admin_live/audit_log_live.ex:24
+#: lib/claper_web/templates/layout/admin.html.heex:246
+#, elixir-autogen, elixir-format
+msgid "Audit Logs"
+msgstr "Auditnaplók"
+
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:66
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:99
+#, elixir-autogen, elixir-format
+msgid "ID"
+msgstr "Azonosító"
+
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:78
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:152
+#, elixir-autogen, elixir-format
+msgid "Metadata"
+msgstr "Metaadatok"
+
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:55
+#, elixir-autogen, elixir-format, fuzzy
+msgid "No results."
+msgstr "Nincsenek találatok."
+
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:145
+#, elixir-autogen, elixir-format
+msgid "Resource ID"
+msgstr "Erőforrás-azonosító"
+
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:137
+#, elixir-autogen, elixir-format, fuzzy
+msgid "Resource Type"
+msgstr "Erőforrás típusa"
+
+#: lib/claper_web/live/admin_live/audit_log_live.ex:33
+#, elixir-autogen, elixir-format
+msgid "Search by user email"
+msgstr "Keresés e-mail cím alapján"
+
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:73
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:130
+#, elixir-autogen, elixir-format
+msgid "Timestamp"
+msgstr "Időbélyeg"
+
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:70
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:111
+#, elixir-autogen, elixir-format, fuzzy
+msgid "User"
+msgstr "Felhasználó"
+
+#: lib/claper_web/components/core_components.ex:74
+#, elixir-autogen, elixir-format, fuzzy
+msgid "close"
+msgstr "bezárás"
+
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:88
+#, elixir-autogen, elixir-format
+msgid "View details for log #%{id}"
+msgstr "Az %{id}. napló részleteinek megtekintése"
+
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:119
+#, elixir-autogen, elixir-format
+msgid "View profile for %{email}"
+msgstr "Az %{email} profil megtekintése"
diff --git a/priv/gettext/it/LC_MESSAGES/default.po b/priv/gettext/it/LC_MESSAGES/default.po
index da913c4..b2c7675 100644
--- a/priv/gettext/it/LC_MESSAGES/default.po
+++ b/priv/gettext/it/LC_MESSAGES/default.po
@@ -19,7 +19,7 @@ msgstr "Impostazioni"
#: lib/claper_web/live/admin_live/user_live.html.heex:74
#: lib/claper_web/live/admin_live/user_live.html.heex:254
#: lib/claper_web/live/admin_live/user_live/form_component.ex:18
-#: lib/claper_web/live/event_live/manage.ex:838
+#: lib/claper_web/live/event_live/manage.ex:844
#: lib/claper_web/live/form_live/form_component.html.heex:32
#: lib/claper_web/live/user_settings_live/show.html.heex:34
#: lib/claper_web/templates/user_registration/new.html.heex:29
@@ -477,9 +477,9 @@ msgstr "Aggiungi interazione"
msgid "Blocking this user will delete all his messages and he will not be able to join again, confirm ?"
msgstr "Bloccando questo utente verranno eliminati tutti i suoi messaggi e non potrà più iscriversi, confermi?"
-#: lib/claper_web/live/event_live/show.ex:51
-#: lib/claper_web/live/event_live/show.ex:206
-#: lib/claper_web/live/event_live/show.ex:221
+#: lib/claper_web/live/event_live/show.ex:64
+#: lib/claper_web/live/event_live/show.ex:219
+#: lib/claper_web/live/event_live/show.ex:234
#, elixir-autogen, elixir-format
msgid "You have been banned from this event"
msgstr "Sei stato bandito da questo evento"
@@ -706,7 +706,7 @@ msgstr "I moduli compilati dai partecipanti appariranno qui."
#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:74
#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:254
#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:24
-#: lib/claper_web/live/event_live/manage.ex:837
+#: lib/claper_web/live/event_live/manage.ex:843
#, elixir-autogen, elixir-format
msgid "Name"
msgstr "Nome"
@@ -1069,6 +1069,7 @@ msgstr "Qui troverai tutte le interazioni dei tuoi partecipanti. Puoi gestire me
msgid "Identify users by their unique avatars."
msgstr "Identifica gli utenti tramite i loro avatar unici."
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:40
#: lib/claper_web/live/event_live/event_form_component.html.heex:5
#: lib/claper_web/live/event_live/index.html.heex:106
#: lib/claper_web/live/event_live/manage.html.heex:427
@@ -1195,7 +1196,7 @@ msgstr "Seleziona la tua presentazione (facoltativo)"
msgid "This code will be used by your attendees to access the event. You have the option to create a custom code."
msgstr "Questo codice verrà utilizzato dai tuoi partecipanti per accedere all'evento. Hai la possibilità di creare un codice personalizzato."
-#: lib/claper_web/live/event_live/show.ex:193
+#: lib/claper_web/live/event_live/show.ex:206
#, elixir-autogen, elixir-format
msgid "This event has been terminated"
msgstr "Questo evento è stato terminato"
@@ -1217,7 +1218,7 @@ msgstr "Crea la tua prossima presentazione con"
#: lib/claper_web/live/event_live/manage.ex:23
#: lib/claper_web/live/event_live/presenter.ex:26
-#: lib/claper_web/live/event_live/show.ex:25
+#: lib/claper_web/live/event_live/show.ex:38
#, elixir-autogen, elixir-format
msgid "Event doesn't exist"
msgstr "L'evento non esiste"
@@ -1273,7 +1274,7 @@ msgid "Event manager"
msgstr "Responsabile eventi"
#: lib/claper_web/templates/layout/_user_menu.html.heex:19
-#: lib/claper_web/templates/layout/admin.html.heex:262
+#: lib/claper_web/templates/layout/admin.html.heex:278
#, elixir-autogen, elixir-format
msgid "Documentation"
msgstr "Documentazione"
@@ -1476,6 +1477,7 @@ msgid "Please enter a valid link starting with http:// or https://"
msgstr "Inserisci un collegamento valido che inizia con http:// o https://"
#: lib/claper/embeds/embed.ex:98
+#: lib/claper/embeds/embed.ex:122
#, elixir-autogen, elixir-format
msgid "Please enter valid HTML content with an iframe tag"
msgstr "Inserisci un contenuto HTML valido con un tag iframe"
@@ -1565,12 +1567,12 @@ msgstr "Fine"
msgid "More options"
msgstr "Altre opzioni"
-#: lib/claper_web/live/event_live/manage.ex:818
+#: lib/claper_web/live/event_live/manage.ex:824
#, elixir-autogen, elixir-format
msgid "No"
msgstr "No"
-#: lib/claper_web/live/event_live/manage.ex:818
+#: lib/claper_web/live/event_live/manage.ex:824
#, elixir-autogen, elixir-format
msgid "Yes"
msgstr "Sì"
@@ -1719,6 +1721,7 @@ msgstr "Nuovo quiz"
msgid "Presentation"
msgstr "Presentazione"
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:34
#: lib/claper_web/live/event_live/manager_settings_component.ex:168
#, elixir-autogen, elixir-format
msgid "Previous"
@@ -1933,6 +1936,7 @@ msgstr "Un nome unico per identificare questo provider OIDC"
msgid "Account is confirmed and active"
msgstr "L'account è confermato e attivo"
+#: lib/claper_web/components/core_components.ex:368
#: lib/claper_web/live/admin_live/event_live.html.heex:126
#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:108
#: lib/claper_web/live/admin_live/user_live.html.heex:111
@@ -2640,7 +2644,7 @@ msgstr "Dettagli provider"
msgid "Admin"
msgstr "Admin"
-#: lib/claper_web/templates/layout/admin.html.heex:285
+#: lib/claper_web/templates/layout/admin.html.heex:301
#, elixir-autogen, elixir-format
msgid "Back to app"
msgstr "Torna all'app"
@@ -2680,3 +2684,84 @@ msgstr "Obbligatorio"
#, elixir-autogen, elixir-format
msgid "(optional)"
msgstr "(facoltativo)"
+
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:67
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:105
+#, elixir-autogen, elixir-format, fuzzy
+msgid "Action"
+msgstr "Azione"
+
+#: lib/claper_web/live/admin_live/audit_log_live.ex:39
+#, elixir-autogen, elixir-format, fuzzy
+msgid "All actions"
+msgstr "Tutte le azioni"
+
+#: lib/claper_web/live/admin_live/audit_log_live.ex:50
+#, elixir-autogen, elixir-format
+msgid "Audit Log Details"
+msgstr "Dettagli del registro di controllo"
+
+#: lib/claper_web/live/admin_live/audit_log_live.ex:24
+#: lib/claper_web/templates/layout/admin.html.heex:246
+#, elixir-autogen, elixir-format
+msgid "Audit Logs"
+msgstr "Registri di controllo"
+
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:66
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:99
+#, elixir-autogen, elixir-format
+msgid "ID"
+msgstr "ID"
+
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:78
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:152
+#, elixir-autogen, elixir-format
+msgid "Metadata"
+msgstr "Metadati"
+
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:55
+#, elixir-autogen, elixir-format, fuzzy
+msgid "No results."
+msgstr "Nessun risultato."
+
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:145
+#, elixir-autogen, elixir-format
+msgid "Resource ID"
+msgstr "ID risorsa"
+
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:137
+#, elixir-autogen, elixir-format, fuzzy
+msgid "Resource Type"
+msgstr "Tipo di risorsa"
+
+#: lib/claper_web/live/admin_live/audit_log_live.ex:33
+#, elixir-autogen, elixir-format
+msgid "Search by user email"
+msgstr ""
+
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:73
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:130
+#, elixir-autogen, elixir-format
+msgid "Timestamp"
+msgstr "Timestamp"
+
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:70
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:111
+#, elixir-autogen, elixir-format, fuzzy
+msgid "User"
+msgstr "Utente"
+
+#: lib/claper_web/components/core_components.ex:74
+#, elixir-autogen, elixir-format, fuzzy
+msgid "close"
+msgstr "chiudi"
+
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:88
+#, elixir-autogen, elixir-format
+msgid "View details for log #%{id}"
+msgstr "Visualizza i dettagli per il registro n. %{id}"
+
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:119
+#, elixir-autogen, elixir-format
+msgid "View profile for %{email}"
+msgstr "Visualizza ir profilo per %{email}"
diff --git a/priv/gettext/lv/LC_MESSAGES/default.po b/priv/gettext/lv/LC_MESSAGES/default.po
index 5c9f9b3..fd34656 100644
--- a/priv/gettext/lv/LC_MESSAGES/default.po
+++ b/priv/gettext/lv/LC_MESSAGES/default.po
@@ -18,7 +18,7 @@ msgstr "Iestatījumi"
#: lib/claper_web/live/admin_live/user_live.html.heex:74
#: lib/claper_web/live/admin_live/user_live.html.heex:254
#: lib/claper_web/live/admin_live/user_live/form_component.ex:18
-#: lib/claper_web/live/event_live/manage.ex:838
+#: lib/claper_web/live/event_live/manage.ex:844
#: lib/claper_web/live/form_live/form_component.html.heex:32
#: lib/claper_web/live/user_settings_live/show.html.heex:34
#: lib/claper_web/templates/user_registration/new.html.heex:29
@@ -477,9 +477,9 @@ msgstr "Pievienot mijiedarbību"
msgid "Blocking this user will delete all his messages and he will not be able to join again, confirm ?"
msgstr "Bloķējot šo lietotāju, tiks dzēsti visi lietotāja ziņojumi un viņš vairs nevarēs pievienoties, apstipriniet?"
-#: lib/claper_web/live/event_live/show.ex:51
-#: lib/claper_web/live/event_live/show.ex:206
-#: lib/claper_web/live/event_live/show.ex:221
+#: lib/claper_web/live/event_live/show.ex:64
+#: lib/claper_web/live/event_live/show.ex:219
+#: lib/claper_web/live/event_live/show.ex:234
#, elixir-autogen, elixir-format
msgid "You have been banned from this event"
msgstr "Jums ir aizliegts piedalīties šajā pasākumā"
@@ -709,7 +709,7 @@ msgstr "Dalībnieku iesniegtās veidlapas parādīsies šeit."
#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:74
#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:254
#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:24
-#: lib/claper_web/live/event_live/manage.ex:837
+#: lib/claper_web/live/event_live/manage.ex:843
#, elixir-autogen, elixir-format
msgid "Name"
msgstr "Nosaukums"
@@ -1072,6 +1072,7 @@ msgstr "Šeit atradīsiet visas dalībnieku mijiedarbības. Varat pārvaldīt zi
msgid "Identify users by their unique avatars."
msgstr "Identificēt lietotājus pēc viņu unikālajiem avatariem."
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:40
#: lib/claper_web/live/event_live/event_form_component.html.heex:5
#: lib/claper_web/live/event_live/index.html.heex:106
#: lib/claper_web/live/event_live/manage.html.heex:427
@@ -1198,7 +1199,7 @@ msgstr "Izvēlieties savu prezentāciju (pēc izvēles)"
msgid "This code will be used by your attendees to access the event. You have the option to create a custom code."
msgstr "Šo kodu dalībnieki izmantos, lai piekļūtu pasākumam. Jums ir iespēja izveidot pielāgotu kodu."
-#: lib/claper_web/live/event_live/show.ex:193
+#: lib/claper_web/live/event_live/show.ex:206
#, elixir-autogen, elixir-format
msgid "This event has been terminated"
msgstr "Šis notikums ir pārtraukts"
@@ -1220,7 +1221,7 @@ msgstr "Izveidojiet nākamo prezentāciju, izmantojot"
#: lib/claper_web/live/event_live/manage.ex:23
#: lib/claper_web/live/event_live/presenter.ex:26
-#: lib/claper_web/live/event_live/show.ex:25
+#: lib/claper_web/live/event_live/show.ex:38
#, elixir-autogen, elixir-format
msgid "Event doesn't exist"
msgstr "Notikums neeksistē"
@@ -1276,7 +1277,7 @@ msgid "Event manager"
msgstr "Pasākumu vadītājs"
#: lib/claper_web/templates/layout/_user_menu.html.heex:19
-#: lib/claper_web/templates/layout/admin.html.heex:262
+#: lib/claper_web/templates/layout/admin.html.heex:278
#, elixir-autogen, elixir-format
msgid "Documentation"
msgstr "Dokumentācija"
@@ -1479,6 +1480,7 @@ msgid "Please enter a valid link starting with http:// or https://"
msgstr "Lūdzu, ievadiet derīgu saiti, kas sākas ar http:// vai https://"
#: lib/claper/embeds/embed.ex:98
+#: lib/claper/embeds/embed.ex:122
#, elixir-autogen, elixir-format
msgid "Please enter valid HTML content with an iframe tag"
msgstr "Lūdzu, ievadiet derīgu HTML saturu ar iframe tagu"
@@ -1568,12 +1570,12 @@ msgstr "Izbeigt"
msgid "More options"
msgstr "Vairāk iespēju"
-#: lib/claper_web/live/event_live/manage.ex:818
+#: lib/claper_web/live/event_live/manage.ex:824
#, elixir-autogen, elixir-format
msgid "No"
msgstr "Nē"
-#: lib/claper_web/live/event_live/manage.ex:818
+#: lib/claper_web/live/event_live/manage.ex:824
#, elixir-autogen, elixir-format
msgid "Yes"
msgstr "Jā"
@@ -1722,6 +1724,7 @@ msgstr "Jauna viktorīna"
msgid "Presentation"
msgstr "Prezentācija"
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:34
#: lib/claper_web/live/event_live/manager_settings_component.ex:168
#, elixir-autogen, elixir-format
msgid "Previous"
@@ -1936,6 +1939,7 @@ msgstr ""
msgid "Account is confirmed and active"
msgstr ""
+#: lib/claper_web/components/core_components.ex:368
#: lib/claper_web/live/admin_live/event_live.html.heex:126
#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:108
#: lib/claper_web/live/admin_live/user_live.html.heex:111
@@ -2643,10 +2647,10 @@ msgstr "Nodrošinātājs"
msgid "Admin"
msgstr ""
-#: lib/claper_web/templates/layout/admin.html.heex:285
+#: lib/claper_web/templates/layout/admin.html.heex:301
#, elixir-autogen, elixir-format
msgid "Back to app"
-msgstr ""
+msgstr "Atpakaļ uz lietotni"
#: lib/claper_web/templates/user_notifier/change.html.heex:17
#, elixir-autogen, elixir-format, fuzzy
@@ -2683,3 +2687,84 @@ msgstr "Obligāti aizpildāms"
#, elixir-autogen, elixir-format
msgid "(optional)"
msgstr "(pēc izvēles)"
+
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:67
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:105
+#, elixir-autogen, elixir-format, fuzzy
+msgid "Action"
+msgstr "Darbība"
+
+#: lib/claper_web/live/admin_live/audit_log_live.ex:39
+#, elixir-autogen, elixir-format, fuzzy
+msgid "All actions"
+msgstr "Visas darbības"
+
+#: lib/claper_web/live/admin_live/audit_log_live.ex:50
+#, elixir-autogen, elixir-format
+msgid "Audit Log Details"
+msgstr "Audita žurnāla informācija"
+
+#: lib/claper_web/live/admin_live/audit_log_live.ex:24
+#: lib/claper_web/templates/layout/admin.html.heex:246
+#, elixir-autogen, elixir-format
+msgid "Audit Logs"
+msgstr "Audita žurnāli"
+
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:66
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:99
+#, elixir-autogen, elixir-format
+msgid "ID"
+msgstr "ID"
+
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:78
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:152
+#, elixir-autogen, elixir-format
+msgid "Metadata"
+msgstr "Metadati"
+
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:55
+#, elixir-autogen, elixir-format, fuzzy
+msgid "No results."
+msgstr "Nav rezultātu."
+
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:145
+#, elixir-autogen, elixir-format
+msgid "Resource ID"
+msgstr "Resursa ID"
+
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:137
+#, elixir-autogen, elixir-format, fuzzy
+msgid "Resource Type"
+msgstr "Resursa veids"
+
+#: lib/claper_web/live/admin_live/audit_log_live.ex:33
+#, elixir-autogen, elixir-format
+msgid "Search by user email"
+msgstr "Meklēt pēc e-pasta"
+
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:73
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:130
+#, elixir-autogen, elixir-format
+msgid "Timestamp"
+msgstr "Laika zīmogs"
+
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:70
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:111
+#, elixir-autogen, elixir-format, fuzzy
+msgid "User"
+msgstr "Lietotājs"
+
+#: lib/claper_web/components/core_components.ex:74
+#, elixir-autogen, elixir-format, fuzzy
+msgid "close"
+msgstr "aizvērt"
+
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:88
+#, elixir-autogen, elixir-format
+msgid "View details for log #%{id}"
+msgstr "Skatīt žurnāla Nr. %{id} informāciju"
+
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:119
+#, elixir-autogen, elixir-format
+msgid "View profile for %{email}"
+msgstr "Skatīt profilu %{email}"
diff --git a/priv/gettext/nl/LC_MESSAGES/default.po b/priv/gettext/nl/LC_MESSAGES/default.po
index 4a59930..6b39574 100644
--- a/priv/gettext/nl/LC_MESSAGES/default.po
+++ b/priv/gettext/nl/LC_MESSAGES/default.po
@@ -18,7 +18,7 @@ msgstr "Instellingen"
#: lib/claper_web/live/admin_live/user_live.html.heex:74
#: lib/claper_web/live/admin_live/user_live.html.heex:254
#: lib/claper_web/live/admin_live/user_live/form_component.ex:18
-#: lib/claper_web/live/event_live/manage.ex:838
+#: lib/claper_web/live/event_live/manage.ex:844
#: lib/claper_web/live/form_live/form_component.html.heex:32
#: lib/claper_web/live/user_settings_live/show.html.heex:34
#: lib/claper_web/templates/user_registration/new.html.heex:29
@@ -476,9 +476,9 @@ msgstr "Voeg interactie toe"
msgid "Blocking this user will delete all his messages and he will not be able to join again, confirm ?"
msgstr "Als je deze gebruiker blokkeert, worden al zijn berichten verwijderd en kan hij niet meer deelnemen. Bevestigen ?"
-#: lib/claper_web/live/event_live/show.ex:51
-#: lib/claper_web/live/event_live/show.ex:206
-#: lib/claper_web/live/event_live/show.ex:221
+#: lib/claper_web/live/event_live/show.ex:64
+#: lib/claper_web/live/event_live/show.ex:219
+#: lib/claper_web/live/event_live/show.ex:234
#, elixir-autogen, elixir-format
msgid "You have been banned from this event"
msgstr "Je bent uitgesloten van dit evenement"
@@ -705,7 +705,7 @@ msgstr "Formulierinzendingen van deelnemers worden hier weergegeven."
#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:74
#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:254
#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:24
-#: lib/claper_web/live/event_live/manage.ex:837
+#: lib/claper_web/live/event_live/manage.ex:843
#, elixir-autogen, elixir-format
msgid "Name"
msgstr "Naam"
@@ -1068,6 +1068,7 @@ msgstr "Hier vind je alle interacties van je bezoekers. Je kunt berichten, vastg
msgid "Identify users by their unique avatars."
msgstr "Identificeer gebruikers aan de hand van hun unieke avatars."
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:40
#: lib/claper_web/live/event_live/event_form_component.html.heex:5
#: lib/claper_web/live/event_live/index.html.heex:106
#: lib/claper_web/live/event_live/manage.html.heex:427
@@ -1194,7 +1195,7 @@ msgstr "Selecteer de presentatie (optioneel)"
msgid "This code will be used by your attendees to access the event. You have the option to create a custom code."
msgstr "Deze code wordt door je bezoekers gebruikt om toegang te krijgen tot het evenement. Je hebt de mogelijkheid om een aangepaste code aan te maken."
-#: lib/claper_web/live/event_live/show.ex:193
+#: lib/claper_web/live/event_live/show.ex:206
#, elixir-autogen, elixir-format
msgid "This event has been terminated"
msgstr "Dit evenement is gestopt"
@@ -1216,7 +1217,7 @@ msgstr "Maak je volgende presentatie met"
#: lib/claper_web/live/event_live/manage.ex:23
#: lib/claper_web/live/event_live/presenter.ex:26
-#: lib/claper_web/live/event_live/show.ex:25
+#: lib/claper_web/live/event_live/show.ex:38
#, elixir-autogen, elixir-format
msgid "Event doesn't exist"
msgstr "Evenement bestaat niet"
@@ -1272,7 +1273,7 @@ msgid "Event manager"
msgstr "Evenementmanager"
#: lib/claper_web/templates/layout/_user_menu.html.heex:19
-#: lib/claper_web/templates/layout/admin.html.heex:262
+#: lib/claper_web/templates/layout/admin.html.heex:278
#, elixir-autogen, elixir-format
msgid "Documentation"
msgstr "Documentatie"
@@ -1475,6 +1476,7 @@ msgid "Please enter a valid link starting with http:// or https://"
msgstr "Voer een geldige link in die begint met http:// of https://"
#: lib/claper/embeds/embed.ex:98
+#: lib/claper/embeds/embed.ex:122
#, elixir-autogen, elixir-format
msgid "Please enter valid HTML content with an iframe tag"
msgstr "Voer geldige HTML-inhoud in met een iframe-tag"
@@ -1564,12 +1566,12 @@ msgstr "Beëindigen"
msgid "More options"
msgstr "Meer opties"
-#: lib/claper_web/live/event_live/manage.ex:818
+#: lib/claper_web/live/event_live/manage.ex:824
#, elixir-autogen, elixir-format
msgid "No"
msgstr "Nee"
-#: lib/claper_web/live/event_live/manage.ex:818
+#: lib/claper_web/live/event_live/manage.ex:824
#, elixir-autogen, elixir-format
msgid "Yes"
msgstr "Ja"
@@ -1718,6 +1720,7 @@ msgstr "Nieuwe quiz"
msgid "Presentation"
msgstr "Presentatie"
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:34
#: lib/claper_web/live/event_live/manager_settings_component.ex:168
#, elixir-autogen, elixir-format
msgid "Previous"
@@ -1932,6 +1935,7 @@ msgstr "Een unieke naam om deze OIDC-aanbieder te identificeren"
msgid "Account is confirmed and active"
msgstr "Account is bevestigd en actief"
+#: lib/claper_web/components/core_components.ex:368
#: lib/claper_web/live/admin_live/event_live.html.heex:126
#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:108
#: lib/claper_web/live/admin_live/user_live.html.heex:111
@@ -2639,7 +2643,7 @@ msgstr "Aanbieder details"
msgid "Admin"
msgstr "Admin"
-#: lib/claper_web/templates/layout/admin.html.heex:285
+#: lib/claper_web/templates/layout/admin.html.heex:301
#, elixir-autogen, elixir-format
msgid "Back to app"
msgstr "Terug naar app"
@@ -2679,3 +2683,84 @@ msgstr "Verplicht"
#, elixir-autogen, elixir-format
msgid "(optional)"
msgstr "(optioneel)"
+
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:67
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:105
+#, elixir-autogen, elixir-format, fuzzy
+msgid "Action"
+msgstr "Actie"
+
+#: lib/claper_web/live/admin_live/audit_log_live.ex:39
+#, elixir-autogen, elixir-format, fuzzy
+msgid "All actions"
+msgstr "Alle acties"
+
+#: lib/claper_web/live/admin_live/audit_log_live.ex:50
+#, elixir-autogen, elixir-format
+msgid "Audit Log Details"
+msgstr "Details auditlogboek"
+
+#: lib/claper_web/live/admin_live/audit_log_live.ex:24
+#: lib/claper_web/templates/layout/admin.html.heex:246
+#, elixir-autogen, elixir-format
+msgid "Audit Logs"
+msgstr "Auditlogboeken"
+
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:66
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:99
+#, elixir-autogen, elixir-format
+msgid "ID"
+msgstr "ID"
+
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:78
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:152
+#, elixir-autogen, elixir-format
+msgid "Metadata"
+msgstr "Metadata"
+
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:55
+#, elixir-autogen, elixir-format, fuzzy
+msgid "No results."
+msgstr "Geen resultaten."
+
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:145
+#, elixir-autogen, elixir-format
+msgid "Resource ID"
+msgstr "Resource-ID"
+
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:137
+#, elixir-autogen, elixir-format, fuzzy
+msgid "Resource Type"
+msgstr "Resourcetype"
+
+#: lib/claper_web/live/admin_live/audit_log_live.ex:33
+#, elixir-autogen, elixir-format
+msgid "Search by user email"
+msgstr "Zoeken op e-mail"
+
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:73
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:130
+#, elixir-autogen, elixir-format
+msgid "Timestamp"
+msgstr "Tijdstempel"
+
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:70
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:111
+#, elixir-autogen, elixir-format, fuzzy
+msgid "User"
+msgstr "Gebruiker"
+
+#: lib/claper_web/components/core_components.ex:74
+#, elixir-autogen, elixir-format, fuzzy
+msgid "close"
+msgstr "sluiten"
+
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:88
+#, elixir-autogen, elixir-format
+msgid "View details for log #%{id}"
+msgstr "Bekijk details voor logboek #%{id}"
+
+#: lib/claper_web/live/admin_live/audit_log_live.html.heex:119
+#, elixir-autogen, elixir-format
+msgid "View profile for %{email}"
+msgstr "Bekijk profiel voor %{email}"
diff --git a/priv/repo/migrations/20260129165937_create_audit_logs.exs b/priv/repo/migrations/20260129165937_create_audit_logs.exs
new file mode 100644
index 0000000..85182f3
--- /dev/null
+++ b/priv/repo/migrations/20260129165937_create_audit_logs.exs
@@ -0,0 +1,19 @@
+defmodule Claper.Repo.Migrations.CreateAuditLogs do
+ use Ecto.Migration
+
+ def change do
+ create table(:audit_logs) do
+ add :action, :string, null: false
+ add :resource_type, :string
+ add :resource_id, :bigint
+ add :metadata, :map, default: %{}
+ add :user_id, references(:users, on_delete: :nilify_all)
+
+ timestamps(updated_at: false)
+ end
+
+ create index(:audit_logs, [:inserted_at])
+ create index(:audit_logs, [:action, :inserted_at])
+ create index(:audit_logs, [:user_id, :inserted_at])
+ end
+end
diff --git a/test/claper/audit_test.exs b/test/claper/audit_test.exs
new file mode 100644
index 0000000..410ca43
--- /dev/null
+++ b/test/claper/audit_test.exs
@@ -0,0 +1,89 @@
+defmodule Claper.AuditTest do
+ use Claper.DataCase
+
+ alias Claper.Audit
+
+ describe "audit_logs" do
+ alias Claper.Audit.Log
+
+ import Claper.AuditFixtures
+ import Claper.AccountsFixtures
+
+ @invalid_attrs %{action: nil}
+
+ test "list_logs/0 paginates all audit_logs" do
+ log = log_fixture()
+ {logs, _meta} = Audit.list_logs()
+ assert Enum.any?(logs, fn l -> l.id == log.id end)
+ end
+
+ test "get_log!/1 returns the log with given id" do
+ log = log_fixture()
+ fetched_log = Audit.get_log!(log.id)
+ assert fetched_log.id == log.id
+ assert fetched_log.action == log.action
+ end
+
+ test "create_log/1 with valid data creates a log" do
+ valid_attrs = %{
+ metadata: %{},
+ action: "some action",
+ resource_type: "some resource_type",
+ resource_id: 42
+ }
+
+ assert {:ok, %Log{} = log} = Audit.create_log(valid_attrs)
+ assert log.metadata == %{}
+ assert log.action == "some action"
+ assert log.resource_type == "some resource_type"
+ assert log.resource_id == 42
+ end
+
+ test "create_log/1 with invalid data returns error changeset" do
+ assert {:error, %Ecto.Changeset{}} = Audit.create_log(@invalid_attrs)
+ end
+
+ test "log_action/3 creates a log for a user" do
+ user = user_fixture()
+ metadata = %{ip_address: "127.0.0.1"}
+
+ assert {:ok, %Log{} = log} = Audit.log_action(user, "user.login", metadata)
+ assert log.user_id == user.id
+ assert log.action == "user.login"
+ assert log.metadata == metadata
+ end
+
+ test "log_action/3 creates a log without a user" do
+ metadata = %{reason: "system startup"}
+
+ assert {:ok, %Log{} = log} = Audit.log_action(nil, "system.startup", metadata)
+ assert log.user_id == nil
+ assert log.action == "system.startup"
+ assert log.metadata == metadata
+ end
+
+ test "log_resource_action/5 creates a log with resource info" do
+ user = user_fixture()
+ metadata = %{}
+
+ assert {:ok, %Log{} = log} =
+ Audit.log_resource_action(user, "event.create", "event", 123, metadata)
+
+ assert log.user_id == user.id
+ assert log.action == "event.create"
+ assert log.resource_type == "event"
+ assert log.resource_id == 123
+ end
+
+ test "list_action_types/0 returns distinct action types" do
+ log_fixture(%{action: "user.login"})
+ log_fixture(%{action: "user.login"})
+ log_fixture(%{action: "event.create"})
+
+ action_types = Audit.list_action_types()
+ assert "user.login" in action_types
+ assert "event.create" in action_types
+ assert length(action_types) == 2
+ end
+ end
+end
diff --git a/test/claper_web/helpers/conn_utils_test.exs b/test/claper_web/helpers/conn_utils_test.exs
new file mode 100644
index 0000000..7bd8151
--- /dev/null
+++ b/test/claper_web/helpers/conn_utils_test.exs
@@ -0,0 +1,29 @@
+defmodule ClaperWeb.Helpers.ConnUtilsTest do
+ use ClaperWeb.ConnCase, async: true
+
+ alias ClaperWeb.Helpers.ConnUtils
+
+ describe "get_client_ip/1" do
+ test "returns the remote_ip from the connection as a string" do
+ conn = build_conn() |> Map.put(:remote_ip, {93, 184, 216, 34})
+ assert ConnUtils.get_client_ip(conn) == "93.184.216.34"
+ end
+
+ test "handles IPv6 addresses" do
+ conn = build_conn() |> Map.put(:remote_ip, {8193, 3512, 0, 0, 0, 0, 0, 1})
+ assert ConnUtils.get_client_ip(conn) == "2001:db8::1"
+ end
+ end
+
+ describe "get_user_agent/1" do
+ test "returns the user agent header when present" do
+ conn = build_conn() |> put_req_header("user-agent", "Mozilla/5.0")
+ assert ConnUtils.get_user_agent(conn) == "Mozilla/5.0"
+ end
+
+ test "returns nil when no user agent header is present" do
+ conn = build_conn()
+ assert ConnUtils.get_user_agent(conn) == nil
+ end
+ end
+end
diff --git a/test/support/conn_case.ex b/test/support/conn_case.ex
index f1b830a..07a7ec3 100644
--- a/test/support/conn_case.ex
+++ b/test/support/conn_case.ex
@@ -36,10 +36,29 @@ defmodule ClaperWeb.ConnCase do
setup tags do
pid = Ecto.Adapters.SQL.Sandbox.start_owner!(Claper.Repo, shared: not tags[:async])
- on_exit(fn -> Ecto.Adapters.SQL.Sandbox.stop_owner(pid) end)
+
+ on_exit(fn ->
+ drain_task_supervisor(Claper.TaskSupervisor)
+ Ecto.Adapters.SQL.Sandbox.stop_owner(pid)
+ end)
+
{:ok, conn: Phoenix.ConnTest.build_conn()}
end
+ defp drain_task_supervisor(supervisor) do
+ supervisor
+ |> Task.Supervisor.children()
+ |> Enum.each(fn pid ->
+ ref = Process.monitor(pid)
+
+ receive do
+ {:DOWN, ^ref, :process, ^pid, _} -> :ok
+ after
+ 1_000 -> Process.demonitor(ref, [:flush])
+ end
+ end)
+ end
+
@doc """
Setup helper that registers and logs in users.
diff --git a/test/support/data_case.ex b/test/support/data_case.ex
index dad6a9b..e73c21b 100644
--- a/test/support/data_case.ex
+++ b/test/support/data_case.ex
@@ -32,12 +32,30 @@ defmodule Claper.DataCase do
# Don't check out a connection if a setup_all did so already
if context[:sandbox_owner_pid] == nil do
pid = Ecto.Adapters.SQL.Sandbox.start_owner!(Claper.Repo, shared: not context[:async])
- on_exit(fn -> Ecto.Adapters.SQL.Sandbox.stop_owner(pid) end)
+
+ on_exit(fn ->
+ drain_task_supervisor(Claper.TaskSupervisor)
+ Ecto.Adapters.SQL.Sandbox.stop_owner(pid)
+ end)
end
:ok
end
+ defp drain_task_supervisor(supervisor) do
+ supervisor
+ |> Task.Supervisor.children()
+ |> Enum.each(fn pid ->
+ ref = Process.monitor(pid)
+
+ receive do
+ {:DOWN, ^ref, :process, ^pid, _} -> :ok
+ after
+ 1_000 -> Process.demonitor(ref, [:flush])
+ end
+ end)
+ end
+
@doc """
A helper that transforms changeset errors into a map of messages.
diff --git a/test/support/fixtures/audit_fixtures.ex b/test/support/fixtures/audit_fixtures.ex
new file mode 100644
index 0000000..65d5d74
--- /dev/null
+++ b/test/support/fixtures/audit_fixtures.ex
@@ -0,0 +1,23 @@
+defmodule Claper.AuditFixtures do
+ @moduledoc """
+ This module defines test helpers for creating
+ entities via the `Claper.Audit` context.
+ """
+
+ @doc """
+ Generate a log.
+ """
+ def log_fixture(attrs \\ %{}) do
+ {:ok, log} =
+ attrs
+ |> Enum.into(%{
+ action: "some action",
+ metadata: %{},
+ resource_id: 42,
+ resource_type: "some resource_type"
+ })
+ |> Claper.Audit.create_log()
+
+ log
+ end
+end