prop/lib/microwaveprop_web/controllers/api/v1/profile_controller.ex
Graham McIntire 0704253af8
fix(security,test): viewer-aware profile queries + create_contact ordering + valkey test isolation
- /u/:callsign profile no longer leaks private contacts or pending beacons;
  Radio.list_contacts_for_user/2 and Beacons.list_beacons_for_user/2 now
  filter by viewer (owner/admin see everything, others see only public).
- Radio.create_contact/2 places user_id on the struct before
  submission_changeset so validate_user_or_email/1 accepts authenticated
  submissions that omit submitter_email.
- valkey_test.exs runs async: false; its setup mutates global Application
  env and Process registry, which otherwise crashed concurrent ConnCase
  GridCache.clear/0 calls (Mox.UnexpectedCallError on SCAN).
2026-05-12 08:49:08 -05:00

32 lines
1,014 B
Elixir

defmodule MicrowavepropWeb.Api.V1.ProfileController do
@moduledoc "Public per-callsign user profile (no email exposed)."
use Phoenix.Controller, formats: [:json]
alias Microwaveprop.Accounts
alias Microwaveprop.Beacons
alias Microwaveprop.Radio
alias MicrowavepropWeb.Api.ErrorJSON
alias MicrowavepropWeb.Api.V1.BeaconJSON
alias MicrowavepropWeb.Api.V1.ContactJSON
alias MicrowavepropWeb.Api.V1.UserJSON
plug :accepts, ["json"]
def show(conn, %{"callsign" => callsign}) do
case Accounts.get_user_by_callsign(callsign) do
nil ->
ErrorJSON.send_problem(conn, 404, "not_found", "Callsign not registered.")
user ->
contacts = Radio.list_contacts_involving_callsign(user.callsign)
beacons = Beacons.list_beacons_for_user(user)
json(conn, %{
user: UserJSON.public(user).data,
contacts: ContactJSON.index(%{contacts: contacts}).data,
beacons: BeaconJSON.index(%{beacons: beacons}).data
})
end
end
end