feat: Accept follow requests
This commit is contained in:
parent
4bb55c08a5
commit
7824edbec0
6 changed files with 72 additions and 6 deletions
17
README.md
17
README.md
|
|
@ -1,10 +1,25 @@
|
|||
# Postland
|
||||
|
||||
## Backend
|
||||
|
||||
- [ ] Posting
|
||||
- [ ] Timeline
|
||||
- [ ] Deleting posts
|
||||
- [x] Following
|
||||
- [ ] Unfollowing
|
||||
- [ ] Being followed
|
||||
- [x] Being followed
|
||||
- [x] Accepting follows
|
||||
- [ ] Liking
|
||||
- [ ] Unliking
|
||||
|
||||
## UX
|
||||
|
||||
- [ ] Posting
|
||||
- [ ] Timeline
|
||||
- [ ] Deleting posts
|
||||
- [x] Following
|
||||
- [ ] Unfollowing
|
||||
- [x] Being followed
|
||||
- [ ] Accepting follows
|
||||
- [ ] Liking
|
||||
- [ ] Unliking
|
||||
|
|
|
|||
|
|
@ -52,11 +52,9 @@ defmodule ActivityPub.Headers do
|
|||
end
|
||||
|
||||
def verify(method, path, headers, actor_fetcher \\ &fetch_actor_key/1) do
|
||||
dbg(headers)
|
||||
|
||||
{_key, signature_header} = Enum.find(headers, fn {key, _} -> key == "signature" end)
|
||||
|
||||
signature_kv = SignatureSplitter.split(signature_header) |> dbg()
|
||||
signature_kv = SignatureSplitter.split(signature_header)
|
||||
key_id = find_value(signature_kv, "keyId")
|
||||
signature = signature_kv |> find_value("signature") |> Base.decode64!()
|
||||
signing_text_headers = signature_kv |> find_value("headers") |> String.split(" ")
|
||||
|
|
|
|||
|
|
@ -28,7 +28,6 @@ defmodule Postland.Activities do
|
|||
|
||||
actor_id = case Regex.run(pattern, follow_id) do
|
||||
[_, encoded_actor_id] ->
|
||||
dbg(encoded_actor_id)
|
||||
Base.url_decode64!(encoded_actor_id, padding: false)
|
||||
|
||||
_other ->
|
||||
|
|
|
|||
|
|
@ -12,13 +12,15 @@ defmodule Postland.Activity do
|
|||
|
||||
def changeset(attrs) do
|
||||
attrs = %{
|
||||
"id" => Map.get(attrs, "id", Ecto.UUID.autogenerate()),
|
||||
"actor_id" => Map.get(attrs, "actor"),
|
||||
"type" => Map.get(attrs, "type"),
|
||||
"data" => attrs
|
||||
}
|
||||
|
||||
%__MODULE__{}
|
||||
|> cast(attrs, [:actor_id, :type, :data])
|
||||
|> cast(attrs, [:id, :actor_id, :type, :data])
|
||||
|> validate_required(:id)
|
||||
|> validate_required(:data)
|
||||
|> validate_required(:type)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -4,12 +4,55 @@ defmodule Postland.Follows do
|
|||
import Ecto.Query, warn: false
|
||||
|
||||
alias Postland.Accounts
|
||||
alias Postland.Activity
|
||||
alias Postland.Follow
|
||||
alias Postland.Repo
|
||||
alias ActivityPub.Headers
|
||||
|
||||
alias Ecto.Multi
|
||||
|
||||
def record_and_send_acceptance(request) do
|
||||
Multi.new()
|
||||
|> Multi.run(:confirm_timestamp, fn _data, _repo -> confirm_request(request) end)
|
||||
|> Multi.run(:send_acceptance, fn _data, _repo ->
|
||||
send_acceptance(request)
|
||||
end)
|
||||
|> Repo.transaction()
|
||||
end
|
||||
|
||||
def send_acceptance(request) do
|
||||
{:ok, actor} = ActivityPub.fetch_actor(request.follower)
|
||||
inbox = Map.get(actor, "inbox")
|
||||
|
||||
case get_follow_activity(request.follower) do
|
||||
nil ->
|
||||
{:error, "could not find Follow activity to Accept"}
|
||||
|
||||
follow_activity ->
|
||||
body =
|
||||
%{
|
||||
"@context" => "https://www.w3.org/ns/activitystreams",
|
||||
"type" => "Accept",
|
||||
"actor" => Postland.my_actor_id(),
|
||||
"object" => %{
|
||||
"actor" => request.follower,
|
||||
"id" => Map.get(follow_activity.data, "id"),
|
||||
"object" => Postland.my_actor_id(),
|
||||
"type" => "Follow"
|
||||
}
|
||||
}
|
||||
|> Jason.encode!()
|
||||
|
||||
headers = Headers.signing_headers("POST", inbox, body, Postland.my_actor_id(), Accounts.solo_user().private_key)
|
||||
|
||||
Req.post(inbox, headers: headers, body: body)
|
||||
end
|
||||
end
|
||||
|
||||
def get_follow_activity(follower) do
|
||||
from(a in Activity, where: a.type == "Follow", where: a.actor_id == ^follower, limit: 1, order_by: [desc: :inserted_at]) |> Repo.one()
|
||||
end
|
||||
|
||||
def record_and_send_follow_request(to_actor_id) do
|
||||
Multi.new()
|
||||
|> Multi.run(:follow_record, fn _data, _repo -> record_outbound_request(to_actor_id) end)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,9 @@
|
|||
defmodule Postland.Repo.Migrations.AddTimestampsToActivities do
|
||||
use Ecto.Migration
|
||||
|
||||
def change do
|
||||
alter table("activities") do
|
||||
timestamps()
|
||||
end
|
||||
end
|
||||
end
|
||||
Loading…
Reference in a new issue