Initial commit on Forgejo
All checks were successful
CI and deploy / Test (push) Successful in 4m52s
CI and deploy / Deploy production (push) Successful in 23s

Fresh repository history for elektrine/tarakan hosted at
https://git.elektrine.com/elektrine/tarakan.
This commit is contained in:
Maxfield Luke 2026-07-29 04:43:40 -04:00
commit af6077b9c3
455 changed files with 78366 additions and 0 deletions

View file

@ -0,0 +1,89 @@
defmodule TarakanWeb.ModerationReportLive.New do
use TarakanWeb, :live_view
alias Tarakan.Moderation
@subject_options [
{"Repository", "repository"},
{"Account", "account"},
{"Scan", "scan"},
{"Finding", "finding"},
{"Job", "review_task"},
{"Contribution", "contribution"}
]
@reason_options [
{"Spam", "spam"},
{"Unsafe disclosure", "unsafe_disclosure"},
{"Harassment", "harassment"},
{"Plagiarism", "plagiarism"},
{"Malicious instructions", "malicious_instructions"},
{"Fabricated evidence", "fabricated_evidence"},
{"Secrets or personal data", "secrets_or_pii"},
{"Other", "other"}
]
@impl true
def mount(params, _session, socket) do
{:ok,
socket
|> assign(:page_title, "Report content")
|> assign(:subject_options, @subject_options)
|> assign(:reason_options, @reason_options)
|> assign(:form, report_form(initial_params(params)))}
end
@impl true
def handle_event("submit", %{"report" => attrs}, socket) do
case Moderation.report(socket.assigns.current_scope, attrs) do
{:ok, case_record} ->
{:noreply,
socket
|> put_flash(:info, "Report submitted for restricted moderator review.")
|> push_navigate(to: ~p"/moderation/cases/#{case_record.id}")}
{:error, %Ecto.Changeset{} = changeset} ->
{:noreply, assign(socket, :form, to_form(changeset, as: :report))}
error ->
{:noreply,
socket
|> assign(:form, report_form(attrs))
|> put_flash(:error, error_message(error))}
end
end
def handle_event("submit", _params, socket) do
{:noreply, put_flash(socket, :error, "Complete the report before submitting it.")}
end
defp initial_params(params) do
%{
"subject_type" => query_value(params, "subject_type", "repository"),
"subject_id" => query_value(params, "subject_id", ""),
"reason" => query_value(params, "reason", "unsafe_disclosure"),
"description" => ""
}
end
defp query_value(params, key, default) do
case Map.get(params, key) do
value when is_binary(value) -> value
_other -> default
end
end
defp report_form(attrs), do: to_form(attrs, as: :report)
defp error_message({:error, :rate_limited}),
do: "You have reached the daily report limit. Try again later."
defp error_message({:error, :subject_not_found}),
do: "That content could not be found or is not visible to your account."
defp error_message({:error, :unauthorized}),
do: "Your account is not authorized to submit this report."
defp error_message({:error, :invalid_report}), do: "The report is incomplete."
defp error_message({:error, _reason}), do: "The report could not be submitted."
end

View file

@ -0,0 +1,70 @@
<Layouts.app flash={@flash} current_scope={@current_scope} current_path={assigns[:current_path]}>
<Layouts.page>
<.breadcrumbs>
<:crumb navigate={~p"/"}>registry</:crumb>
<:crumb>report</:crumb>
</.breadcrumbs>
<main id="moderation-report" class="border-2 border-strong">
<header class="border-b-2 border-strong bg-panel px-5 py-6 sm:px-8 sm:py-8">
<h1 class="font-display text-3xl uppercase tracking-[0.02em] text-ink sm:text-4xl">
Report content
</h1>
<p class="mt-3 max-w-2xl text-sm leading-6 text-ink-muted">
Flag unsafe, abusive, or fabricated material for restricted review.
</p>
</header>
<section class="px-5 py-6 sm:px-8 sm:py-8">
<.form for={@form} id="moderation-report-form" phx-submit="submit">
<div class="grid gap-4 sm:grid-cols-[minmax(0,1fr)_minmax(0,1fr)]">
<.input
field={@form[:subject_type]}
type="select"
label="Content type"
options={@subject_options}
/>
<.input
field={@form[:subject_id]}
type="number"
min="1"
label="Content ID"
placeholder="123"
/>
</div>
<div class="mt-4">
<.input
field={@form[:reason]}
type="select"
label="Reason"
options={@reason_options}
/>
</div>
<div class="mt-4">
<.input
field={@form[:description]}
type="textarea"
label="What should moderators review?"
minlength="10"
maxlength="5000"
rows="8"
placeholder="Describe the specific problem and where it appears. Do not include secrets or unnecessary personal data."
/>
</div>
<div class="mt-6 flex justify-end border-t border-rule pt-5">
<button
id="submit-moderation-report"
type="submit"
class="clip-notch bg-btn px-5 py-2.5 font-display text-xs uppercase tracking-[0.12em] text-btn-fg transition hover:opacity-90 phx-submit-loading:opacity-60"
>
Submit report
</button>
</div>
</.form>
</section>
</main>
</Layouts.page>
</Layouts.app>