diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 8f1839c42..09ce2efd9 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -169,25 +169,6 @@ unit-testing-1.12-erratic:
- mix ecto.migrate
- mix test --only=erratic
-unit-testing-1.12-rum:
- extends:
- - .build_changes_policy
- - .using-ci-base
- stage: test
- cache: *testing_cache_policy
- services:
- - name: git.pleroma.social:5050/pleroma/pleroma/postgres-with-rum-13
- alias: postgres
- command: ["postgres", "-c", "fsync=off", "-c", "synchronous_commit=off", "-c", "full_page_writes=off"]
- variables:
- <<: *global_variables
- RUM_ENABLED: "true"
- script:
- - mix ecto.create
- - mix ecto.migrate
- - "mix ecto.migrate --migrations-path priv/repo/optional_migrations/rum_indexing/"
- - mix test --preload-modules
-
formatting-1.13:
extends: .build_changes_policy
image: &formatting_elixir elixir:1.13-alpine
diff --git a/changelog.d/backups-follows.add b/changelog.d/backups-follows.add
new file mode 100644
index 000000000..a55c436f6
--- /dev/null
+++ b/changelog.d/backups-follows.add
@@ -0,0 +1 @@
+Include following/followers in backups
\ No newline at end of file
diff --git a/changelog.d/exile-freebsd.skip b/changelog.d/exile-freebsd.skip
new file mode 100644
index 000000000..e69de29bb
diff --git a/changelog.d/force-mention-mrf.add b/changelog.d/force-mention-mrf.add
new file mode 100644
index 000000000..46ac14244
--- /dev/null
+++ b/changelog.d/force-mention-mrf.add
@@ -0,0 +1 @@
+Add ForceMention MRF
\ No newline at end of file
diff --git a/changelog.d/framegrabs.fix b/changelog.d/framegrabs.fix
new file mode 100644
index 000000000..dc0466f1b
--- /dev/null
+++ b/changelog.d/framegrabs.fix
@@ -0,0 +1 @@
+Video framegrabs were not working correctly after the change to use Exile to execute ffmpeg
diff --git a/changelog.d/gun_pool2.fix b/changelog.d/gun_pool2.fix
new file mode 100644
index 000000000..a1f98b49c
--- /dev/null
+++ b/changelog.d/gun_pool2.fix
@@ -0,0 +1 @@
+Connection pool errors when publishing an activity is a soft-error that will be retried shortly.
diff --git a/changelog.d/gun_pool3.skip b/changelog.d/gun_pool3.skip
new file mode 100644
index 000000000..e69de29bb
diff --git a/changelog.d/instance-contact-account.add b/changelog.d/instance-contact-account.add
new file mode 100644
index 000000000..e119446d2
--- /dev/null
+++ b/changelog.d/instance-contact-account.add
@@ -0,0 +1 @@
+Add contact account to InstanceView
\ No newline at end of file
diff --git a/changelog.d/instance-v2.skip b/changelog.d/instance-v2.skip
new file mode 100644
index 000000000..e69de29bb
diff --git a/changelog.d/issue-3241.fix b/changelog.d/issue-3241.fix
new file mode 100644
index 000000000..d46db9805
--- /dev/null
+++ b/changelog.d/issue-3241.fix
@@ -0,0 +1 @@
+Handle cases when users.inbox is nil.
diff --git a/changelog.d/link-verification.add b/changelog.d/link-verification.add
new file mode 100644
index 000000000..d8b11ebbc
--- /dev/null
+++ b/changelog.d/link-verification.add
@@ -0,0 +1 @@
+Verify profile link ownership with rel="me"
\ No newline at end of file
diff --git a/changelog.d/notifications.fix b/changelog.d/notifications.fix
new file mode 100644
index 000000000..a2d2eaea9
--- /dev/null
+++ b/changelog.d/notifications.fix
@@ -0,0 +1 @@
+Notifications: improve performance by filtering on users table instead of activities table
\ No newline at end of file
diff --git a/changelog.d/public-polls.add b/changelog.d/public-polls.add
new file mode 100644
index 000000000..0dae0c38e
--- /dev/null
+++ b/changelog.d/public-polls.add
@@ -0,0 +1 @@
+Expose nonAnonymous field from Smithereen polls
\ No newline at end of file
diff --git a/changelog.d/remote-fetcher-error.skip b/changelog.d/remote-fetcher-error.skip
new file mode 100644
index 000000000..e69de29bb
diff --git a/config/config.exs b/config/config.exs
index 435387a64..d0496cef8 100644
--- a/config/config.exs
+++ b/config/config.exs
@@ -415,6 +415,10 @@ config :pleroma, :mrf_follow_bot, follower_nickname: nil
config :pleroma, :mrf_inline_quote, template: "RT: {url}"
+config :pleroma, :mrf_force_mention,
+ mention_parent: true,
+ mention_quoted: true
+
config :pleroma, :rich_media,
enabled: true,
ignore_hosts: [],
diff --git a/config/description.exs b/config/description.exs
index 78e7710cb..7a9c027de 100644
--- a/config/description.exs
+++ b/config/description.exs
@@ -566,6 +566,20 @@ config :pleroma, :config_description, [
"Cool instance"
]
},
+ %{
+ key: :status_page,
+ type: :string,
+ description: "A page where people can see the status of the server during an outage",
+ suggestions: [
+ "https://status.pleroma.example.org"
+ ]
+ },
+ %{
+ key: :contact_username,
+ type: :string,
+ description: "Instance owner username",
+ suggestions: ["admin"]
+ },
%{
key: :limit,
type: :integer,
diff --git a/docs/configuration/cheatsheet.md b/docs/configuration/cheatsheet.md
index 7bba7b26e..89a461b47 100644
--- a/docs/configuration/cheatsheet.md
+++ b/docs/configuration/cheatsheet.md
@@ -161,7 +161,8 @@ To add configuration to your config file, you can copy it from the base config.
* `Pleroma.Web.ActivityPub.MRF.KeywordPolicy`: Rejects or removes from the federated timeline or replaces keywords. (See [`:mrf_keyword`](#mrf_keyword)).
* `Pleroma.Web.ActivityPub.MRF.ForceMentionsInContent`: Forces every mentioned user to be reflected in the post content.
* `Pleroma.Web.ActivityPub.MRF.InlineQuotePolicy`: Forces quote post URLs to be reflected in the message content inline.
- * `Pleroma.Web.ActivityPub.MRF.QuoteToLinkTagPolicy`: Force a Link tag for posts quoting another post. (may break outgoing federation of quote posts with older Pleroma versions)
+ * `Pleroma.Web.ActivityPub.MRF.QuoteToLinkTagPolicy`: Force a Link tag for posts quoting another post. (may break outgoing federation of quote posts with older Pleroma versions).
+ * `Pleroma.Web.ActivityPub.MRF.ForceMention`: Forces posts to include a mention of the author of parent post or the author of quoted post.
* `transparency`: Make the content of your Message Rewrite Facility settings public (via nodeinfo).
* `transparency_exclusions`: Exclude specific instance names from MRF transparency. The use of the exclusions feature will be disclosed in nodeinfo as a boolean value.
@@ -272,6 +273,10 @@ Notes:
#### :mrf_inline_quote
* `template`: The template to append to the post. `{url}` will be replaced with the actual link to the quoted post. Default: `RT: {url}`
+#### :mrf_force_mention
+* `mention_parent`: Whether to append mention of parent post author
+* `mention_quoted`: Whether to append mention of parent quoted author
+
### :activitypub
* `unfollow_blocked`: Whether blocks result in people getting unfollowed
* `outgoing_blocks`: Whether to federate blocks to other instances
diff --git a/docs/development/API/differences_in_mastoapi_responses.md b/docs/development/API/differences_in_mastoapi_responses.md
index d72717483..e3b6a3c77 100644
--- a/docs/development/API/differences_in_mastoapi_responses.md
+++ b/docs/development/API/differences_in_mastoapi_responses.md
@@ -40,6 +40,7 @@ Has these additional fields under the `pleroma` object:
- `parent_visible`: If the parent of this post is visible to the user or not.
- `pinned_at`: a datetime (iso8601) when status was pinned, `null` otherwise.
- `quotes_count`: the count of status quotes.
+- `non_anonymous`: true if the source post specifies the poll results are not anonymous. Currently only implemented by Smithereen.
- `bookmark_folder`: the ID of the folder bookmark is stored within (if any).
The `GET /api/v1/statuses/:id/source` endpoint additionally has the following attributes:
diff --git a/lib/pleroma/following_relationship.ex b/lib/pleroma/following_relationship.ex
index 15664c876..f38c2fce9 100644
--- a/lib/pleroma/following_relationship.ex
+++ b/lib/pleroma/following_relationship.ex
@@ -241,13 +241,13 @@ defmodule Pleroma.FollowingRelationship do
end
@doc """
- For a query with joined activity,
- keeps rows where activity's actor is followed by user -or- is NOT domain-blocked by user.
+ For a query with joined activity's actor,
+ keeps rows where actor is followed by user -or- is NOT domain-blocked by user.
"""
def keep_following_or_not_domain_blocked(query, user) do
where(
query,
- [_, activity],
+ [_, user_actor: user_actor],
fragment(
# "(actor's domain NOT in domain_blocks) OR (actor IS in followed AP IDs)"
"""
@@ -255,9 +255,9 @@ defmodule Pleroma.FollowingRelationship do
? = ANY(SELECT ap_id FROM users AS u INNER JOIN following_relationships AS fr
ON u.id = fr.following_id WHERE fr.follower_id = ? AND fr.state = ?)
""",
- activity.actor,
+ user_actor.ap_id,
^user.domain_blocks,
- activity.actor,
+ user_actor.ap_id,
^User.binary_id(user.id),
^accept_state_code()
)
diff --git a/lib/pleroma/gun/connection_pool/worker_supervisor.ex b/lib/pleroma/gun/connection_pool/worker_supervisor.ex
index 24ad61117..eb83962d8 100644
--- a/lib/pleroma/gun/connection_pool/worker_supervisor.ex
+++ b/lib/pleroma/gun/connection_pool/worker_supervisor.ex
@@ -18,10 +18,10 @@ defmodule Pleroma.Gun.ConnectionPool.WorkerSupervisor do
)
end
- def start_worker(opts, retry \\ false) do
+ def start_worker(opts, last_attempt \\ false) do
case DynamicSupervisor.start_child(__MODULE__, {Pleroma.Gun.ConnectionPool.Worker, opts}) do
{:error, :max_children} ->
- funs = [fn -> !retry end, fn -> match?(:error, free_pool()) end]
+ funs = [fn -> last_attempt end, fn -> match?(:error, free_pool()) end]
if Enum.any?(funs, fn fun -> fun.() end) do
:telemetry.execute([:pleroma, :connection_pool, :provision_failure], %{opts: opts})
diff --git a/lib/pleroma/helpers/media_helper.ex b/lib/pleroma/helpers/media_helper.ex
index 1a414b37f..7864296fa 100644
--- a/lib/pleroma/helpers/media_helper.ex
+++ b/lib/pleroma/helpers/media_helper.ex
@@ -40,28 +40,32 @@ defmodule Pleroma.Helpers.MediaHelper do
end
# Note: video thumbnail is intentionally not resized (always has original dimensions)
+ @spec video_framegrab(String.t()) :: {:ok, binary()} | {:error, any()}
def video_framegrab(url) do
with executable when is_binary(executable) <- System.find_executable("ffmpeg"),
{:ok, env} <- HTTP.get(url, [], pool: :media),
{:ok, pid} <- StringIO.open(env.body) do
body_stream = IO.binstream(pid, 1)
- Exile.stream!(
- [
- executable,
- "-i",
- "pipe:0",
- "-vframes",
- "1",
- "-f",
- "mjpeg",
- "pipe:1"
- ],
- input: body_stream,
- ignore_epipe: true,
- stderr: :disable
- )
- |> Enum.into(<<>>)
+ result =
+ Exile.stream!(
+ [
+ executable,
+ "-i",
+ "pipe:0",
+ "-vframes",
+ "1",
+ "-f",
+ "mjpeg",
+ "pipe:1"
+ ],
+ input: body_stream,
+ ignore_epipe: true,
+ stderr: :disable
+ )
+ |> Enum.into(<<>>)
+
+ {:ok, result}
else
nil -> {:error, {:ffmpeg, :command_not_found}}
{:error, _} = error -> error
diff --git a/lib/pleroma/notification.ex b/lib/pleroma/notification.ex
index 368e609d2..710b19866 100644
--- a/lib/pleroma/notification.ex
+++ b/lib/pleroma/notification.ex
@@ -137,7 +137,7 @@ defmodule Pleroma.Notification do
blocked_ap_ids = opts[:blocked_users_ap_ids] || User.blocked_users_ap_ids(user)
query
- |> where([n, a], a.actor not in ^blocked_ap_ids)
+ |> where([..., user_actor: user_actor], user_actor.ap_id not in ^blocked_ap_ids)
|> FollowingRelationship.keep_following_or_not_domain_blocked(user)
end
@@ -148,7 +148,7 @@ defmodule Pleroma.Notification do
blocker_ap_ids = User.incoming_relationships_ungrouped_ap_ids(user, [:block])
query
- |> where([n, a], a.actor not in ^blocker_ap_ids)
+ |> where([..., user_actor: user_actor], user_actor.ap_id not in ^blocker_ap_ids)
end
end
@@ -161,7 +161,7 @@ defmodule Pleroma.Notification do
opts[:notification_muted_users_ap_ids] || User.notification_muted_users_ap_ids(user)
query
- |> where([n, a], a.actor not in ^notification_muted_ap_ids)
+ |> where([..., user_actor: user_actor], user_actor.ap_id not in ^notification_muted_ap_ids)
|> join(:left, [n, a], tm in ThreadMute,
on: tm.user_id == ^user.id and tm.context == fragment("?->>'context'", a.data),
as: :thread_mute
diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex
index 0773434c5..778e20526 100644
--- a/lib/pleroma/user.ex
+++ b/lib/pleroma/user.ex
@@ -8,6 +8,7 @@ defmodule Pleroma.User do
import Ecto.Changeset
import Ecto.Query
import Ecto, only: [assoc: 2]
+ import Pleroma.Web.Utils.Guards, only: [not_empty_string: 1]
alias Ecto.Multi
alias Pleroma.Activity
@@ -596,9 +597,23 @@ defmodule Pleroma.User do
defp put_fields(changeset) do
if raw_fields = get_change(changeset, :raw_fields) do
+ old_fields = changeset.data.raw_fields
+
raw_fields =
raw_fields
|> Enum.filter(fn %{"name" => n} -> n != "" end)
+ |> Enum.map(fn field ->
+ previous =
+ old_fields
+ |> Enum.find(fn %{"value" => value} -> field["value"] == value end)
+
+ if previous && Map.has_key?(previous, "verified_at") do
+ field
+ |> Map.put("verified_at", previous["verified_at"])
+ else
+ field
+ end
+ end)
fields =
raw_fields
@@ -1200,6 +1215,10 @@ defmodule Pleroma.User do
def update_and_set_cache(changeset) do
with {:ok, user} <- Repo.update(changeset, stale_error_field: :id) do
+ if get_change(changeset, :raw_fields) do
+ BackgroundWorker.enqueue("verify_fields_links", %{"user_id" => user.id})
+ end
+
set_cache(user)
end
end
@@ -1975,8 +1994,45 @@ defmodule Pleroma.User do
maybe_delete_from_db(user)
end
+ def perform(:verify_fields_links, user) do
+ profile_urls = [user.ap_id]
+
+ fields =
+ user.raw_fields
+ |> Enum.map(&verify_field_link(&1, profile_urls))
+
+ changeset =
+ user
+ |> update_changeset(%{raw_fields: fields})
+
+ with {:ok, user} <- Repo.update(changeset, stale_error_field: :id) do
+ set_cache(user)
+ end
+ end
+
def perform(:set_activation_async, user, status), do: set_activation(user, status)
+ defp verify_field_link(field, profile_urls) do
+ verified_at =
+ with %{"value" => value} <- field,
+ {:verified_at, nil} <- {:verified_at, Map.get(field, "verified_at")},
+ %{scheme: scheme, userinfo: nil, host: host}
+ when not_empty_string(host) and scheme in ["http", "https"] <-
+ URI.parse(value),
+ {:not_idn, true} <- {:not_idn, to_string(:idna.encode(host)) == host},
+ "me" <- Pleroma.Web.RelMe.maybe_put_rel_me(value, profile_urls) do
+ CommonUtils.to_masto_date(NaiveDateTime.utc_now())
+ else
+ {:verified_at, value} when not_empty_string(value) ->
+ value
+
+ _ ->
+ nil
+ end
+
+ Map.put(field, "verified_at", verified_at)
+ end
+
@spec external_users_query() :: Ecto.Query.t()
def external_users_query do
User.Query.build(%{
@@ -2664,10 +2720,11 @@ defmodule Pleroma.User do
# - display name
def sanitize_html(%User{} = user, filter) do
fields =
- Enum.map(user.fields, fn %{"name" => name, "value" => value} ->
+ Enum.map(user.fields, fn %{"name" => name, "value" => value} = fields ->
%{
"name" => name,
- "value" => HTML.filter_tags(value, Pleroma.HTML.Scrubber.LinksOnly)
+ "value" => HTML.filter_tags(value, Pleroma.HTML.Scrubber.LinksOnly),
+ "verified_at" => Map.get(fields, "verified_at")
}
end)
diff --git a/lib/pleroma/user/backup.ex b/lib/pleroma/user/backup.ex
index b7f00bbf7..65e0baccd 100644
--- a/lib/pleroma/user/backup.ex
+++ b/lib/pleroma/user/backup.ex
@@ -196,7 +196,14 @@ defmodule Pleroma.User.Backup do
end
end
- @files ['actor.json', 'outbox.json', 'likes.json', 'bookmarks.json']
+ @files [
+ 'actor.json',
+ 'outbox.json',
+ 'likes.json',
+ 'bookmarks.json',
+ 'followers.json',
+ 'following.json'
+ ]
@spec export(Pleroma.User.Backup.t(), pid()) :: {:ok, String.t()} | :error
def export(%__MODULE__{} = backup, caller_pid) do
backup = Repo.preload(backup, :user)
@@ -207,6 +214,8 @@ defmodule Pleroma.User.Backup do
:ok <- statuses(dir, backup.user, caller_pid),
:ok <- likes(dir, backup.user, caller_pid),
:ok <- bookmarks(dir, backup.user, caller_pid),
+ :ok <- followers(dir, backup.user, caller_pid),
+ :ok <- following(dir, backup.user, caller_pid),
{:ok, zip_path} <- :zip.create(backup.file_name, @files, cwd: dir),
{:ok, _} <- File.rm_rf(dir) do
{:ok, zip_path}
@@ -357,6 +366,16 @@ defmodule Pleroma.User.Backup do
caller_pid
)
end
+
+ defp followers(dir, user, caller_pid) do
+ User.get_followers_query(user)
+ |> write(dir, "followers", fn a -> {:ok, a.ap_id} end, caller_pid)
+ end
+
+ defp following(dir, user, caller_pid) do
+ User.get_friends_query(user)
+ |> write(dir, "following", fn a -> {:ok, a.ap_id} end, caller_pid)
+ end
end
defmodule Pleroma.User.Backup.ProcessorAPI do
diff --git a/lib/pleroma/web/activity_pub/mrf/force_mention.ex b/lib/pleroma/web/activity_pub/mrf/force_mention.ex
new file mode 100644
index 000000000..3853489fc
--- /dev/null
+++ b/lib/pleroma/web/activity_pub/mrf/force_mention.ex
@@ -0,0 +1,59 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2024 Pleroma Authors
здесь тоже можно что-то написать отдельно от опроса
","published":"2021-09-04T00:22:16Z","url":"https://friends.grishka.me/posts/54642","to":["https://www.w3.org/ns/activitystreams#Public"],"cc":["https://friends.grishka.me/users/1/followers"],"replies":{"type":"Collection","id":"https://friends.grishka.me/posts/54642/replies","first":{"type":"CollectionPage","items":[],"partOf":"https://friends.grishka.me/posts/54642/replies","next":"https://friends.grishka.me/posts/54642/replies?page=1"}},"sensitive":false,"likes":"https://friends.grishka.me/posts/54642/likes","name":"тестовый опрос","oneOf":[{"type":"Note","id":"https://friends.grishka.me/posts/54642#options/76","name":"тестовый ответ 1","replies":{"type":"Collection","id":"https://friends.grishka.me/activitypub/objects/polls/24/options/76/votes","totalItems":4,"items":[]}},{"type":"Note","id":"https://friends.grishka.me/posts/54642#options/77","name":"тестовый ответ 2","replies":{"type":"Collection","id":"https://friends.grishka.me/activitypub/objects/polls/24/options/77/votes","totalItems":4,"items":[]}},{"type":"Note","id":"https://friends.grishka.me/posts/54642#options/78","name":"тестовый ответ 3","replies":{"type":"Collection","id":"https://friends.grishka.me/activitypub/objects/polls/24/options/78/votes","totalItems":6,"items":[]}}],"votersCount":14,"nonAnonymous":true,"@context":["https://www.w3.org/ns/activitystreams",{"sensitive":"as:sensitive","toot":"http://joinmastodon.org/ns#","sm":"http://smithereen.software/ns#","votersCount":"toot:votersCount","nonAnonymous":"sm:nonAnonymous"}]} \ No newline at end of file diff --git a/test/fixtures/tesla_mock/smithereen_user.json b/test/fixtures/tesla_mock/smithereen_user.json new file mode 100644 index 000000000..6468fc519 --- /dev/null +++ b/test/fixtures/tesla_mock/smithereen_user.json @@ -0,0 +1 @@ +{"type":"Person","id":"https://friends.grishka.me/users/1","name":"Григорий Клюшников","icon":{"type":"Image","image":{"type":"Image","url":"https://friends.grishka.me/i/6QLsOws97AWp5N_osd74C1IC1ijnFopyCBD9MSEeXNQ/q:93/bG9jYWw6Ly8vcy91cGxvYWRzL2F2YXRhcnMvNTYzODRhODEwODk5ZTRjMzI4YmY4YmQwM2Q2MWM3NmMud2VicA.jpg","mediaType":"image/jpeg","width":1280,"height":960},"width":573,"height":572,"cropRegion":[0.26422762870788574,0.3766937553882599,0.7113820910453796,0.9728997349739075],"url":"https://friends.grishka.me/i/ql_49PQcETAWgY_nC-Qj63H_Oa6FyOAEoWFkUSSkUvQ/c:573:572:nowe:338:362/q:93/bG9jYWw6Ly8vcy91cGxvYWRzL2F2YXRhcnMvNTYzODRhODEwODk5ZTRjMzI4YmY4YmQwM2Q2MWM3NmMud2VicA.jpg","mediaType":"image/jpeg"},"summary":"Делаю эту хрень, пытаюсь вырвать социальные сети из жадных лап корпораций
\n\n\n\n\n\n\n\nThis server does NOT support direct messages. Please write me on Telegram or Matrix.
","url":"https://friends.grishka.me/grishka","preferredUsername":"grishka","inbox":"https://friends.grishka.me/users/1/inbox","outbox":"https://friends.grishka.me/users/1/outbox","followers":"https://friends.grishka.me/users/1/followers","following":"https://friends.grishka.me/users/1/following","endpoints":{"sharedInbox":"https://friends.grishka.me/activitypub/sharedInbox","collectionSimpleQuery":"https://friends.grishka.me/users/1/collectionQuery"},"publicKey":{"id":"https://friends.grishka.me/users/1#main-key","owner":"https://friends.grishka.me/users/1","publicKeyPem":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAjlakm+i/d9ER/hIeR7KfiFW+SdLZj2SkKIeM8cmR+YFJuh9ghFqXrkFEjcaqUnAFqe5gYDNSQACnDLA8y4DnzjfGNIohKAnRoa9x6GORmfKQvcnjaTZ53S1NvUiPPyc0Pv/vfCtY/Ab0CEXe5BLqL38oZn817Jf7pBrPRTYH7m012kvwAUTT6k0Y8lPITBEG7nzYbbuGcrN9Y/RDdwE08jmBXlZ45bahRH3VNXVpQE17dCzJB+7k+iJ1R7YCoI+DuMlBYGXGE2KVk46NZTuLnOjFV9SyXfWX4/SrJM4oxev+SX2N75tQgmNZmVVHeqg2ZcbC0WCfNjJOi2HHS9MujwIDAQAB\n-----END PUBLIC KEY-----\n"},"wall":"https://friends.grishka.me/users/1/wall","firstName":"Григорий","lastName":"Клюшников","middleName":"Александрович","vcard:bday":"1993-01-22","gender":"http://schema.org#Male","supportsFriendRequests":true,"friends":"https://friends.grishka.me/users/1/friends","groups":"https://friends.grishka.me/users/1/groups","capabilities":{"supportsFriendRequests":true},"@context":["https://www.w3.org/ns/activitystreams",{"sm":"http://smithereen.software/ns#","cropRegion":{"@id":"sm:cropRegion","@container":"@list"},"wall":{"@id":"sm:wall","@type":"@id"},"collectionSimpleQuery":"sm:collectionSimpleQuery","sc":"http://schema.org#","firstName":"sc:givenName","lastName":"sc:familyName","middleName":"sc:additionalName","gender":{"@id":"sc:gender","@type":"sc:GenderType"},"maidenName":"sm:maidenName","friends":{"@id":"sm:friends","@type":"@id"},"groups":{"@id":"sm:groups","@type":"@id"},"vcard":"http://www.w3.org/2006/vcard/ns#","capabilities":"litepub:capabilities","supportsFriendRequests":"sm:supportsFriendRequests","litepub":"http://litepub.social/ns#"},"https://w3id.org/security/v1"]} \ No newline at end of file diff --git a/test/pleroma/user/backup_test.exs b/test/pleroma/user/backup_test.exs index 0ac57e334..5503d15bc 100644 --- a/test/pleroma/user/backup_test.exs +++ b/test/pleroma/user/backup_test.exs @@ -166,6 +166,7 @@ defmodule Pleroma.User.BackupTest do test "it creates a zip archive with user data" do user = insert(:user, %{nickname: "cofe", name: "Cofe", ap_id: "http://cofe.io/users/cofe"}) + %{ap_id: other_ap_id} = other_user = insert(:user) {:ok, %{object: %{data: %{"id" => id1}}} = status1} = CommonAPI.post(user, %{status: "status1"}) @@ -182,6 +183,8 @@ defmodule Pleroma.User.BackupTest do Bookmark.create(user.id, status2.id) Bookmark.create(user.id, status3.id) + CommonAPI.follow(user, other_user) + assert {:ok, backup} = user |> Backup.new() |> Repo.insert() assert {:ok, path} = Backup.export(backup, self()) assert {:ok, zipfile} = :zip.zip_open(String.to_charlist(path), [:memory]) @@ -261,6 +264,16 @@ defmodule Pleroma.User.BackupTest do "type" => "OrderedCollection" } = Jason.decode!(json) + assert {:ok, {'following.json', json}} = :zip.zip_get('following.json', zipfile) + + assert %{ + "@context" => "https://www.w3.org/ns/activitystreams", + "id" => "following.json", + "orderedItems" => [^other_ap_id], + "totalItems" => 1, + "type" => "OrderedCollection" + } = Jason.decode!(json) + :zip.zip_close(zipfile) File.rm!(path) end diff --git a/test/pleroma/user_test.exs b/test/pleroma/user_test.exs index 15809ad63..a93f81659 100644 --- a/test/pleroma/user_test.exs +++ b/test/pleroma/user_test.exs @@ -2928,4 +2928,51 @@ defmodule Pleroma.UserTest do refute User.endorses?(user, pinned_user) end end + + test "it checks fields links for a backlink" do + user = insert(:user, ap_id: "https://social.example.org/users/lain") + + fields = [ + %{"name" => "Link", "value" => "http://example.com/rel_me/null"}, + %{"name" => "Verified link", "value" => "http://example.com/rel_me/link"}, + %{"name" => "Not a link", "value" => "i'm not a link"} + ] + + user + |> User.update_and_set_cache(%{raw_fields: fields}) + + ObanHelpers.perform_all() + + user = User.get_cached_by_id(user.id) + + assert [ + %{"verified_at" => nil}, + %{"verified_at" => verified_at}, + %{"verified_at" => nil} + ] = user.fields + + assert is_binary(verified_at) + end + + test "updating fields does not invalidate previously validated links" do + user = insert(:user, ap_id: "https://social.example.org/users/lain") + + user + |> User.update_and_set_cache(%{ + raw_fields: [%{"name" => "verified link", "value" => "http://example.com/rel_me/link"}] + }) + + ObanHelpers.perform_all() + + %User{fields: [%{"verified_at" => verified_at}]} = user = User.get_cached_by_id(user.id) + + user + |> User.update_and_set_cache(%{ + raw_fields: [%{"name" => "Verified link", "value" => "http://example.com/rel_me/link"}] + }) + + user = User.get_cached_by_id(user.id) + + assert [%{"verified_at" => ^verified_at}] = user.fields + end end diff --git a/test/pleroma/web/activity_pub/mrf/force_mention_test.exs b/test/pleroma/web/activity_pub/mrf/force_mention_test.exs new file mode 100644 index 000000000..b026bab66 --- /dev/null +++ b/test/pleroma/web/activity_pub/mrf/force_mention_test.exs @@ -0,0 +1,73 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2024 Pleroma Authors