diff --git a/lib/nulla/activitypub.ex b/lib/nulla/activitypub.ex index 0787fc5..21f5507 100644 --- a/lib/nulla/activitypub.ex +++ b/lib/nulla/activitypub.ex @@ -349,15 +349,4 @@ defmodule Nulla.ActivityPub do ) ) end - - @spec follow_accept(Activity.t()) :: Jason.OrderedObject.t() - def follow_accept(activity) do - Jason.OrderedObject.new( - "@context": "https://www.w3.org/ns/activitystreams", - id: activity.ap_id, - type: activity.type, - actor: activity.actor, - object: activity.object - ) - end end diff --git a/lib/nulla_web/controllers/inbox_controller.ex b/lib/nulla_web/controllers/inbox_controller.ex index a58ffec..2ca8159 100644 --- a/lib/nulla_web/controllers/inbox_controller.ex +++ b/lib/nulla_web/controllers/inbox_controller.ex @@ -22,14 +22,14 @@ defmodule NullaWeb.InboxController do |> Map.put("domain", URI.parse(remote_actor_json["id"]).host) ), follow_activity <- - Activity.create_activity(%{ + Activity.activity(%{ ap_id: follow_id, type: "Follow", actor: remote_actor.id, object: target_uri }), accept_activity <- - Activity.create_activity(%{ + Activity.activity(%{ type: "Accept", actor: local_actor.ap_id, object: follow_activity @@ -40,12 +40,57 @@ defmodule NullaWeb.InboxController do local_actor_id: local_actor.id, remote_actor_id: remote_actor.id }) do + body = Jason.encode!(ActivityPub.follow_accept(accept_activity)) + + digest = + :crypto.hash(:sha256, body) + |> Base.encode64() + |> then(&("SHA-256=" <> &1)) + + date = + DateTime.utc_now() + |> Calendar.strftime("%a, %d %b %Y %H:%M:%S GMT") + + host = URI.parse(actor_uri).host + request_target = "post /inbox" + + signature_string = + """ + (request-target): #{request_target} + host: #{host} + date: #{date} + digest: #{digest} + """ + + user = User.get_user(id: local_actor.id) + privateKeyPem = user.privateKey["privateKeyPem"] + + private_key = + :public_key.pem_decode(local_actor.private_key_pem) + |> hd() + |> :public_key.pem_entry_decode() + + signature = + :public_key.sign(signature_string, :sha256, private_key) + |> Base.encode64() + + signature_header = + """ + keyId="#{local_actor.publicKey["id"]}", + algorithm="rsa-sha256", + headers="(request-target) host date digest content-type", + signature="#{signature}" + """ + |> String.replace("\n", "") + |> String.trim() + conn |> put_resp_content_type("application/activity+json") - |> send_resp( - 200, - Jason.encode!(ActivityPub.follow_accept(accept_activity)) - ) + |> put_resp_header("host", host) + |> put_resp_header("date", date) + |> put_resp_header("signature", signature_header) + |> put_resp_header("digest", digest) + |> send_resp(200, body) else error -> IO.inspect(error, label: "Follow error")