defmodule NullaWeb.InboxController do use NullaWeb, :controller alias Nulla.HTTPSignature alias Nulla.ActivityPub alias Nulla.Utils alias Nulla.Models.Actor alias Nulla.Models.Relation alias Nulla.Models.Activity def inbox( conn, %{"id" => follow_id, "type" => "Follow", "actor" => actor_uri, "object" => target_uri} ) do with {:ok, local_actor} <- Utils.resolve_local_actor(target_uri), {:ok, remote_actor_json} <- Utils.fetch_remote_actor(actor_uri), :ok <- HTTPSignature.verify(conn, remote_actor_json), remote_actor <- Actor.create_actor( remote_actor_json |> Map.put("ap_id", remote_actor_json["id"]) |> Map.delete("id") |> Map.put("domain", URI.parse(remote_actor_json["id"]).host) ), follow_activity <- Activity.create_activity(%{ ap_id: follow_id, type: "Follow", actor: remote_actor.id, object: target_uri }), accept_activity <- Activity.create_activity(%{ type: "Accept", actor: local_actor.id, object: follow_activity }), _ <- Relation.create_relation(%{ followed_by: true, local_actor_id: local_actor.id, remote_actor_id: remote_actor.id }) do conn |> put_resp_content_type("application/activity+json") |> send_resp( 200, Jason.encode!(ActivityPub.follow_accept(accept_activity)) ) else error -> IO.inspect(error, label: "Follow error") json(conn, %{"error" => "Failed to process Follow"}) end end end