Packages

Official Elixir SDK for Coffrify, encrypted file-transfer infrastructure: transfers, webhooks (Standard Webhooks v2), API keys, audit, vaults and 30+ resources, with retry policies, circuit breaker, rate limiter, idempotency and Phoenix/Plug helpers.

Current section

Files

Jump to
coffrify lib coffrify resources audit.ex
Raw

lib/coffrify/resources/audit.ex

defmodule Coffrify.Resources.Audit do
@moduledoc "Audit log — every privileged action in the workspace."
alias Coffrify
alias Coffrify.Runtime.Paginate
@type list_opts :: [
action: String.t(),
actor_id: String.t(),
resource_type: String.t(),
since: String.t() | DateTime.t(),
until: String.t() | DateTime.t(),
limit: pos_integer(),
offset: non_neg_integer()
]
@doc "List audit entries (most recent first)."
@spec list(Coffrify.t(), list_opts()) :: {:ok, map()} | {:error, Exception.t()}
def list(client, opts \\ []) do
Coffrify.request(client, :get, "/audit", nil, query: serialize_query(opts))
end
@doc "Lazy `Stream` over every audit entry."
@spec iterate(Coffrify.t(), keyword()) :: Enumerable.t()
def iterate(client, opts \\ []) do
page_size = opts |> Keyword.get(:page_size, 100) |> min(500) |> max(1)
limit = Keyword.get(opts, :max_items, :infinity)
base_query = opts |> Keyword.drop([:page_size, :max_items]) |> serialize_query()
Paginate.paginate(
fn page_opts ->
query =
base_query
|> Keyword.put(:limit, page_opts[:limit])
|> Keyword.put(:cursor, page_opts[:cursor])
|> Enum.reject(fn {_k, v} -> is_nil(v) end)
case Coffrify.request(client, :get, "/audit", nil, query: query) do
{:ok, page} -> normalize_page(page)
{:error, _} -> %{data: []}
end
end,
page_size: page_size,
limit: limit,
mode: :cursor
)
end
@doc "Trigger an audit export — returns a presigned URL."
@spec export(Coffrify.t(), keyword()) :: {:ok, map()} | {:error, Exception.t()}
def export(client, opts \\ []) do
body = %{
format: Keyword.get(opts, :format, "json"),
since: serialize_date(Keyword.get(opts, :since)),
until: serialize_date(Keyword.get(opts, :until))
}
Coffrify.request(client, :post, "/audit/export", body)
end
defp serialize_query(opts) do
opts
|> Enum.map(fn
{k, %DateTime{} = dt} -> {k, DateTime.to_iso8601(dt)}
{k, %Date{} = d} -> {k, Date.to_iso8601(d)}
{k, v} -> {k, v}
end)
end
defp serialize_date(%DateTime{} = dt), do: DateTime.to_iso8601(dt)
defp serialize_date(%Date{} = d), do: Date.to_iso8601(d)
defp serialize_date(other), do: other
defp normalize_page(%{"entries" => data} = page),
do: %{data: data, has_more: Map.get(page, "has_more"), next_cursor: Map.get(page, "next_cursor")}
defp normalize_page(%{"data" => data} = page),
do: %{data: data, has_more: Map.get(page, "has_more"), next_cursor: Map.get(page, "next_cursor")}
defp normalize_page(_other), do: %{data: [], has_more: false}
end