diff --git a/lib/federator/transformer.ex b/lib/federator/transformer.ex index 0065258..81b83d1 100644 --- a/lib/federator/transformer.ex +++ b/lib/federator/transformer.ex @@ -90,7 +90,7 @@ defmodule ActivityPub.Federator.Transformer do end defp prepare_outgoing_object(object) do - case Object.normalize(object, true) do + case Object.normalize(object, false) do %Object{} = object -> prepare_outgoing_object(object) @@ -104,8 +104,8 @@ defmodule ActivityPub.Federator.Transformer do object else error(other, "Unexpected normalised object") - debug(object, "Non-normalised object") - nil + debug(object, "Just return the non-normalised object") + object end end end diff --git a/lib/web/controllers/activity_pub_controller.ex b/lib/web/controllers/activity_pub_controller.ex index 9f79090..4ba482f 100644 --- a/lib/web/controllers/activity_pub_controller.ex +++ b/lib/web/controllers/activity_pub_controller.ex @@ -240,6 +240,21 @@ defmodule ActivityPub.Web.ActivityPubController do |> put_resp_content_type("application/activity+json") |> put_view(ObjectView) |> render("outbox.json", %{actor: actor}) + else + e -> + Utils.error_json(conn, "Invalid actor", 500) + end + end + + def outbox(conn, _) do + with true <- Config.env() != :prod do + conn + |> put_resp_content_type("application/activity+json") + |> put_view(ObjectView) + |> render("outbox.json", %{outbox: :shared_outbox}) + else + e -> + Utils.error_json(conn, "Not allowed", 400) end end diff --git a/lib/web/controllers/incoming_activity_pub_controller.ex b/lib/web/controllers/incoming_activity_pub_controller.ex index aed04cd..350f3dd 100644 --- a/lib/web/controllers/incoming_activity_pub_controller.ex +++ b/lib/web/controllers/incoming_activity_pub_controller.ex @@ -57,6 +57,14 @@ defmodule ActivityPub.Web.IncomingActivityPubController do end end + def outbox_info(conn, params) do + if Config.federating?() do + Utils.error_json(conn, "this API path only accepts GET requests", 403) + else + Utils.error_json(conn, "this instance is not currently federating", 403) + end + end + defp apply_process(conn, %{"type" => "Delete"} = params, fun) do # TODO: check if the actor/object being deleted is even known locally before bothering? #  workaround in case the remote actor is not yet actually deleted diff --git a/lib/web/router.ex b/lib/web/router.ex index 1da63e3..e05f403 100644 --- a/lib/web/router.ex +++ b/lib/web/router.ex @@ -49,6 +49,8 @@ defmodule ActivityPub.Web.Router do get("/actors/:username/followers", ActivityPubController, :followers) get("/actors/:username/following", ActivityPubController, :following) get("/actors/:username/outbox", ActivityPubController, :outbox) + # return error saying only POST supported + get("/actors/:username/inbox", IncomingActivityPubController, :inbox_info) pipe_through(:activity_json_or_html) @@ -60,9 +62,35 @@ defmodule ActivityPub.Web.Router do # note: singular is not canonical get("/actor/:username", ActivityPubController, :actor) + # maybe return the public outbox + get("/shared_outbox", ActivityPubController, :outbox) + # return error saying only POST supported get("/shared_inbox", IncomingActivityPubController, :inbox_info) end + scope "/", ActivityPub.Web do + pipe_through(:activity_json) + pipe_through(:signed_activity_pub_fetch) + + pipe_through(:activity_json_or_html) + + # URLs for interop with Mastodon clients / AP testing tools + # get("/api/v1/timelines/public", ActivityPubController, :outbox) # maybe return the public outbox + get("/users/:username", ActivityPubController, :actor) + end + + scope "/", ActivityPub.Web do + pipe_through(:activity_json) + + pipe_through(:signed_activity_pub_incoming) + + # URLs for interop with Mastodon clients / AP testing tools + post("/users/:username", IncomingActivityPubController, :inbox) + post("/users/:username/inbox", IncomingActivityPubController, :inbox) + # return error saying only POST supported - TODO: implement this for AP C2S API + post("/users/:username/outbox", IncomingActivityPubController, :outbox_info) + end + scope unquote(ap_base_path), ActivityPub.Web do pipe_through(:activity_json) pipe_through(:signed_activity_pub_incoming) diff --git a/lib/web/views/object_view.ex b/lib/web/views/object_view.ex index 51bc278..9e646d9 100644 --- a/lib/web/views/object_view.ex +++ b/lib/web/views/object_view.ex @@ -30,7 +30,7 @@ defmodule ActivityPub.Web.ObjectView do %{ "id" => "#{actor.ap_id}/outbox", - "type" => "Collection", + "type" => "OrderedCollection", "first" => collection(outbox, "#{actor.ap_id}/outbox", 1, total), "totalItems" => total } @@ -39,16 +39,16 @@ defmodule ActivityPub.Web.ObjectView do # only for testing purposes def render("outbox.json", %{outbox: :shared_outbox} = params) do - instance = ActivityPub.Web.base_url() + ap_base_url = Utils.ap_base_url() page = params[:page] || 1 outbox = Object.get_outbox_for_instance() total = length(outbox) %{ - "id" => "#{instance}/shared_outbox", - "type" => "Collection", - "first" => collection(outbox, "#{instance}/shared_outbox", page, total), + "id" => "#{ap_base_url}/shared_outbox", + "type" => "OrderedCollection", + "first" => collection(outbox, "#{ap_base_url}/shared_outbox", page, total), "totalItems" => total } |> Map.merge(Utils.make_json_ld_header(:object))