diff --git a/README.md b/README.md
index 1074593fce..0a907902e2 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-`pl` is my personal fork of Pleroma that I use on my single-user instance.
+Pleroma by mkljczk is a fork of Pleroma I'm developing for personal use.
Added features:
@@ -28,9 +28,9 @@ Features not authored by me:
There might be more, it's hard to keep track of it. I'm trying to keep the fork as close to upstream and I hope the list will eventually get much shorter.
**DISCLAIMER:**
-Although `pl` *just works* for me, I cannot guarantee that it'll work well for you. There might be bugs I simply don't care about or I might decide to abandon the project one day.
+Although Pleroma by mkljczk *just works* for me, I cannot guarantee that it'll work well for you. There might be bugs I simply don't care about or I might decide to abandon the project one day.
-It should be possible to migrate from Pleroma or Rebased to `pl` without issues. It is recommended to use `pl` with [`pl-fe`](https://github.com/mkljczk/pl-fe/tree/develop/packages/pl-fe) for full feature compatibility, but pleroma-fe and other frontends work fine too.
+It should be possible to migrate from Pleroma or Rebased to Pleroma by mkljczk without issues. It is recommended to use Pleroma by mkljczk with [`pl-fe`](https://github.com/mkljczk/pl-fe/tree/develop/packages/pl-fe) for full feature compatibility, but pleroma-fe and other frontends work fine too.
---
diff --git a/changelog.d/debian-install-improve.skip b/changelog.d/debian-install-improve.skip
new file mode 100644
index 0000000000..6068a30664
--- /dev/null
+++ b/changelog.d/debian-install-improve.skip
@@ -0,0 +1 @@
+Fixed a formatting issue that had a required commend embedded in a textblock, and change the language to make it a bit more idiomatic.
\ No newline at end of file
diff --git a/config/config.exs b/config/config.exs
index 776c5eef28..80ea57ddd2 100644
--- a/config/config.exs
+++ b/config/config.exs
@@ -747,7 +747,8 @@
events_actions: {10_000, 15},
password_reset: {1_800_000, 5},
account_confirmation_resend: {8_640_000, 5},
- ap_routes: {60_000, 15}
+ ap_routes: {60_000, 15},
+ bites: {10_000, 10}
config :pleroma, Pleroma.Workers.PurgeExpiredActivity, enabled: true, min_lifetime: 600
diff --git a/docs/installation/debian_based_en.md b/docs/installation/debian_based_en.md
index b61e4addd6..21cfe2bff3 100644
--- a/docs/installation/debian_based_en.md
+++ b/docs/installation/debian_based_en.md
@@ -69,12 +69,18 @@ cd /opt/pleroma
sudo -Hu pleroma mix deps.get
```
-* Generate the configuration: `sudo -Hu pleroma MIX_ENV=prod mix pleroma.instance gen`
+* Generate the configuration:
+
+```shell
+sudo -Hu pleroma MIX_ENV=prod mix pleroma.instance gen`
+```
+
+* During this process:
* Answer with `yes` if it asks you to install `rebar3`.
* This may take some time, because parts of pleroma get compiled first.
* After that it will ask you a few questions about your instance and generates a configuration file in `config/generated_config.exs`.
-* Check the configuration and if all looks right, rename it, so Pleroma will load it (`prod.secret.exs` for productive instance, `dev.secret.exs` for development instances):
+* Check the configuration and if all looks right, rename it, so Pleroma will load it (`prod.secret.exs` for production instances, `dev.secret.exs` for development instances):
```shell
sudo -Hu pleroma mv config/{generated_config.exs,prod.secret.exs}
diff --git a/lib/pleroma/constants.ex b/lib/pleroma/constants.ex
index 5894ece22a..f8a6d24f34 100644
--- a/lib/pleroma/constants.ex
+++ b/lib/pleroma/constants.ex
@@ -116,7 +116,10 @@ defmodule Pleroma.Constants do
"Announce",
"Undo",
"Flag",
- "EmojiReact"
+ "EmojiReact",
+ "Bite",
+ "Join",
+ "Leave"
]
)
diff --git a/lib/pleroma/object/updater.ex b/lib/pleroma/object/updater.ex
index 8fd7da0a42..27c315acb3 100644
--- a/lib/pleroma/object/updater.ex
+++ b/lib/pleroma/object/updater.ex
@@ -5,6 +5,7 @@
defmodule Pleroma.Object.Updater do
require Pleroma.Constants
+ alias Pleroma.Maps
alias Pleroma.Object
alias Pleroma.Repo
alias Pleroma.Workers.EventReminderWorker
@@ -116,6 +117,7 @@ defp maybe_update_poll(to_be_updated, updated_object) do
# Choices are the same, but counts are different
to_be_updated
|> Map.put(key, updated_object[key])
+ |> Maps.put_if_present("votersCount", updated_object["votersCount"])
else
# Choices (or vote type) have changed, do not allow this
_ -> to_be_updated
diff --git a/lib/pleroma/web/activity_pub/object_validators/bite_validator.ex b/lib/pleroma/web/activity_pub/object_validators/bite_validator.ex
index a2e0bac85e..51e58640e3 100644
--- a/lib/pleroma/web/activity_pub/object_validators/bite_validator.ex
+++ b/lib/pleroma/web/activity_pub/object_validators/bite_validator.ex
@@ -38,7 +38,7 @@ defp validate_data(cng) do
|> validate_required([:id, :type, :actor, :to, :target])
|> validate_inclusion(:type, ["Bite"])
|> validate_actor_presence()
- |> validate_actor_presence(field_name: :target)
+ |> validate_object_or_user_presence(field_name: :target)
end
def cast_and_validate(data) do
diff --git a/lib/pleroma/web/activity_pub/object_validators/event_validator.ex b/lib/pleroma/web/activity_pub/object_validators/event_validator.ex
index 08a1db7a1f..e8abe6d70f 100644
--- a/lib/pleroma/web/activity_pub/object_validators/event_validator.ex
+++ b/lib/pleroma/web/activity_pub/object_validators/event_validator.ex
@@ -78,7 +78,7 @@ def changeset(struct, data, meta) do
defp validate_data(data_cng, _meta) do
data_cng
|> validate_inclusion(:type, ["Event"])
- |> validate_inclusion(:joinMode, ~w[free restricted invite])
+ |> validate_inclusion(:joinMode, ~w[free restricted invite external])
|> validate_required([:id, :actor, :attributedTo, :type, :context])
|> CommonValidations.validate_any_presence([:cc, :to])
|> CommonValidations.validate_fields_match([:actor, :attributedTo])
diff --git a/lib/pleroma/web/activity_pub/transmogrifier.ex b/lib/pleroma/web/activity_pub/transmogrifier.ex
index c5fe2fa56a..aa0276b2bf 100644
--- a/lib/pleroma/web/activity_pub/transmogrifier.ex
+++ b/lib/pleroma/web/activity_pub/transmogrifier.ex
@@ -498,6 +498,32 @@ def handle_incoming(
end
end
+ def handle_incoming(
+ %{"type" => "Bite", "target" => target_id} = data,
+ _options
+ ) do
+ target_id =
+ cond do
+ %User{ap_id: actor_id} = User.get_by_ap_id(target_id) ->
+ actor_id
+
+ %Object{data: data} = Object.get_by_ap_id(target_id) ->
+ data["actor"] || data["attributedTo"]
+
+ true ->
+ target_id
+ end
+
+ with data = Map.put(data, "target", target_id),
+ :ok <- ObjectValidator.fetch_actor_and_object(data),
+ {:ok, activity, _meta} <-
+ Pipeline.common_pipeline(data, local: false) do
+ {:ok, activity}
+ else
+ e -> {:error, e}
+ end
+ end
+
def handle_incoming(%{"type" => type} = data, _options)
when type in ~w{Like EmojiReact Announce Add Remove} do
with :ok <- ObjectValidator.fetch_actor_and_object(data),
diff --git a/lib/pleroma/web/activity_pub/utils.ex b/lib/pleroma/web/activity_pub/utils.ex
index 6b2983d9d8..19b1438717 100644
--- a/lib/pleroma/web/activity_pub/utils.ex
+++ b/lib/pleroma/web/activity_pub/utils.ex
@@ -1070,6 +1070,7 @@ def fetch_latest_bite(
|> maybe_exclude_activity_id(exclude_activity)
|> Activity.Queries.by_object_id(bitten_ap_id)
|> order_by([activity], fragment("? desc nulls last", activity.id))
+ |> exclude_rejected()
|> limit(1)
|> Repo.one()
end
@@ -1080,4 +1081,14 @@ defp maybe_exclude_activity_id(query, %Activity{id: activity_id}) do
query
|> where([a], a.id != ^activity_id)
end
+
+ defp exclude_rejected(query) do
+ rejected_activities =
+ "Reject"
+ |> Activity.Queries.by_type()
+ |> select([a], fragment("?->>'object'", a.data))
+
+ query
+ |> where([a], fragment("?->>'id'", a.data) not in subquery(rejected_activities))
+ end
end
diff --git a/lib/pleroma/web/mastodon_api/controllers/bite_controller.ex b/lib/pleroma/web/mastodon_api/controllers/bite_controller.ex
index 69d865cb9b..b9b1310103 100644
--- a/lib/pleroma/web/mastodon_api/controllers/bite_controller.ex
+++ b/lib/pleroma/web/mastodon_api/controllers/bite_controller.ex
@@ -9,14 +9,13 @@ defmodule Pleroma.Web.MastodonAPI.BiteController do
alias Pleroma.Web.CommonAPI
alias Pleroma.Web.Plugs.OAuthScopesPlug
- # alias Pleroma.Web.Plugs.RateLimiter
+ alias Pleroma.Web.Plugs.RateLimiter
plug(Pleroma.Web.ApiSpec.CastAndValidate, replace_params: false)
- plug(OAuthScopesPlug, %{scopes: ["write:bite"]} when action == :bite)
+ plug(OAuthScopesPlug, %{scopes: ["write:bites"]} when action == :bite)
- # plug(RateLimiter, [name: :relations_actions] when action in @relationship_actions)
- # plug(RateLimiter, [name: :app_account_creation] when action == :create)
+ plug(RateLimiter, name: :bites)
plug(:assign_account_by_id)
diff --git a/mix.exs b/mix.exs
index dd1076cf27..80d1237d0f 100644
--- a/mix.exs
+++ b/mix.exs
@@ -20,10 +20,10 @@ def project do
deps: deps(),
test_coverage: [tool: :covertool, summary: true],
# Docs
- homepage_url: "https://github.com/mkljczk/pleroma",
- source_url: "https://github.com/mkljczk/pleroma",
+ homepage_url: "https://github.com/mkljczk/pl",
+ source_url: "https://github.com/mkljczk/pl",
docs: [
- source_url_pattern: "https://github.com/mkljczk/pleroma/blob/develop/%{path}#L%{line}",
+ source_url_pattern: "https://github.com/mkljczk/pl/blob/develop/%{path}#L%{line}",
logo: "priv/static/images/logo.png",
extras: ["README.md", "CHANGELOG.md"] ++ Path.wildcard("docs/**/*.md"),
groups_for_extras: [
diff --git a/priv/static/instance/static.css b/priv/static/instance/static.css
index 183f9156dd..f3b77aaa6b 100644
Binary files a/priv/static/instance/static.css and b/priv/static/instance/static.css differ
diff --git a/priv/static/schemas/litepub-0.1.jsonld b/priv/static/schemas/litepub-0.1.jsonld
index 921c373af1..5a9e5c4bdc 100644
--- a/priv/static/schemas/litepub-0.1.jsonld
+++ b/priv/static/schemas/litepub-0.1.jsonld
@@ -44,6 +44,7 @@
"formerRepresentations": "litepub:formerRepresentations",
"sm": "http://smithereen.software/ns#",
"nonAnonymous": "sm:nonAnonymous",
+<<<<<<< HEAD
"votersCount": "toot:votersCount",
"mz": "https://joinmobilizon.org/ns#",
"joinMode": {
@@ -67,6 +68,8 @@
"@id": "schema:location",
"@type": "schema:Place"
},
+=======
+>>>>>>> bites-pleroma
"Bite": "https://ns.mia.jetzt/as#Bite"
}
]
diff --git a/test/pleroma/web/activity_pub/object_validators/bite_validator_test.exs b/test/pleroma/web/activity_pub/object_validators/bite_validator_test.exs
new file mode 100644
index 0000000000..94e433d5af
--- /dev/null
+++ b/test/pleroma/web/activity_pub/object_validators/bite_validator_test.exs
@@ -0,0 +1,51 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2024 Pleroma Authors
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.ActivityPub.ObjectValidators.BiteValidationTest do
+ use Pleroma.DataCase, async: true
+
+ alias Pleroma.Web.ActivityPub.ObjectValidator
+ alias Pleroma.Web.ActivityPub.ObjectValidators.BiteValidator
+ alias Pleroma.Web.ActivityPub.Utils
+ alias Pleroma.Web.CommonAPI
+
+ import Pleroma.Factory
+
+ describe "bites" do
+ setup do
+ biting = insert(:user)
+ bitten = insert(:user)
+
+ valid_bite = %{
+ "id" => Utils.generate_activity_id(),
+ "type" => "Bite",
+ "actor" => biting.ap_id,
+ "target" => bitten.ap_id,
+ "to" => [bitten.ap_id]
+ }
+
+ %{valid_bite: valid_bite, biting: biting, bitten: bitten}
+ end
+
+ test "returns ok when called in the ObjectValidator", %{valid_bite: valid_bite} do
+ {:ok, object, _meta} = ObjectValidator.validate(valid_bite, [])
+
+ assert "id" in Map.keys(object)
+ end
+
+ test "is valid for a valid object", %{valid_bite: valid_bite} do
+ assert BiteValidator.cast_and_validate(valid_bite).valid?
+ end
+
+ test "is valid when biting an object", %{valid_bite: valid_bite, bitten: bitten} do
+ {:ok, activity} = CommonAPI.post(bitten, %{status: "uguu"})
+
+ valid_bite =
+ valid_bite
+ |> Map.put("target", activity.data["object"])
+
+ assert BiteValidator.cast_and_validate(valid_bite).valid?
+ end
+ end
+end
diff --git a/test/pleroma/web/mastodon_api/controllers/bite_controller_test.exs b/test/pleroma/web/mastodon_api/controllers/bite_controller_test.exs
new file mode 100644
index 0000000000..96cd38e762
--- /dev/null
+++ b/test/pleroma/web/mastodon_api/controllers/bite_controller_test.exs
@@ -0,0 +1,30 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2024 Pleroma Authors
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.MastodonAPI.BiteControllerTest do
+ use Pleroma.Web.ConnCase
+ import Pleroma.Factory
+
+ setup do: oauth_access(["write:bites"])
+
+ test "bites a user", %{conn: conn} do
+ %{id: bitten_id} = insert(:user)
+
+ response =
+ conn
+ |> post("/api/v1/bite?id=#{bitten_id}")
+ |> json_response_and_validate_schema(200)
+
+ assert response == %{}
+ end
+
+ test "self harm is not supported", %{conn: conn, user: %{id: self_id}} do
+ response =
+ conn
+ |> post("/api/v1/bite?id=#{self_id}")
+ |> json_response_and_validate_schema(400)
+
+ assert %{"error" => "Can not bite yourself"} = response
+ end
+end